diff options
author | Caolán McNamara <caolanm@redhat.com> | 2019-03-26 16:27:17 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2019-03-28 22:07:06 +0100 |
commit | 3e078e17ee2144fb976a7e6b9227152113cea0d4 (patch) | |
tree | 01faab7d3c82c5b027b42a6722700736b249a775 /sfx2 | |
parent | 1e2868296730d3548574f61a3c6e323aa5c0598a (diff) |
weld SfxTemplateManagerDlg
like expert configuration change the gear menu not to display a down indicator
and use CommandEvent to distinguish mouse/non-mouse context menus
Change-Id: I64bb660a9c7dacb5b90b240d9d76d29324c5fd9f
Reviewed-on: https://gerrit.libreoffice.org/69893
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sfx2')
-rw-r--r-- | sfx2/source/appl/appopen.cxx | 6 | ||||
-rw-r--r-- | sfx2/source/appl/appserv.cxx | 4 | ||||
-rw-r--r-- | sfx2/source/control/emojiviewitem.cxx | 2 | ||||
-rw-r--r-- | sfx2/source/control/recentdocsviewitem.cxx | 7 | ||||
-rw-r--r-- | sfx2/source/control/templatelocalview.cxx | 888 | ||||
-rw-r--r-- | sfx2/source/control/templatesearchview.cxx | 143 | ||||
-rw-r--r-- | sfx2/source/control/templateviewitem.cxx | 2 | ||||
-rw-r--r-- | sfx2/source/control/thumbnailview.cxx | 1176 | ||||
-rw-r--r-- | sfx2/source/control/thumbnailviewacc.cxx | 560 | ||||
-rw-r--r-- | sfx2/source/control/thumbnailviewacc.hxx | 112 | ||||
-rw-r--r-- | sfx2/source/control/thumbnailviewitem.cxx | 2 | ||||
-rw-r--r-- | sfx2/source/dialog/inputdlg.cxx | 2 | ||||
-rw-r--r-- | sfx2/source/doc/templatedlg.cxx | 690 | ||||
-rw-r--r-- | sfx2/source/inc/templatesearchview.hxx | 13 | ||||
-rw-r--r-- | sfx2/source/inc/templatesearchviewitem.hxx | 2 | ||||
-rw-r--r-- | sfx2/uiconfig/ui/templatedlg.ui | 170 |
16 files changed, 3234 insertions, 545 deletions
diff --git a/sfx2/source/appl/appopen.cxx b/sfx2/source/appl/appopen.cxx index 4a655f940d4c..0c5288289098 100644 --- a/sfx2/source/appl/appopen.cxx +++ b/sfx2/source/appl/appopen.cxx @@ -448,12 +448,12 @@ void SfxApplication::NewDocExec_Impl( SfxRequest& rReq ) if(pCurrentShell) xModel = pCurrentShell->GetModel(); - ScopedVclPtrInstance< SfxTemplateManagerDlg > aTemplDlg; + SfxTemplateManagerDlg aTemplDlg(rReq.GetFrameWeld()); if (xModel.is()) - aTemplDlg->setDocumentModel(xModel); + aTemplDlg.setDocumentModel(xModel); - int nRet = aTemplDlg->Execute(); + int nRet = aTemplDlg.run(); if ( nRet == RET_OK ) { rReq.Done(); diff --git a/sfx2/source/appl/appserv.cxx b/sfx2/source/appl/appserv.cxx index d2ac03b9c2ac..bfe3fb24abc3 100644 --- a/sfx2/source/appl/appserv.cxx +++ b/sfx2/source/appl/appserv.cxx @@ -660,8 +660,8 @@ void SfxApplication::MiscExec_Impl( SfxRequest& rReq ) case SID_TEMPLATE_MANAGER: { - ScopedVclPtrInstance< SfxTemplateManagerDlg > dlg; - dlg->Execute(); + SfxTemplateManagerDlg aDialog(rReq.GetFrameWeld()); + aDialog.run(); bDone = true; break; } diff --git a/sfx2/source/control/emojiviewitem.cxx b/sfx2/source/control/emojiviewitem.cxx index e4f1e701363e..f393738d045f 100644 --- a/sfx2/source/control/emojiviewitem.cxx +++ b/sfx2/source/control/emojiviewitem.cxx @@ -27,7 +27,7 @@ using namespace basegfx::utils; using namespace drawinglayer::attribute; using namespace drawinglayer::primitive2d; -EmojiViewItem::EmojiViewItem (ThumbnailView &rView, sal_uInt16 nId) +EmojiViewItem::EmojiViewItem (ThumbnailViewBase &rView, sal_uInt16 nId) : ThumbnailViewItem(rView, nId) { } diff --git a/sfx2/source/control/recentdocsviewitem.cxx b/sfx2/source/control/recentdocsviewitem.cxx index f1992285e782..cddbe57ae500 100644 --- a/sfx2/source/control/recentdocsviewitem.cxx +++ b/sfx2/source/control/recentdocsviewitem.cxx @@ -32,9 +32,10 @@ using namespace com::sun::star::uno; using namespace drawinglayer::primitive2d; using namespace drawinglayer::processor2d; -RecentDocsViewItem::RecentDocsViewItem(ThumbnailView &rView, const OUString &rURL, +RecentDocsViewItem::RecentDocsViewItem(sfx2::RecentDocsView &rView, const OUString &rURL, const OUString &rTitle, const BitmapEx &rThumbnail, sal_uInt16 nId, long nThumbnailSize) : ThumbnailViewItem(rView, nId), + mrParentView(rView), maURL(rURL), m_bRemoveIconHighlighted(false), m_aRemoveRecentBitmap(BMP_RECENTDOC_REMOVE), @@ -178,7 +179,7 @@ void RecentDocsViewItem::MouseButtonUp(const MouseEvent& rMEvt) void RecentDocsViewItem::OpenDocument() { // show busy mouse pointer - mrParent.SetPointer(PointerStyle::Wait); + mrParentView.SetPointer(PointerStyle::Wait); Reference<frame::XDispatch> xDispatch; Reference<frame::XDispatchProvider> xDispatchProvider; @@ -216,7 +217,7 @@ void RecentDocsViewItem::OpenDocument() pLoadRecentFile->xDispatch = xDispatch; pLoadRecentFile->aTargetURL = aTargetURL; pLoadRecentFile->aArgSeq = aArgsList; - pLoadRecentFile->pView.set(&mrParent); + pLoadRecentFile->pView = &mrParentView; Application::PostUserEvent(LINK(nullptr, sfx2::RecentDocsView, ExecuteHdl_Impl), pLoadRecentFile, true); } diff --git a/sfx2/source/control/templatelocalview.cxx b/sfx2/source/control/templatelocalview.cxx index d15109f8943b..816448a3b298 100644 --- a/sfx2/source/control/templatelocalview.cxx +++ b/sfx2/source/control/templatelocalview.cxx @@ -96,8 +96,6 @@ TemplateLocalView::TemplateLocalView ( vcl::Window* pParent, WinBits nWinStyle) { } -VCL_BUILDER_FACTORY(TemplateLocalView) - TemplateLocalView::~TemplateLocalView() { disposeOnce(); @@ -1017,4 +1015,890 @@ void TemplateLocalView::OnItemDblClicked (ThumbnailViewItem *pItem) maOpenTemplateHdl.Call(pViewItem); } +SfxTemplateLocalView::SfxTemplateLocalView(std::unique_ptr<weld::ScrolledWindow> xWindow, + std::unique_ptr<weld::Menu> xMenu) + : SfxThumbnailView(std::move(xWindow), std::move(xMenu)) + , mnCurRegionId(0) + , maSelectedItem(nullptr) + , mnThumbnailWidth(TEMPLATE_THUMBNAIL_MAX_WIDTH) + , mnThumbnailHeight(TEMPLATE_THUMBNAIL_MAX_HEIGHT) + , maPosition(0,0) + , mpDocTemplates(new SfxDocumentTemplates) +{ +} + +SfxTemplateLocalView::~SfxTemplateLocalView() +{ +} + +void SfxTemplateLocalView::Populate() +{ + maRegions.clear(); + maAllTemplates.clear(); + + sal_uInt16 nCount = mpDocTemplates->GetRegionCount(); + for (sal_uInt16 i = 0; i < nCount; ++i) + { + OUString aRegionName(mpDocTemplates->GetFullRegionName(i)); + + std::unique_ptr<TemplateContainerItem> pItem(new TemplateContainerItem( i+1 )); + pItem->mnRegionId = i; + pItem->maTitle = aRegionName; + + sal_uInt16 nEntries = mpDocTemplates->GetCount(i); + + for (sal_uInt16 j = 0; j < nEntries; ++j) + { + OUString aName = mpDocTemplates->GetName(i,j); + OUString aURL = mpDocTemplates->GetPath(i,j); + + TemplateItemProperties aProperties; + aProperties.nId = j+1; + aProperties.nDocId = j; + aProperties.nRegionId = i; + aProperties.aName = aName; + aProperties.aPath = aURL; + aProperties.aRegionName = aRegionName; + aProperties.aThumbnail = TemplateLocalView::fetchThumbnail(aURL, + mnThumbnailWidth, + mnThumbnailHeight); + + pItem->maTemplates.push_back(aProperties); + maAllTemplates.push_back(aProperties); + } + + maRegions.push_back(std::move(pItem)); + } +} + +void SfxTemplateLocalView::reload() +{ + mpDocTemplates->Update(); + + Populate(); + + // Check if we are currently browsing a region or root folder + if (mnCurRegionId) + { + sal_uInt16 nRegionId = mnCurRegionId - 1; //Is offset by 1 + + for (auto const & pRegion : maRegions) + { + if (pRegion->mnRegionId == nRegionId) + { + showRegion(pRegion.get()); + break; + } + } + } + else + showAllTemplates(); + + //No items should be selected by default + deselectItems(); +} + +void SfxTemplateLocalView::showAllTemplates() +{ + mnCurRegionId = 0; + + insertItems(maAllTemplates, false, true); + + maOpenRegionHdl.Call(nullptr); +} + +void SfxTemplateLocalView::showRegion(TemplateContainerItem const *pItem) +{ + mnCurRegionId = pItem->mnRegionId+1; + + insertItems(pItem->maTemplates); + + maOpenRegionHdl.Call(nullptr); +} + +void SfxTemplateLocalView::showRegion(const OUString &rName) +{ + for (auto const & pRegion : maRegions) + { + if (pRegion->maTitle == rName) + { + showRegion(pRegion.get()); + break; + } + } +} + +TemplateContainerItem* SfxTemplateLocalView::getRegion(OUString const & rName) +{ + for (auto const & pRegion : maRegions) + if (pRegion->maTitle == rName) + return pRegion.get(); + + return nullptr; +} + +void SfxTemplateLocalView::createContextMenu(const bool bIsDefault) +{ + mxContextMenu->clear(); + mxContextMenu->append("open",SfxResId(STR_OPEN)); + mxContextMenu->append("edit",SfxResId(STR_EDIT_TEMPLATE)); + + if(!bIsDefault) + mxContextMenu->append("default",SfxResId(STR_DEFAULT_TEMPLATE)); + else + mxContextMenu->append("default",SfxResId(STR_RESET_DEFAULT)); + + mxContextMenu->append_separator("separator"); + mxContextMenu->append("rename",SfxResId(STR_RENAME)); + mxContextMenu->append("delete",SfxResId(STR_DELETE)); + deselectItems(); + maSelectedItem->setSelection(true); + maItemStateHdl.Call(maSelectedItem); + ContextMenuSelectHdl(mxContextMenu->popup_at_rect(GetDrawingArea(), tools::Rectangle(maPosition, Size(1,1)))); + Invalidate(); +} + +void SfxTemplateLocalView::ContextMenuSelectHdl(const OString& rIdent) +{ + if (rIdent == "open") + maOpenTemplateHdl.Call(maSelectedItem); + else if (rIdent == "edit") + maEditTemplateHdl.Call(maSelectedItem); + else if (rIdent == "rename") + { + InputDialog aTitleEditDlg(GetDrawingArea(), SfxResId(STR_RENAME_TEMPLATE)); + OUString sOldTitle = maSelectedItem->getTitle(); + aTitleEditDlg.SetEntryText(sOldTitle); + aTitleEditDlg.HideHelpBtn(); + + if (!aTitleEditDlg.run()) + return; + OUString sNewTitle = comphelper::string::strip(aTitleEditDlg.GetEntryText(), ' '); + + if ( !sNewTitle.isEmpty() && sNewTitle != sOldTitle ) + { + maSelectedItem->setTitle(sNewTitle); + } + } + else if (rIdent == "delete") + { + std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question, VclButtonsType::YesNo, + SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE))); + if (xQueryDlg->run() != RET_YES) + return; + + maDeleteTemplateHdl.Call(maSelectedItem); + reload(); + } + else if (rIdent == "default") + maDefaultTemplateHdl.Call(maSelectedItem); +} + +sal_uInt16 SfxTemplateLocalView::getRegionId(size_t pos) const +{ + assert(pos < maRegions.size()); + + return maRegions[pos]->mnId; +} + +sal_uInt16 SfxTemplateLocalView::getRegionId(OUString const & sRegion) const +{ + for (auto const & pRegion : maRegions) + { + if (pRegion->maTitle == sRegion) + return pRegion->mnId; + } + + return 0; +} + +OUString SfxTemplateLocalView::getRegionName(const sal_uInt16 nRegionId) const +{ + return mpDocTemplates->GetRegionName(nRegionId); +} + +OUString SfxTemplateLocalView::getRegionItemName(const sal_uInt16 nItemId) const +{ + for (auto const & pRegion : maRegions) + { + if (pRegion->mnId == nItemId) + return pRegion->maTitle; + } + + return OUString(); +} + +std::vector<OUString> SfxTemplateLocalView::getFolderNames() +{ + size_t n = maRegions.size(); + std::vector<OUString> ret(n); + + for (size_t i = 0; i < n; ++i) + ret[i] = maRegions[i]->maTitle; + + return ret; +} + +std::vector<TemplateItemProperties> +SfxTemplateLocalView::getFilteredItems(const std::function<bool (const TemplateItemProperties&)> &rFunc) const +{ + std::vector<TemplateItemProperties> aItems; + + if (mnCurRegionId) + { + TemplateContainerItem *pFolderItem = maRegions[mnCurRegionId-1].get(); + + for (TemplateItemProperties & rItemProps : pFolderItem->maTemplates) + { + if (rFunc(rItemProps)) + aItems.push_back(rItemProps); + } + } + else + { + for (auto const & pFolderItem : maRegions) + { + for (const TemplateItemProperties & rItemProps : pFolderItem->maTemplates) + { + if (rFunc(rItemProps)) + aItems.push_back(rItemProps); + } + } + } + + return aItems; +} + +sal_uInt16 SfxTemplateLocalView::createRegion(const OUString &rName) +{ + sal_uInt16 nRegionId = mpDocTemplates->GetRegionCount(); // Next regionId + sal_uInt16 nItemId = getNextItemId(); + + if (!mpDocTemplates->InsertDir(rName,nRegionId)) + return 0; + + // Insert to the region cache list and to the thumbnail item list + std::unique_ptr<TemplateContainerItem> pItem(new TemplateContainerItem( nItemId )); + pItem->mnRegionId = nRegionId; + pItem->maTitle = rName; + + maRegions.push_back(std::move(pItem)); + + return nItemId; +} + +bool SfxTemplateLocalView::renameRegion(const OUString &rTitle, const OUString &rNewTitle) +{ + TemplateContainerItem *pRegion = getRegion(rTitle); + + if(pRegion) + { + sal_uInt16 nRegionId = pRegion->mnRegionId; + return mpDocTemplates->SetName( rNewTitle, nRegionId, USHRT_MAX/*nDocId*/ ); + } + return false; +} + +bool SfxTemplateLocalView::removeRegion(const sal_uInt16 nItemId) +{ + sal_uInt16 nRegionId = USHRT_MAX; + + // Remove from the region cache list + for (auto pRegionIt = maRegions.begin(); pRegionIt != maRegions.end();) + { + if ( (*pRegionIt)->mnId == nItemId ) + { + if (!mpDocTemplates->Delete((*pRegionIt)->mnRegionId,USHRT_MAX)) + return false; + + nRegionId = (*pRegionIt)->mnRegionId; + + pRegionIt = maRegions.erase(pRegionIt); + } + else + { + // Synchronize regions cache ids with SfxDocumentTemplates + if (nRegionId != USHRT_MAX && (*pRegionIt)->mnRegionId > nRegionId) + --(*pRegionIt)->mnRegionId; + + ++pRegionIt; + } + } + + if (nRegionId == USHRT_MAX) + return false; + + // Synchronize view regions ids with SfxDocumentTemplates + for (auto const& region : maRegions) + { + if (region->mnRegionId > nRegionId) + --region->mnRegionId; + } + + return true; +} + +bool SfxTemplateLocalView::removeTemplate (const sal_uInt16 nItemId, const sal_uInt16 nSrcItemId) +{ + for (auto const & pRegion : maRegions) + { + if (pRegion->mnId == nSrcItemId) + { + TemplateContainerItem *pItem = pRegion.get(); + auto pIter = std::find_if(pItem->maTemplates.begin(), pItem->maTemplates.end(), + [nItemId](const TemplateItemProperties& rTemplate) { return rTemplate.nId == nItemId; }); + if (pIter != pItem->maTemplates.end()) + { + if (!mpDocTemplates->Delete(pItem->mnRegionId,pIter->nDocId)) + return false; + + pIter = pItem->maTemplates.erase(pIter); + + if (pRegion->mnRegionId == mnCurRegionId-1) + { + RemoveItem(nItemId); + Invalidate(); + } + + // Update Doc Idx for all templates that follow + for (; pIter != pItem->maTemplates.end(); ++pIter) + pIter->nDocId = pIter->nDocId - 1; + } + + CalculateItemPositions(); + break; + } + } + + return true; +} + +bool SfxTemplateLocalView::moveTemplate (const ThumbnailViewItem *pItem, const sal_uInt16 nSrcItem, + const sal_uInt16 nTargetItem) +{ + TemplateContainerItem *pTarget = nullptr; + TemplateContainerItem *pSrc = nullptr; + + for (auto const & pRegion : maRegions) + { + if (pRegion->mnId == nTargetItem) + pTarget = pRegion.get(); + else if (pRegion->mnId == nSrcItem) + pSrc = pRegion.get(); + } + + if (pTarget && pSrc) + { + sal_uInt16 nSrcRegionId = pSrc->mnRegionId; + sal_uInt16 nTargetRegion = pTarget->mnRegionId; + sal_uInt16 nTargetIdx = mpDocTemplates->GetCount(nTargetRegion); // Next Idx + + const TemplateViewItem *pViewItem = static_cast<const TemplateViewItem*>(pItem); + + bool bCopy = !mpDocTemplates->Move(nTargetRegion,nTargetIdx,nSrcRegionId,pViewItem->mnDocId); + + if (bCopy) + { + OUString sQuery = SfxResId(STR_MSG_QUERY_COPY).replaceFirst("$1", pViewItem->maTitle).replaceFirst("$2", + getRegionName(nTargetRegion)); + + std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question, VclButtonsType::YesNo, sQuery)); + if (xQueryDlg->run() != RET_YES) + return false; + + if (!mpDocTemplates->Copy(nTargetRegion,nTargetIdx,nSrcRegionId,pViewItem->mnDocId)) + return false; + } + // move template to destination + + TemplateItemProperties aTemplateItem; + aTemplateItem.nId = nTargetIdx + 1; + aTemplateItem.nDocId = nTargetIdx; + aTemplateItem.nRegionId = nTargetRegion; + aTemplateItem.aName = pViewItem->maTitle; + aTemplateItem.aPath = mpDocTemplates->GetPath(nTargetRegion,nTargetIdx); + aTemplateItem.aRegionName = pViewItem->maHelpText; + aTemplateItem.aThumbnail = pViewItem->maPreview1; + + pTarget->maTemplates.push_back(aTemplateItem); + + if (!bCopy) + { + // remove template from region cached data + + std::vector<TemplateItemProperties>::iterator aIter; + for (aIter = pSrc->maTemplates.begin(); aIter != pSrc->maTemplates.end();) + { + if (aIter->nDocId == pViewItem->mnDocId) + { + aIter = pSrc->maTemplates.erase(aIter); + } + else + { + // Keep region document id synchronized with SfxDocumentTemplates + if (aIter->nDocId > pViewItem->mnDocId) + --aIter->nDocId; + + ++aIter; + } + } + + // Keep view document id synchronized with SfxDocumentTemplates + for (auto const& item : mItemList) + { + auto pTemplateViewItem = static_cast<TemplateViewItem*>(item.get()); + if (pTemplateViewItem->mnDocId > pViewItem->mnDocId) + --pTemplateViewItem->mnDocId; + } + } + + CalculateItemPositions(); + Invalidate(); + + return true; + } + + return false; +} + +void SfxTemplateLocalView::moveTemplates(const std::set<const ThumbnailViewItem*, selection_cmp_fn> &rItems, + const sal_uInt16 nTargetItem) +{ + TemplateContainerItem *pTarget = nullptr; + TemplateContainerItem *pSrc = nullptr; + + for (auto const & pRegion : maRegions) + { + if (pRegion->mnId == nTargetItem) + pTarget = pRegion.get(); + } + + if (!pTarget) + return; + + bool refresh = false; + + sal_uInt16 nTargetRegion = pTarget->mnRegionId; + sal_uInt16 nTargetIdx = mpDocTemplates->GetCount(nTargetRegion); // Next Idx + std::vector<sal_uInt16> aItemIds; // List of moved items ids (also prevents the invalidation of rItems iterators when we remove them as we go) + + std::set<const ThumbnailViewItem*,selection_cmp_fn>::const_iterator aSelIter; + for ( aSelIter = rItems.begin(); aSelIter != rItems.end(); ++aSelIter, ++nTargetIdx ) + { + const TemplateViewItem *pViewItem = static_cast<const TemplateViewItem*>(*aSelIter); + sal_uInt16 nSrcRegionId = pViewItem->mnRegionId; + + for (auto const & pRegion : maRegions) + { + if (pRegion->mnRegionId == nSrcRegionId) + pSrc = pRegion.get(); + } + + if(pSrc) + { + bool bCopy = !mpDocTemplates->Move(nTargetRegion,nTargetIdx,nSrcRegionId,pViewItem->mnDocId); + + if (bCopy) + { + OUString sQuery = SfxResId(STR_MSG_QUERY_COPY).replaceFirst("$1", pViewItem->maTitle).replaceFirst("$2", + getRegionName(nTargetRegion)); + std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question, VclButtonsType::YesNo, sQuery)); + if (xQueryDlg->run() != RET_YES) + { + OUString sMsg(SfxResId(STR_MSG_ERROR_LOCAL_MOVE)); + sMsg = sMsg.replaceFirst("$1",getRegionName(nTargetRegion)); + std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetDrawingArea(), + VclMessageType::Warning, VclButtonsType::Ok, sMsg.replaceFirst( "$2",pViewItem->maTitle))); + xBox->run(); + + return; //return if any single move operation fails + } + + if (!mpDocTemplates->Copy(nTargetRegion,nTargetIdx,nSrcRegionId,pViewItem->mnDocId)) + { + continue; + } + } + + // move template to destination + + TemplateItemProperties aTemplateItem; + aTemplateItem.nId = nTargetIdx + 1; + aTemplateItem.nDocId = nTargetIdx; + aTemplateItem.nRegionId = nTargetRegion; + aTemplateItem.aName = pViewItem->maTitle; + aTemplateItem.aPath = mpDocTemplates->GetPath(nTargetRegion,nTargetIdx); + aTemplateItem.aRegionName = pViewItem->maHelpText; + aTemplateItem.aThumbnail = pViewItem->maPreview1; + + pTarget->maTemplates.push_back(aTemplateItem); + + if (!bCopy) + { + // remove template from region cached data + + std::vector<TemplateItemProperties>::iterator pPropIter; + for (pPropIter = pSrc->maTemplates.begin(); pPropIter != pSrc->maTemplates.end();) + { + if (pPropIter->nDocId == pViewItem->mnDocId) + { + pPropIter = pSrc->maTemplates.erase(pPropIter); + aItemIds.push_back(pViewItem->mnDocId + 1);//mnid + } + else + { + // Keep region document id synchronized with SfxDocumentTemplates + if (pPropIter->nDocId > pViewItem->mnDocId) + --pPropIter->nDocId; + + ++pPropIter; + } + } + + // Keep view document id synchronized with SfxDocumentTemplates + for (auto const& item : mItemList) + { + auto pTemplateViewItem = static_cast<TemplateViewItem*>(item.get()); + if (pTemplateViewItem->mnDocId > pViewItem->mnDocId) + --pTemplateViewItem->mnDocId; + } + } + } + + refresh = true; + } + + // Remove items from the current view + for (auto const& itemId : aItemIds) + RemoveItem(itemId); + + if (refresh) + { + CalculateItemPositions(); + Invalidate(); + } +} + +bool SfxTemplateLocalView::copyFrom (TemplateContainerItem *pItem, const OUString &rPath) +{ + sal_uInt16 nId = 1; + sal_uInt16 nDocId = 0; + sal_uInt16 nRegionId = pItem->mnRegionId; + OUString aPath(rPath); + + if (!pItem->maTemplates.empty()) + { + nId = pItem->maTemplates.back().nId+1; + nDocId = pItem->maTemplates.back().nDocId+1; + } + + if (mpDocTemplates->CopyFrom(nRegionId,nDocId,aPath)) + { + TemplateItemProperties aTemplate; + aTemplate.nId = nId; + aTemplate.nDocId = nDocId; + aTemplate.nRegionId = nRegionId; + aTemplate.aName = aPath; + aTemplate.aThumbnail = SfxTemplateLocalView::fetchThumbnail(rPath, + TEMPLATE_THUMBNAIL_MAX_WIDTH, + TEMPLATE_THUMBNAIL_MAX_HEIGHT); + aTemplate.aPath = rPath; + aTemplate.aRegionName = getRegionName(nRegionId); + + pItem->maTemplates.push_back(aTemplate); + + CalculateItemPositions(); + + return true; + } + + return false; +} + +bool SfxTemplateLocalView::exportTo(const sal_uInt16 nItemId, const sal_uInt16 nRegionItemId, const OUString &rName) +{ + for (auto const & pRegItem : maRegions) + { + if (pRegItem->mnId == nRegionItemId) + { + for (auto const& elem : pRegItem->maTemplates) + { + if (elem.nId == nItemId) + { + return mpDocTemplates->CopyTo(pRegItem->mnRegionId,elem.nDocId,rName); + } + } + + break; + } + } + + return false; +} + +bool SfxTemplateLocalView::renameItem(ThumbnailViewItem* pItem, const OUString& sNewTitle) +{ + sal_uInt16 nRegionId = 0; + sal_uInt16 nDocId = USHRT_MAX; + TemplateViewItem* pDocItem = dynamic_cast<TemplateViewItem*>( pItem ); + + if ( pDocItem ) + { + nRegionId = pDocItem->mnRegionId; + nDocId = pDocItem->mnDocId; + } + + return mpDocTemplates->SetName( sNewTitle, nRegionId, nDocId ); +} + +void SfxTemplateLocalView::insertItems(const std::vector<TemplateItemProperties> &rTemplates, bool isRegionSelected, bool bShowCategoryInTooltip) +{ + std::vector<std::unique_ptr<ThumbnailViewItem>> aItems(rTemplates.size()); + for (size_t i = 0, n = rTemplates.size(); i < n; ++i ) + { + const TemplateItemProperties *pCur = &rTemplates[i]; + + std::unique_ptr<TemplateViewItem> pChild; + if(isRegionSelected) + pChild.reset(new TemplateViewItem(*this, pCur->nId)); + else + pChild.reset(new TemplateViewItem(*this, i+1)); + + pChild->mnDocId = pCur->nDocId; + pChild->mnRegionId = pCur->nRegionId; + pChild->maTitle = pCur->aName; + pChild->setPath(pCur->aPath); + + if(!bShowCategoryInTooltip) + pChild->setHelpText(pCur->aName); + else + { + OUString sHelpText = SfxResId(STR_TEMPLATE_TOOLTIP); + sHelpText = (sHelpText.replaceFirst("$1", pCur->aName)).replaceFirst("$2", pCur->aRegionName); + pChild->setHelpText(sHelpText); + } + + pChild->maPreview1 = pCur->aThumbnail; + + if(IsDefaultTemplate(pCur->aPath)) + pChild->showDefaultIcon(true); + + if ( pCur->aThumbnail.IsEmpty() ) + { + // Use the default thumbnail if we have nothing else + pChild->maPreview1 = SfxTemplateLocalView::getDefaultThumbnail(pCur->aPath); + } + + aItems[i] = std::move(pChild); + } + + updateItems(std::move(aItems)); +} + +void SfxTemplateLocalView::updateThumbnailDimensions(long itemMaxSize) +{ + mnThumbnailWidth = itemMaxSize; + mnThumbnailHeight = itemMaxSize; +} + +bool SfxTemplateLocalView::MouseButtonDown( const MouseEvent& rMEvt ) +{ + GrabFocus(); + return SfxThumbnailView::MouseButtonDown(rMEvt); +} + +bool SfxTemplateLocalView::ContextMenu(const CommandEvent& rCEvt) +{ + if (rCEvt.IsMouseEvent()) + { + deselectItems(); + size_t nPos = ImplGetItem(rCEvt.GetMousePosPixel()); + Point aPosition(rCEvt.GetMousePosPixel()); + maPosition = aPosition; + ThumbnailViewItem* pItem = ImplGetItem(nPos); + const TemplateViewItem *pViewItem = dynamic_cast<const TemplateViewItem*>(pItem); + + if(pViewItem) + { + maSelectedItem = dynamic_cast<TemplateViewItem*>(pItem); + maCreateContextMenuHdl.Call(pItem); + } + } + else + { + for (ThumbnailViewItem* pItem : mFilteredItemList) + { + //create context menu for the first selected item + if (pItem->isSelected()) + { + deselectItems(); + pItem->setSelection(true); + maItemStateHdl.Call(pItem); + tools::Rectangle aRect = pItem->getDrawArea(); + maPosition = aRect.Center(); + maSelectedItem = dynamic_cast<TemplateViewItem*>(pItem); + maCreateContextMenuHdl.Call(pItem); + break; + } + } + } + return true; +} + +bool SfxTemplateLocalView::KeyInput( const KeyEvent& rKEvt ) +{ + vcl::KeyCode aKeyCode = rKEvt.GetKeyCode(); + + if(aKeyCode == ( KEY_MOD1 | KEY_A ) ) + { + for (ThumbnailViewItem* pItem : mFilteredItemList) + { + if (!pItem->isSelected()) + { + pItem->setSelection(true); + maItemStateHdl.Call(pItem); + } + } + + if (IsReallyVisible() && IsUpdateMode()) + Invalidate(); + return true; + } + else if( aKeyCode == KEY_DELETE && !mFilteredItemList.empty()) + { + std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question, VclButtonsType::YesNo, + SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE))); + if (xQueryDlg->run() != RET_YES) + return true; + + //copy to avoid changing filtered item list during deletion + ThumbnailValueItemList mFilteredItemListCopy = mFilteredItemList; + + for (ThumbnailViewItem* pItem : mFilteredItemListCopy) + { + if (pItem->isSelected()) + { + maDeleteTemplateHdl.Call(pItem); + } + } + reload(); + } + + return SfxThumbnailView::KeyInput(rKEvt); +} + +void SfxTemplateLocalView::setOpenRegionHdl(const Link<void*,void> &rLink) +{ + maOpenRegionHdl = rLink; +} + +void SfxTemplateLocalView::setCreateContextMenuHdl(const Link<ThumbnailViewItem*,void> &rLink) +{ + maCreateContextMenuHdl = rLink; +} + +void SfxTemplateLocalView::setOpenTemplateHdl(const Link<ThumbnailViewItem*,void> &rLink) +{ + maOpenTemplateHdl = rLink; +} + +void SfxTemplateLocalView::setEditTemplateHdl(const Link<ThumbnailViewItem*,void> &rLink) +{ + maEditTemplateHdl = rLink; +} + +void SfxTemplateLocalView::setDeleteTemplateHdl(const Link<ThumbnailViewItem*,void> &rLink) +{ + maDeleteTemplateHdl = rLink; +} + +void SfxTemplateLocalView::setDefaultTemplateHdl(const Link<ThumbnailViewItem*,void> &rLink) +{ + maDefaultTemplateHdl = rLink; +} + +BitmapEx SfxTemplateLocalView::scaleImg (const BitmapEx &rImg, long width, long height) +{ + BitmapEx aImg = rImg; + + if (!rImg.IsEmpty()) + { + Size aSize = rImg.GetSizePixel(); + + if (aSize.Width() == 0) + aSize.setWidth( 1 ); + + if (aSize.Height() == 0) + aSize.setHeight( 1 ); + + // make the picture fit the given width/height constraints + double nRatio = std::min(double(width)/double(aSize.Width()), double(height)/double(aSize.Height())); + + aImg.Scale(Size(aSize.Width() * nRatio, aSize.Height() * nRatio)); + } + + return aImg; +} + +bool SfxTemplateLocalView::IsDefaultTemplate(const OUString& rPath) +{ + SvtModuleOptions aModOpt; + const css::uno::Sequence<OUString> &aServiceNames = aModOpt.GetAllServiceNames(); + + for( sal_Int32 i=0, nCount = aServiceNames.getLength(); i < nCount; ++i ) + { + const OUString defaultPath = SfxObjectFactory::GetStandardTemplate( aServiceNames[i] ); + if(defaultPath.match(rPath)) + return true; + } + + return false; +} + +void SfxTemplateLocalView::RemoveDefaultTemplateIcon(const OUString& rPath) +{ + for (std::unique_ptr<ThumbnailViewItem>& pItem : mItemList) + { + TemplateViewItem* pViewItem = dynamic_cast<TemplateViewItem*>(pItem.get()); + if (pViewItem && pViewItem->getPath().match(rPath)) + { + pViewItem->showDefaultIcon(false); + Invalidate(); + return; + } + } +} + +BitmapEx SfxTemplateLocalView::getDefaultThumbnail( const OUString& rPath ) +{ + BitmapEx aImg; + INetURLObject aUrl(rPath); + OUString aExt = aUrl.getExtension(); + + if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::WRITER, aExt) ) + aImg = BitmapEx(SFX_THUMBNAIL_TEXT); + else if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::CALC, aExt) ) + aImg = BitmapEx(SFX_THUMBNAIL_SHEET); + else if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::IMPRESS, aExt) ) + aImg = BitmapEx(SFX_THUMBNAIL_PRESENTATION); + else if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::DRAW, aExt) ) + aImg = BitmapEx(SFX_THUMBNAIL_DRAWING); + + return aImg; +} + +BitmapEx SfxTemplateLocalView::fetchThumbnail (const OUString &msURL, long width, long height) +{ + return SfxTemplateLocalView::scaleImg(ThumbnailView::readThumbnail(msURL), width, height); +} + +void SfxTemplateLocalView::OnItemDblClicked (ThumbnailViewItem *pItem) +{ + TemplateViewItem* pViewItem = dynamic_cast<TemplateViewItem*>(pItem); + + if( pViewItem ) + maOpenTemplateHdl.Call(pViewItem); +} + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/source/control/templatesearchview.cxx b/sfx2/source/control/templatesearchview.cxx index 279b8bc596ad..97848d65e28a 100644 --- a/sfx2/source/control/templatesearchview.cxx +++ b/sfx2/source/control/templatesearchview.cxx @@ -22,27 +22,26 @@ #include <vcl/builderfactory.hxx> -#define MNI_OPEN 1 -#define MNI_EDIT 2 -#define MNI_DEFAULT_TEMPLATE 3 -#define MNI_DELETE 4 - -TemplateSearchView::TemplateSearchView (vcl::Window *pParent) - : ThumbnailView(pParent,WB_TABSTOP | WB_VSCROLL | WB_BORDER), - maSelectedItem(nullptr), - maPosition(0,0) +#define MNI_OPEN "open" +#define MNI_EDIT "edit" +#define MNI_DEFAULT_TEMPLATE "default" +#define MNI_DELETE "delete" + +TemplateSearchView::TemplateSearchView(std::unique_ptr<weld::ScrolledWindow> xWindow, + std::unique_ptr<weld::Menu> xMenu) + : SfxThumbnailView(std::move(xWindow), std::move(xMenu)) + , maSelectedItem(nullptr) + , maPosition(0,0) { } -VCL_BUILDER_FACTORY(TemplateSearchView) - -void TemplateSearchView::MouseButtonDown( const MouseEvent& rMEvt ) +bool TemplateSearchView::MouseButtonDown( const MouseEvent& rMEvt ) { GrabFocus(); - ThumbnailView::MouseButtonDown(rMEvt); + return SfxThumbnailView::MouseButtonDown(rMEvt); } -void TemplateSearchView::KeyInput( const KeyEvent& rKEvt ) +bool TemplateSearchView::KeyInput( const KeyEvent& rKEvt ) { vcl::KeyCode aKeyCode = rKEvt.GetKeyCode(); @@ -59,14 +58,14 @@ void TemplateSearchView::KeyInput( const KeyEvent& rKEvt ) if (IsReallyVisible() && IsUpdateMode()) Invalidate(); - return; + return true; } else if( aKeyCode == KEY_DELETE && !mFilteredItemList.empty()) { - std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo, + std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question, VclButtonsType::YesNo, SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE))); if (xQueryDlg->run() != RET_YES) - return; + return true; //copy to avoid changing filtered item list during deletion ThumbnailValueItemList mFilteredItemListCopy = mFilteredItemList; @@ -83,104 +82,86 @@ void TemplateSearchView::KeyInput( const KeyEvent& rKEvt ) } } - ThumbnailView::KeyInput(rKEvt); + return SfxThumbnailView::KeyInput(rKEvt); } -void TemplateSearchView::Command( const CommandEvent& rCEvt ) +bool TemplateSearchView::ContextMenu(const CommandEvent& rCEvt) { - if ( rCEvt.GetCommand() == CommandEventId::ContextMenu ) + if (rCEvt.IsMouseEvent()) { - if(rCEvt.IsMouseEvent()) + deselectItems(); + size_t nPos = ImplGetItem(rCEvt.GetMousePosPixel()); + Point aPosition(rCEvt.GetMousePosPixel()); + maPosition = aPosition; + ThumbnailViewItem* pItem = ImplGetItem(nPos); + const TemplateViewItem *pViewItem = dynamic_cast<const TemplateViewItem*>(pItem); + + if(pViewItem) { - deselectItems(); - size_t nPos = ImplGetItem(rCEvt.GetMousePosPixel()); - Point aPosition (rCEvt.GetMousePosPixel()); - maPosition = aPosition; - ThumbnailViewItem* pItem = ImplGetItem(nPos); - const TemplateViewItem *pViewItem = dynamic_cast<const TemplateViewItem*>(pItem); - - if(pViewItem) - { - maSelectedItem = dynamic_cast<TemplateViewItem*>(pItem); - maCreateContextMenuHdl.Call(pItem); - } + maSelectedItem = dynamic_cast<TemplateViewItem*>(pItem); + maCreateContextMenuHdl.Call(pItem); } - else + } + else + { + for (ThumbnailViewItem* pItem : mFilteredItemList) { - for (ThumbnailViewItem* pItem : mFilteredItemList) + //create context menu for the first selected item + if (pItem->isSelected()) { - //create context menu for the first selected item - if (pItem->isSelected()) - { - deselectItems(); - pItem->setSelection(true); - maItemStateHdl.Call(pItem); - tools::Rectangle aRect = pItem->getDrawArea(); - maPosition = aRect.Center(); - maSelectedItem = dynamic_cast<TemplateViewItem*>(pItem); - maCreateContextMenuHdl.Call(pItem); - break; - } + deselectItems(); + pItem->setSelection(true); + maItemStateHdl.Call(pItem); + tools::Rectangle aRect = pItem->getDrawArea(); + maPosition = aRect.Center(); + maSelectedItem = dynamic_cast<TemplateViewItem*>(pItem); + maCreateContextMenuHdl.Call(pItem); + break; } } } - - ThumbnailView::Command(rCEvt); + return true; } -void TemplateSearchView::createContextMenu( const bool bIsDefault) +void TemplateSearchView::createContextMenu(const bool bIsDefault) { - ScopedVclPtrInstance<PopupMenu> pItemMenu; - pItemMenu->InsertItem(MNI_OPEN,SfxResId(STR_OPEN)); - pItemMenu->InsertItem(MNI_EDIT,SfxResId(STR_EDIT_TEMPLATE)); + mxContextMenu->clear(); + mxContextMenu->append(MNI_OPEN,SfxResId(STR_OPEN)); + mxContextMenu->append(MNI_EDIT,SfxResId(STR_EDIT_TEMPLATE)); - if(!bIsDefault) - pItemMenu->InsertItem(MNI_DEFAULT_TEMPLATE,SfxResId(STR_DEFAULT_TEMPLATE)); + if (!bIsDefault) + mxContextMenu->append(MNI_DEFAULT_TEMPLATE,SfxResId(STR_DEFAULT_TEMPLATE)); else - pItemMenu->InsertItem(MNI_DEFAULT_TEMPLATE,SfxResId(STR_RESET_DEFAULT)); + mxContextMenu->append(MNI_DEFAULT_TEMPLATE,SfxResId(STR_RESET_DEFAULT)); - pItemMenu->InsertSeparator(); - pItemMenu->InsertItem(MNI_DELETE,SfxResId(STR_DELETE)); + mxContextMenu->append_separator("separator"); + mxContextMenu->append(MNI_DELETE,SfxResId(STR_DELETE)); maSelectedItem->setSelection(true); maItemStateHdl.Call(maSelectedItem); - pItemMenu->SetSelectHdl(LINK(this, TemplateSearchView, ContextMenuSelectHdl)); - pItemMenu->Execute(this, tools::Rectangle(maPosition,Size(1,1)), PopupMenuFlags::ExecuteDown); + ContextMenuSelectHdl(mxContextMenu->popup_at_rect(GetDrawingArea(), tools::Rectangle(maPosition, Size(1,1)))); Invalidate(); } -IMPL_LINK(TemplateSearchView, ContextMenuSelectHdl, Menu*, pMenu, bool) +void TemplateSearchView::ContextMenuSelectHdl(const OString& rIdent) { - sal_uInt16 nMenuId = pMenu->GetCurItemId(); - - switch(nMenuId) - { - case MNI_OPEN: + if (rIdent == MNI_OPEN) maOpenTemplateHdl.Call(maSelectedItem); - break; - case MNI_EDIT: + else if (rIdent == MNI_EDIT) maEditTemplateHdl.Call(maSelectedItem); - break; - case MNI_DELETE: + else if (rIdent == MNI_DELETE) { - std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo, + std::unique_ptr<weld::MessageDialog> xQueryDlg(Application::CreateMessageDialog(GetDrawingArea(), VclMessageType::Question, VclButtonsType::YesNo, SfxResId(STR_QMSG_SEL_TEMPLATE_DELETE))); if (xQueryDlg->run() != RET_YES) - break; + return; maDeleteTemplateHdl.Call(maSelectedItem); RemoveItem(maSelectedItem->mnId); CalculateItemPositions(); } - break; - case MNI_DEFAULT_TEMPLATE: + else if (rIdent == MNI_DEFAULT_TEMPLATE) maDefaultTemplateHdl.Call(maSelectedItem); - break; - default: - break; - } - - return false; } void TemplateSearchView::setCreateContextMenuHdl(const Link<ThumbnailViewItem*,void> &rLink) @@ -235,7 +216,7 @@ void TemplateSearchView::AppendItem(sal_uInt16 nAssocItemId, sal_uInt16 nRegionI if(TemplateLocalView::IsDefaultTemplate(rPath)) pItem->showDefaultIcon(true); - ThumbnailView::AppendItem(std::move(pItem)); + SfxThumbnailView::AppendItem(std::move(pItem)); CalculateItemPositions(); } diff --git a/sfx2/source/control/templateviewitem.cxx b/sfx2/source/control/templateviewitem.cxx index 6d6207554382..b6918de9445b 100644 --- a/sfx2/source/control/templateviewitem.cxx +++ b/sfx2/source/control/templateviewitem.cxx @@ -29,7 +29,7 @@ using namespace basegfx::utils; using namespace drawinglayer::attribute; using namespace drawinglayer::primitive2d; -TemplateViewItem::TemplateViewItem (ThumbnailView &rView, sal_uInt16 nId) +TemplateViewItem::TemplateViewItem (ThumbnailViewBase &rView, sal_uInt16 nId) : ThumbnailViewItem(rView, nId), mnRegionId(USHRT_MAX), mnDocId(USHRT_MAX), diff --git a/sfx2/source/control/thumbnailview.cxx b/sfx2/source/control/thumbnailview.cxx index 04c47f81ffc0..9c4986a16220 100644 --- a/sfx2/source/control/thumbnailview.cxx +++ b/sfx2/source/control/thumbnailview.cxx @@ -229,6 +229,11 @@ css::uno::Reference< css::accessibility::XAccessible > ThumbnailView::CreateAcce return new ThumbnailViewAcc( this ); } +css::uno::Reference< css::accessibility::XAccessible > ThumbnailView::getAccessible() +{ + return GetAccessible(); +} + void ThumbnailView::CalculateItemPositions (bool bScrollBarUsed) { if (!mnItemHeight || !mnItemWidth) @@ -1206,12 +1211,16 @@ void ThumbnailView::filterItems(const std::function<bool (const ThumbnailViewIte Invalidate(); } -bool ThumbnailView::renameItem(ThumbnailViewItem*, const OUString&) +bool ThumbnailViewBase::renameItem(ThumbnailViewItem*, const OUString&) { // Do nothing by default return false; } +ThumbnailViewBase::~ThumbnailViewBase() +{ +} + BitmapEx ThumbnailView::readThumbnail(const OUString &msURL) { using namespace ::com::sun::star; @@ -1306,4 +1315,1169 @@ BitmapEx ThumbnailView::readThumbnail(const OUString &msURL) return aThumbnail; } +SfxThumbnailView::SfxThumbnailView(std::unique_ptr<weld::ScrolledWindow> xWindow, std::unique_ptr<weld::Menu> xMenu) + : mpItemAttrs(new ThumbnailItemAttributes) + , mxScrolledWindow(std::move(xWindow)) + , mxContextMenu(std::move(xMenu)) +{ + mxScrolledWindow->set_user_managed_scrolling(); + ImplInit(); + mxScrolledWindow->connect_vadjustment_changed(LINK(this, SfxThumbnailView, ImplScrollHdl)); +} + +SfxThumbnailView::~SfxThumbnailView() +{ + css::uno::Reference< css::lang::XComponent> xComponent(mxAccessible, css::uno::UNO_QUERY); + + if (xComponent.is()) + xComponent->dispose(); + + mpItemAttrs.reset(); + + ImplDeleteItems(); +} + +bool SfxThumbnailView::MouseMove(const MouseEvent& rMEvt) +{ + size_t nItemCount = mFilteredItemList.size(); + Point aPoint = rMEvt.GetPosPixel(); + + for (size_t i = 0; i < nItemCount; i++) + { + ThumbnailViewItem *pItem = mFilteredItemList[i]; + ::tools::Rectangle aToInvalidate(pItem->updateHighlight(pItem->mbVisible && !rMEvt.IsLeaveWindow(), aPoint)); + if (!aToInvalidate.IsEmpty() && IsReallyVisible() && IsUpdateMode()) + Invalidate(aToInvalidate); + } + + return true; +} + +OUString SfxThumbnailView::RequestHelp(tools::Rectangle& rHelpRect) +{ + if (!mbShowTooltips) + return OUString(); + + Point aPos = rHelpRect.TopLeft(); + size_t nItemCount = mFilteredItemList.size(); + for (size_t i = 0; i < nItemCount; i++) + { + ThumbnailViewItem *pItem = mFilteredItemList[i]; + if (!pItem->mbVisible) + continue; + const tools::Rectangle& rDrawArea = pItem->getDrawArea(); + if (pItem->mbVisible && rDrawArea.IsInside(aPos)) + { + rHelpRect = rDrawArea; + return pItem->getHelpText(); + } + } + + return OUString(); +} + +void SfxThumbnailView::AppendItem(std::unique_ptr<ThumbnailViewItem> pItem) +{ + if (maFilterFunc(pItem.get())) + { + // Save current start,end range, iterator might get invalidated + size_t nSelStartPos = 0; + ThumbnailViewItem *pSelStartItem = nullptr; + + if (mpStartSelRange != mFilteredItemList.end()) + { + pSelStartItem = *mpStartSelRange; + nSelStartPos = mpStartSelRange - mFilteredItemList.begin(); + } + + mFilteredItemList.push_back(pItem.get()); + mpStartSelRange = pSelStartItem != nullptr ? mFilteredItemList.begin() + nSelStartPos : mFilteredItemList.end(); + } + + mItemList.push_back(std::move(pItem)); +} + +void SfxThumbnailView::ImplInit() +{ + mnItemWidth = 0; + mnItemHeight = 0; + mnItemPadding = 0; + mnVisLines = 0; + mnLines = 0; + mnFirstLine = 0; + mnCols = 0; + mbScroll = false; + mbHasVisibleItems = false; + mbShowTooltips = false; + mbIsMultiSelectionEnabled = true; + maFilterFunc = ViewFilterAll(); + + const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings(); + maFillColor = rSettings.GetFieldColor(); + maTextColor = rSettings.GetWindowTextColor(); + maHighlightColor = rSettings.GetHighlightColor(); + maHighlightTextColor = rSettings.GetWindowTextColor(); + maSelectHighlightColor = rSettings.GetActiveColor(); + maSelectHighlightTextColor = rSettings.GetActiveTextColor(); + + const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; + mfHighlightTransparence = aSvtOptionsDrawinglayer.GetTransparentSelectionPercent() * 0.01; + + mpStartSelRange = mFilteredItemList.end(); + + mpItemAttrs->aFillColor = maFillColor.getBColor(); + mpItemAttrs->aTextColor = maTextColor.getBColor(); + mpItemAttrs->aHighlightColor = maHighlightColor.getBColor(); + mpItemAttrs->aHighlightTextColor = maHighlightTextColor.getBColor(); + mpItemAttrs->aSelectHighlightColor = maSelectHighlightColor.getBColor(); + mpItemAttrs->aSelectHighlightTextColor = maSelectHighlightTextColor.getBColor(); + mpItemAttrs->fHighlightTransparence = mfHighlightTransparence; + + mpItemAttrs->nMaxTextLength = 0; +} + +void SfxThumbnailView::ImplDeleteItems() +{ + const size_t n = mItemList.size(); + + for ( size_t i = 0; i < n; ++i ) + { + ThumbnailViewItem *const pItem = mItemList[i].get(); + + // deselect all current selected items and fire events + if (pItem->isSelected()) + { + pItem->setSelection(false); + maItemStateHdl.Call(pItem); + + // fire accessible event??? + } + + if ( pItem->isVisible() && ImplHasAccessibleListeners() ) + { + css::uno::Any aOldAny, aNewAny; + + aOldAny <<= pItem->GetAccessible( false ); + ImplFireAccessibleEvent( css::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny ); + } + + mItemList[i].reset(); + } + + mItemList.clear(); + mFilteredItemList.clear(); + + mpStartSelRange = mFilteredItemList.end(); +} + +void SfxThumbnailView::DrawItem(ThumbnailViewItem const *pItem) +{ + if (pItem->isVisible()) + { + ::tools::Rectangle aRect = pItem->getDrawArea(); + + if ((aRect.GetHeight() > 0) && (aRect.GetWidth() > 0)) + Invalidate(aRect); + } +} + +void SfxThumbnailView::OnItemDblClicked (ThumbnailViewItem*) +{ +} + +css::uno::Reference< css::accessibility::XAccessible > SfxThumbnailView::CreateAccessible() +{ + mxAccessible.set(new SfxThumbnailViewAcc(this)); + return mxAccessible; +} + +css::uno::Reference< css::accessibility::XAccessible > SfxThumbnailView::getAccessible() +{ + return mxAccessible; +} + +void SfxThumbnailView::CalculateItemPositions(bool bScrollBarUsed) +{ + if (!mnItemHeight || !mnItemWidth) + return; + + Size aWinSize = GetOutputSizePixel(); + size_t nItemCount = mFilteredItemList.size(); + + // calculate window scroll ratio + float nScrollRatio; + if (bScrollBarUsed) + nScrollRatio = static_cast<float>(mxScrolledWindow->vadjustment_get_value()) / + static_cast<float>(mxScrolledWindow->vadjustment_get_upper()-2); + else + nScrollRatio = 0; + + // calculate ScrollBar width + long nScrBarWidth = mxScrolledWindow->get_vscroll_width(); + + // calculate maximum number of visible columns + mnCols = static_cast<sal_uInt16>((aWinSize.Width()-nScrBarWidth) / mnItemWidth); + + if (!mnCols) + mnCols = 1; + + // calculate maximum number of visible rows + mnVisLines = static_cast<sal_uInt16>(aWinSize.Height() / mnItemHeight); + + // calculate empty space + long nHSpace = aWinSize.Width()-nScrBarWidth - mnCols*mnItemWidth; + long nVSpace = aWinSize.Height() - mnVisLines*mnItemHeight; + long nHItemSpace = nHSpace / (mnCols+1); + long nVItemSpace = nVSpace / (mnVisLines+1); + + // calculate maximum number of rows + // Floor( (M+N-1)/N )==Ceiling( M/N ) + mnLines = (static_cast<long>(nItemCount)+mnCols-1) / mnCols; + + if ( !mnLines ) + mnLines = 1; + + if ( mnLines <= mnVisLines ) + mnFirstLine = 0; + else if ( mnFirstLine > static_cast<sal_uInt16>(mnLines-mnVisLines) ) + mnFirstLine = static_cast<sal_uInt16>(mnLines-mnVisLines); + + mbHasVisibleItems = true; + + long nItemHeightOffset = mnItemHeight + nVItemSpace; + long nHiddenLines = (static_cast<long>( + ( mnLines - 1 ) * nItemHeightOffset * nScrollRatio ) - + nVItemSpace ) / + nItemHeightOffset; + + // calculate offsets + long nStartX = nHItemSpace; + long nStartY = nVItemSpace; + + // calculate and draw items + long x = nStartX; + long y = nStartY - ( mnLines - 1 ) * nItemHeightOffset * nScrollRatio + + nHiddenLines * nItemHeightOffset; + + // draw items + // Unless we are scrolling (via scrollbar) we just use the precalculated + // mnFirstLine -- our nHiddenLines calculation takes into account only + // what the user has done with the scrollbar but not any changes of selection + // using the keyboard, meaning we could accidentally hide the selected item + // if we believe the scrollbar (fdo#72287). + size_t nFirstItem = (bScrollBarUsed ? nHiddenLines : mnFirstLine) * mnCols; + size_t nLastItem = nFirstItem + (mnVisLines + 1) * mnCols; + + // If want also draw parts of items in the last line, + // then we add one more line if parts of these line are + // visible + + size_t nCurCount = 0; + for ( size_t i = 0; i < nItemCount; i++ ) + { + ThumbnailViewItem *const pItem = mFilteredItemList[i]; + + if ((nCurCount >= nFirstItem) && (nCurCount < nLastItem)) + { + if( !pItem->isVisible()) + { + if ( ImplHasAccessibleListeners() ) + { + css::uno::Any aOldAny, aNewAny; + + aNewAny <<= pItem->GetAccessible( false ); + ImplFireAccessibleEvent( css::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny ); + } + + pItem->show(true); + + maItemStateHdl.Call(pItem); + } + + pItem->setDrawArea(::tools::Rectangle( Point(x,y), Size(mnItemWidth, mnItemHeight) )); + pItem->calculateItemsPosition(mnThumbnailHeight,mnDisplayHeight,mnItemPadding,mpItemAttrs->nMaxTextLength,mpItemAttrs.get()); + + if ( !((nCurCount+1) % mnCols) ) + { + x = nStartX; + y += mnItemHeight+nVItemSpace; + } + else + x += mnItemWidth+nHItemSpace; + } + else + { + if( pItem->isVisible()) + { + if ( ImplHasAccessibleListeners() ) + { + css::uno::Any aOldAny, aNewAny; + + aOldAny <<= pItem->GetAccessible( false ); + ImplFireAccessibleEvent( css::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny ); + } + + pItem->show(false); + + maItemStateHdl.Call(pItem); + } + + } + + ++nCurCount; + } + + // arrange ScrollBar, set values and show it + mnLines = (nCurCount+mnCols-1)/mnCols; + + // check if scroll is needed + mbScroll = mnLines > mnVisLines; + + mxScrolledWindow->vadjustment_set_upper((nCurCount+mnCols-1)*gnFineness/mnCols); + mxScrolledWindow->vadjustment_set_page_size(mnVisLines); + if (!bScrollBarUsed) + mxScrolledWindow->vadjustment_set_value(static_cast<long>(mnFirstLine)*gnFineness); + long nPageSize = mnVisLines; + if ( nPageSize < 1 ) + nPageSize = 1; + mxScrolledWindow->vadjustment_set_page_increment(nPageSize); + mxScrolledWindow->set_vpolicy(mbScroll ? VclPolicyType::ALWAYS : VclPolicyType::NEVER); +} + +size_t SfxThumbnailView::ImplGetItem( const Point& rPos ) const +{ + if ( !mbHasVisibleItems ) + { + return THUMBNAILVIEW_ITEM_NOTFOUND; + } + + for (size_t i = 0; i < mFilteredItemList.size(); ++i) + { + if (mFilteredItemList[i]->isVisible() && mFilteredItemList[i]->getDrawArea().IsInside(rPos)) + return i; + } + + return THUMBNAILVIEW_ITEM_NOTFOUND; +} + +ThumbnailViewItem* SfxThumbnailView::ImplGetItem( size_t nPos ) +{ + return ( nPos < mFilteredItemList.size() ) ? mFilteredItemList[nPos] : nullptr; +} + +sal_uInt16 SfxThumbnailView::ImplGetVisibleItemCount() const +{ + sal_uInt16 nRet = 0; + const size_t nItemCount = mItemList.size(); + + for ( size_t n = 0; n < nItemCount; ++n ) + { + if ( mItemList[n]->isVisible() ) + ++nRet; + } + + return nRet; +} + +ThumbnailViewItem* SfxThumbnailView::ImplGetVisibleItem( sal_uInt16 nVisiblePos ) +{ + const size_t nItemCount = mItemList.size(); + + for ( size_t n = 0; n < nItemCount; ++n ) + { + ThumbnailViewItem *const pItem = mItemList[n].get(); + + if ( pItem->isVisible() && !nVisiblePos-- ) + return pItem; + } + + return nullptr; +} + +void SfxThumbnailView::ImplFireAccessibleEvent( short nEventId, const css::uno::Any& rOldValue, const css::uno::Any& rNewValue ) +{ + ThumbnailViewAcc* pAcc = ThumbnailViewAcc::getImplementation(mxAccessible); + + if( pAcc ) + pAcc->FireAccessibleEvent( nEventId, rOldValue, rNewValue ); +} + +bool SfxThumbnailView::ImplHasAccessibleListeners() +{ + ThumbnailViewAcc* pAcc = ThumbnailViewAcc::getImplementation(mxAccessible); + return( pAcc && pAcc->HasAccessibleListeners() ); +} + +IMPL_LINK_NOARG(SfxThumbnailView, ImplScrollHdl, weld::ScrolledWindow&, void) +{ + CalculateItemPositions(true); + if (IsReallyVisible() && IsUpdateMode()) + Invalidate(); +} + +bool SfxThumbnailView::KeyInput( const KeyEvent& rKEvt ) +{ + bool bHandled = true; + + // Get the last selected item in the list + size_t nLastPos = 0; + bool bFoundLast = false; + for ( long i = mFilteredItemList.size() - 1; !bFoundLast && i >= 0; --i ) + { + ThumbnailViewItem* pItem = mFilteredItemList[i]; + if ( pItem->isSelected() ) + { + nLastPos = i; + bFoundLast = true; + } + } + + bool bValidRange = false; + bool bHasSelRange = mpStartSelRange != mFilteredItemList.end(); + size_t nNextPos = nLastPos; + vcl::KeyCode aKeyCode = rKEvt.GetKeyCode(); + ThumbnailViewItem* pNext = nullptr; + + if (aKeyCode.IsShift() && bHasSelRange) + { + //If the last element selected is the start range position + //search for the first selected item + size_t nSelPos = mpStartSelRange - mFilteredItemList.begin(); + + if (nLastPos == nSelPos) + { + while (nLastPos && mFilteredItemList[nLastPos-1]->isSelected()) + --nLastPos; + } + } + + switch ( aKeyCode.GetCode() ) + { + case KEY_RIGHT: + if (!mFilteredItemList.empty()) + { + if ( bFoundLast && nLastPos + 1 < mFilteredItemList.size() ) + { + bValidRange = true; + nNextPos = nLastPos + 1; + } + + pNext = mFilteredItemList[nNextPos]; + } + break; + case KEY_LEFT: + if (!mFilteredItemList.empty()) + { + if ( nLastPos > 0 ) + { + bValidRange = true; + nNextPos = nLastPos - 1; + } + + pNext = mFilteredItemList[nNextPos]; + } + break; + case KEY_DOWN: + if (!mFilteredItemList.empty()) + { + if ( bFoundLast ) + { + //If we are in the second last row just go the one in + //the row below, if there's not row below just go to the + //last item but for the last row don't do anything. + if ( nLastPos + mnCols < mFilteredItemList.size( ) ) + { + bValidRange = true; + nNextPos = nLastPos + mnCols; + } + else + { + int curRow = nLastPos/mnCols; + + if (curRow < mnLines-1) + nNextPos = mFilteredItemList.size()-1; + } + } + + pNext = mFilteredItemList[nNextPos]; + } + break; + case KEY_UP: + if (!mFilteredItemList.empty()) + { + if ( nLastPos >= mnCols ) + { + bValidRange = true; + nNextPos = nLastPos - mnCols; + } + + pNext = mFilteredItemList[nNextPos]; + } + break; + case KEY_RETURN: + { + if ( bFoundLast ) + OnItemDblClicked( mFilteredItemList[nLastPos] ); + } + [[fallthrough]]; + default: + bHandled = CustomWidgetController::KeyInput(rKEvt); + } + + if ( pNext && mbIsMultiSelectionEnabled) + { + if (aKeyCode.IsShift() && bValidRange) + { + std::pair<size_t,size_t> aRange; + size_t nSelPos = mpStartSelRange - mFilteredItemList.begin(); + + if (nLastPos < nSelPos) + { + if (nNextPos > nLastPos) + { + if ( nNextPos > nSelPos) + aRange = std::make_pair(nLastPos,nNextPos); + else + aRange = std::make_pair(nLastPos,nNextPos-1); + } + else + aRange = std::make_pair(nNextPos,nLastPos-1); + } + else if (nLastPos == nSelPos) + { + if (nNextPos > nLastPos) + aRange = std::make_pair(nLastPos+1,nNextPos); + else + aRange = std::make_pair(nNextPos,nLastPos-1); + } + else + { + if (nNextPos > nLastPos) + aRange = std::make_pair(nLastPos+1,nNextPos); + else + { + if ( nNextPos < nSelPos) + aRange = std::make_pair(nNextPos,nLastPos); + else + aRange = std::make_pair(nNextPos+1,nLastPos); + } + } + + for (size_t i = aRange.first; i <= aRange.second; ++i) + { + if (i != nSelPos) + { + ThumbnailViewItem *pCurItem = mFilteredItemList[i]; + + pCurItem->setSelection(!pCurItem->isSelected()); + + if (pCurItem->isVisible()) + DrawItem(pCurItem); + + maItemStateHdl.Call(pCurItem); + } + } + } + else if (!aKeyCode.IsShift()) + { + deselectItems(); + SelectItem(pNext->mnId); + + //Mark it as the selection range start position + mpStartSelRange = mFilteredItemList.begin() + nNextPos; + } + + MakeItemVisible(pNext->mnId); + } + else if(pNext && !mbIsMultiSelectionEnabled) + { + deselectItems(); + SelectItem(pNext->mnId); + MakeItemVisible(pNext->mnId); + } + return bHandled; +} + +void SfxThumbnailView::MakeItemVisible( sal_uInt16 nItemId ) +{ + // Get the item row + size_t nPos = 0; + bool bFound = false; + for ( size_t i = 0; !bFound && i < mFilteredItemList.size(); ++i ) + { + ThumbnailViewItem* pItem = mFilteredItemList[i]; + if ( pItem->mnId == nItemId ) + { + nPos = i; + bFound = true; + } + } + sal_uInt16 nRow = mnCols ? nPos / mnCols : 0; + + // Move the visible rows as little as possible to include that one + if ( nRow < mnFirstLine ) + mnFirstLine = nRow; + else if ( nRow > mnFirstLine + mnVisLines ) + mnFirstLine = nRow - mnVisLines; + + CalculateItemPositions(); + Invalidate(); +} + +bool SfxThumbnailView::MouseButtonDown( const MouseEvent& rMEvt ) +{ + if (!rMEvt.IsLeft()) + { + return CustomWidgetController::MouseButtonDown( rMEvt ); + } + + size_t nPos = ImplGetItem(rMEvt.GetPosPixel()); + ThumbnailViewItem* pItem = ImplGetItem(nPos); + + if ( !pItem ) + { + deselectItems(); + return CustomWidgetController::MouseButtonDown( rMEvt ); + } + + if ( rMEvt.GetClicks() == 2 ) + { + OnItemDblClicked(pItem); + return true; + } + + if ( rMEvt.GetClicks() == 1 && !mbIsMultiSelectionEnabled ) + { + deselectItems(); + pItem->setSelection(!pItem->isSelected()); + + if (!pItem->isHighlighted()) + DrawItem(pItem); + + maItemStateHdl.Call(pItem); + } + else if(rMEvt.GetClicks() == 1) + { + if (rMEvt.IsMod1()) + { + //Keep selected item group state and just invert current desired one state + pItem->setSelection(!pItem->isSelected()); + + //This one becomes the selection range start position if it changes its state to selected otherwise resets it + mpStartSelRange = pItem->isSelected() ? mFilteredItemList.begin() + nPos : mFilteredItemList.end(); + } + else if (rMEvt.IsShift() && mpStartSelRange != mFilteredItemList.end()) + { + std::pair<size_t,size_t> aNewRange; + aNewRange.first = mpStartSelRange - mFilteredItemList.begin(); + aNewRange.second = nPos; + + if (aNewRange.first > aNewRange.second) + std::swap(aNewRange.first,aNewRange.second); + + //Deselect the ones outside of it + for (size_t i = 0, n = mFilteredItemList.size(); i < n; ++i) + { + ThumbnailViewItem *pCurItem = mFilteredItemList[i]; + + if (pCurItem->isSelected() && (i < aNewRange.first || i > aNewRange.second)) + { + pCurItem->setSelection(false); + + if (pCurItem->isVisible()) + DrawItem(pCurItem); + + maItemStateHdl.Call(pCurItem); + } + } + + size_t nSelPos = mpStartSelRange - mFilteredItemList.begin(); + + //Select the items between start range and the selected item + if (nSelPos != nPos) + { + int dir = nSelPos < nPos ? 1 : -1; + size_t nCurPos = nSelPos + dir; + + while (nCurPos != nPos) + { + ThumbnailViewItem *pCurItem = mFilteredItemList[nCurPos]; + + if (!pCurItem->isSelected()) + { + pCurItem->setSelection(true); + + if (pCurItem->isVisible()) + DrawItem(pCurItem); + + maItemStateHdl.Call(pCurItem); + } + + nCurPos += dir; + } + } + + pItem->setSelection(true); + } + else + { + //If we got a group of selected items deselect the rest and only keep the desired one + //mark items as not selected to not fire unnecessary change state events. + pItem->setSelection(false); + deselectItems(); + pItem->setSelection(true); + + //Mark as initial selection range position and reset end one + mpStartSelRange = mFilteredItemList.begin() + nPos; + } + + if (!pItem->isHighlighted()) + DrawItem(pItem); + + maItemStateHdl.Call(pItem); + + //fire accessible event?? + } + return true; +} + +void SfxThumbnailView::SetDrawingArea(weld::DrawingArea* pDrawingArea) +{ + CustomWidgetController::SetDrawingArea(pDrawingArea); + + if (vcl::Window* pDefaultDevice = dynamic_cast<vcl::Window*>(Application::GetDefaultDevice())) + { + OutputDevice& rDevice = pDrawingArea->get_ref_device(); + pDefaultDevice->SetPointFont(rDevice, pDrawingArea->get_font()); + mpItemAttrs->aFontAttr = getFontAttributeFromVclFont(mpItemAttrs->aFontSize, rDevice.GetFont(), false, true); + } + + SetOutputSizePixel(pDrawingArea->get_preferred_size()); +} + +void SfxThumbnailView::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& /*rRect*/) +{ + rRenderContext.Push(PushFlags::ALL); + + rRenderContext.SetTextFillColor(); + rRenderContext.SetBackground(maFillColor); + + size_t nItemCount = mItemList.size(); + + // Draw background + drawinglayer::primitive2d::Primitive2DContainer aSeq(1); + aSeq[0] = drawinglayer::primitive2d::Primitive2DReference( + new PolyPolygonColorPrimitive2D( + B2DPolyPolygon( ::tools::Polygon(::tools::Rectangle(Point(), GetOutputSizePixel()), 0, 0).getB2DPolygon()), + maFillColor.getBColor())); + + // Create the processor and process the primitives + const drawinglayer::geometry::ViewInformation2D aNewViewInfos; + + std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor( + drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(rRenderContext, aNewViewInfos)); + pProcessor->process(aSeq); + + // draw items + for (size_t i = 0; i < nItemCount; i++) + { + ThumbnailViewItem *const pItem = mItemList[i].get(); + + if (pItem->isVisible()) + { + pItem->Paint(pProcessor.get(), mpItemAttrs.get()); + } + } + + rRenderContext.Pop(); +} + +void SfxThumbnailView::GetFocus() +{ + // Select the first item if nothing selected + int nSelected = -1; + for (size_t i = 0, n = mItemList.size(); i < n && nSelected == -1; ++i) + { + if (mItemList[i]->isSelected()) + nSelected = i; + } + + if (nSelected == -1 && !mItemList.empty()) + { + SelectItem(1); + } + + // Tell the accessible object that we got the focus. + ThumbnailViewAcc* pAcc = ThumbnailViewAcc::getImplementation(mxAccessible); + if( pAcc ) + pAcc->GetFocus(); + + CustomWidgetController::GetFocus(); +} + +void SfxThumbnailView::LoseFocus() +{ + CustomWidgetController::LoseFocus(); + + // Tell the accessible object that we lost the focus. + ThumbnailViewAcc* pAcc = ThumbnailViewAcc::getImplementation(mxAccessible); + if( pAcc ) + pAcc->LoseFocus(); +} + +void SfxThumbnailView::Resize() +{ + CustomWidgetController::Resize(); + CalculateItemPositions(); + + if ( IsReallyVisible() && IsUpdateMode() ) + Invalidate(); +} + +void SfxThumbnailView::RemoveItem( sal_uInt16 nItemId ) +{ + size_t nPos = GetItemPos( nItemId ); + + if ( nPos == THUMBNAILVIEW_ITEM_NOTFOUND ) + return; + + if ( nPos < mFilteredItemList.size() ) { + + // delete item from the thumbnail list + for (size_t i = 0, n = mItemList.size(); i < n; ++i) + { + if (mItemList[i]->mnId == nItemId) + { + mItemList.erase(mItemList.begin()+i); + break; + } + } + + // delete item from the filter item list + ThumbnailValueItemList::iterator it = mFilteredItemList.begin(); + ::std::advance( it, nPos ); + + if ((*it)->isSelected()) + { + (*it)->setSelection(false); + maItemStateHdl.Call(*it); + } + + delete *it; + mFilteredItemList.erase( it ); + mpStartSelRange = mFilteredItemList.end(); + } + + CalculateItemPositions(); + + if ( IsReallyVisible() && IsUpdateMode() ) + Invalidate(); +} + +void SfxThumbnailView::Clear() +{ + ImplDeleteItems(); + + // reset variables + mnFirstLine = 0; + + CalculateItemPositions(); + + if ( IsReallyVisible() && IsUpdateMode() ) + Invalidate(); +} + +void SfxThumbnailView::updateItems (std::vector<std::unique_ptr<ThumbnailViewItem>> items) +{ + ImplDeleteItems(); + + // reset variables + mnFirstLine = 0; + + mItemList = std::move(items); + + filterItems(maFilterFunc); +} + +size_t SfxThumbnailView::GetItemPos( sal_uInt16 nItemId ) const +{ + for ( size_t i = 0, n = mFilteredItemList.size(); i < n; ++i ) { + if ( mFilteredItemList[i]->mnId == nItemId ) { + return i; + } + } + return THUMBNAILVIEW_ITEM_NOTFOUND; +} + +sal_uInt16 SfxThumbnailView::GetItemId( size_t nPos ) const +{ + return ( nPos < mFilteredItemList.size() ) ? mFilteredItemList[nPos]->mnId : 0 ; +} + +sal_uInt16 SfxThumbnailView::GetItemId( const Point& rPos ) const +{ + size_t nItemPos = ImplGetItem( rPos ); + if ( nItemPos != THUMBNAILVIEW_ITEM_NOTFOUND ) + return GetItemId( nItemPos ); + + return 0; +} + +sal_uInt16 SfxThumbnailView::getNextItemId() const +{ + return mItemList.empty() ? 1 : mItemList.back()->mnId + 1; +} + +void SfxThumbnailView::setItemMaxTextLength(sal_uInt32 nLength) +{ + mpItemAttrs->nMaxTextLength = nLength; +} + +void SfxThumbnailView::setItemDimensions(long itemWidth, long thumbnailHeight, long displayHeight, int itemPadding) +{ + mnItemWidth = itemWidth + 2*itemPadding; + mnThumbnailHeight = thumbnailHeight; + mnDisplayHeight = displayHeight; + mnItemPadding = itemPadding; + mnItemHeight = mnDisplayHeight + mnThumbnailHeight + 2*itemPadding; +} + +void SfxThumbnailView::SelectItem( sal_uInt16 nItemId ) +{ + size_t nItemPos = GetItemPos( nItemId ); + if ( nItemPos == THUMBNAILVIEW_ITEM_NOTFOUND ) + return; + + ThumbnailViewItem* pItem = mFilteredItemList[nItemPos]; + if (pItem->isSelected()) + return; + + pItem->setSelection(true); + maItemStateHdl.Call(pItem); + + if (IsReallyVisible() && IsUpdateMode()) + Invalidate(); + + bool bNewOut = IsReallyVisible() && IsUpdateMode(); + + // if necessary scroll to the visible area + if (mbScroll && nItemId && mnCols) + { + sal_uInt16 nNewLine = static_cast<sal_uInt16>(nItemPos / mnCols); + if ( nNewLine < mnFirstLine ) + { + mnFirstLine = nNewLine; + } + else if ( nNewLine > static_cast<sal_uInt16>(mnFirstLine+mnVisLines-1) ) + { + mnFirstLine = static_cast<sal_uInt16>(nNewLine-mnVisLines+1); + } + } + + if ( bNewOut ) + { + if ( IsReallyVisible() && IsUpdateMode() ) + Invalidate(); + } + + if( !ImplHasAccessibleListeners() ) + return; + + // focus event (select) + ThumbnailViewItemAcc* pItemAcc = ThumbnailViewItemAcc::getImplementation( pItem->GetAccessible( false ) ); + + if( pItemAcc ) + { + css::uno::Any aOldAny, aNewAny; + aNewAny <<= css::uno::Reference< css::uno::XInterface >( + static_cast< ::cppu::OWeakObject* >( pItemAcc )); + ImplFireAccessibleEvent( css::accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldAny, aNewAny ); + } + + // selection event + css::uno::Any aOldAny, aNewAny; + ImplFireAccessibleEvent( css::accessibility::AccessibleEventId::SELECTION_CHANGED, aOldAny, aNewAny ); +} + +bool SfxThumbnailView::IsItemSelected( sal_uInt16 nItemId ) const +{ + size_t nItemPos = GetItemPos( nItemId ); + if ( nItemPos == THUMBNAILVIEW_ITEM_NOTFOUND ) + return false; + + ThumbnailViewItem* pItem = mFilteredItemList[nItemPos]; + return pItem->isSelected(); +} + +void SfxThumbnailView::deselectItems() +{ + for (std::unique_ptr<ThumbnailViewItem>& p : mItemList) + { + if (p->isSelected()) + { + p->setSelection(false); + + maItemStateHdl.Call(p.get()); + } + } + + if (IsReallyVisible() && IsUpdateMode()) + Invalidate(); +} + +void SfxThumbnailView::ShowTooltips( bool bShowTooltips ) +{ + mbShowTooltips = bShowTooltips; +} + +void SfxThumbnailView::SetMultiSelectionEnabled( bool bIsMultiSelectionEnabled ) +{ + mbIsMultiSelectionEnabled = bIsMultiSelectionEnabled; +} + +void SfxThumbnailView::filterItems(const std::function<bool (const ThumbnailViewItem*)> &func) +{ + mnFirstLine = 0; // start at the top of the list instead of the current position + maFilterFunc = func; + + size_t nSelPos = 0; + bool bHasSelRange = false; + ThumbnailViewItem *curSel = mpStartSelRange != mFilteredItemList.end() ? *mpStartSelRange : nullptr; + + mFilteredItemList.clear(); + + for (size_t i = 0, n = mItemList.size(); i < n; ++i) + { + ThumbnailViewItem *const pItem = mItemList[i].get(); + + if (maFilterFunc(pItem)) + { + if (curSel == pItem) + { + nSelPos = i; + bHasSelRange = true; + } + + mFilteredItemList.push_back(pItem); + } + else + { + if( pItem->isVisible()) + { + if ( ImplHasAccessibleListeners() ) + { + css::uno::Any aOldAny, aNewAny; + + aOldAny <<= pItem->GetAccessible( false ); + ImplFireAccessibleEvent( css::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny ); + } + + pItem->show(false); + pItem->setSelection(false); + + maItemStateHdl.Call(pItem); + } + } + } + + mpStartSelRange = bHasSelRange ? mFilteredItemList.begin() + nSelPos : mFilteredItemList.end(); + CalculateItemPositions(); + + Invalidate(); +} + +BitmapEx SfxThumbnailView::readThumbnail(const OUString &msURL) +{ + using namespace ::com::sun::star; + using namespace ::com::sun::star::uno; + + // Load the thumbnail from a template document. + uno::Reference<io::XInputStream> xIStream; + + uno::Reference< uno::XComponentContext > xContext(::comphelper::getProcessComponentContext()); + try + { + uno::Reference<lang::XSingleServiceFactory> xStorageFactory = embed::StorageFactory::create(xContext); + + uno::Sequence<uno::Any> aArgs (2); + aArgs[0] <<= msURL; + aArgs[1] <<= embed::ElementModes::READ; + uno::Reference<embed::XStorage> xDocStorage ( + xStorageFactory->createInstanceWithArguments(aArgs), + uno::UNO_QUERY); + + try + { + if (xDocStorage.is()) + { + uno::Reference<embed::XStorage> xStorage ( + xDocStorage->openStorageElement( + "Thumbnails", + embed::ElementModes::READ)); + if (xStorage.is()) + { + uno::Reference<io::XStream> xThumbnailCopy ( + xStorage->cloneStreamElement("thumbnail.png")); + if (xThumbnailCopy.is()) + xIStream = xThumbnailCopy->getInputStream(); + } + } + } + catch (const uno::Exception& rException) + { + SAL_WARN("sfx", + "caught exception while trying to access Thumbnail/thumbnail.png of " + << msURL << ": " << rException); + } + + try + { + // An (older) implementation had a bug - The storage + // name was "Thumbnail" instead of "Thumbnails". The + // old name is still used as fallback but this code can + // be removed soon. + if ( ! xIStream.is()) + { + uno::Reference<embed::XStorage> xStorage ( + xDocStorage->openStorageElement( "Thumbnail", + embed::ElementModes::READ)); + if (xStorage.is()) + { + uno::Reference<io::XStream> xThumbnailCopy ( + xStorage->cloneStreamElement("thumbnail.png")); + if (xThumbnailCopy.is()) + xIStream = xThumbnailCopy->getInputStream(); + } + } + } + catch (const uno::Exception& rException) + { + SAL_WARN("sfx", + "caught exception while trying to access Thumbnails/thumbnail.png of " + << msURL << ": " << rException); + } + } + catch (const uno::Exception& rException) + { + SAL_WARN("sfx", + "caught exception while trying to access thumbnail of " + << msURL << ": " << rException); + } + + // Extract the image from the stream. + BitmapEx aThumbnail; + if (xIStream.is()) + { + std::unique_ptr<SvStream> pStream ( + ::utl::UcbStreamHelper::CreateStream (xIStream)); + vcl::PNGReader aReader (*pStream); + aThumbnail = aReader.Read (); + } + + // Note that the preview is returned without scaling it to the desired + // width. This gives the caller the chance to take advantage of a + // possibly larger resolution then was asked for. + return aThumbnail; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/source/control/thumbnailviewacc.cxx b/sfx2/source/control/thumbnailviewacc.cxx index 1cb7a5e085c7..405b874c1d51 100644 --- a/sfx2/source/control/thumbnailviewacc.cxx +++ b/sfx2/source/control/thumbnailviewacc.cxx @@ -550,6 +550,532 @@ void ThumbnailViewAcc::ThrowIfDisposed() } } +SfxThumbnailViewAcc::SfxThumbnailViewAcc( SfxThumbnailView* pParent ) : + ValueSetAccComponentBase (m_aMutex), + mpParent( pParent ), + mbIsFocused(false) +{ +} + +SfxThumbnailViewAcc::~SfxThumbnailViewAcc() +{ +} + +void SfxThumbnailViewAcc::FireAccessibleEvent( short nEventId, const uno::Any& rOldValue, const uno::Any& rNewValue ) +{ + if( !nEventId ) + return; + + ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > > aTmpListeners( mxEventListeners ); + accessibility::AccessibleEventObject aEvtObject; + + aEvtObject.EventId = nEventId; + aEvtObject.Source = static_cast<uno::XWeak*>(this); + aEvtObject.NewValue = rNewValue; + aEvtObject.OldValue = rOldValue; + + for (auto const& tmpListener : aTmpListeners) + { + try + { + tmpListener->notifyEvent( aEvtObject ); + } + catch(const uno::Exception&) + { + } + } +} + +namespace +{ + class theSfxValueSetAccUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSfxValueSetAccUnoTunnelId > {}; +} + +const uno::Sequence< sal_Int8 >& SfxThumbnailViewAcc::getUnoTunnelId() +{ + return theSfxValueSetAccUnoTunnelId::get().getSeq(); +} + +SfxThumbnailViewAcc* SfxThumbnailViewAcc::getImplementation( const uno::Reference< uno::XInterface >& rxData ) + throw() +{ + try + { + uno::Reference< lang::XUnoTunnel > xUnoTunnel( rxData, uno::UNO_QUERY ); + return( xUnoTunnel.is() ? reinterpret_cast<SfxThumbnailViewAcc*>(sal::static_int_cast<sal_IntPtr>(xUnoTunnel->getSomething( SfxThumbnailViewAcc::getUnoTunnelId() ))) : nullptr ); + } + catch(const css::uno::Exception&) + { + return nullptr; + } +} + +void SfxThumbnailViewAcc::GetFocus() +{ + mbIsFocused = true; + + // Broadcast the state change. + css::uno::Any aOldState, aNewState; + aNewState <<= css::accessibility::AccessibleStateType::FOCUSED; + FireAccessibleEvent( + css::accessibility::AccessibleEventId::STATE_CHANGED, + aOldState, aNewState); +} + +void SfxThumbnailViewAcc::LoseFocus() +{ + mbIsFocused = false; + + // Broadcast the state change. + css::uno::Any aOldState, aNewState; + aOldState <<= css::accessibility::AccessibleStateType::FOCUSED; + FireAccessibleEvent( + css::accessibility::AccessibleEventId::STATE_CHANGED, + aOldState, aNewState); +} + +uno::Reference< accessibility::XAccessibleContext > SAL_CALL SfxThumbnailViewAcc::getAccessibleContext() +{ + ThrowIfDisposed(); + return this; +} + +sal_Int32 SAL_CALL SfxThumbnailViewAcc::getAccessibleChildCount() +{ + const SolarMutexGuard aSolarGuard; + ThrowIfDisposed(); + + sal_Int32 nCount = mpParent->ImplGetVisibleItemCount(); + return nCount; +} + +uno::Reference< accessibility::XAccessible > SAL_CALL SfxThumbnailViewAcc::getAccessibleChild( sal_Int32 i ) +{ + ThrowIfDisposed(); + const SolarMutexGuard aSolarGuard; + ThumbnailViewItem* pItem = getItem (sal::static_int_cast< sal_uInt16 >(i)); + + if( !pItem ) + throw lang::IndexOutOfBoundsException(); + + uno::Reference< accessibility::XAccessible > xRet = pItem->GetAccessible( /*bIsTransientChildrenDisabled*/false ); + return xRet; +} + +uno::Reference< accessibility::XAccessible > SAL_CALL SfxThumbnailViewAcc::getAccessibleParent() +{ + ThrowIfDisposed(); + const SolarMutexGuard aSolarGuard; + return mpParent->GetDrawingArea()->get_accessible_parent(); +} + +sal_Int32 SAL_CALL SfxThumbnailViewAcc::getAccessibleIndexInParent() +{ + ThrowIfDisposed(); + const SolarMutexGuard aSolarGuard; + + // -1 for child not found/no parent (according to specification) + sal_Int32 nRet = -1; + + uno::Reference<accessibility::XAccessible> xParent(getAccessibleParent()); + if (!xParent) + return nRet; + + try + { + uno::Reference<accessibility::XAccessibleContext> xParentContext(xParent->getAccessibleContext()); + + // iterate over parent's children and search for this object + if ( xParentContext.is() ) + { + sal_Int32 nChildCount = xParentContext->getAccessibleChildCount(); + for ( sal_Int32 nChild = 0; ( nChild < nChildCount ) && ( -1 == nRet ); ++nChild ) + { + uno::Reference<XAccessible> xChild(xParentContext->getAccessibleChild(nChild)); + if ( xChild.get() == this ) + nRet = nChild; + } + } + } + catch (const uno::Exception&) + { + OSL_FAIL( "OAccessibleContextHelper::getAccessibleIndexInParent: caught an exception!" ); + } + + return nRet; +} + +sal_Int16 SAL_CALL SfxThumbnailViewAcc::getAccessibleRole() +{ + ThrowIfDisposed(); + // #i73746# As the Java Access Bridge (v 2.0.1) uses "managesDescendants" + // always if the role is LIST, we need a different role in this case + return accessibility::AccessibleRole::LIST; +} + +OUString SAL_CALL SfxThumbnailViewAcc::getAccessibleDescription() +{ + ThrowIfDisposed(); + return OUString("ThumbnailView"); +} + +OUString SAL_CALL SfxThumbnailViewAcc::getAccessibleName() +{ + ThrowIfDisposed(); + const SolarMutexGuard aSolarGuard; + OUString aRet; + + if (mpParent) + { + aRet = mpParent->GetAccessibleName(); + } + + return aRet; +} + +uno::Reference< accessibility::XAccessibleRelationSet > SAL_CALL SfxThumbnailViewAcc::getAccessibleRelationSet() +{ + ThrowIfDisposed(); + return uno::Reference< accessibility::XAccessibleRelationSet >(); +} + +uno::Reference< accessibility::XAccessibleStateSet > SAL_CALL SfxThumbnailViewAcc::getAccessibleStateSet() +{ + ThrowIfDisposed(); + ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper(); + + // Set some states. + pStateSet->AddState (accessibility::AccessibleStateType::ENABLED); + pStateSet->AddState (accessibility::AccessibleStateType::SENSITIVE); + pStateSet->AddState (accessibility::AccessibleStateType::SHOWING); + pStateSet->AddState (accessibility::AccessibleStateType::VISIBLE); + pStateSet->AddState (accessibility::AccessibleStateType::MANAGES_DESCENDANTS); + pStateSet->AddState (accessibility::AccessibleStateType::FOCUSABLE); + if (mbIsFocused) + pStateSet->AddState (accessibility::AccessibleStateType::FOCUSED); + + return pStateSet; +} + +lang::Locale SAL_CALL SfxThumbnailViewAcc::getLocale() +{ + ThrowIfDisposed(); + const SolarMutexGuard aSolarGuard; + uno::Reference< accessibility::XAccessible > xParent( getAccessibleParent() ); + lang::Locale aRet( "", "", "" ); + + if( xParent.is() ) + { + uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() ); + + if( xParentContext.is() ) + aRet = xParentContext->getLocale (); + } + + return aRet; +} + +void SAL_CALL SfxThumbnailViewAcc::addAccessibleEventListener( const uno::Reference< accessibility::XAccessibleEventListener >& rxListener ) +{ + ThrowIfDisposed(); + ::osl::MutexGuard aGuard (m_aMutex); + + if( !rxListener.is() ) + return; + + bool bFound = false; + + for (auto const& eventListener : mxEventListeners) + { + if( eventListener == rxListener ) + { + bFound = true; + break; + } + } + + if (!bFound) + mxEventListeners.push_back( rxListener ); +} + +void SAL_CALL SfxThumbnailViewAcc::removeAccessibleEventListener( const uno::Reference< accessibility::XAccessibleEventListener >& rxListener ) +{ + ThrowIfDisposed(); + ::osl::MutexGuard aGuard (m_aMutex); + + if( rxListener.is() ) + { + std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::iterator aIter = + std::find(mxEventListeners.begin(), mxEventListeners.end(), rxListener); + + if (aIter != mxEventListeners.end()) + mxEventListeners.erase( aIter ); + } +} + +sal_Bool SAL_CALL SfxThumbnailViewAcc::containsPoint( const awt::Point& aPoint ) +{ + ThrowIfDisposed(); + const awt::Rectangle aRect( getBounds() ); + const Point aSize( aRect.Width, aRect.Height ); + const Point aNullPoint, aTestPoint( aPoint.X, aPoint.Y ); + + return tools::Rectangle( aNullPoint, aSize ).IsInside( aTestPoint ); +} + +uno::Reference< accessibility::XAccessible > SAL_CALL SfxThumbnailViewAcc::getAccessibleAtPoint( const awt::Point& aPoint ) +{ + ThrowIfDisposed(); + const SolarMutexGuard aSolarGuard; + const sal_uInt16 nItemId = mpParent->GetItemId( Point( aPoint.X, aPoint.Y ) ); + uno::Reference< accessibility::XAccessible > xRet; + + if ( nItemId ) + { + const size_t nItemPos = mpParent->GetItemPos( nItemId ); + + if( THUMBNAILVIEW_ITEM_NONEITEM != nItemPos ) + { + ThumbnailViewItem *const pItem = mpParent->mFilteredItemList[nItemPos]; + xRet = pItem->GetAccessible( /*bIsTransientChildrenDisabled*/false ); + } + } + + return xRet; +} + +awt::Rectangle SAL_CALL SfxThumbnailViewAcc::getBounds() +{ + ThrowIfDisposed(); + const SolarMutexGuard aSolarGuard; + const Point aOutPos; + const Size aOutSize( mpParent->GetOutputSizePixel() ); + awt::Rectangle aRet; + + aRet.X = aOutPos.X(); + aRet.Y = aOutPos.Y(); + aRet.Width = aOutSize.Width(); + aRet.Height = aOutSize.Height(); + + return aRet; +} + +awt::Point SAL_CALL SfxThumbnailViewAcc::getLocation() +{ + ThrowIfDisposed(); + const awt::Rectangle aRect( getBounds() ); + awt::Point aRet; + + aRet.X = aRect.X; + aRet.Y = aRect.Y; + + return aRet; +} + +awt::Point SAL_CALL SfxThumbnailViewAcc::getLocationOnScreen() +{ + ThrowIfDisposed(); + const SolarMutexGuard aSolarGuard; + awt::Point aScreenLoc(0, 0); + + uno::Reference<accessibility::XAccessible> xParent(getAccessibleParent()); + if (xParent) + { + uno::Reference<accessibility::XAccessibleContext> xParentContext(xParent->getAccessibleContext()); + uno::Reference<accessibility::XAccessibleComponent> xParentComponent(xParentContext, css::uno::UNO_QUERY); + OSL_ENSURE( xParentComponent.is(), "SfxThumbnailViewAcc::getLocationOnScreen: no parent component!" ); + if ( xParentComponent.is() ) + { + awt::Point aParentScreenLoc( xParentComponent->getLocationOnScreen() ); + awt::Point aOwnRelativeLoc( getLocation() ); + aScreenLoc.X = aParentScreenLoc.X + aOwnRelativeLoc.X; + aScreenLoc.Y = aParentScreenLoc.Y + aOwnRelativeLoc.Y; + } + } + + return aScreenLoc; +} + +awt::Size SAL_CALL SfxThumbnailViewAcc::getSize() +{ + ThrowIfDisposed(); + const awt::Rectangle aRect( getBounds() ); + awt::Size aRet; + + aRet.Width = aRect.Width; + aRet.Height = aRect.Height; + + return aRet; +} + +void SAL_CALL SfxThumbnailViewAcc::grabFocus() +{ + ThrowIfDisposed(); + const SolarMutexGuard aSolarGuard; + mpParent->GrabFocus(); +} + +sal_Int32 SAL_CALL SfxThumbnailViewAcc::getForeground( ) +{ + ThrowIfDisposed(); + Color nColor = Application::GetSettings().GetStyleSettings().GetWindowTextColor(); + return static_cast<sal_Int32>(nColor); +} + +sal_Int32 SAL_CALL SfxThumbnailViewAcc::getBackground( ) +{ + ThrowIfDisposed(); + Color nColor = Application::GetSettings().GetStyleSettings().GetWindowColor(); + return static_cast<sal_Int32>(nColor); +} + +void SAL_CALL SfxThumbnailViewAcc::selectAccessibleChild( sal_Int32 nChildIndex ) +{ + ThrowIfDisposed(); + const SolarMutexGuard aSolarGuard; + ThumbnailViewItem* pItem = getItem (sal::static_int_cast< sal_uInt16 >(nChildIndex)); + + if(pItem == nullptr) + throw lang::IndexOutOfBoundsException(); + + mpParent->SelectItem( pItem->mnId ); +} + +sal_Bool SAL_CALL SfxThumbnailViewAcc::isAccessibleChildSelected( sal_Int32 nChildIndex ) +{ + ThrowIfDisposed(); + const SolarMutexGuard aSolarGuard; + ThumbnailViewItem* pItem = getItem (sal::static_int_cast< sal_uInt16 >(nChildIndex)); + + if (pItem == nullptr) + throw lang::IndexOutOfBoundsException(); + + return mpParent->IsItemSelected( pItem->mnId ); +} + +void SAL_CALL SfxThumbnailViewAcc::clearAccessibleSelection() +{ + ThrowIfDisposed(); +} + +void SAL_CALL SfxThumbnailViewAcc::selectAllAccessibleChildren() +{ + ThrowIfDisposed(); + // unsupported due to single selection only +} + +sal_Int32 SAL_CALL SfxThumbnailViewAcc::getSelectedAccessibleChildCount() +{ + ThrowIfDisposed(); + const SolarMutexGuard aSolarGuard; + sal_Int32 nRet = 0; + + for( sal_uInt16 i = 0, nCount = getItemCount(); i < nCount; i++ ) + { + ThumbnailViewItem* pItem = getItem (i); + + if( pItem && mpParent->IsItemSelected( pItem->mnId ) ) + ++nRet; + } + + return nRet; +} + +uno::Reference< accessibility::XAccessible > SAL_CALL SfxThumbnailViewAcc::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) +{ + ThrowIfDisposed(); + const SolarMutexGuard aSolarGuard; + uno::Reference< accessibility::XAccessible > xRet; + + for( sal_uInt16 i = 0, nCount = getItemCount(), nSel = 0; ( i < nCount ) && !xRet.is(); i++ ) + { + ThumbnailViewItem* pItem = getItem(i); + + if( pItem && mpParent->IsItemSelected( pItem->mnId ) && ( nSelectedChildIndex == static_cast< sal_Int32 >( nSel++ ) ) ) + xRet = pItem->GetAccessible( /*bIsTransientChildrenDisabled*/false ); + } + + return xRet; +} + +void SAL_CALL SfxThumbnailViewAcc::deselectAccessibleChild( sal_Int32 ) +{ + ThrowIfDisposed(); + const SolarMutexGuard aSolarGuard; + // Because of the single selection we can reset the whole selection when + // the specified child is currently selected. +//FIXME TODO if (isAccessibleChildSelected(nChildIndex)) +//FIXME TODO ; +} + +sal_Int64 SAL_CALL SfxThumbnailViewAcc::getSomething( const uno::Sequence< sal_Int8 >& rId ) +{ + sal_Int64 nRet; + + if( ( rId.getLength() == 16 ) && ( 0 == memcmp( SfxThumbnailViewAcc::getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) ) + nRet = reinterpret_cast< sal_Int64 >( this ); + else + nRet = 0; + + return nRet; +} + +void SAL_CALL SfxThumbnailViewAcc::disposing() +{ + ::std::vector<uno::Reference<accessibility::XAccessibleEventListener> > aListenerListCopy; + + { + // Make a copy of the list and clear the original. + const SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard (m_aMutex); + aListenerListCopy = mxEventListeners; + mxEventListeners.clear(); + + // Reset the pointer to the parent. It has to be the one who has + // disposed us because he is dying. + mpParent = nullptr; + } + + // Inform all listeners that this objects is disposing. + lang::EventObject aEvent (static_cast<accessibility::XAccessible*>(this)); + for (auto const& listener : aListenerListCopy) + { + try + { + listener->disposing (aEvent); + } + catch(const uno::Exception&) + { + // Ignore exceptions. + } + } +} + +sal_uInt16 SfxThumbnailViewAcc::getItemCount() const +{ + return mpParent->ImplGetVisibleItemCount(); +} + +ThumbnailViewItem* SfxThumbnailViewAcc::getItem (sal_uInt16 nIndex) const +{ + return mpParent->ImplGetVisibleItem (nIndex); +} + +void SfxThumbnailViewAcc::ThrowIfDisposed() +{ + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + SAL_WARN("sfx", "Calling disposed object. Throwing exception:"); + throw lang::DisposedException ( + "object has been already disposed", + static_cast<uno::XWeak*>(this)); + } + else + { + DBG_ASSERT (mpParent!=nullptr, "ValueSetAcc not disposed but mpParent == NULL"); + } +} + ThumbnailViewItemAcc::ThumbnailViewItemAcc( ThumbnailViewItem* pParent, bool bIsTransientChildrenDisabled ) : mpParent( pParent ), mbIsTransientChildrenDisabled( bIsTransientChildrenDisabled ) @@ -614,7 +1140,7 @@ uno::Reference< accessibility::XAccessible > SAL_CALL ThumbnailViewItemAcc::getA uno::Reference< accessibility::XAccessible > xRet; if( mpParent ) - xRet = mpParent->mrParent.GetAccessible(); + xRet = mpParent->mrParent.getAccessible(); return xRet; } @@ -798,7 +1324,19 @@ awt::Rectangle SAL_CALL ThumbnailViewItemAcc::getBounds() if( mpParent ) { tools::Rectangle aRect( mpParent->getDrawArea() ); - tools::Rectangle aParentRect( Point(), mpParent->mrParent.GetOutputSizePixel() ); + tools::Rectangle aParentRect; + + // get position of the accessible parent in screen coordinates + uno::Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + uno::Reference<XAccessibleComponent> xParentComponent(xParent->getAccessibleContext(), uno::UNO_QUERY); + if (xParentComponent.is()) + { + awt::Size aParentSize = xParentComponent->getSize(); + aParentRect = tools::Rectangle(0, 0, aParentSize.Width, aParentSize.Height); + } + } aRect.Intersection( aParentRect ); @@ -830,10 +1368,22 @@ awt::Point SAL_CALL ThumbnailViewItemAcc::getLocationOnScreen() if( mpParent ) { const Point aPos = mpParent->getDrawArea().TopLeft(); - const Point aScreenPos( mpParent->mrParent.OutputToAbsoluteScreenPixel( aPos ) ); - aRet.X = aScreenPos.X(); - aRet.Y = aScreenPos.Y(); + aRet.X = aPos.X(); + aRet.Y = aPos.Y(); + + // get position of the accessible parent in screen coordinates + uno::Reference< XAccessible > xParent = getAccessibleParent(); + if ( xParent.is() ) + { + uno::Reference<XAccessibleComponent> xParentComponent(xParent->getAccessibleContext(), uno::UNO_QUERY); + if (xParentComponent.is()) + { + awt::Point aParentScreenLoc = xParentComponent->getLocationOnScreen(); + aRet.X += aParentScreenLoc.X; + aRet.Y += aParentScreenLoc.Y; + } + } } return aRet; diff --git a/sfx2/source/control/thumbnailviewacc.hxx b/sfx2/source/control/thumbnailviewacc.hxx index ecddba7efce0..0cc51229165a 100644 --- a/sfx2/source/control/thumbnailviewacc.hxx +++ b/sfx2/source/control/thumbnailviewacc.hxx @@ -37,6 +37,7 @@ #include <vector> class ThumbnailView; +class SfxThumbnailView; class ThumbnailViewItem; typedef ::cppu::WeakComponentImplHelper< @@ -158,6 +159,117 @@ private: void ThrowIfDisposed(); }; +class SfxThumbnailViewAcc : + public ::cppu::BaseMutex, + public ValueSetAccComponentBase +{ +public: + + SfxThumbnailViewAcc( SfxThumbnailView* pParent ); + virtual ~SfxThumbnailViewAcc() override; + + void FireAccessibleEvent( short nEventId, + const css::uno::Any& rOldValue, + const css::uno::Any& rNewValue ); + + bool HasAccessibleListeners() const { return( mxEventListeners.size() > 0 ); } + + static SfxThumbnailViewAcc* getImplementation( const css::uno::Reference< css::uno::XInterface >& rxData ) throw(); + +public: + + /** Called by the corresponding ValueSet when it gets the focus. + Stores the new focus state and broadcasts a state change event. + */ + void GetFocus(); + + /** Called by the corresponding ValueSet when it loses the focus. + Stores the new focus state and broadcasts a state change event. + */ + void LoseFocus(); + + // XAccessible + virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) override; + + // XAccessibleEventBroadcaster + virtual void SAL_CALL addAccessibleEventListener( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener ) override; + virtual void SAL_CALL removeAccessibleEventListener( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener ) override; + + // XAccessibleContext + virtual sal_Int32 SAL_CALL getAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override; + virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) override; + virtual sal_Int16 SAL_CALL getAccessibleRole( ) override; + virtual OUString SAL_CALL getAccessibleDescription( ) override; + virtual OUString SAL_CALL getAccessibleName( ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) override; + virtual css::uno::Reference< css::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet( ) override; + virtual css::lang::Locale SAL_CALL getLocale( ) override; + + // XAccessibleComponent + virtual sal_Bool SAL_CALL containsPoint( const css::awt::Point& aPoint ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override; + virtual css::awt::Rectangle SAL_CALL getBounds( ) override; + virtual css::awt::Point SAL_CALL getLocation( ) override; + virtual css::awt::Point SAL_CALL getLocationOnScreen( ) override; + virtual css::awt::Size SAL_CALL getSize( ) override; + virtual void SAL_CALL grabFocus( ) override; + virtual sal_Int32 SAL_CALL getForeground( ) override; + virtual sal_Int32 SAL_CALL getBackground( ) override; + + // XAccessibleSelection + virtual void SAL_CALL selectAccessibleChild( sal_Int32 nChildIndex ) override; + virtual sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int32 nChildIndex ) override; + virtual void SAL_CALL clearAccessibleSelection( ) override; + virtual void SAL_CALL selectAllAccessibleChildren( ) override; + virtual sal_Int32 SAL_CALL getSelectedAccessibleChildCount( ) override; + virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) override; + virtual void SAL_CALL deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) override; + + // XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( const css::uno::Sequence< sal_Int8 >& rId ) override; + +private: + ::std::vector< css::uno::Reference< + css::accessibility::XAccessibleEventListener > > mxEventListeners; + SfxThumbnailView* mpParent; + /// The current FOCUSED state. + bool mbIsFocused; + + static const css::uno::Sequence< sal_Int8 >& getUnoTunnelId(); + + /** Tell all listeners that the object is dying. This callback is + usually called from the WeakComponentImplHelper class. + */ + virtual void SAL_CALL disposing() override; + + /** Return the number of items. This takes the None-Item into account. + */ + sal_uInt16 getItemCount() const; + + /** Return the item associated with the given index. The None-Item is + taken into account which, when present, is taken to be the first + (with index 0) item. + @param nIndex + Index of the item to return. The index 0 denotes the None-Item + when present. + @return + Returns NULL when the given index is out of range. + */ + ThumbnailViewItem* getItem (sal_uInt16 nIndex) const; + + /** Check whether or not the object has been disposed (or is in the + state of being disposed). If that is the case then + DisposedException is thrown to inform the (indirect) caller of the + foul deed. + + @throws css::lang::DisposedException + */ + void ThrowIfDisposed(); +}; + + class ThumbnailViewItemAcc : public ::cppu::WeakImplHelper< css::accessibility::XAccessible, css::accessibility::XAccessibleEventBroadcaster, css::accessibility::XAccessibleContext, diff --git a/sfx2/source/control/thumbnailviewitem.cxx b/sfx2/source/control/thumbnailviewitem.cxx index a59d2377884b..6e0619daf945 100644 --- a/sfx2/source/control/thumbnailviewitem.cxx +++ b/sfx2/source/control/thumbnailviewitem.cxx @@ -45,7 +45,7 @@ using namespace ::com::sun::star; using namespace drawinglayer::attribute; using namespace drawinglayer::primitive2d; -ThumbnailViewItem::ThumbnailViewItem(ThumbnailView &rView, sal_uInt16 nId) +ThumbnailViewItem::ThumbnailViewItem(ThumbnailViewBase &rView, sal_uInt16 nId) : mrParent(rView) , mnId(nId) , mbVisible(true) diff --git a/sfx2/source/dialog/inputdlg.cxx b/sfx2/source/dialog/inputdlg.cxx index 55849915ec39..7919e9ca6faf 100644 --- a/sfx2/source/dialog/inputdlg.cxx +++ b/sfx2/source/dialog/inputdlg.cxx @@ -10,7 +10,7 @@ #include <sfx2/inputdlg.hxx> #include <vcl/svapp.hxx> -InputDialog::InputDialog(weld::Window* pParent, const OUString &rLabelText) +InputDialog::InputDialog(weld::Widget* pParent, const OUString &rLabelText) : GenericDialogController(pParent, "sfx/ui/inputdialog.ui", "InputDialog") , m_xEntry(m_xBuilder->weld_entry("entry")) , m_xLabel(m_xBuilder->weld_label("label")) diff --git a/sfx2/source/doc/templatedlg.cxx b/sfx2/source/doc/templatedlg.cxx index 351e610d6e71..f713b4966b5e 100644 --- a/sfx2/source/doc/templatedlg.cxx +++ b/sfx2/source/doc/templatedlg.cxx @@ -68,13 +68,11 @@ const char TM_SETTING_MANAGER[] = "TemplateManager"; const char TM_SETTING_LASTFOLDER[] = "LastFolder"; const char TM_SETTING_LASTAPPLICATION[] = "LastApplication"; -const char ACTIONBAR_ACTION[] = "action_menu"; - -#define MNI_ACTION_NEW_FOLDER 1 -#define MNI_ACTION_RENAME_FOLDER 2 -#define MNI_ACTION_DELETE_FOLDER 3 -#define MNI_ACTION_REFRESH 4 -#define MNI_ACTION_DEFAULT 5 +#define MNI_ACTION_NEW_FOLDER "new" +#define MNI_ACTION_RENAME_FOLDER "rename" +#define MNI_ACTION_DELETE_FOLDER "delete" +#define MNI_ACTION_REFRESH "refresh" +#define MNI_ACTION_DEFAULT "default" #define MNI_WRITER 1 #define MNI_CALC 2 #define MNI_IMPRESS 3 @@ -153,174 +151,138 @@ static bool cmpSelectionItems (const ThumbnailViewItem *pItem1, const ThumbnailV return pItem1->mnId > pItem2->mnId; } -SfxTemplateManagerDlg::SfxTemplateManagerDlg(vcl::Window *parent) - : ModalDialog(parent, "TemplateDialog", "sfx/ui/templatedlg.ui"), - maSelTemplates(cmpSelectionItems), - mxDesktop( Desktop::create(comphelper::getProcessComponentContext()) ) +SfxTemplateManagerDlg::SfxTemplateManagerDlg(weld::Window *pParent) + : GenericDialogController(pParent, "sfx/ui/templatedlg.ui", "TemplateDialog") + , maSelTemplates(cmpSelectionItems) + , mxDesktop(Desktop::create(comphelper::getProcessComponentContext())) + , m_aUpdateDataTimer("UpdateDataTimer") + , mxSearchFilter(m_xBuilder->weld_entry("search_filter")) + , mxCBApp(m_xBuilder->weld_combo_box("filter_application")) + , mxCBFolder(m_xBuilder->weld_combo_box("filter_folder")) + , mxOKButton(m_xBuilder->weld_button("ok")) + , mxMoveButton(m_xBuilder->weld_button("move_btn")) + , mxExportButton(m_xBuilder->weld_button("export_btn")) + , mxImportButton(m_xBuilder->weld_button("import_btn")) + , mxLinkButton(m_xBuilder->weld_button("online_link")) + , mxCBXHideDlg(m_xBuilder->weld_check_button("hidedialogcb")) + , mxActionBar(m_xBuilder->weld_menu_button("action_menu")) + , mxSearchView(new TemplateSearchView(m_xBuilder->weld_scrolled_window("scrollsearch"), + m_xBuilder->weld_menu("contextmenu1"))) + , mxLocalView(new SfxTemplateLocalView(m_xBuilder->weld_scrolled_window("scrolllocal"), + m_xBuilder->weld_menu("contextmenu2"))) + , mxTemplateDefaultMenu(m_xBuilder->weld_menu("submenu")) + , mxSearchViewWeld(new weld::CustomWeld(*m_xBuilder, "search_view", *mxSearchView)) + , mxLocalViewWeld(new weld::CustomWeld(*m_xBuilder, "template_view", *mxLocalView)) { - get(mpSearchFilter, "search_filter"); - get(mpCBApp, "filter_application"); - get(mpCBFolder, "filter_folder"); - get(mpActionBar, "action_action"); - get(mpLocalView, "template_view"); - get(mpSearchView, "search_view"); - get(mpOKButton, "ok"); - get(mpMoveButton, "move_btn"); - get(mpExportButton, "export_btn"); - get(mpImportButton, "import_btn"); - get(mpLinkButton, "online_link"); - get(mpCBXHideDlg, "hidedialogcb"); - // Create popup menus - mpActionMenu = VclPtr<PopupMenu>::Create(); - mpActionMenu->InsertItem(MNI_ACTION_NEW_FOLDER, - SfxResId(STR_CATEGORY_NEW), - Image(StockImage::Yes, BMP_ACTION_REFRESH)); - mpActionMenu->InsertItem(MNI_ACTION_RENAME_FOLDER, - SfxResId(STR_CATEGORY_RENAME)); - mpActionMenu->InsertItem(MNI_ACTION_DELETE_FOLDER, - SfxResId(STR_CATEGORY_DELETE)); - mpActionMenu->InsertSeparator(); - mpActionMenu->InsertItem(MNI_ACTION_REFRESH, - SfxResId(STR_ACTION_REFRESH), - Image(StockImage::Yes, BMP_ACTION_REFRESH)); - mpActionMenu->InsertItem(MNI_ACTION_DEFAULT,SfxResId(STR_ACTION_DEFAULT)); - mpActionMenu->SetSelectHdl(LINK(this,SfxTemplateManagerDlg,MenuSelectHdl)); - - mpTemplateDefaultMenu = VclPtr<PopupMenu>::Create(); - mpTemplateDefaultMenu->SetSelectHdl(LINK(this,SfxTemplateManagerDlg,DefaultTemplateMenuSelectHdl)); - mpActionMenu->SetPopupMenu(MNI_ACTION_DEFAULT,mpTemplateDefaultMenu); - - // Set toolbox button bits - mpActionBar->SetItemBits(mpActionBar->GetItemId(ACTIONBAR_ACTION), ToolBoxItemBits::DROPDOWNONLY); - - // Set toolbox handlers - mpActionBar->SetDropdownClickHdl(LINK(this,SfxTemplateManagerDlg,TBXDropdownHdl)); - - mpLocalView->SetStyle(mpLocalView->GetStyle() | WB_VSCROLL); - mpLocalView->setItemMaxTextLength(TEMPLATE_ITEM_MAX_TEXT_LENGTH); - - mpLocalView->setItemDimensions(TEMPLATE_ITEM_MAX_WIDTH,TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT, + OUString sBmp(BMP_ACTION_REFRESH); + mxActionBar->insert_item(0, MNI_ACTION_NEW_FOLDER, SfxResId(STR_CATEGORY_NEW), &sBmp, nullptr, false); + mxActionBar->insert_item(1, MNI_ACTION_RENAME_FOLDER, SfxResId(STR_CATEGORY_RENAME), nullptr, nullptr, false); + mxActionBar->insert_item(2, MNI_ACTION_DELETE_FOLDER, SfxResId(STR_CATEGORY_DELETE), nullptr, nullptr, false); + mxActionBar->insert_separator(3, "separator"); + mxActionBar->insert_item(4, MNI_ACTION_REFRESH, SfxResId(STR_ACTION_REFRESH), &sBmp, nullptr, false); + mxActionBar->connect_selected(LINK(this,SfxTemplateManagerDlg,MenuSelectHdl)); + + mxLocalView->setItemMaxTextLength(TEMPLATE_ITEM_MAX_TEXT_LENGTH); + mxLocalView->setItemDimensions(TEMPLATE_ITEM_MAX_WIDTH,TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT, TEMPLATE_ITEM_MAX_HEIGHT-TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT, TEMPLATE_ITEM_PADDING); - mpLocalView->setItemStateHdl(LINK(this,SfxTemplateManagerDlg,TVItemStateHdl)); - mpLocalView->setCreateContextMenuHdl(LINK(this,SfxTemplateManagerDlg, CreateContextMenuHdl)); - mpLocalView->setOpenRegionHdl(LINK(this,SfxTemplateManagerDlg, OpenRegionHdl)); - mpLocalView->setOpenTemplateHdl(LINK(this,SfxTemplateManagerDlg, OpenTemplateHdl)); - mpLocalView->setEditTemplateHdl(LINK(this,SfxTemplateManagerDlg, EditTemplateHdl)); - mpLocalView->setDeleteTemplateHdl(LINK(this,SfxTemplateManagerDlg, DeleteTemplateHdl)); - mpLocalView->setDefaultTemplateHdl(LINK(this,SfxTemplateManagerDlg, DefaultTemplateHdl)); + mxLocalView->setItemStateHdl(LINK(this,SfxTemplateManagerDlg,TVItemStateHdl)); + mxLocalView->setCreateContextMenuHdl(LINK(this,SfxTemplateManagerDlg, CreateContextMenuHdl)); + mxLocalView->setOpenRegionHdl(LINK(this,SfxTemplateManagerDlg, OpenRegionHdl)); + mxLocalView->setOpenTemplateHdl(LINK(this,SfxTemplateManagerDlg, OpenTemplateHdl)); + mxLocalView->setEditTemplateHdl(LINK(this,SfxTemplateManagerDlg, EditTemplateHdl)); + mxLocalView->setDeleteTemplateHdl(LINK(this,SfxTemplateManagerDlg, DeleteTemplateHdl)); + mxLocalView->setDefaultTemplateHdl(LINK(this,SfxTemplateManagerDlg, DefaultTemplateHdl)); - mpSearchView->setItemMaxTextLength(TEMPLATE_ITEM_MAX_TEXT_LENGTH); + mxSearchView->setItemMaxTextLength(TEMPLATE_ITEM_MAX_TEXT_LENGTH); - mpSearchView->setItemDimensions(TEMPLATE_ITEM_MAX_WIDTH,TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT, + mxSearchView->setItemDimensions(TEMPLATE_ITEM_MAX_WIDTH,TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT, TEMPLATE_ITEM_MAX_HEIGHT_SUB-TEMPLATE_ITEM_THUMBNAIL_MAX_HEIGHT, TEMPLATE_ITEM_PADDING); - mpSearchView->setItemStateHdl(LINK(this,SfxTemplateManagerDlg,TVItemStateHdl)); - mpSearchView->setCreateContextMenuHdl(LINK(this,SfxTemplateManagerDlg, CreateContextMenuHdl)); - mpSearchView->setOpenTemplateHdl(LINK(this,SfxTemplateManagerDlg,OpenTemplateHdl)); - mpSearchView->setEditTemplateHdl(LINK(this,SfxTemplateManagerDlg, EditTemplateHdl)); - mpSearchView->setDeleteTemplateHdl(LINK(this,SfxTemplateManagerDlg, DeleteTemplateHdl)); - mpSearchView->setDefaultTemplateHdl(LINK(this,SfxTemplateManagerDlg, DefaultTemplateHdl)); + mxSearchView->setItemStateHdl(LINK(this,SfxTemplateManagerDlg,TVItemStateHdl)); + mxSearchView->setCreateContextMenuHdl(LINK(this,SfxTemplateManagerDlg, CreateContextMenuHdl)); + mxSearchView->setOpenTemplateHdl(LINK(this,SfxTemplateManagerDlg,OpenTemplateHdl)); + mxSearchView->setEditTemplateHdl(LINK(this,SfxTemplateManagerDlg, EditTemplateHdl)); + mxSearchView->setDeleteTemplateHdl(LINK(this,SfxTemplateManagerDlg, DeleteTemplateHdl)); + mxSearchView->setDefaultTemplateHdl(LINK(this,SfxTemplateManagerDlg, DefaultTemplateHdl)); - mpLocalView->ShowTooltips(true); - mpSearchView->ShowTooltips(true); + mxLocalView->ShowTooltips(true); + mxSearchView->ShowTooltips(true); - mpOKButton->SetClickHdl(LINK(this, SfxTemplateManagerDlg, OkClickHdl)); - mpMoveButton->SetClickHdl(LINK(this, SfxTemplateManagerDlg, MoveClickHdl)); - mpExportButton->SetClickHdl(LINK(this, SfxTemplateManagerDlg, ExportClickHdl)); - mpImportButton->SetClickHdl(LINK(this, SfxTemplateManagerDlg, ImportClickHdl)); - mpLinkButton->SetClickHdl(LINK(this, SfxTemplateManagerDlg, LinkClickHdl)); + mxOKButton->connect_clicked(LINK(this, SfxTemplateManagerDlg, OkClickHdl)); + mxMoveButton->connect_clicked(LINK(this, SfxTemplateManagerDlg, MoveClickHdl)); + mxExportButton->connect_clicked(LINK(this, SfxTemplateManagerDlg, ExportClickHdl)); + mxImportButton->connect_clicked(LINK(this, SfxTemplateManagerDlg, ImportClickHdl)); + mxLinkButton->connect_clicked(LINK(this, SfxTemplateManagerDlg, LinkClickHdl)); - mpSearchFilter->SetUpdateDataHdl(LINK(this, SfxTemplateManagerDlg, SearchUpdateHdl)); - mpSearchFilter->EnableUpdateData(); - mpSearchFilter->SetGetFocusHdl(LINK( this, SfxTemplateManagerDlg, GetFocusHdl )); + mxSearchFilter->connect_changed(LINK(this, SfxTemplateManagerDlg, SearchUpdateHdl)); + mxSearchFilter->connect_focus_in(LINK( this, SfxTemplateManagerDlg, GetFocusHdl )); + mxSearchFilter->connect_focus_out(LINK( this, SfxTemplateManagerDlg, LoseFocusHdl )); + mxSearchFilter->connect_key_press(LINK( this, SfxTemplateManagerDlg, KeyInputHdl)); - mpActionBar->Show(); + mxActionBar->show(); createDefaultTemplateMenu(); - mpLocalView->Populate(); - mpLocalView->filterItems(ViewFilter_Application(FILTER_APPLICATION::NONE)); + mxLocalView->Populate(); + mxLocalView->filterItems(ViewFilter_Application(FILTER_APPLICATION::NONE)); - mpCBApp->SelectEntryPos(0); + mxCBApp->set_active(0); fillFolderComboBox(); - mpExportButton->Disable(); - mpMoveButton->Disable(); - mpOKButton->SetText(SfxResId(STR_OPEN)); + mxExportButton->set_sensitive(false); + mxMoveButton->set_sensitive(false); + mxOKButton->set_label(SfxResId(STR_OPEN)); - mpCBApp->SetSelectHdl(LINK(this, SfxTemplateManagerDlg, SelectApplicationHdl)); - mpCBFolder->SetSelectHdl(LINK(this, SfxTemplateManagerDlg, SelectRegionHdl)); + mxCBApp->connect_changed(LINK(this, SfxTemplateManagerDlg, SelectApplicationHdl)); + mxCBFolder->connect_changed(LINK(this, SfxTemplateManagerDlg, SelectRegionHdl)); - mpLocalView->Show(); -} + mxLocalView->Show(); -SfxTemplateManagerDlg::~SfxTemplateManagerDlg() -{ - disposeOnce(); + m_aUpdateDataTimer.SetInvokeHandler(LINK(this, SfxTemplateManagerDlg, ImplUpdateDataHdl)); + m_aUpdateDataTimer.SetDebugName( "SfxTemplateManagerDlg UpdateDataTimer" ); + m_aUpdateDataTimer.SetTimeout(EDIT_UPDATEDATA_TIMEOUT); } -void SfxTemplateManagerDlg::dispose() +SfxTemplateManagerDlg::~SfxTemplateManagerDlg() { writeSettings(); // Ignore view events since we are cleaning the object - mpLocalView->setItemStateHdl(Link<const ThumbnailViewItem*,void>()); - mpLocalView->setOpenRegionHdl(Link<void*,void>()); - mpLocalView->setOpenTemplateHdl(Link<ThumbnailViewItem*, void>()); - - mpSearchView->setItemStateHdl(Link<const ThumbnailViewItem*,void>()); - mpSearchView->setOpenTemplateHdl(Link<ThumbnailViewItem*, void>()); - - mpOKButton.clear(); - mpMoveButton.clear(); - mpExportButton.clear(); - mpImportButton.clear(); - mpLinkButton.clear(); - mpCBXHideDlg.clear(); - mpSearchFilter.clear(); - mpCBApp.clear(); - mpCBFolder.clear(); - mpActionBar.clear(); - mpSearchView.clear(); - mpLocalView.clear(); - mpActionMenu.disposeAndClear(); - mpTemplateDefaultMenu.clear(); - - ModalDialog::dispose(); + mxLocalView->setItemStateHdl(Link<const ThumbnailViewItem*,void>()); + mxLocalView->setOpenRegionHdl(Link<void*,void>()); + mxLocalView->setOpenTemplateHdl(Link<ThumbnailViewItem*, void>()); + mxSearchView->setItemStateHdl(Link<const ThumbnailViewItem*,void>()); + mxSearchView->setOpenTemplateHdl(Link<ThumbnailViewItem*, void>()); } -short SfxTemplateManagerDlg::Execute() +short SfxTemplateManagerDlg::run() { //use application specific settings if there's no previous setting getApplicationSpecificSettings(); readSettings(); - return ModalDialog::Execute(); + return weld::GenericDialogController::run(); } -bool SfxTemplateManagerDlg::EventNotify( NotifyEvent& rNEvt ) +IMPL_LINK(SfxTemplateManagerDlg, KeyInputHdl, const KeyEvent&, rKeyEvent, bool) { - if (mpSearchFilter != nullptr && - mpSearchFilter->HasControlFocus() && - !mpSearchFilter->GetText().isEmpty() && - rNEvt.GetType() == MouseNotifyEvent::KEYINPUT) + if (mxSearchFilter != nullptr && !mxSearchFilter->get_text().isEmpty()) { - const KeyEvent* pKEvt = rNEvt.GetKeyEvent(); - vcl::KeyCode aKeyCode = pKEvt->GetKeyCode(); + vcl::KeyCode aKeyCode = rKeyEvent.GetKeyCode(); sal_uInt16 nKeyCode = aKeyCode.GetCode(); if ( nKeyCode == KEY_ESCAPE ) { - mpSearchFilter->SetText(""); - mpSearchFilter->UpdateData(); + mxSearchFilter->set_text(""); + SearchUpdateHdl(*mxSearchFilter); return true; } } - return ModalDialog::EventNotify(rNEvt); + return false; } void SfxTemplateManagerDlg::setDocumentModel(const uno::Reference<frame::XModel> &rModel) @@ -330,7 +292,7 @@ void SfxTemplateManagerDlg::setDocumentModel(const uno::Reference<frame::XModel> FILTER_APPLICATION SfxTemplateManagerDlg::getCurrentApplicationFilter() { - const sal_Int16 nCurAppId = mpCBApp->GetSelectedEntryPos(); + const sal_Int16 nCurAppId = mxCBApp->get_active(); if (nCurAppId == MNI_WRITER) return FILTER_APPLICATION::WRITER; @@ -346,23 +308,23 @@ FILTER_APPLICATION SfxTemplateManagerDlg::getCurrentApplicationFilter() void SfxTemplateManagerDlg::fillFolderComboBox() { - std::vector<OUString> aFolderNames = mpLocalView->getFolderNames(); + std::vector<OUString> aFolderNames = mxLocalView->getFolderNames(); for (size_t i = 0, n = aFolderNames.size(); i < n; ++i) - mpCBFolder->InsertEntry(aFolderNames[i], i+1); - mpCBFolder->SelectEntryPos(0); - mpActionMenu->HideItem(MNI_ACTION_RENAME_FOLDER); + mxCBFolder->append_text(aFolderNames[i]); + mxCBFolder->set_active(0); + mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, false); } void SfxTemplateManagerDlg::getApplicationSpecificSettings() { if ( ! m_xModel.is() ) { - mpCBApp->SelectEntryPos(0); - mpCBFolder->SelectEntryPos(0); - mpActionMenu->HideItem(MNI_ACTION_RENAME_FOLDER); - mpLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter())); - mpLocalView->showAllTemplates(); + mxCBApp->set_active(0); + mxCBFolder->set_active(0); + mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, false); + mxLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter())); + mxLocalView->showAllTemplates(); return; } @@ -373,26 +335,26 @@ void SfxTemplateManagerDlg::getApplicationSpecificSettings() case SvtModuleOptions::EFactory::WRITER: case SvtModuleOptions::EFactory::WRITERWEB: case SvtModuleOptions::EFactory::WRITERGLOBAL: - mpCBApp->SelectEntryPos(MNI_WRITER); + mxCBApp->set_active(MNI_WRITER); break; case SvtModuleOptions::EFactory::CALC: - mpCBApp->SelectEntryPos(MNI_CALC); + mxCBApp->set_active(MNI_CALC); break; case SvtModuleOptions::EFactory::IMPRESS: - mpCBApp->SelectEntryPos(MNI_IMPRESS); + mxCBApp->set_active(MNI_IMPRESS); break; case SvtModuleOptions::EFactory::DRAW: - mpCBApp->SelectEntryPos(MNI_DRAW); + mxCBApp->set_active(MNI_DRAW); break; default: - mpCBApp->SelectEntryPos(0); + mxCBApp->set_active(0); break; } - mpLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter())); - mpCBFolder->SelectEntryPos(0); - mpActionMenu->HideItem(MNI_ACTION_RENAME_FOLDER); - mpLocalView->showAllTemplates(); + mxLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter())); + mxCBFolder->set_active(0); + mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, false); + mxLocalView->showAllTemplates(); } void SfxTemplateManagerDlg::readSettings () @@ -412,38 +374,38 @@ void SfxTemplateManagerDlg::readSettings () switch (nTmp) { case MNI_WRITER: - mpCBApp->SelectEntryPos(MNI_WRITER); + mxCBApp->set_active(MNI_WRITER); break; case MNI_CALC: - mpCBApp->SelectEntryPos(MNI_CALC); + mxCBApp->set_active(MNI_CALC); break; case MNI_IMPRESS: - mpCBApp->SelectEntryPos(MNI_IMPRESS); + mxCBApp->set_active(MNI_IMPRESS); break; case MNI_DRAW: - mpCBApp->SelectEntryPos(MNI_DRAW); + mxCBApp->set_active(MNI_DRAW); break; default: - mpCBApp->SelectEntryPos(0); + mxCBApp->set_active(0); break; } } } - mpLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter())); + mxLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter())); if (aLastFolder.isEmpty()) { //show all categories - mpCBFolder->SelectEntryPos(0); - mpActionMenu->HideItem(MNI_ACTION_RENAME_FOLDER); - mpLocalView->showAllTemplates(); + mxCBFolder->set_active(0); + mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, false); + mxLocalView->showAllTemplates(); } else { - mpCBFolder->SelectEntry(aLastFolder); - mpLocalView->showRegion(aLastFolder); - mpActionMenu->ShowItem(MNI_ACTION_RENAME_FOLDER); + mxCBFolder->set_active_text(aLastFolder); + mxLocalView->showRegion(aLastFolder); + mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, true); } } @@ -451,14 +413,14 @@ void SfxTemplateManagerDlg::writeSettings () { OUString aLastFolder; - if (mpLocalView->getCurRegionId()) - aLastFolder = mpLocalView->getRegionName(mpLocalView->getCurRegionId()-1); + if (mxLocalView->getCurRegionId()) + aLastFolder = mxLocalView->getRegionName(mxLocalView->getCurRegionId()-1); // last folder Sequence< NamedValue > aSettings { { TM_SETTING_LASTFOLDER, css::uno::makeAny(aLastFolder) }, - { TM_SETTING_LASTAPPLICATION, css::uno::makeAny(sal_uInt16(mpCBApp->GetSelectedEntryPos())) } + { TM_SETTING_LASTAPPLICATION, css::uno::makeAny(sal_uInt16(mxCBApp->get_active())) } }; // write @@ -466,50 +428,35 @@ void SfxTemplateManagerDlg::writeSettings () aViewSettings.SetUserData(aSettings); } -IMPL_LINK_NOARG(SfxTemplateManagerDlg, SelectApplicationHdl, ListBox&, void) +IMPL_LINK_NOARG(SfxTemplateManagerDlg, SelectApplicationHdl, weld::ComboBox&, void) { - if(mpLocalView->IsVisible()) + if (mxLocalView->IsVisible()) { - mpLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter())); - mpLocalView->showAllTemplates(); - mpCBFolder->SelectEntryPos(0); - mpActionMenu->HideItem(MNI_ACTION_RENAME_FOLDER); + mxLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter())); + mxLocalView->showAllTemplates(); + mxCBFolder->set_active(0); + mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, false); } - - if(mpSearchView->IsVisible()) - SearchUpdateHdl(*mpSearchFilter); + if (mxSearchView->IsVisible()) + SearchUpdate(); } -IMPL_LINK_NOARG(SfxTemplateManagerDlg, SelectRegionHdl, ListBox&, void) +IMPL_LINK_NOARG(SfxTemplateManagerDlg, SelectRegionHdl, weld::ComboBox&, void) { - const OUString sSelectedRegion = mpCBFolder->GetSelectedEntry(); + const OUString sSelectedRegion = mxCBFolder->get_active_text(); - if(mpCBFolder->GetSelectedEntryPos() == 0) + if(mxCBFolder->get_active() == 0) { - mpLocalView->showAllTemplates(); - mpActionMenu->HideItem(MNI_ACTION_RENAME_FOLDER); + mxLocalView->showAllTemplates(); + mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, false); } else { - mpLocalView->showRegion(sSelectedRegion); - mpActionMenu->ShowItem(MNI_ACTION_RENAME_FOLDER); + mxLocalView->showRegion(sSelectedRegion); + mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, true); } - - if(mpSearchView->IsVisible()) - SearchUpdateHdl(*mpSearchFilter); -} - -IMPL_LINK_NOARG(SfxTemplateManagerDlg, TBXDropdownHdl, ToolBox*, void) -{ - const sal_uInt16 nCurItemId = mpActionBar->GetCurItemId(); - mpActionBar->SetItemDown( nCurItemId, true ); - - if (nCurItemId == mpActionBar->GetItemId(ACTIONBAR_ACTION)) - mpActionMenu->Execute(mpActionBar, mpActionBar->GetItemRect(nCurItemId), PopupMenuFlags::ExecuteDown); - - mpActionBar->SetItemDown( nCurItemId, false ); - mpActionBar->EndSelection(); - mpActionBar->Invalidate(); + if (mxSearchView->IsVisible()) + SearchUpdate(); } IMPL_LINK(SfxTemplateManagerDlg, TVItemStateHdl, const ThumbnailViewItem*, pItem, void) @@ -520,59 +467,46 @@ IMPL_LINK(SfxTemplateManagerDlg, TVItemStateHdl, const ThumbnailViewItem*, pItem OnTemplateState(pItem); } -IMPL_LINK(SfxTemplateManagerDlg, MenuSelectHdl, Menu*, pMenu, bool) +IMPL_LINK(SfxTemplateManagerDlg, MenuSelectHdl, const OString&, rIdent, void) { - sal_uInt16 nMenuId = pMenu->GetCurItemId(); - - switch(nMenuId) - { - case MNI_ACTION_NEW_FOLDER: + if (rIdent == MNI_ACTION_NEW_FOLDER) OnCategoryNew(); - break; - case MNI_ACTION_RENAME_FOLDER: + else if (rIdent == MNI_ACTION_RENAME_FOLDER) OnCategoryRename(); - break; - case MNI_ACTION_DELETE_FOLDER: + else if (rIdent == MNI_ACTION_DELETE_FOLDER) OnCategoryDelete(); - break; - case MNI_ACTION_REFRESH: - mpLocalView->reload(); - break; - default: - break; - } - - return false; + else if (rIdent == MNI_ACTION_REFRESH) + mxLocalView->reload(); + else if (rIdent != MNI_ACTION_DEFAULT) + DefaultTemplateMenuSelectHdl(rIdent); } -IMPL_LINK(SfxTemplateManagerDlg, DefaultTemplateMenuSelectHdl, Menu*, pMenu, bool) +void SfxTemplateManagerDlg::DefaultTemplateMenuSelectHdl(const OString& rIdent) { - sal_uInt16 nId = pMenu->GetCurItemId(); + fprintf(stderr, "DefaultTemplateMenuSelectHdl ident %s\n", rIdent.getStr()); - OUString aServiceName = SfxObjectShell::GetServiceNameFromFactory( mpTemplateDefaultMenu->GetItemCommand(nId)); + OUString aServiceName = SfxObjectShell::GetServiceNameFromFactory(OUString::fromUtf8(rIdent)); OUString sPrevDefault = SfxObjectFactory::GetStandardTemplate( aServiceName ); if(!sPrevDefault.isEmpty()) - mpLocalView->RemoveDefaultTemplateIcon(sPrevDefault); + mxLocalView->RemoveDefaultTemplateIcon(sPrevDefault); SfxObjectFactory::SetStandardTemplate( aServiceName, OUString() ); createDefaultTemplateMenu(); - - return false; } -IMPL_LINK_NOARG(SfxTemplateManagerDlg, OkClickHdl, Button*, void) +IMPL_LINK_NOARG(SfxTemplateManagerDlg, OkClickHdl, weld::Button&, void) { OnTemplateOpen(); - EndDialog(RET_OK); + m_xDialog->response(RET_OK); } -IMPL_LINK_NOARG(SfxTemplateManagerDlg, MoveClickHdl, Button*, void) +IMPL_LINK_NOARG(SfxTemplateManagerDlg, MoveClickHdl, weld::Button&, void) { // modal dialog to select templates category - SfxTemplateCategoryDialog aDlg(GetFrameWeld()); - aDlg.SetCategoryLBEntries(mpLocalView->getFolderNames()); + SfxTemplateCategoryDialog aDlg(m_xDialog.get()); + aDlg.SetCategoryLBEntries(mxLocalView->getFolderNames()); size_t nItemId = 0; @@ -584,36 +518,36 @@ IMPL_LINK_NOARG(SfxTemplateManagerDlg, MoveClickHdl, Button*, void) { if (!sCategory.isEmpty()) { - nItemId = mpLocalView->createRegion(sCategory); + nItemId = mxLocalView->createRegion(sCategory); if(nItemId) - mpCBFolder->InsertEntry(sCategory); + mxCBFolder->append_text(sCategory); } } else - nItemId = mpLocalView->getRegionId(sCategory); + nItemId = mxLocalView->getRegionId(sCategory); } if(nItemId) { - if (mpSearchView->IsVisible()) + if (mxSearchView->IsVisible()) localSearchMoveTo(nItemId); else localMoveTo(nItemId); } - mpLocalView->reload(); + mxLocalView->reload(); } -IMPL_LINK_NOARG(SfxTemplateManagerDlg, ExportClickHdl, Button*, void) +IMPL_LINK_NOARG(SfxTemplateManagerDlg, ExportClickHdl, weld::Button&, void) { OnTemplateExport(); } -IMPL_LINK_NOARG(SfxTemplateManagerDlg, ImportClickHdl, Button*, void) +IMPL_LINK_NOARG(SfxTemplateManagerDlg, ImportClickHdl, weld::Button&, void) { //Modal Dialog to select Category - SfxTemplateCategoryDialog aDlg(GetFrameWeld()); - aDlg.SetCategoryLBEntries(mpLocalView->getFolderNames()); + SfxTemplateCategoryDialog aDlg(m_xDialog.get()); + aDlg.SetCategoryLBEntries(mxLocalView->getFolderNames()); if (aDlg.run() == RET_OK) { @@ -621,15 +555,16 @@ IMPL_LINK_NOARG(SfxTemplateManagerDlg, ImportClickHdl, Button*, void) bool bIsNewCategory = aDlg.IsNewCategoryCreated(); if(bIsNewCategory) { - if(mpLocalView->createRegion(sCategory)) + if(mxLocalView->createRegion(sCategory)) { - mpCBFolder->InsertEntry(sCategory); + mxCBFolder->append_text(sCategory); OnTemplateImportCategory(sCategory); } else { OUString aMsg( SfxResId(STR_CREATE_ERROR) ); - std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, VclButtonsType::Ok, + std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(), + VclMessageType::Warning, VclButtonsType::Ok, aMsg.replaceFirst("$1", sCategory))); xBox->run(); return; @@ -639,14 +574,14 @@ IMPL_LINK_NOARG(SfxTemplateManagerDlg, ImportClickHdl, Button*, void) OnTemplateImportCategory(sCategory); } - mpLocalView->reload(); - mpLocalView->showAllTemplates(); - mpCBApp->SelectEntryPos(0); - mpCBFolder->SelectEntryPos(0); - mpActionMenu->HideItem(MNI_ACTION_RENAME_FOLDER); + mxLocalView->reload(); + mxLocalView->showAllTemplates(); + mxCBApp->set_active(0); + mxCBFolder->set_active(0); + mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, false); } -IMPL_STATIC_LINK_NOARG(SfxTemplateManagerDlg, LinkClickHdl, Button*, void) +IMPL_STATIC_LINK_NOARG(SfxTemplateManagerDlg, LinkClickHdl, weld::Button&, void) { OnTemplateLink(); } @@ -654,8 +589,8 @@ IMPL_STATIC_LINK_NOARG(SfxTemplateManagerDlg, LinkClickHdl, Button*, void) IMPL_LINK_NOARG(SfxTemplateManagerDlg, OpenRegionHdl, void*, void) { maSelTemplates.clear(); - mpOKButton->Disable(); - mpActionBar->Show(); + mxOKButton->set_sensitive(false); + mxActionBar->show(); } IMPL_LINK(SfxTemplateManagerDlg, CreateContextMenuHdl, ThumbnailViewItem*, pItem, void) @@ -664,14 +599,13 @@ IMPL_LINK(SfxTemplateManagerDlg, CreateContextMenuHdl, ThumbnailViewItem*, pItem if (pViewItem) { - if(mpSearchView->IsVisible()) - mpSearchView->createContextMenu(pViewItem->IsDefaultTemplate()); + if (mxSearchView->IsVisible()) + mxSearchView->createContextMenu(pViewItem->IsDefaultTemplate()); else - mpLocalView->createContextMenu(pViewItem->IsDefaultTemplate()); + mxLocalView->createContextMenu(pViewItem->IsDefaultTemplate()); } } - IMPL_LINK(SfxTemplateManagerDlg, OpenTemplateHdl, ThumbnailViewItem*, pItem, void) { uno::Sequence< PropertyValue > aArgs(5); @@ -696,7 +630,7 @@ IMPL_LINK(SfxTemplateManagerDlg, OpenTemplateHdl, ThumbnailViewItem*, pItem, voi { } - Close(); + m_xDialog->response(RET_OK); } IMPL_LINK(SfxTemplateManagerDlg, EditTemplateHdl, ThumbnailViewItem*, pItem, void) @@ -721,18 +655,17 @@ IMPL_LINK(SfxTemplateManagerDlg, EditTemplateHdl, ThumbnailViewItem*, pItem, voi { } - Close(); + m_xDialog->response(RET_OK); } IMPL_LINK(SfxTemplateManagerDlg, DeleteTemplateHdl, ThumbnailViewItem*, pItem, void) { OUString aDeletedTemplate; - - if(mpSearchView->IsVisible()) + if(mxSearchView->IsVisible()) { TemplateSearchViewItem *pSrchItem = static_cast<TemplateSearchViewItem*>(pItem); - if (!mpLocalView->removeTemplate(pSrchItem->mnAssocId, pSrchItem->mnRegionId)) + if (!mxLocalView->removeTemplate(pSrchItem->mnAssocId, pSrchItem->mnRegionId)) { aDeletedTemplate = pSrchItem->maTitle; } @@ -740,9 +673,9 @@ IMPL_LINK(SfxTemplateManagerDlg, DeleteTemplateHdl, ThumbnailViewItem*, pItem, v else { TemplateViewItem *pViewItem = static_cast<TemplateViewItem*>(pItem); - sal_uInt16 nRegionItemId = mpLocalView->getRegionId(pViewItem->mnRegionId); + sal_uInt16 nRegionItemId = mxLocalView->getRegionId(pViewItem->mnRegionId); - if (!mpLocalView->removeTemplate(pViewItem->mnDocId + 1, nRegionItemId))//mnId w.r.t. region is mnDocId + 1; + if (!mxLocalView->removeTemplate(pViewItem->mnDocId + 1, nRegionItemId))//mnId w.r.t. region is mnDocId + 1; { aDeletedTemplate = pItem->maTitle; } @@ -751,7 +684,8 @@ IMPL_LINK(SfxTemplateManagerDlg, DeleteTemplateHdl, ThumbnailViewItem*, pItem, v if (!aDeletedTemplate.isEmpty()) { OUString aMsg( SfxResId(STR_MSG_ERROR_DELETE_TEMPLATE) ); - std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, VclButtonsType::Ok, + std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(), + VclMessageType::Warning, VclButtonsType::Ok, aMsg.replaceFirst("$1",aDeletedTemplate))); xBox->run(); } @@ -768,7 +702,7 @@ IMPL_LINK(SfxTemplateManagerDlg, DefaultTemplateHdl, ThumbnailViewItem*, pItem, { OUString sPrevDefault = SfxObjectFactory::GetStandardTemplate( aServiceName ); if(!sPrevDefault.isEmpty()) - mpLocalView->RemoveDefaultTemplateIcon(sPrevDefault); + mxLocalView->RemoveDefaultTemplateIcon(sPrevDefault); SfxObjectFactory::SetStandardTemplate(aServiceName,pViewItem->getPath()); pViewItem->showDefaultIcon(true); @@ -786,32 +720,51 @@ IMPL_LINK(SfxTemplateManagerDlg, DefaultTemplateHdl, ThumbnailViewItem*, pItem, createDefaultTemplateMenu(); } -IMPL_LINK_NOARG(SfxTemplateManagerDlg, SearchUpdateHdl, Edit&, void) +IMPL_LINK_NOARG(SfxTemplateManagerDlg, SearchUpdateHdl, weld::Entry&, void) { - OUString aKeyword = mpSearchFilter->GetText(); + m_aUpdateDataTimer.Start(); +} + +IMPL_LINK_NOARG(SfxTemplateManagerDlg, ImplUpdateDataHdl, Timer*, void) +{ + SearchUpdate(); +} + +IMPL_LINK_NOARG(SfxTemplateManagerDlg, LoseFocusHdl, weld::Widget&, void) +{ + if (m_aUpdateDataTimer.IsActive()) + { + m_aUpdateDataTimer.Stop(); + m_aUpdateDataTimer.Invoke(); + } +} + +void SfxTemplateManagerDlg::SearchUpdate() +{ + OUString aKeyword = mxSearchFilter->get_text(); if (!aKeyword.isEmpty()) { - mpSearchView->Clear(); + mxSearchView->Clear(); // if the search view is hidden, hide the folder view and display search one - if (!mpSearchView->IsVisible()) + if (!mxSearchView->IsVisible()) { - mpLocalView->deselectItems(); - mpSearchView->Show(); - mpLocalView->Hide(); + mxLocalView->deselectItems(); + mxSearchView->Show(); + mxLocalView->Hide(); } std::vector<TemplateItemProperties> aItems = - mpLocalView->getFilteredItems(SearchView_Keyword(aKeyword, getCurrentApplicationFilter())); + mxLocalView->getFilteredItems(SearchView_Keyword(aKeyword, getCurrentApplicationFilter())); for (TemplateItemProperties& rItem : aItems) { OUString aFolderName; - aFolderName = mpLocalView->getRegionName(rItem.nRegionId); + aFolderName = mxLocalView->getRegionName(rItem.nRegionId); - mpSearchView->AppendItem(rItem.nId,mpLocalView->getRegionId(rItem.nRegionId), + mxSearchView->AppendItem(rItem.nId,mxLocalView->getRegionId(rItem.nRegionId), rItem.nDocId, rItem.aName, aFolderName, @@ -819,25 +772,25 @@ IMPL_LINK_NOARG(SfxTemplateManagerDlg, SearchUpdateHdl, Edit&, void) rItem.aThumbnail); } - mpSearchView->Invalidate(); + mxSearchView->Invalidate(); } else { - mpSearchView->deselectItems(); - mpSearchView->Hide(); - mpLocalView->Show(); - mpLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter())); - mpLocalView->reload(); - OUString sLastFolder = mpCBFolder->GetSelectedEntry(); - mpLocalView->showRegion(sLastFolder); - mpActionMenu->ShowItem(MNI_ACTION_RENAME_FOLDER); + mxSearchView->deselectItems(); + mxSearchView->Hide(); + mxLocalView->Show(); + mxLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter())); + mxLocalView->reload(); + OUString sLastFolder = mxCBFolder->get_active_text(); + mxLocalView->showRegion(sLastFolder); + mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, true); } } -IMPL_LINK_NOARG(SfxTemplateManagerDlg, GetFocusHdl, Control&, void) +IMPL_LINK_NOARG(SfxTemplateManagerDlg, GetFocusHdl, weld::Widget&, void) { - mpLocalView->deselectItems(); - mpSearchView->deselectItems(); + mxLocalView->deselectItems(); + mxSearchView->deselectItems(); maSelTemplates.clear(); } @@ -850,11 +803,11 @@ void SfxTemplateManagerDlg::OnTemplateState (const ThumbnailViewItem *pItem) { if (maSelTemplates.empty()) { - mpOKButton->Enable(); + mxOKButton->set_sensitive(true); } else if (maSelTemplates.size() != 1 || !bInSelection) { - mpOKButton->Disable(); + mxOKButton->set_sensitive(false); } if (!bInSelection) @@ -868,31 +821,31 @@ void SfxTemplateManagerDlg::OnTemplateState (const ThumbnailViewItem *pItem) if (maSelTemplates.empty()) { - mpOKButton->Disable(); + mxOKButton->set_sensitive(false); } else if (maSelTemplates.size() == 1) { - mpOKButton->Enable(); + mxOKButton->set_sensitive(true); } } } if(maSelTemplates.empty()) { - mpMoveButton->Disable(); - mpExportButton->Disable(); + mxMoveButton->set_sensitive(false); + mxExportButton->set_sensitive(false); } else { - mpMoveButton->Enable(); - mpExportButton->Enable(); + mxMoveButton->set_sensitive(true); + mxExportButton->set_sensitive(true); } } void SfxTemplateManagerDlg::OnTemplateImportCategory(const OUString& sCategory) { sfx2::FileDialogHelper aFileDlg(css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, - FileDialogFlags::MultiSelection, GetFrameWeld()); + FileDialogFlags::MultiSelection, m_xDialog.get()); // add "All" filter aFileDlg.AddFilter( SfxResId(STR_SFX_FILTERNAME_ALL), @@ -954,7 +907,7 @@ void SfxTemplateManagerDlg::OnTemplateImportCategory(const OUString& sCategory) return; //Import to the selected regions - TemplateContainerItem* pContItem = mpLocalView->getRegion(sCategory); + TemplateContainerItem* pContItem = mxLocalView->getRegion(sCategory); if(!pContItem) return; @@ -962,7 +915,7 @@ void SfxTemplateManagerDlg::OnTemplateImportCategory(const OUString& sCategory) for (size_t i = 0, n = aFiles.getLength(); i < n; ++i) { - if(!mpLocalView->copyFrom(pContItem,aFiles[i])) + if(!mxLocalView->copyFrom(pContItem,aFiles[i])) { if (aTemplateList.isEmpty()) aTemplateList = aFiles[i]; @@ -975,7 +928,8 @@ void SfxTemplateManagerDlg::OnTemplateImportCategory(const OUString& sCategory) { OUString aMsg(SfxResId(STR_MSG_ERROR_IMPORT)); aMsg = aMsg.replaceFirst("$1",pContItem->maTitle); - std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, VclButtonsType::Ok, + std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(), + VclMessageType::Warning, VclButtonsType::Ok, aMsg.replaceFirst("$2",aTemplateList))); xBox->run(); } @@ -998,7 +952,7 @@ void SfxTemplateManagerDlg::OnTemplateExport() INetURLObject aPathObj(xFolderPicker->getDirectory()); aPathObj.setFinalSlash(); - if (mpSearchView->IsVisible()) + if (mxSearchView->IsVisible()) { sal_uInt16 i = 1; @@ -1015,7 +969,7 @@ void SfxTemplateManagerDlg::OnTemplateExport() OUString aPath = aPathObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); - if (!mpLocalView->exportTo(pItem->mnAssocId,pItem->mnRegionId,aPath)) + if (!mxLocalView->exportTo(pItem->mnAssocId,pItem->mnRegionId,aPath)) { if (aTemplateList.isEmpty()) aTemplateList = pItem->maTitle; @@ -1025,7 +979,7 @@ void SfxTemplateManagerDlg::OnTemplateExport() ++i; } - mpSearchView->deselectItems(); + mxSearchView->deselectItems(); } else { @@ -1046,8 +1000,8 @@ void SfxTemplateManagerDlg::OnTemplateExport() OUString aPath = aPathObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); - if (!mpLocalView->exportTo(pItem->mnDocId + 1, //mnId w.r.t. region = mDocId + 1 - mpLocalView->getRegionId(pItem->mnRegionId), //pItem->mnRegionId does not store actual region Id + if (!mxLocalView->exportTo(pItem->mnDocId + 1, //mnId w.r.t. region = mDocId + 1 + mxLocalView->getRegionId(pItem->mnRegionId), //pItem->mnRegionId does not store actual region Id aPath)) { if (aTemplateList.isEmpty()) @@ -1058,20 +1012,22 @@ void SfxTemplateManagerDlg::OnTemplateExport() ++i; } - mpLocalView->deselectItems(); + mxLocalView->deselectItems(); } if (!aTemplateList.isEmpty()) { OUString aText( SfxResId(STR_MSG_ERROR_EXPORT) ); - std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, VclButtonsType::Ok, + std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(), + VclMessageType::Warning, VclButtonsType::Ok, aText.replaceFirst("$1",aTemplateList))); xBox->run(); } else { OUString sText( SfxResId(STR_MSG_EXPORT_SUCCESS) ); - std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Info, VclButtonsType::Ok, + std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(), + VclMessageType::Info, VclButtonsType::Ok, sText.replaceFirst("$1", OUString::number(nCount)))); xBox->run(); } @@ -1115,7 +1071,7 @@ void SfxTemplateManagerDlg::OnTemplateOpen () void SfxTemplateManagerDlg::OnCategoryNew() { - InputDialog dlg(GetFrameWeld(), SfxResId(STR_INPUT_NEW)); + InputDialog dlg(m_xDialog.get(), SfxResId(STR_INPUT_NEW)); int ret = dlg.run(); @@ -1124,12 +1080,13 @@ void SfxTemplateManagerDlg::OnCategoryNew() OUString aName = dlg.GetEntryText(); - if(mpLocalView->createRegion(aName)) - mpCBFolder->InsertEntry(aName); + if(mxLocalView->createRegion(aName)) + mxCBFolder->append_text(aName); else { OUString aMsg( SfxResId(STR_CREATE_ERROR) ); - std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, VclButtonsType::Ok, + std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(), + VclMessageType::Warning, VclButtonsType::Ok, aMsg.replaceFirst("$1", aName))); xBox->run(); } @@ -1137,8 +1094,8 @@ void SfxTemplateManagerDlg::OnCategoryNew() void SfxTemplateManagerDlg::OnCategoryRename() { - OUString sCategory = mpCBFolder->GetSelectedEntry(); - InputDialog dlg(GetFrameWeld(), SfxResId(STR_INPUT_NEW)); + OUString sCategory = mxCBFolder->get_active_text(); + InputDialog dlg(m_xDialog.get(), SfxResId(STR_INPUT_NEW)); dlg.SetEntryText(sCategory); int ret = dlg.run(); @@ -1148,20 +1105,21 @@ void SfxTemplateManagerDlg::OnCategoryRename() OUString aName = dlg.GetEntryText(); - if(mpLocalView->renameRegion(sCategory, aName)) + if(mxLocalView->renameRegion(sCategory, aName)) { - sal_Int32 nPos = mpCBFolder->GetEntryPos(sCategory); - mpCBFolder->RemoveEntry(nPos); - mpCBFolder->InsertEntry(aName, nPos); - mpCBFolder->SelectEntryPos(nPos); + sal_Int32 nPos = mxCBFolder->find_text(sCategory); + mxCBFolder->remove(nPos); + mxCBFolder->insert_text(nPos, aName); + mxCBFolder->set_active(nPos); - mpLocalView->reload(); - mpLocalView->showRegion(aName); + mxLocalView->reload(); + mxLocalView->showRegion(aName); } else { OUString aMsg( SfxResId(STR_CREATE_ERROR) ); - std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, VclButtonsType::Ok, + std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(), + VclMessageType::Warning, VclButtonsType::Ok, aMsg.replaceFirst("$1", aName))); xBox->run(); } @@ -1169,8 +1127,8 @@ void SfxTemplateManagerDlg::OnCategoryRename() void SfxTemplateManagerDlg::OnCategoryDelete() { - SfxTemplateCategoryDialog aDlg(GetFrameWeld()); - aDlg.SetCategoryLBEntries(mpLocalView->getFolderNames()); + SfxTemplateCategoryDialog aDlg(m_xDialog.get()); + aDlg.SetCategoryLBEntries(mxLocalView->getFolderNames()); aDlg.HideNewCategoryOption(); aDlg.set_title(SfxResId(STR_CATEGORY_DELETE)); aDlg.SetSelectLabelText(SfxResId(STR_CATEGORY_SELECT)); @@ -1178,31 +1136,33 @@ void SfxTemplateManagerDlg::OnCategoryDelete() if (aDlg.run() == RET_OK) { const OUString& sCategory = aDlg.GetSelectedCategory(); - std::unique_ptr<weld::MessageDialog> popupDlg(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo, + std::unique_ptr<weld::MessageDialog> popupDlg(Application::CreateMessageDialog(m_xDialog.get(), + VclMessageType::Question, VclButtonsType::YesNo, SfxResId(STR_QMSG_SEL_FOLDER_DELETE))); if (popupDlg->run() != RET_YES) return; - sal_Int16 nItemId = mpLocalView->getRegionId(sCategory); + sal_Int16 nItemId = mxLocalView->getRegionId(sCategory); - if (!mpLocalView->removeRegion(nItemId)) + if (!mxLocalView->removeRegion(nItemId)) { OUString sMsg( SfxResId(STR_MSG_ERROR_DELETE_FOLDER) ); - std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, VclButtonsType::Ok, + std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(), + VclMessageType::Warning, VclButtonsType::Ok, sMsg.replaceFirst("$1",sCategory))); xBox->run(); } else { - mpCBFolder->RemoveEntry(sCategory); + mxCBFolder->remove_text(sCategory); } } - mpLocalView->reload(); - mpLocalView->showAllTemplates(); - mpCBApp->SelectEntryPos(0); - mpCBFolder->SelectEntryPos(0); - mpActionMenu->HideItem(MNI_ACTION_RENAME_FOLDER); + mxLocalView->reload(); + mxLocalView->showAllTemplates(); + mxCBApp->set_active(0); + mxCBFolder->set_active(0); + mxActionBar->set_item_visible(MNI_ACTION_RENAME_FOLDER, false); } void SfxTemplateManagerDlg::createDefaultTemplateMenu () @@ -1211,21 +1171,19 @@ void SfxTemplateManagerDlg::createDefaultTemplateMenu () if (!aList.empty()) { - mpTemplateDefaultMenu->Clear(); + mxTemplateDefaultMenu->clear(); - sal_uInt16 nItemId = MNI_ACTION_DEFAULT + 1; for (auto const& elem : aList) { INetURLObject aObj(elem); OUString aTitle = SvFileInformationManager::GetDescription(aObj); - mpTemplateDefaultMenu->InsertItem(nItemId, aTitle, SvFileInformationManager::GetImage(aObj)); - mpTemplateDefaultMenu->SetItemCommand(nItemId++, elem); + mxTemplateDefaultMenu->append(elem, aTitle, SvFileInformationManager::GetImageId(aObj)); } - mpActionMenu->ShowItem(MNI_ACTION_DEFAULT); + mxActionBar->set_item_visible(MNI_ACTION_DEFAULT, true); } else - mpActionMenu->HideItem(MNI_ACTION_DEFAULT); + mxActionBar->set_item_visible(MNI_ACTION_DEFAULT, false); } void SfxTemplateManagerDlg::localMoveTo(sal_uInt16 nItemId) @@ -1234,7 +1192,7 @@ void SfxTemplateManagerDlg::localMoveTo(sal_uInt16 nItemId) { // Move templates to desired folder if for some reason move fails // try copying them. - mpLocalView->moveTemplates(maSelTemplates,nItemId); + mxLocalView->moveTemplates(maSelTemplates,nItemId); } } @@ -1251,12 +1209,13 @@ void SfxTemplateManagerDlg::localSearchMoveTo(sal_uInt16 nItemId) const TemplateSearchViewItem *pItem = static_cast<const TemplateSearchViewItem*>(selTemplate); - if(!mpLocalView->moveTemplate(pItem,pItem->mnRegionId,nItemId)) + if(!mxLocalView->moveTemplate(pItem,pItem->mnRegionId,nItemId)) { - OUString sDst = mpLocalView->getRegionItemName(nItemId); + OUString sDst = mxLocalView->getRegionItemName(nItemId); OUString sMsg(SfxResId(STR_MSG_ERROR_LOCAL_MOVE)); sMsg = sMsg.replaceFirst("$1",sDst); - std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, VclButtonsType::Ok, + std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(), + VclMessageType::Warning, VclButtonsType::Ok, sMsg.replaceFirst( "$2",pItem->maTitle))); xBox->run(); } @@ -1264,9 +1223,9 @@ void SfxTemplateManagerDlg::localSearchMoveTo(sal_uInt16 nItemId) } // Deselect all items and update search results - mpSearchView->deselectItems(); + mxSearchView->deselectItems(); - SearchUpdateHdl(*mpSearchFilter); + SearchUpdateHdl(*mxSearchFilter); } static bool lcl_getServiceName ( const OUString &rFileURL, OUString &rName ) @@ -1391,50 +1350,43 @@ void SfxTemplateCategoryDialog::HideNewCategoryOption() // SfxTemplateSelectionDialog ----------------------------------------------------------------- -SfxTemplateSelectionDlg::SfxTemplateSelectionDlg(vcl::Window* pParent): - SfxTemplateManagerDlg(pParent), - msTemplatePath(OUString()) +SfxTemplateSelectionDlg::SfxTemplateSelectionDlg(weld::Window* pParent) + : SfxTemplateManagerDlg(pParent) + , msTemplatePath(OUString()) { - mpCBApp->SelectEntryPos(MNI_IMPRESS); - mpCBFolder->SelectEntryPos(0); - SetText(SfxResId(STR_TEMPLATE_SELECTION)); + mxCBApp->set_active(MNI_IMPRESS); + mxCBFolder->set_active(0); + m_xDialog->set_title(SfxResId(STR_TEMPLATE_SELECTION)); - if(mpLocalView->IsVisible()) + if (mxLocalView->IsVisible()) { - mpLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter())); - mpLocalView->showAllTemplates(); + mxLocalView->filterItems(ViewFilter_Application(getCurrentApplicationFilter())); + mxLocalView->showAllTemplates(); } - mpCBApp->Disable(); - mpActionBar->Hide(); - mpLinkButton->Hide(); - mpMoveButton->Hide(); - mpExportButton->Hide(); - mpCBXHideDlg->Show(); - mpCBXHideDlg->Check(); + mxCBApp->set_sensitive(false); + mxActionBar->hide(); + mxLinkButton->hide(); + mxMoveButton->hide(); + mxExportButton->hide(); + mxCBXHideDlg->show(); + mxCBXHideDlg->set_active(true); - mpLocalView->setOpenTemplateHdl(LINK(this,SfxTemplateSelectionDlg, OpenTemplateHdl)); - mpSearchView->setOpenTemplateHdl(LINK(this,SfxTemplateSelectionDlg, OpenTemplateHdl)); + mxLocalView->setOpenTemplateHdl(LINK(this,SfxTemplateSelectionDlg, OpenTemplateHdl)); + mxSearchView->setOpenTemplateHdl(LINK(this,SfxTemplateSelectionDlg, OpenTemplateHdl)); - mpLocalView->SetMultiSelectionEnabled(false); - mpSearchView->SetMultiSelectionEnabled(false); + mxSearchView->SetMultiSelectionEnabled(false); - mpOKButton->SetClickHdl(LINK(this, SfxTemplateSelectionDlg, OkClickHdl)); + mxOKButton->connect_clicked(LINK(this, SfxTemplateSelectionDlg, OkClickHdl)); } SfxTemplateSelectionDlg::~SfxTemplateSelectionDlg() { - disposeOnce(); -} - -void SfxTemplateSelectionDlg::dispose() -{ - SfxTemplateManagerDlg::dispose(); } -short SfxTemplateSelectionDlg::Execute() +short SfxTemplateSelectionDlg::run() { - return ModalDialog::Execute(); + return weld::GenericDialogController::run(); } IMPL_LINK(SfxTemplateSelectionDlg, OpenTemplateHdl, ThumbnailViewItem*, pItem, void) @@ -1442,15 +1394,15 @@ IMPL_LINK(SfxTemplateSelectionDlg, OpenTemplateHdl, ThumbnailViewItem*, pItem, v TemplateViewItem *pViewItem = static_cast<TemplateViewItem*>(pItem); msTemplatePath = pViewItem->getPath(); - EndDialog(RET_OK); + m_xDialog->response(RET_OK); } -IMPL_LINK_NOARG(SfxTemplateSelectionDlg, OkClickHdl, Button*, void) +IMPL_LINK_NOARG(SfxTemplateSelectionDlg, OkClickHdl, weld::Button&, void) { TemplateViewItem *pViewItem = static_cast<TemplateViewItem*>(const_cast<ThumbnailViewItem*>(*maSelTemplates.begin())); msTemplatePath = pViewItem->getPath(); - EndDialog(RET_OK); + m_xDialog->response(RET_OK); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/source/inc/templatesearchview.hxx b/sfx2/source/inc/templatesearchview.hxx index 9e5fd4134995..ae7658f3ae44 100644 --- a/sfx2/source/inc/templatesearchview.hxx +++ b/sfx2/source/inc/templatesearchview.hxx @@ -16,15 +16,16 @@ class TemplateViewItem; class PopupMenu; class Menu; -class TemplateSearchView final : public ThumbnailView +class TemplateSearchView final : public SfxThumbnailView { public: - TemplateSearchView ( vcl::Window* pParent); + TemplateSearchView(std::unique_ptr<weld::ScrolledWindow> xWindow, + std::unique_ptr<weld::Menu> xMenu); void setOpenTemplateHdl (const Link<ThumbnailViewItem*, void> &rLink); - DECL_LINK(ContextMenuSelectHdl, Menu*, bool); + void ContextMenuSelectHdl(const OString& rIdent); void setCreateContextMenuHdl(const Link<ThumbnailViewItem*,void> &rLink); @@ -45,11 +46,11 @@ public: private: virtual void OnItemDblClicked(ThumbnailViewItem *pItem) override; - virtual void MouseButtonDown( const MouseEvent& rMEvt ) override; + virtual bool MouseButtonDown( const MouseEvent& rMEvt ) override; - virtual void Command( const CommandEvent& rCEvt ) override; + virtual bool ContextMenu(const CommandEvent& rPos) override; - virtual void KeyInput( const KeyEvent& rKEvt ) override; + virtual bool KeyInput( const KeyEvent& rKEvt ) override; TemplateViewItem *maSelectedItem; diff --git a/sfx2/source/inc/templatesearchviewitem.hxx b/sfx2/source/inc/templatesearchviewitem.hxx index 6e1b7d39cc93..4df92e8916e1 100644 --- a/sfx2/source/inc/templatesearchviewitem.hxx +++ b/sfx2/source/inc/templatesearchviewitem.hxx @@ -14,7 +14,7 @@ struct TemplateSearchViewItem : public TemplateViewItem { - TemplateSearchViewItem (ThumbnailView &rView, sal_uInt16 nId) + TemplateSearchViewItem (ThumbnailViewBase &rView, sal_uInt16 nId) : TemplateViewItem(rView, nId) , mnAssocId(0) {} diff --git a/sfx2/uiconfig/ui/templatedlg.ui b/sfx2/uiconfig/ui/templatedlg.ui index a1534928a8fb..6fc6ff48a671 100644 --- a/sfx2/uiconfig/ui/templatedlg.ui +++ b/sfx2/uiconfig/ui/templatedlg.ui @@ -2,60 +2,56 @@ <!-- Generated with glade 3.22.1 --> <interface domain="sfx"> <requires lib="gtk+" version="3.18"/> - <requires lib="LibreOffice" version="1.0"/> - <object class="GtkListStore" id="applist"> - <columns> - <!-- column-name gchararray1 --> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes" context="templatedlg|applist">All Applications</col> - </row> - <row> - <col id="0" translatable="yes" context="templatedlg|applist">Documents</col> - </row> - <row> - <col id="0" translatable="yes" context="templatedlg|applist">Spreadsheets</col> - </row> - <row> - <col id="0" translatable="yes" context="templatedlg|applist">Presentations</col> - </row> - <row> - <col id="0" translatable="yes" context="templatedlg|applist">Drawings</col> - </row> - </data> + <object class="GtkMenu" id="contextmenu1"> + <property name="visible">True</property> + <property name="can_focus">False</property> </object> - <object class="GtkListStore" id="folderlist"> - <columns> - <!-- column-name gchararray1 --> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes" context="templatedlg|folderlist">All Categories</col> - </row> - </data> + <object class="GtkMenu" id="contextmenu2"> + <property name="visible">True</property> + <property name="can_focus">False</property> </object> <object class="GtkImage" id="image1"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="pixbuf">sfx2/res/actiontemplates020.png</property> + <property name="icon_name">sfx2/res/actiontemplates020.png</property> </object> <object class="GtkImage" id="image3"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="pixbuf">sfx2/res/actiontemplates017.png</property> + <property name="icon_name">sfx2/res/actiontemplates017.png</property> </object> <object class="GtkImage" id="image4"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="pixbuf">sfx2/res/actionview010.png</property> + <property name="icon_name">sfx2/res/actionview010.png</property> </object> <object class="GtkImage" id="image5"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="pixbuf">cmd/lc_webhtml.png</property> + <property name="icon_name">cmd/lc_webhtml.png</property> + </object> + <object class="GtkImage" id="image7"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="icon_name">sfx2/res/actionaction013.png</property> + </object> + <object class="GtkMenu" id="menu1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkMenuItem" id="default"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes" context="colsmenu|insert">Reset Default Template</property> + <property name="use_underline">True</property> + <child type="submenu"> + <object class="GtkMenu" id="submenu"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + </child> + </object> + </child> </object> <object class="GtkDialog" id="TemplateDialog"> <property name="width_request">800</property> @@ -64,7 +60,12 @@ <property name="border_width">6</property> <property name="title" translatable="yes" context="templatedlg|TemplateDialog">Templates</property> <property name="modal">True</property> + <property name="default_width">0</property> + <property name="default_height">0</property> <property name="type_hint">normal</property> + <child> + <placeholder/> + </child> <child internal-child="vbox"> <object class="GtkBox" id="dialog-vbox1"> <property name="can_focus">False</property> @@ -144,6 +145,7 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="tooltip_text" translatable="yes" context="templatedlg|search_filter|tooltip_text">Search</property> + <property name="activates_default">True</property> <property name="placeholder_text" translatable="yes" context="templatedlg|search_filter">Search...</property> </object> <packing> @@ -163,12 +165,18 @@ <property name="can_focus">False</property> <property name="spacing">12</property> <child> - <object class="GtkComboBox" id="filter_application"> + <object class="GtkComboBoxText" id="filter_application"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="tooltip_text" translatable="yes" context="templatedlg|filter_application|tooltip_text">Filter by Application</property> <property name="resize_mode">queue</property> - <property name="model">applist</property> + <items> + <item id="0" translatable="yes" context="templatedlg|applist">All Applications</item> + <item id="0" translatable="yes" context="templatedlg|applist">Documents</item> + <item id="0" translatable="yes" context="templatedlg|applist">Spreadsheets</item> + <item id="0" translatable="yes" context="templatedlg|applist">Presentations</item> + <item id="0" translatable="yes" context="templatedlg|applist">Drawings</item> + </items> </object> <packing> <property name="expand">False</property> @@ -177,12 +185,14 @@ </packing> </child> <child> - <object class="GtkComboBox" id="filter_folder"> + <object class="GtkComboBoxText" id="filter_folder"> <property name="width_request">250</property> <property name="visible">True</property> <property name="can_focus">False</property> <property name="tooltip_text" translatable="yes" context="templatedlg|filter_folder|tooltip_text">Filter by Category</property> - <property name="model">folderlist</property> + <items> + <item id="0" translatable="yes" context="templatedlg|folderlist">All Categories</item> + </items> </object> <packing> <property name="expand">False</property> @@ -248,30 +258,65 @@ <property name="orientation">vertical</property> <property name="spacing">6</property> <child> - <object class="sfxlo-TemplateLocalView" id="template_view"> - <property name="visible">True</property> + <object class="GtkScrolledWindow" id="scrolllocal"> <property name="can_focus">True</property> + <property name="no_show_all">True</property> <property name="hexpand">True</property> <property name="vexpand">True</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkViewport"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <child> + <object class="GtkDrawingArea" id="template_view"> + <property name="can_focus">True</property> + <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property> + <property name="no_show_all">True</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + </object> + </child> + </object> + </child> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">2</property> + <property name="position">0</property> </packing> </child> <child> - <object class="sfxlo-TemplateSearchView" id="search_view"> + <object class="GtkScrolledWindow" id="scrollsearch"> <property name="can_focus">True</property> <property name="no_show_all">True</property> - <property name="margin">0</property> <property name="hexpand">True</property> <property name="vexpand">True</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkViewport"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <child> + <object class="GtkDrawingArea" id="search_view"> + <property name="can_focus">True</property> + <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property> + <property name="no_show_all">True</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + </object> + </child> + </object> + </child> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">3</property> + <property name="position">1</property> </packing> </child> </object> @@ -300,24 +345,14 @@ <property name="visible">True</property> <property name="can_focus">False</property> <child> - <object class="GtkToolbar" id="action_action"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">end</property> - <property name="hexpand">True</property> - <child> - <object class="GtkToolButton" id="action_menu"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="tooltip_text" translatable="yes" context="templatedlg|action_menu|tooltip_text">Settings</property> - <property name="action_name">action_menu</property> - <property name="icon_name">sfx2/res/actionaction013.png</property> - </object> - <packing> - <property name="expand">False</property> - <property name="homogeneous">True</property> - </packing> - </child> + <object class="GtkMenuButton" id="action_menu"> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="tooltip_text" translatable="yes" context="templatedlg|action_menu|tooltip_text">Settings</property> + <property name="image">image7</property> + <property name="always_show_image">True</property> + <property name="popup">menu1</property> + <property name="use_popover">False</property> </object> <packing> <property name="expand">False</property> @@ -333,7 +368,6 @@ <property name="tooltip_text" translatable="yes" context="templatedlg|online_link|tooltip_text">Browse online templates</property> <property name="image">image5</property> <property name="relief">none</property> - <property name="yalign">0.49000000953674316</property> <property name="always_show_image">True</property> </object> <packing> @@ -365,10 +399,11 @@ </packing> </child> <child> - <object class="GtkBox" id="bottom_action_box"> + <object class="GtkButtonBox" id="bottom_action_box"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="halign">end</property> + <property name="spacing">3</property> <child> <object class="GtkButton" id="move_btn"> <property name="label" translatable="yes" context="templatedlg|move_btn">Move</property> @@ -378,7 +413,6 @@ <property name="tooltip_text" translatable="yes" context="templatedlg|move_btn|tooltip_text">Move Templates</property> <property name="image">image3</property> <property name="relief">none</property> - <property name="yalign">0.50999999046325684</property> <property name="always_show_image">True</property> </object> <packing> |