diff --git a/offapi/com/sun/star/document/XCmisDocument.idl b/offapi/com/sun/star/document/XCmisDocument.idl index 246a1b7f3d10..82ac4ff8e4a9 100644 --- a/offapi/com/sun/star/document/XCmisDocument.idl +++ b/offapi/com/sun/star/document/XCmisDocument.idl @@ -19,6 +19,11 @@ module com { module sun { module star { module document { */ interface XCmisDocument : com::sun::star::uno::XInterface { + /** Check out the document into a private working copy on the + server, and update the loaded document to reflect this change. + */ + void checkOut( ); + /** Contains the properties values named after their CMIS ID. */ [attribute] com::sun::star::beans::PropertyValues CmisPropertiesValues; diff --git a/sc/source/ui/view/tabvwsh.cxx b/sc/source/ui/view/tabvwsh.cxx index 4e744a0b9466..06f6dd45162d 100644 --- a/sc/source/ui/view/tabvwsh.cxx +++ b/sc/source/ui/view/tabvwsh.cxx @@ -35,6 +35,7 @@ #include #include #include +#include #include "tabvwsh.hxx" #include "docsh.hxx" @@ -59,6 +60,7 @@ SFX_IMPL_INTERFACE(ScTabViewShell,SfxViewShell,ScResId(SCSTR_TABVIEWSHELL)) SFX_CHILDWINDOW_REGISTRATION(FID_INPUTLINE_STATUS); SFX_CHILDWINDOW_REGISTRATION(SfxTemplateDialogWrapper::GetChildWindowId()); + SFX_CHILDWINDOW_REGISTRATION(SfxInfoBarContainerChild::GetChildWindowId()); SFX_CHILDWINDOW_CONTEXT_REGISTRATION(SID_NAVIGATOR); SFX_CHILDWINDOW_REGISTRATION(SID_TASKPANE); SFX_CHILDWINDOW_REGISTRATION(ScNameDlgWrapper::GetChildWindowId()); diff --git a/sd/source/ui/slideshow/slideshowimpl.cxx b/sd/source/ui/slideshow/slideshowimpl.cxx index e085f47a6d86..2cc9d30f8bf2 100644 --- a/sd/source/ui/slideshow/slideshowimpl.cxx +++ b/sd/source/ui/slideshow/slideshowimpl.cxx @@ -44,6 +44,7 @@ #include +#include #include #include #include @@ -2570,7 +2571,8 @@ FncGetChildWindowId aShowChildren[] = &SvxIMapDlgChildWindow::GetChildWindowId, &SvxHlinkDlgWrapper::GetChildWindowId, &SfxTemplateDialogWrapper::GetChildWindowId, - &GalleryChildWindow::GetChildWindowId + &GalleryChildWindow::GetChildWindowId, + &SfxInfoBarContainerChild::GetChildWindowId }; #define NAVIGATOR_CHILD_MASK 0x80000000UL diff --git a/sd/source/ui/view/drvwshrg.cxx b/sd/source/ui/view/drvwshrg.cxx index 6f21afefa53c..51b9e2773cee 100644 --- a/sd/source/ui/view/drvwshrg.cxx +++ b/sd/source/ui/view/drvwshrg.cxx @@ -29,6 +29,7 @@ #include "DrawViewShell.hxx" #include +#include #include #include @@ -77,6 +78,7 @@ SFX_IMPL_INTERFACE(DrawViewShell, SfxShell, SdResId(STR_DRAWVIEWSHELL)) SFX_POPUPMENU_REGISTRATION( SdResId(RID_DRAW_TEXTOBJ_INSIDE_POPUP) ); SFX_CHILDWINDOW_CONTEXT_REGISTRATION( SID_NAVIGATOR ); SFX_CHILDWINDOW_REGISTRATION( SfxTemplateDialogWrapper::GetChildWindowId() ); + SFX_CHILDWINDOW_REGISTRATION( SfxInfoBarContainerChild::GetChildWindowId() ); SFX_CHILDWINDOW_REGISTRATION( SvxFontWorkChildWindow::GetChildWindowId() ); SFX_CHILDWINDOW_REGISTRATION( SvxColorChildWindow::GetChildWindowId() ); SFX_CHILDWINDOW_REGISTRATION( AnimationChildWindow::GetChildWindowId() ); diff --git a/sd/source/ui/view/outlnvsh.cxx b/sd/source/ui/view/outlnvsh.cxx index fbf2b18b2720..2b93ed6213b9 100644 --- a/sd/source/ui/view/outlnvsh.cxx +++ b/sd/source/ui/view/outlnvsh.cxx @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -126,6 +127,7 @@ SFX_IMPL_INTERFACE(OutlineViewShell, SfxShell, SdResId(STR_OUTLINEVIEWSHELL)) SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_APPLICATION | SFX_VISIBILITY_DESKTOP | SFX_VISIBILITY_STANDARD | SFX_VISIBILITY_CLIENT | SFX_VISIBILITY_VIEWER | SFX_VISIBILITY_READONLYDOC, SdResId(RID_DRAW_VIEWER_TOOLBOX) ); SFX_CHILDWINDOW_REGISTRATION( SfxTemplateDialogWrapper::GetChildWindowId() ); + SFX_CHILDWINDOW_REGISTRATION( SfxInfoBarContainerChild::GetChildWindowId() ); SFX_CHILDWINDOW_REGISTRATION( SvxHlinkDlgWrapper::GetChildWindowId() ); SFX_CHILDWINDOW_REGISTRATION( ::sd::SpellDialogChildWindow::GetChildWindowId() ); SFX_CHILDWINDOW_REGISTRATION( SID_SEARCH_DLG ); diff --git a/sfx2/inc/sfx2/sfxbasecontroller.hxx b/sfx2/inc/sfx2/sfxbasecontroller.hxx index cf265300a1bd..b8daf8b24e88 100644 --- a/sfx2/inc/sfx2/sfxbasecontroller.hxx +++ b/sfx2/inc/sfx2/sfxbasecontroller.hxx @@ -44,6 +44,8 @@ #include #include #include +#include +#include #include #include @@ -385,6 +387,8 @@ private: SAL_DLLPRIVATE SfxViewFrame& GetViewFrame_Impl() const; SAL_DLLPRIVATE void ShowInfoBars( ); + DECL_LINK( CheckOutHandler, PushButton * ); + //________________________________________________________________________________________________________ // private variables //________________________________________________________________________________________________________ diff --git a/sfx2/inc/sfx2/sfxbasemodel.hxx b/sfx2/inc/sfx2/sfxbasemodel.hxx index 8b7097f4ff68..7a3b4a592281 100644 --- a/sfx2/inc/sfx2/sfxbasemodel.hxx +++ b/sfx2/inc/sfx2/sfxbasemodel.hxx @@ -1421,6 +1421,7 @@ public: ::com::sun::star::beans::PropertyValue >& _cmispropertiesdisplaynames ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL checkOut( ) throw ( ::com::sun::star::uno::RuntimeException ); //____________________________________________________________________________________________________ // SfxListener @@ -1542,6 +1543,8 @@ private: SAL_DLLPRIVATE void NotifyModifyListeners_Impl() const; + SAL_DLLPRIVATE void loadCmisProperties(); + //________________________________________________________________________________________________________ // private variables and methods //________________________________________________________________________________________________________ diff --git a/sfx2/inc/sfx2/viewfrm.hxx b/sfx2/inc/sfx2/viewfrm.hxx index 26b5e47ca584..c3d889364522 100644 --- a/sfx2/inc/sfx2/viewfrm.hxx +++ b/sfx2/inc/sfx2/viewfrm.hxx @@ -23,6 +23,7 @@ #include "sfx2/dllapi.h" #include "sal/types.h" #include +#include #include #include #include @@ -191,6 +192,7 @@ public: and position of each button will be changed: only the width will remain unchanged. */ void AppendInfoBar( const rtl::OUString& sMessage, std::vector< PushButton* > aButtons ); + void RemoveInfoBar( SfxInfoBarWindow* pInfoBar ); SAL_DLLPRIVATE void SetDowning_Impl(); SAL_DLLPRIVATE void GetDocNumber_Impl(); diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx index fa4116b565c0..b9b5f0480551 100644 --- a/sfx2/source/doc/objstor.cxx +++ b/sfx2/source/doc/objstor.cxx @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -745,23 +744,6 @@ sal_Bool SfxObjectShell::DoLoad( SfxMedium *pMed ) com::sun::star::uno::Reference < XPropertySetInfo > xProps = aContent.getProperties(); if ( xProps.is() ) { - // Copy all the CMIS properties to the document (if there is any) - ::rtl::OUString aCmisPropsValues( "CmisPropertiesValues" ); - ::rtl::OUString aCmisPropsNames( "CmisPropertiesDisplayNames" ); - uno::Reference< document::XCmisDocument > xCmisDoc( GetModel( ), uno::UNO_QUERY_THROW ); - if ( xProps->hasPropertyByName( aCmisPropsValues ) ) - { - beans::PropertyValues aCmisValues; - aContent.getPropertyValue( aCmisPropsValues ) >>= aCmisValues; - xCmisDoc->setCmisPropertiesValues( aCmisValues ); - } - if ( xProps->hasPropertyByName( aCmisPropsNames ) ) - { - beans::PropertyValues aPropNames; - aContent.getPropertyValue( aCmisPropsNames ) >>= aPropNames; - xCmisDoc->setCmisPropertiesDisplayNames( aPropNames ); - } - ::rtl::OUString aAuthor( "Author" ); ::rtl::OUString aKeywords( "Keywords" ); ::rtl::OUString aSubject( "Subject" ); diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx index ea8fdfabf8f7..872bdbca3b59 100644 --- a/sfx2/source/doc/sfxbasemodel.cxx +++ b/sfx2/source/doc/sfxbasemodel.cxx @@ -2001,6 +2001,8 @@ void SAL_CALL SfxBaseModel::load( const uno::Sequence< beans::PropertyValue >& } } + loadCmisProperties( ); + sal_Bool bHidden = sal_False; SFX_ITEMSET_ARG( pMedium->GetItemSet(), pHidItem, SfxBoolItem, SID_HIDDEN, sal_False); if ( pHidItem ) @@ -2542,6 +2544,74 @@ void SAL_CALL SfxBaseModel::setCmisPropertiesDisplayNames( const uno::Sequence< m_pData->m_cmisPropertiesDisplayNames = _cmispropertiesdisplaynames; } +void SAL_CALL SfxBaseModel::checkOut( ) throw ( uno::RuntimeException ) +{ + SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium(); + if ( pMedium ) + { + try + { + ::ucbhelper::Content aContent( pMedium->GetName(), + uno::Reference(), + comphelper::getProcessComponentContext() ); + + uno::Any aResult = aContent.executeCommand( "checkout", uno::Any( ) ); + rtl::OUString sURL; + aResult >>= sURL; + + m_pData->m_pObjectShell->GetMedium( )->SwitchDocumentToFile( sURL ); + m_pData->m_xDocumentProperties->setTitle( getTitle( ) ); + uno::Sequence< beans::PropertyValue > aSequence ; + TransformItems( SID_OPENDOC, *pMedium->GetItemSet(), aSequence ); + attachResource( sURL, aSequence ); + + // Reload the CMIS properties + loadCmisProperties( ); + } + catch (const ucb::ContentCreationException &) + { + } + catch (const ucb::CommandAbortedException &) + { + } + } +} + +void SfxBaseModel::loadCmisProperties( ) +{ + SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium(); + if ( pMedium ) + { + try + { + ::ucbhelper::Content aContent( pMedium->GetName( ), + uno::Reference(), + comphelper::getProcessComponentContext() ); + com::sun::star::uno::Reference < beans::XPropertySetInfo > xProps = aContent.getProperties(); + ::rtl::OUString aCmisPropsValues( "CmisPropertiesValues" ); + ::rtl::OUString aCmisPropsNames( "CmisPropertiesDisplayNames" ); + if ( xProps->hasPropertyByName( aCmisPropsValues ) ) + { + beans::PropertyValues aCmisValues; + aContent.getPropertyValue( aCmisPropsValues ) >>= aCmisValues; + setCmisPropertiesValues( aCmisValues ); + } + if ( xProps->hasPropertyByName( aCmisPropsNames ) ) + { + beans::PropertyValues aPropNames; + aContent.getPropertyValue( aCmisPropsNames ) >>= aPropNames; + setCmisPropertiesDisplayNames( aPropNames ); + } + } + catch (const ucb::ContentCreationException &) + { + } + catch (const ucb::CommandAbortedException &) + { + } + } +} + //________________________________________________________________________________________________________ // SfxListener //________________________________________________________________________________________________________ @@ -3587,6 +3657,7 @@ void SAL_CALL SfxBaseModel::loadFromStorage( const uno::Reference< XSTORAGE >& x uno::Reference< uno::XInterface >(), nError ? nError : ERRCODE_IO_CANTREAD ); } + loadCmisProperties( ); } void SAL_CALL SfxBaseModel::storeToStorage( const uno::Reference< XSTORAGE >& xStorage, diff --git a/sfx2/source/view/sfxbasecontroller.cxx b/sfx2/source/view/sfxbasecontroller.cxx index 89ead633f11b..7b315a6b62ed 100644 --- a/sfx2/source/view/sfxbasecontroller.cxx +++ b/sfx2/source/view/sfxbasecontroller.cxx @@ -63,6 +63,7 @@ #include #include #include +#include #include #include @@ -1460,7 +1461,7 @@ void SfxBaseController::ShowInfoBars( ) SfxViewFrame* pViewFrame = m_pData->m_pViewShell->GetFrame(); std::vector< PushButton* > aButtons; PushButton* pBtn = new PushButton( &pViewFrame->GetWindow(), SfxResId( BT_CHECKOUT ) ); - // TODO Set the handler + pBtn->SetClickHdl( LINK( this, SfxBaseController, CheckOutHandler ) ); aButtons.push_back( pBtn ); pViewFrame->AppendInfoBar( SfxResId( STR_NONCHECKEDOUT_DOCUMENT ), aButtons ); } @@ -1468,6 +1469,28 @@ void SfxBaseController::ShowInfoBars( ) } } +IMPL_LINK( SfxBaseController, CheckOutHandler, PushButton*, pBtn ) +{ + if ( m_pData->m_pViewShell ) + { + try + { + REFERENCE< document::XCmisDocument > xCmisDoc( m_pData->m_pViewShell->GetObjectShell()->GetModel(), uno::UNO_QUERY_THROW ); + xCmisDoc->checkOut( ); + + // Remove the info bar + SfxInfoBarWindow* pInfoBar = ( SfxInfoBarWindow* )pBtn->GetParent( ); + SfxViewFrame* pViewFrame = m_pData->m_pViewShell->GetFrame(); + pViewFrame->RemoveInfoBar( pInfoBar ); + } + catch ( const uno::RuntimeException& ) + { + // TODO Handle the problem in some way? + } + } + return 0; +} + //============================================================================= css::uno::Reference< css::frame::XTitle > SfxBaseController::impl_getTitleHelper () diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx index 9d459c6daedf..d9ed89314e47 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -3358,9 +3358,28 @@ void SfxViewFrame::AppendInfoBar( const rtl::OUString& sMessage, std::vector< Pu if ( !HasChildWindow( nId ) ) ToggleChildWindow( nId ); SfxChildWindow* pChild = GetChildWindow( nId ); - SfxInfoBarContainerWindow* pInfoBars = ( SfxInfoBarContainerWindow* )pChild->GetWindow(); - pInfoBars->appendInfoBar( sMessage, aButtons ); - ShowChildWindow( nId ); + if ( pChild ) + { + SfxInfoBarContainerWindow* pInfoBars = ( SfxInfoBarContainerWindow* )pChild->GetWindow(); + pInfoBars->appendInfoBar( sMessage, aButtons ); + ShowChildWindow( nId ); + } +} + +void SfxViewFrame::RemoveInfoBar( SfxInfoBarWindow* pInfoBar ) +{ + const sal_uInt16 nId = SfxInfoBarContainerChild::GetChildWindowId(); + + // Make sure the InfoBar container is visible + if ( !HasChildWindow( nId ) ) + ToggleChildWindow( nId ); + SfxChildWindow* pChild = GetChildWindow( nId ); + if ( pChild ) + { + SfxInfoBarContainerWindow* pInfoBars = ( SfxInfoBarContainerWindow* )pChild->GetWindow(); + pInfoBars->removeInfoBar( pInfoBar ); + ShowChildWindow( nId ); + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/uiview/view0.cxx b/sw/source/ui/uiview/view0.cxx index 8e212c5efcb2..3d171cad97a0 100644 --- a/sw/source/ui/uiview/view0.cxx +++ b/sw/source/ui/uiview/view0.cxx @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -100,6 +101,7 @@ SFX_IMPL_INTERFACE( SwView, SfxViewShell, SW_RES(RID_TOOLS_TOOLBOX) ) SFX_CHILDWINDOW_CONTEXT_REGISTRATION(SID_NAVIGATOR); SFX_CHILDWINDOW_REGISTRATION(SID_TASKPANE); SFX_CHILDWINDOW_REGISTRATION(SfxTemplateDialogWrapper::GetChildWindowId()); + SFX_CHILDWINDOW_REGISTRATION(SfxInfoBarContainerChild::GetChildWindowId()); SFX_CHILDWINDOW_REGISTRATION(SvxSearchDialogWrapper::GetChildWindowId()); SFX_CHILDWINDOW_REGISTRATION(SwSpellDialogChildWindow::GetChildWindowId()); SFX_CHILDWINDOW_REGISTRATION(FN_REDLINE_ACCEPT); diff --git a/sw/source/ui/web/wview.cxx b/sw/source/ui/web/wview.cxx index d4808474433c..d6541a2d605b 100644 --- a/sw/source/ui/web/wview.cxx +++ b/sw/source/ui/web/wview.cxx @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,7 @@ SFX_IMPL_INTERFACE( SwWebView, SwView, SW_RES(RID_WEBTOOLS_TOOLBOX) ) { SFX_CHILDWINDOW_REGISTRATION(SfxTemplateDialogWrapper::GetChildWindowId()); SFX_CHILDWINDOW_REGISTRATION(SvxSearchDialogWrapper::GetChildWindowId()); + SFX_CHILDWINDOW_REGISTRATION(SfxInfoBarContainerChild::GetChildWindowId()); SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_TOOLS| SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER, SW_RES(RID_WEBTOOLS_TOOLBOX) ); diff --git a/ucb/source/ucp/cmis/cmis_content.cxx b/ucb/source/ucp/cmis/cmis_content.cxx index fbfa83bda138..0baee4fdea16 100644 --- a/ucb/source/ucp/cmis/cmis_content.cxx +++ b/ucb/source/ucp/cmis/cmis_content.cxx @@ -1005,6 +1005,9 @@ namespace cmis ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ), -1, getCppuType( static_cast( 0 ) ) ), + // Mandatory CMIS-only commands + ucb::CommandInfo ( rtl::OUString( "checkout" ), -1, getCppuVoidType() ), + // Folder Only, omitted if not a folder ucb::CommandInfo ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ), @@ -1187,6 +1190,49 @@ namespace cmis rtl::OUString::createFromAscii( e.what() ) ); } } + else if ( aCommand.Name == "checkout" ) + { + try + { + // Checkout the document if possible + libcmis::DocumentPtr pDoc = boost::dynamic_pointer_cast< libcmis::Document >( getObject( xEnv ) ); + if ( pDoc.get( ) == NULL ) + { + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_GENERAL, + uno::Sequence< uno::Any >( 0 ), + xEnv, + "Checkout only supported by documents" ); + } + libcmis::DocumentPtr pPwc = pDoc->checkOut( ); + + // Compute the URL of the Private Working Copy (PWC) + URL aCmisUrl( m_sURL ); + vector< string > aPaths = pPwc->getPaths( ); + if ( !aPaths.empty() ) + { + string sPath = aPaths.front( ); + aCmisUrl.setObjectPath( STD_TO_OUSTR( sPath ) ); + } + else + { + // We may have unfiled PWC depending on the server, those + // won't have any path, use their ID instead + string sId = pPwc->getId( ); + aCmisUrl.setObjectId( STD_TO_OUSTR( sId ) ); + } + aRet <<= aCmisUrl.asString( ); + } + catch ( const libcmis::Exception& e ) + { + SAL_INFO( "cmisucp", "Unexpected libcmis exception: " << e.what( ) ); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_GENERAL, + uno::Sequence< uno::Any >( 0 ), + xEnv, + rtl::OUString::createFromAscii( e.what() ) ); + } + } else { SAL_INFO( "cmisucp", "Unknown command to execute" ); diff --git a/ucb/source/ucp/cmis/cmis_url.cxx b/ucb/source/ucp/cmis/cmis_url.cxx index e184d709d745..dfd0cc73e5cd 100644 --- a/ucb/source/ucp/cmis/cmis_url.cxx +++ b/ucb/source/ucp/cmis/cmis_url.cxx @@ -89,6 +89,12 @@ namespace cmis m_sId = rtl::OUString( ); } + void URL::setObjectId( rtl::OUString sId ) + { + m_sPath = rtl::OUString( ); + m_sId = sId; + } + rtl::OUString URL::asString( ) { rtl::OUString sUrl; diff --git a/ucb/source/ucp/cmis/cmis_url.hxx b/ucb/source/ucp/cmis/cmis_url.hxx index 6283d7aa874e..e2912d4bb494 100644 --- a/ucb/source/ucp/cmis/cmis_url.hxx +++ b/ucb/source/ucp/cmis/cmis_url.hxx @@ -56,6 +56,7 @@ namespace cmis rtl::OUString& getUsername( ) { return m_sUser; } rtl::OUString& getPassword( ) { return m_sPass; } void setObjectPath( rtl::OUString sPath ); + void setObjectId( rtl::OUString sId ); rtl::OUString asString( ); };