CMIS: added cancelCheckOut and checkIn implementations and menu items

Although the implementation is here, the dialogs to show when clicking
on the menu items aren't there yet.

Change-Id: I14886ec8ea8b97a35ca6c8474bc33e30da1a86d3
This commit is contained in:
Cédric Bosdonnat 2012-10-30 11:06:18 +01:00
parent 1eb7a92164
commit 1a9261124e
44 changed files with 900 additions and 82 deletions

View File

@ -30,6 +30,8 @@
<menu:menuitem menu:id=".uno:SaveAs"/>
<menu:menuitem menu:id=".uno:SaveAll"/>
<menu:menuitem menu:id=".uno:CheckOut"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menu menu:id=".uno:TemplateMenu">
<menu:menupopup>
<menu:menuitem menu:id=".uno:Organizer"/>

View File

@ -28,6 +28,8 @@
<menu:menuitem menu:id=".uno:SaveAs" menu:helpid="5502" menu:label="" />
<menu:menuitem menu:id=".uno:SaveAll" menu:helpid="5309" menu:label="" />
<menu:menuitem menu:id=".uno:CheckOut"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menuitem menu:id=".uno:Reload" menu:helpid="5508" menu:label="" />
<menu:menuitem menu:id=".uno:VersionDialog" menu:helpid="6583" menu:label="" />
<menu:menuitem menu:id=".uno:SendMail" menu:helpid="5331" menu:label="" />

View File

@ -30,6 +30,8 @@
<menu:menuitem menu:id=".uno:SaveAs"/>
<menu:menuitem menu:id=".uno:SaveAll"/>
<menu:menuitem menu:id=".uno:CheckOut"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:ExportTo"/>
<menu:menu menu:id=".uno:SendToMenu">

View File

@ -28,6 +28,8 @@
<menu:menuitem menu:id=".uno:Save"/>
<menu:menuitem menu:id=".uno:SaveAs"/>
<menu:menuitem menu:id=".uno:CheckOut"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:Quit"/>
</menu:menupopup>

View File

@ -27,6 +27,8 @@
<menu:menuitem menu:id=".uno:SaveAll"/>
<menu:menuitem menu:id=".uno:Save"/>
<menu:menuitem menu:id=".uno:CheckOut"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:Quit"/>
</menu:menupopup>

View File

@ -28,6 +28,8 @@
<menu:menuitem menu:id=".uno:Save"/>
<menu:menuitem menu:id=".uno:SaveAs"/>
<menu:menuitem menu:id=".uno:CheckOut"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:Quit"/>
</menu:menupopup>

View File

@ -28,6 +28,8 @@
<menu:menuitem menu:id=".uno:Save"/>
<menu:menuitem menu:id=".uno:SaveAs"/>
<menu:menuitem menu:id=".uno:CheckOut"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:Quit"/>
</menu:menupopup>

View File

@ -11,6 +11,8 @@
<menu:menuitem menu:id=".uno:SaveAs"/>
<menu:menuitem menu:id=".uno:SaveAll"/>
<menu:menuitem menu:id=".uno:CheckOut"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menuitem menu:id=".uno:Reload"/>
<menu:menuitem menu:id=".uno:VersionDialog"/>
<menu:menuseparator/>

View File

@ -3768,6 +3768,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,offapi/com/sun/star/ucb,\
AlreadyInitializedException \
AuthenticationRequest \
CHAOSProgressStart \
CheckinArgument \
CertificateValidationRequest \
Command \
CommandAbortedException \

View File

@ -24,10 +24,26 @@ interface XCmisDocument : com::sun::star::uno::XInterface
*/
void checkOut( );
/** Cancel checked out document, this will discard all changes since
check-out.
*/
void cancelCheckOut( );
/** Creates a new version of the document from the private working
copy.
*/
void checkIn( [in] boolean isMajor, [in] string comment );
/** Tells whether a document can support versioning or not.
*/
boolean isVersionable( );
boolean canCheckOut( );
boolean canCancelCheckOut( );
boolean canCheckIn( );
/** Contains the properties values named after their CMIS ID.
*/
[attribute] com::sun::star::beans::PropertyValues CmisPropertiesValues;

View File

@ -0,0 +1,60 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef __com_sun_star_ucb_CheckinArgument_idl__
#define __com_sun_star_ucb_CheckinArgument_idl__
module com { module sun { module star { module ucb {
/** contains information needed to checkin a document.
<p>The checkin command is always called on the target private
working copy document.</p>
*/
struct CheckinArgument
{
/** Tells whether to create a new major or minor version during the
checkin.
*/
boolean MajorVersion;
/** Contains the version comment to set during the checkin.
*/
string VersionComment;
/** contains the URL of the source of the action (e.g. the URL of
the temporary file to checkin).
*/
string SourceURL;
/** contains the URL of the private working copy to checkin.
*/
string TargetURL;
/** contains the title of the transferred object, if it is different
from the original one.
<p>If this field is filled, for example, a file will be renamed
while it is being checked in.</p>
*/
string NewTitle;
/** contains the Mime-Type of the content to check-in as it may be
different from the original one.
*/
string MimeType;
};
}; }; }; };
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@ -1901,6 +1901,16 @@
<value xml:lang="en-US">Check-Out</value>
</prop>
</node>
<node oor:name=".uno:CancelCheckOut" oor:op="replace">
<prop oor:name="Label" oor:type="xs:string">
<value xml:lang="en-US">Cancel Check-Out...</value>
</prop>
</node>
<node oor:name=".uno:CheckIn" oor:op="replace">
<prop oor:name="Label" oor:type="xs:string">
<value xml:lang="en-US">Check-In...</value>
</prop>
</node>
<node oor:name=".uno:CloseDoc" oor:op="replace">
<prop oor:name="Label" oor:type="xs:string">
<value xml:lang="en-US">~Close</value>

View File

@ -14,6 +14,8 @@
<menu:menuitem menu:id=".uno:SaveAsTemplate"/>
<menu:menuitem menu:id=".uno:SaveAll"/>
<menu:menuitem menu:id=".uno:CheckOut"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:Reload"/>
<menu:menuitem menu:id=".uno:VersionDialog"/>

View File

@ -14,6 +14,8 @@
<menu:menuitem menu:id=".uno:SaveAsTemplate"/>
<menu:menuitem menu:id=".uno:SaveAll"/>
<menu:menuitem menu:id=".uno:CheckOut"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:Reload"/>
<menu:menuitem menu:id=".uno:VersionDialog"/>

View File

@ -14,6 +14,8 @@
<menu:menuitem menu:id=".uno:SaveAsTemplate"/>
<menu:menuitem menu:id=".uno:SaveAll"/>
<menu:menuitem menu:id=".uno:CheckOut"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:Reload"/>
<menu:menuitem menu:id=".uno:VersionDialog"/>

View File

@ -194,6 +194,8 @@ public:
sal_Bool SwitchDocumentToFile( const rtl::OUString& aURL );
::rtl::OUString GetBaseURL( bool bForSaving=false );
void SetInCheckIn( bool bInCheckIn );
bool IsInCheckIn( );
#if _SOLAR__PRIVATE
SAL_DLLPRIVATE sal_Bool HasStorage_Impl() const;

View File

@ -734,6 +734,8 @@ public:
SAL_DLLPRIVATE sal_Bool QuerySaveSizeExceededModules_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler );
SAL_DLLPRIVATE void CheckOut( );
SAL_DLLPRIVATE void CancelCheckOut( );
SAL_DLLPRIVATE void CheckIn( );
};
#define SFX_GLOBAL_CLASSID \

View File

@ -387,7 +387,7 @@ private:
SAL_DLLPRIVATE SfxViewFrame& GetViewFrame_Impl() const;
SAL_DLLPRIVATE void ShowInfoBars( );
DECL_LINK( CheckOutHandler, PushButton * );
DECL_LINK( CheckOutHandler, void * );
//________________________________________________________________________________________________________
// private variables

View File

@ -1422,8 +1422,16 @@ public:
throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL checkOut( ) throw ( ::com::sun::star::uno::RuntimeException );
virtual void SAL_CALL cancelCheckOut( ) throw ( ::com::sun::star::uno::RuntimeException );
virtual void SAL_CALL checkIn( sal_Bool bIsMajor, const rtl::OUString & rMessage )
throw ( ::com::sun::star::uno::RuntimeException );
virtual sal_Bool SAL_CALL isVersionable( ) throw ( ::com::sun::star::uno::RuntimeException );
virtual sal_Bool SAL_CALL canCheckOut( ) throw ( ::com::sun::star::uno::RuntimeException );
virtual sal_Bool SAL_CALL canCancelCheckOut( ) throw ( ::com::sun::star::uno::RuntimeException );
virtual sal_Bool SAL_CALL canCheckIn( ) throw ( ::com::sun::star::uno::RuntimeException );
sal_Bool getBoolPropertyValue( const rtl::OUString& rName ) throw ( ::com::sun::star::uno::RuntimeException );
//____________________________________________________________________________________________________
// SfxListener

View File

@ -45,6 +45,8 @@
#define CMD_SID_DOCINFO_TITLE ".uno:DocInfoTitle"
#define CMD_SID_OPENTEMPLATE ".uno:OpenTemplate"
#define CMD_SID_CHECKOUT ".uno:CheckOut"
#define CMD_SID_CANCELCHECKOUT ".uno:CancelCheckOut"
#define CMD_SID_CHECKIN ".uno:CheckIn"
#define CMD_SID_OPENURL ".uno:OpenUrl"
#define CMD_SID_OPTIONS ".uno:Options"
#define CMD_SID_ORGANIZER ".uno:Organizer"

View File

@ -144,6 +144,8 @@
#define SID_DIRECTEXPORTDOCASPDF (SID_SFX_START + 1674)
#define SID_UPDATEDOCMODE (SID_SFX_START + 1668)
#define SID_CHECKOUT (SID_SFX_START + 512)
#define SID_CANCELCHECKOUT (SID_SFX_START + 513)
#define SID_CHECKIN (SID_SFX_START + 514)
#define SID_FORCERELOAD (SID_SFX_START + 1502)
#define SID_FILE_DIALOG (SID_SFX_START + 304)
@ -310,6 +312,7 @@
#define SID_DOCINFO_KEYWORDS (SID_SFX_START + 591)
#define SID_DOCINFO_COMMENTS (SID_SFX_START + 592)
#define SID_DOCINFO_AUTHOR (SID_SFX_START + 593)
#define SID_DOCINFO_MAJOR (SID_SFX_START + 594)
#define SID_NEWDOCDIRECT (SID_SFX_START + 537)
#define SID_DOCFRAME (SID_SFX_START + 598)
#define SID_TARGETNAME (SID_SFX_START + 560)

View File

@ -182,6 +182,16 @@ interface OfficeDocument : Document
ExecMethod = ExecFile_Impl;
StateMethod = GetState_Impl;
]
SID_CANCELCHECKOUT
[
ExecMethod = ExecFile_Impl;
StateMethod = GetState_Impl;
]
SID_CHECKIN
[
ExecMethod = ExecFile_Impl;
StateMethod = GetState_Impl;
]
}
//=========================================================================

View File

@ -4468,6 +4468,54 @@ SfxVoidItem CheckOut SID_CHECKOUT
GroupId = GID_DOCUMENT;
]
SfxVoidItem CancelCheckOut SID_CANCELCHECKOUT
()
[
/* flags: */
AutoUpdate = FALSE,
Cachable = Cachable,
FastCall = FALSE,
HasCoreId = FALSE,
HasDialog = FALSE,
ReadOnlyDoc = TRUE,
Toggle = FALSE,
Container = TRUE,
RecordAbsolute = FALSE,
RecordPerSet;
Asynchron;
/* config: */
AccelConfig = TRUE,
MenuConfig = TRUE,
StatusBarConfig = FALSE,
ToolBoxConfig = TRUE,
GroupId = GID_DOCUMENT;
]
SfxVoidItem CheckIn SID_CHECKIN
(SfxStringItem VersionComment SID_DOCINFO_COMMENTS,SfxBoolItem VersionMajor SID_DOCINFO_MAJOR)
[
/* flags: */
AutoUpdate = FALSE,
Cachable = Cachable,
FastCall = FALSE,
HasCoreId = FALSE,
HasDialog = FALSE,
ReadOnlyDoc = TRUE,
Toggle = FALSE,
Container = TRUE,
RecordAbsolute = FALSE,
RecordPerSet;
Asynchron;
/* config: */
AccelConfig = TRUE,
MenuConfig = TRUE,
StatusBarConfig = FALSE,
ToolBoxConfig = TRUE,
GroupId = GID_DOCUMENT;
]
//--------------------------------------------------------------------------
SfxStringItem OpenUrl SID_OPENURL

View File

@ -131,7 +131,8 @@ SfxFormalArgument aFormalArgs[] = {
SFX_ARGUMENT(SID_DEFAULTFILENAME,"SuggestedSaveAsName",SfxStringItem),
SFX_ARGUMENT(SID_DEFAULTFILEPATH,"SuggestedSaveAsDir",SfxStringItem),
SFX_ARGUMENT(SID_DOCINFO_AUTHOR,"VersionAuthor",SfxStringItem),
SFX_ARGUMENT(SID_DOCINFO_COMMENTS,"VersionComment",SfxStringItem),
SFX_ARGUMENT(SID_DOCINFO_COMMENTS,"VersionComment",SfxBoolItem),
SFX_ARGUMENT(SID_DOCINFO_MAJOR,"VersionMajor",SfxStringItem),
SFX_ARGUMENT(SID_FILE_FILTEROPTIONS,"FilterOptions",SfxStringItem),
SFX_ARGUMENT(SID_FILTER_NAME,"FilterName",SfxStringItem),
// SFX_ARGUMENT(SID_FILE_NAME,"FileName",SfxStringItem),

View File

@ -262,6 +262,7 @@ public:
bool m_bTriedStorage:1;
bool m_bRemote:1;
bool m_bInputStreamIsReadOnly:1;
bool m_bInCheckIn:1;
OUString m_aName;
OUString m_aLogicName;
@ -336,6 +337,7 @@ SfxMedium_Impl::SfxMedium_Impl( SfxMedium* pAntiImplP ) :
m_bTriedStorage(false),
m_bRemote(false),
m_bInputStreamIsReadOnly(false),
m_bInCheckIn(false),
m_pSet(NULL),
m_pURLObj(NULL),
m_pFilter(NULL),
@ -1924,10 +1926,12 @@ void SfxMedium::Transfer_Impl()
::ucbhelper::Content aSourceContent;
::ucbhelper::Content aTransferContent;
// Get the parent URL from the XChild if possible: why would the URL necessarily have
// a hierarchical path? It's not always the case for CMIS.
::ucbhelper::Content aDestContent;
::ucbhelper::Content::create( aDestURL, xComEnv, comphelper::getProcessComponentContext(), aDestContent );
if ( !IsInCheckIn( ) )
{
// Get the parent URL from the XChild if possible: why would the URL necessarily have
// a hierarchical path? It's not always the case for CMIS.
Reference< ::com::sun::star::container::XChild> xChild( aDestContent.get(), uno::UNO_QUERY );
rtl::OUString sParentUrl;
if ( xChild.is( ) )
@ -1941,6 +1945,12 @@ void SfxMedium::Transfer_Impl()
if ( !sParentUrl.isEmpty() )
aDest = INetURLObject( sParentUrl );
}
else
{
// For checkin, we need the object URL, not the parent folder
aDest = INetURLObject( aDestURL );
}
// LongName wasn't defined anywhere, only used here... get the Title instead
// as it's less probably empty
@ -1997,8 +2007,24 @@ void SfxMedium::Transfer_Impl()
try
{
rtl::OUString aMimeType = GetFilter()->GetMimeType( );
if (!aTransferContent.transferContent( aSourceContent, ::ucbhelper::InsertOperation_COPY, aFileName, nNameClash, aMimeType ))
::ucbhelper::InsertOperation eOperation = ::ucbhelper::InsertOperation_COPY;
bool bMajor = false;
rtl::OUString sComment;
if ( IsInCheckIn( ) )
{
eOperation = ::ucbhelper::InsertOperation_CHECKIN;
SFX_ITEMSET_ARG( GetItemSet(), pMajor, SfxBoolItem, SID_DOCINFO_MAJOR, false );
bMajor = pMajor && pMajor->GetValue( );
SFX_ITEMSET_ARG( GetItemSet(), pComments, SfxStringItem, SID_DOCINFO_COMMENTS, false );
if ( pComments )
sComment = pComments->GetValue( );
}
rtl::OUString sResultURL;
if (!aTransferContent.transferContent( aSourceContent, eOperation,
aFileName, nNameClash, aMimeType, bMajor, sComment, &sResultURL ))
pImp->m_eError = ERRCODE_IO_GENERAL;
else if ( !sResultURL.isEmpty( ) ) // Likely to happen only for checkin
SwitchDocumentToFile( sResultURL );
}
catch ( const ::com::sun::star::ucb::CommandAbortedException& )
{
@ -3694,4 +3720,14 @@ sal_Bool SfxMedium::SwitchDocumentToFile( const rtl::OUString& aURL )
return bResult;
}
void SfxMedium::SetInCheckIn( bool bInCheckIn )
{
pImp->m_bInCheckIn = bInCheckIn;
}
bool SfxMedium::IsInCheckIn( )
{
return pImp->m_bInCheckIn;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@ -361,6 +361,43 @@ void SfxObjectShell::CheckOut( )
}
}
void SfxObjectShell::CancelCheckOut( )
{
try
{
uno::Reference< document::XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY_THROW );
// TODO Pop up dialog to ask whether to loose data or not
xCmisDoc->cancelCheckOut( );
}
catch ( const uno::RuntimeException& e )
{
ErrorBox* pErrorBox = new ErrorBox( &GetFrame()->GetWindow(), WB_OK, e.Message );
pErrorBox->Execute( );
delete pErrorBox;
}
}
void SfxObjectShell::CheckIn( )
{
try
{
uno::Reference< document::XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY_THROW );
sal_Bool bIsMajor = sal_False;
rtl::OUString sComment( "Some sample comment" );
// TODO Pop up dialog to ask for comment and major
xCmisDoc->checkIn( bIsMajor, sComment );
uno::Reference< util::XModifiable > xModifiable( GetModel( ), uno::UNO_QUERY );
if ( xModifiable.is( ) )
xModifiable->setModified( sal_False );
}
catch ( const uno::RuntimeException& e )
{
ErrorBox* pErrorBox = new ErrorBox( &GetFrame()->GetWindow(), WB_OK, e.Message );
pErrorBox->Execute( );
delete pErrorBox;
}
}
//--------------------------------------------------------------------
void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq)
@ -912,6 +949,16 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq)
CheckOut( );
break;
}
case SID_CANCELCHECKOUT:
{
CancelCheckOut( );
break;
}
case SID_CHECKIN:
{
CheckIn( );
break;
}
}
// Prevent entry in the Pick-lists
@ -976,6 +1023,37 @@ void SfxObjectShell::GetState_Impl(SfxItemSet &rSet)
}
break;
case SID_CANCELCHECKOUT:
case SID_CHECKIN:
{
bool bShow = false;
Reference< XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY );
beans::PropertyValues aCmisProperties = xCmisDoc->getCmisPropertiesValues( );
if ( xCmisDoc->isVersionable( ) && aCmisProperties.hasElements( ) )
{
// Loop over the CMIS Properties to find cmis:isVersionSeriesCheckedOut
bool bFoundCheckedout = false;
sal_Bool bCheckedOut = sal_False;
for ( sal_Int32 i = 0; i < aCmisProperties.getLength() && !bFoundCheckedout; ++i )
{
if ( aCmisProperties[i].Name == "cmis:isVersionSeriesCheckedOut" )
{
bFoundCheckedout = true;
aCmisProperties[i].Value >>= bCheckedOut;
}
}
bShow = bCheckedOut;
}
if ( !bShow )
{
rSet.DisableItem( nWhich );
rSet.Put( SfxVisibilityItem( nWhich, sal_False ) );
}
}
break;
case SID_VERSION:
{
SfxObjectShell *pDoc = this;

View File

@ -1374,7 +1374,7 @@ sal_Bool SfxObjectShell::SaveTo_Impl
pFilter = rMedium.GetFilter();
const SfxStringItem *pVersionItem = pSet ? (const SfxStringItem*)
const SfxStringItem *pVersionItem = ( !rMedium.IsInCheckIn( ) && pSet ) ? (const SfxStringItem*)
SfxRequest::GetItem( pSet, SID_DOCINFO_COMMENTS, sal_False, TYPE(SfxStringItem) ) : NULL;
::rtl::OUString aTmpVersionURL;
@ -1460,7 +1460,7 @@ sal_Bool SfxObjectShell::SaveTo_Impl
}
}
if ( bOk && pVersionItem )
if ( bOk && pVersionItem && !rMedium.IsInCheckIn() )
{
// store a version also
const SfxStringItem *pAuthorItem = pSet ? (const SfxStringItem*)
@ -1624,7 +1624,12 @@ sal_Bool SfxObjectShell::SaveTo_Impl
AddLog( ::rtl::OUString( OSL_LOG_PREFIX "Medium commit." ) );
rtl::OUString sName( rMedium.GetName( ) );
bOk = rMedium.Commit();
rtl::OUString sNewName( rMedium.GetName( ) );
if ( sName != sNewName )
GetMedium( )->SwitchDocumentToFile( sNewName );
if ( bOk )
{
@ -2414,10 +2419,23 @@ sal_Bool SfxObjectShell::DoSave_Impl( const SfxItemSet* pArgs )
pSet->ClearItem( SID_VERSION );
pSet->ClearItem( SID_DOC_BASEURL );
// copy the version comment and major items for the checkin only
if ( pRetrMedium->IsInCheckIn( ) )
{
const SfxPoolItem* pMajor = pArgs->GetItem( SID_DOCINFO_MAJOR );
if ( pMajor )
pSet->Put( *pMajor );
const SfxPoolItem* pComments = pArgs->GetItem( SID_DOCINFO_COMMENTS );
if ( pComments )
pSet->Put( *pComments );
}
// create a medium as a copy; this medium is only for writingm, because it
// uses the same name as the original one writing is done through a copy,
// that will be transferred to the target (of course after calling HandsOff)
SfxMedium* pMediumTmp = new SfxMedium( pRetrMedium->GetName(), pRetrMedium->GetOpenMode(), pFilter, pSet );
pMediumTmp->SetInCheckIn( pRetrMedium->IsInCheckIn( ) );
pMediumTmp->SetLongName( pRetrMedium->GetLongName() );
if ( pMediumTmp->GetErrorCode() != ERRCODE_NONE )
{

View File

@ -1621,11 +1621,13 @@ void SAL_CALL SfxBaseModel::storeSelf( const uno::Sequence< beans::PropertyVa
m_pData->m_pObjectShell->AddLog( ::rtl::OUString( OSL_LOG_PREFIX "storeSelf" ) );
SfxSaveGuard aSaveGuard(this, m_pData, sal_False);
sal_Bool bCheckIn = sal_False;
for ( sal_Int32 nInd = 0; nInd < aSeqArgs.getLength(); nInd++ )
{
// check that only acceptable parameters are provided here
if ( aSeqArgs[nInd].Name != "VersionComment" && aSeqArgs[nInd].Name != "Author"
&& aSeqArgs[nInd].Name != "InteractionHandler" && aSeqArgs[nInd].Name != "StatusIndicator" )
&& aSeqArgs[nInd].Name != "InteractionHandler" && aSeqArgs[nInd].Name != "StatusIndicator"
&& aSeqArgs[nInd].Name != "VersionMajor" && aSeqArgs[nInd].Name != "CheckIn" )
{
m_pData->m_pObjectShell->AddLog( ::rtl::OUString( OSL_LOG_PREFIX "unexpected parameter for storeSelf, might be no problem if SaveAs is executed." ) );
m_pData->m_pObjectShell->StoreLog();
@ -1634,10 +1636,34 @@ void SAL_CALL SfxBaseModel::storeSelf( const uno::Sequence< beans::PropertyVa
aMessage += aSeqArgs[nInd].Name;
throw lang::IllegalArgumentException( aMessage, uno::Reference< uno::XInterface >(), 1 );
}
else if ( aSeqArgs[nInd].Name == "CheckIn" )
{
aSeqArgs[nInd].Value >>= bCheckIn;
}
}
// Remove CheckIn property if needed
sal_uInt16 nSlotId = SID_SAVEDOC;
uno::Sequence< beans::PropertyValue > aArgs = aSeqArgs;
if ( bCheckIn )
{
nSlotId = SID_CHECKIN;
sal_Int32 nLength = aSeqArgs.getLength( );
aArgs = uno::Sequence< beans::PropertyValue >( nLength - 1 );
sal_Int32 nNewI = 0;
for ( sal_Int32 i = 0; i < nLength; ++i )
{
beans::PropertyValue aProp = aSeqArgs[i];
if ( aProp.Name != "CheckIn" )
{
aArgs[nNewI] = aProp;
++nNewI;
}
}
}
SfxAllItemSet *pParams = new SfxAllItemSet( SFX_APP()->GetPool() );
TransformParameters( SID_SAVEDOC, aSeqArgs, *pParams );
TransformParameters( nSlotId, aArgs, *pParams );
SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_SAVEDOC, GlobalEventConfig::GetEventName(STR_EVENT_SAVEDOC), m_pData->m_pObjectShell ) );
@ -1662,7 +1688,12 @@ void SAL_CALL SfxBaseModel::storeSelf( const uno::Sequence< beans::PropertyVa
}
}
else
{
// Tell the SfxMedium if we are in checkin instead of normal save
m_pData->m_pObjectShell->GetMedium( )->SetInCheckIn( nSlotId == SID_CHECKIN );
bRet = m_pData->m_pObjectShell->Save_Impl( pParams );
m_pData->m_pObjectShell->GetMedium( )->SetInCheckIn( nSlotId != SID_CHECKIN );
}
DELETEZ( pParams );
@ -2577,9 +2608,81 @@ void SAL_CALL SfxBaseModel::checkOut( ) throw ( uno::RuntimeException )
}
}
sal_Bool SAL_CALL SfxBaseModel::isVersionable( ) throw ( uno::RuntimeException )
void SAL_CALL SfxBaseModel::cancelCheckOut( ) throw ( uno::RuntimeException )
{
sal_Bool bVersionable = sal_False;
SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
if ( pMedium )
{
try
{
::ucbhelper::Content aContent( pMedium->GetName(),
uno::Reference<ucb::XCommandEnvironment>(),
comphelper::getProcessComponentContext() );
uno::Any aResult = aContent.executeCommand( "cancelCheckout", 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 uno::Exception & e )
{
throw uno::RuntimeException( e.Message, e.Context );
}
}
}
void SAL_CALL SfxBaseModel::checkIn( sal_Bool bIsMajor, const rtl::OUString& rMessage ) throw ( uno::RuntimeException )
{
SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
if ( pMedium )
{
try
{
uno::Sequence< beans::PropertyValue > aProps( 3 );
aProps[0].Name = "VersionMajor";
aProps[0].Value = uno::makeAny( bIsMajor );
aProps[1].Name = "VersionComment";
aProps[1].Value = uno::makeAny( rMessage );
aProps[2].Name = "CheckIn";
aProps[2].Value = uno::makeAny( sal_True );
rtl::OUString sName( pMedium->GetName( ) );
storeSelf( aProps );
// Refresh pMedium as it has probably changed during the storeSelf call
pMedium = m_pData->m_pObjectShell->GetMedium( );
rtl::OUString sNewName( pMedium->GetName( ) );
// URL has changed, update the document
if ( sName != sNewName )
{
m_pData->m_xDocumentProperties->setTitle( getTitle( ) );
uno::Sequence< beans::PropertyValue > aSequence ;
TransformItems( SID_OPENDOC, *pMedium->GetItemSet(), aSequence );
attachResource( sNewName, aSequence );
// Reload the CMIS properties
loadCmisProperties( );
}
}
catch ( const uno::Exception & e )
{
throw uno::RuntimeException( e.Message, e.Context );
}
}
}
sal_Bool SfxBaseModel::getBoolPropertyValue( const rtl::OUString& rName ) throw ( uno::RuntimeException )
{
sal_Bool bValue = sal_False;
SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
if ( pMedium )
{
@ -2589,10 +2692,9 @@ sal_Bool SAL_CALL SfxBaseModel::isVersionable( ) throw ( uno::RuntimeException )
uno::Reference<ucb::XCommandEnvironment>(),
comphelper::getProcessComponentContext() );
com::sun::star::uno::Reference < beans::XPropertySetInfo > xProps = aContent.getProperties();
::rtl::OUString aIsVersionableProp( "IsVersionable" );
if ( xProps->hasPropertyByName( aIsVersionableProp ) )
if ( xProps->hasPropertyByName( rName ) )
{
aContent.getPropertyValue( aIsVersionableProp ) >>= bVersionable;
aContent.getPropertyValue( rName ) >>= bValue;
}
}
catch ( const uno::Exception & e )
@ -2600,7 +2702,27 @@ sal_Bool SAL_CALL SfxBaseModel::isVersionable( ) throw ( uno::RuntimeException )
throw uno::RuntimeException( e.Message, e.Context );
}
}
return bVersionable;
return bValue;
}
sal_Bool SAL_CALL SfxBaseModel::isVersionable( ) throw ( uno::RuntimeException )
{
return getBoolPropertyValue( "IsVersionable" );
}
sal_Bool SAL_CALL SfxBaseModel::canCheckOut( ) throw ( uno::RuntimeException )
{
return getBoolPropertyValue( "CanCheckOut" );
}
sal_Bool SAL_CALL SfxBaseModel::canCancelCheckOut( ) throw ( uno::RuntimeException )
{
return getBoolPropertyValue( "CanCancelCheckOut" );
}
sal_Bool SAL_CALL SfxBaseModel::canCheckIn( ) throw ( uno::RuntimeException )
{
return getBoolPropertyValue( "CanCheckIn" );
}
void SfxBaseModel::loadCmisProperties( )

View File

@ -1470,7 +1470,7 @@ void SfxBaseController::ShowInfoBars( )
}
}
IMPL_LINK( SfxBaseController, CheckOutHandler, PushButton*, pBtn )
IMPL_LINK_NOARG ( SfxBaseController, CheckOutHandler )
{
if ( m_pData->m_pViewShell )
m_pData->m_pViewShell->GetObjectShell()->CheckOut( );

View File

@ -30,6 +30,10 @@
<menu:menuitem menu:id=".uno:SaveAs"/>
<menu:menuitem menu:id=".uno:SaveAll"/>
<menu:menuitem menu:id=".uno:CheckOut"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:Reload"/>
<menu:menuitem menu:id=".uno:VersionDialog"/>

View File

@ -14,6 +14,8 @@
<menu:menuitem menu:id=".uno:SaveAsTemplate"/>
<menu:menuitem menu:id=".uno:SaveAll"/>
<menu:menuitem menu:id=".uno:CheckOut"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:Reload"/>
<menu:menuitem menu:id=".uno:VersionDialog"/>

View File

@ -14,6 +14,8 @@
<menu:menuitem menu:id=".uno:SaveAsTemplate"/>
<menu:menuitem menu:id=".uno:SaveAll"/>
<menu:menuitem menu:id=".uno:CheckOut"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menuitem menu:id=".uno:Reload"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:ExportTo"/>

View File

@ -14,6 +14,8 @@
<menu:menuitem menu:id=".uno:SaveAsTemplate"/>
<menu:menuitem menu:id=".uno:SaveAll"/>
<menu:menuitem menu:id=".uno:CheckOut"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:Reload"/>
<menu:menuitem menu:id=".uno:VersionDialog"/>

View File

@ -14,6 +14,8 @@
<menu:menuitem menu:id=".uno:SaveAsTemplate"/>
<menu:menuitem menu:id=".uno:SaveAll"/>
<menu:menuitem menu:id=".uno:CheckOut"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:Reload"/>
<menu:menuitem menu:id=".uno:VersionDialog"/>

View File

@ -14,6 +14,8 @@
<menu:menuitem menu:id=".uno:SaveAsTemplate"/>
<menu:menuitem menu:id=".uno:SaveAll"/>
<menu:menuitem menu:id=".uno:CheckOut"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:Reload"/>
<menu:menuitem menu:id=".uno:VersionDialog"/>

View File

@ -14,6 +14,8 @@
<menu:menuitem menu:id=".uno:SaveAsTemplate"/>
<menu:menuitem menu:id=".uno:SaveAll"/>
<menu:menuitem menu:id=".uno:CheckOut"/>
<menu:menuitem menu:id=".uno:CancelCheckOut"/>
<menu:menuitem menu:id=".uno:CheckIn"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:Reload"/>
<menu:menuitem menu:id=".uno:VersionDialog"/>

View File

@ -679,6 +679,21 @@ Any SAL_CALL UniversalContentBroker::execute(
globalTransfer( aTransferArg, Environment );
}
else if ( ( aCommand.Handle == CHECKIN_HANDLE ) || aCommand.Name == CHECKIN_NAME )
{
ucb::CheckinArgument aCheckinArg;
if ( !( aCommand.Argument >>= aCheckinArg ) )
{
ucbhelper::cancelCommandExecution(
makeAny( IllegalArgumentException(
OUString( "Wrong argument type!" ),
static_cast< cppu::OWeakObject * >( this ),
-1 ) ),
Environment );
// Unreachable
}
aRet <<= checkIn( aCheckinArg, Environment );
}
else
{
//////////////////////////////////////////////////////////////////

View File

@ -21,6 +21,7 @@
#define _UCB_HXX
#include <com/sun/star/ucb/CheckinArgument.hpp>
#include <com/sun/star/ucb/XUniversalContentBroker.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
@ -181,6 +182,10 @@ private:
com::sun::star::ucb::XCommandEnvironment >& xEnv )
throw( com::sun::star::uno::Exception );
com::sun::star::uno::Any checkIn( const com::sun::star::ucb::CheckinArgument& rArg,
const com::sun::star::uno::Reference<
com::sun::star::ucb::XCommandEnvironment >& xEnv ) throw( com::sun::star::uno::Exception );
bool configureUcb()
throw ( com::sun::star::uno::RuntimeException);

View File

@ -249,6 +249,13 @@ CommandProcessorInfo::CommandProcessorInfo()
getCppuType(
static_cast<
ucb::GlobalTransferCommandArgument * >( 0 ) ) ); // ArgType
(*m_pInfo)[ 2 ]
= ucb::CommandInfo(
rtl::OUString( CHECKIN_NAME ), // Name
CHECKIN_HANDLE, // Handle
getCppuType(
static_cast<
ucb::GlobalTransferCommandArgument * >( 0 ) ) ); // ArgType
}
//=========================================================================
@ -2028,4 +2035,88 @@ void UniversalContentBroker::globalTransfer(
}
}
uno::Any UniversalContentBroker::checkIn( const ucb::CheckinArgument& rArg,
const uno::Reference< ucb::XCommandEnvironment >& xEnv ) throw ( uno::Exception )
{
uno::Any aRet;
// Use own command environment with own interaction handler intercepting
// some interaction requests that shall not be handled by the user-supplied
// interaction handler.
uno::Reference< ucb::XCommandEnvironment > xLocalEnv;
if (xEnv.is())
{
uno::Reference< uno::XComponentContext > xCtx(
comphelper::getComponentContext( m_xSMgr ) );
xLocalEnv.set( ucb::CommandEnvironment::create(
xCtx,
new InteractionHandlerProxy( xEnv->getInteractionHandler() ),
xEnv->getProgressHandler() ) );
}
uno::Reference< ucb::XContent > xTarget;
uno::Reference< ucb::XContentIdentifier > xId
= createContentIdentifier( rArg.TargetURL );
if ( xId.is() )
{
try
{
xTarget = queryContent( xId );
}
catch ( ucb::IllegalIdentifierException const & )
{
}
}
if ( !xTarget.is() )
{
uno::Any aProps
= uno::makeAny(beans::PropertyValue(
rtl::OUString( "Uri" ), -1,
uno::makeAny( rArg.TargetURL ),
beans::PropertyState_DIRECT_VALUE ) );
ucbhelper::cancelCommandExecution(
ucb::IOErrorCode_CANT_READ,
uno::Sequence< uno::Any >( &aProps, 1 ),
xEnv,
rtl::OUString( "Can't instanciate target object!" ),
this );
// Unreachable
}
uno::Reference< ucb::XCommandProcessor > xCommandProcessor(
xTarget, uno::UNO_QUERY );
if ( !xCommandProcessor.is() )
{
uno::Any aProps
= uno::makeAny(
beans::PropertyValue(
rtl::OUString( "Uri" ), -1,
uno::makeAny( rArg.TargetURL ),
beans::PropertyState_DIRECT_VALUE ) );
ucbhelper::cancelCommandExecution(
ucb::IOErrorCode_CANT_READ,
uno::Sequence< uno::Any >( &aProps, 1 ),
xEnv,
rtl::OUString( "Target content is not a XCommandProcessor!" ),
this );
// Unreachable
}
try
{
ucb::Command aCommand(
rtl::OUString( "checkin" ), -1,
uno::makeAny( rArg ) );
aRet = xCommandProcessor->execute( aCommand, 0, xLocalEnv );
}
catch ( ucb::UnsupportedCommandException const & )
{
// 'checkin' command is not supported by commandprocessor:
// ignore.
}
return aRet;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@ -32,6 +32,9 @@
#define GLOBALTRANSFER_NAME "globalTransfer"
#define GLOBALTRANSFER_HANDLE 1025
#define CHECKIN_NAME "checkin"
#define CHECKIN_HANDLE 1026
#endif /* !_UCBCMDS_HXX */
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@ -53,7 +53,9 @@
#include <libcmis/document.hxx>
#include <comphelper/processfactory.hxx>
#include <ucbhelper/cancelcommandexecution.hxx>
#include <ucbhelper/content.hxx>
#include <ucbhelper/contentidentifier.hxx>
#include <ucbhelper/std_inputstream.hxx>
#include <ucbhelper/std_outputstream.hxx>
@ -454,7 +456,8 @@ namespace cmis
{
boost::shared_ptr< libcmis::AllowableActions > allowableActions = getObject( xEnv )->getAllowableActions( );
sal_Bool bReadOnly = sal_False;
if ( !allowableActions->isAllowed( libcmis::ObjectAction::SetContentStream ) )
if ( !allowableActions->isAllowed( libcmis::ObjectAction::SetContentStream ) &&
!allowableActions->isAllowed( libcmis::ObjectAction::CheckIn ) )
bReadOnly = sal_True;
xRow->appendBoolean( rProp, bReadOnly );
@ -563,6 +566,60 @@ namespace cmis
xRow->appendVoid( rProp );
}
}
else if ( rProp.Name == "CanCheckOut" )
{
try
{
libcmis::ObjectPtr pObject = getObject( xEnv );
libcmis::AllowableActionsPtr aAllowables = pObject->getAllowableActions( );
bool bAllowed = false;
if ( aAllowables )
{
bAllowed = aAllowables->isAllowed( libcmis::ObjectAction::CheckOut );
}
xRow->appendBoolean( rProp, bAllowed );
}
catch ( const libcmis::Exception& )
{
xRow->appendVoid( rProp );
}
}
else if ( rProp.Name == "CanCancelCheckOut" )
{
try
{
libcmis::ObjectPtr pObject = getObject( xEnv );
libcmis::AllowableActionsPtr aAllowables = pObject->getAllowableActions( );
bool bAllowed = false;
if ( aAllowables )
{
bAllowed = aAllowables->isAllowed( libcmis::ObjectAction::CancelCheckOut );
}
xRow->appendBoolean( rProp, bAllowed );
}
catch ( const libcmis::Exception& )
{
xRow->appendVoid( rProp );
}
}
else if ( rProp.Name == "CanCheckIn" )
{
try
{
libcmis::ObjectPtr pObject = getObject( xEnv );
libcmis::AllowableActionsPtr aAllowables = pObject->getAllowableActions( );
bool bAllowed = false;
if ( aAllowables )
{
bAllowed = aAllowables->isAllowed( libcmis::ObjectAction::CheckIn );
}
xRow->appendBoolean( rProp, bAllowed );
}
catch ( const libcmis::Exception& )
{
xRow->appendVoid( rProp );
}
}
else
SAL_INFO( "cmisucp", "Looking for unsupported property " << rProp.Name );
}
@ -662,6 +719,170 @@ namespace cmis
return aRet;
}
rtl::OUString Content::checkIn( const ucb::CheckinArgument& rArg,
const uno::Reference< ucb::XCommandEnvironment > & xEnv )
throw( uno::Exception )
{
ucbhelper::Content aSourceContent( rArg.SourceURL, xEnv, comphelper::getProcessComponentContext( ) );
uno::Reference< io::XInputStream > xIn = aSourceContent.openStream( );
libcmis::ObjectPtr object;
try
{
object = getObject( xEnv );
}
catch ( const libcmis::Exception& )
{
}
libcmis::Document* pPwc = dynamic_cast< libcmis::Document* >( object.get( ) );
if ( !pPwc )
{
ucbhelper::cancelCommandExecution(
ucb::IOErrorCode_GENERAL,
uno::Sequence< uno::Any >( 0 ),
xEnv,
"Checkin only supported by documents" );
}
boost::shared_ptr< ostream > pOut( new ostringstream ( ios_base::binary | ios_base::in | ios_base::out ) );
uno::Reference < io::XOutputStream > xOutput = new ucbhelper::StdOutputStream( pOut );
copyData( xIn, xOutput );
map< string, libcmis::PropertyPtr > newProperties;
libcmis::DocumentPtr pDoc = pPwc->checkIn( rArg.MajorVersion, OUSTR_TO_STDSTR( rArg.VersionComment ), newProperties,
pOut, OUSTR_TO_STDSTR( rArg.MimeType ), OUSTR_TO_STDSTR( rArg.NewTitle ) );
// Get the URL and send it back as a result
URL aCmisUrl( m_sURL );
vector< string > aPaths = pDoc->getPaths( );
if ( !aPaths.empty() )
{
string sPath = aPaths.front( );
aCmisUrl.setObjectPath( STD_TO_OUSTR( sPath ) );
}
else
{
// We may have unfiled document depending on the server, those
// won't have any path, use their ID instead
string sId = pDoc->getId( );
aCmisUrl.setObjectId( STD_TO_OUSTR( sId ) );
}
return aCmisUrl.asString( );
}
rtl::OUString Content::checkOut( const uno::Reference< ucb::XCommandEnvironment > & xEnv )
throw( uno::Exception )
{
rtl::OUString aRet;
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() ) );
}
return aRet;
}
rtl::OUString Content::cancelCheckOut( const uno::Reference< ucb::XCommandEnvironment > & xEnv )
throw( uno::Exception )
{
rtl::OUString aRet;
try
{
libcmis::DocumentPtr pPwc = boost::dynamic_pointer_cast< libcmis::Document >( getObject( xEnv ) );
if ( pPwc.get( ) == NULL )
{
ucbhelper::cancelCommandExecution(
ucb::IOErrorCode_GENERAL,
uno::Sequence< uno::Any >( 0 ),
xEnv,
"CancelCheckout only supported by documents" );
}
pPwc->cancelCheckout( );
// Get the Original document (latest version)
vector< libcmis::DocumentPtr > aVersions = pPwc->getAllVersions( );
libcmis::DocumentPtr pDoc;
for ( vector< libcmis::DocumentPtr >::iterator it = aVersions.begin();
it != aVersions.end( ) && pDoc != NULL; ++it )
{
libcmis::DocumentPtr pVersion = *it;
map< string, libcmis::PropertyPtr > aProps = pVersion->getProperties( );
bool bIsLatestVersion = false;
map< string, libcmis::PropertyPtr >::iterator propIt = aProps.find( string( "cmis:isLatestVersion" ) );
if ( propIt != aProps.end( ) && !propIt->second->getBools( ).empty( ) )
{
bIsLatestVersion = propIt->second->getBools( ).front( );
}
if ( bIsLatestVersion )
pDoc.reset( pVersion.get( ) );
}
// Compute the URL of the Document
URL aCmisUrl( m_sURL );
vector< string > aPaths = pDoc->getPaths( );
if ( !aPaths.empty() )
{
string sPath = aPaths.front( );
aCmisUrl.setObjectPath( STD_TO_OUSTR( sPath ) );
}
else
{
// We may have unfiled doc depending on the server, those
// won't have any path, use their ID instead
string sId = pDoc->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() ) );
}
return aRet;
}
void Content::transfer( const ucb::TransferInfo& rTransferInfo,
const uno::Reference< ucb::XCommandEnvironment > & xEnv )
throw( uno::Exception )
@ -756,11 +977,10 @@ namespace cmis
libcmis::Document* document = dynamic_cast< libcmis::Document* >( object.get( ) );
if ( NULL != document )
{
string sMime = document->getContentType( );
boost::shared_ptr< ostream > pOut( new ostringstream ( ios_base::binary | ios_base::in | ios_base::out ) );
uno::Reference < io::XOutputStream > xOutput = new ucbhelper::StdOutputStream( pOut );
copyData( xInputStream, xOutput );
document->setContentStream( pOut, sMime, OUSTR_TO_STDSTR( rMimeType ), bReplaceExisting );
document->setContentStream( pOut, OUSTR_TO_STDSTR( rMimeType ), string( ), bReplaceExisting );
}
}
else
@ -997,6 +1217,15 @@ namespace cmis
beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVersionable" ) ),
-1, getCppuBooleanType(),
beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CanCheckOut" ) ),
-1, getCppuBooleanType(),
beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CanCancelCheckOut" ) ),
-1, getCppuBooleanType(),
beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CanCheckIn" ) ),
-1, getCppuBooleanType(),
beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
};
const int nProps = SAL_N_ELEMENTS(aGenericProperties);
@ -1035,6 +1264,9 @@ namespace cmis
// Mandatory CMIS-only commands
ucb::CommandInfo ( rtl::OUString( "checkout" ), -1, getCppuVoidType() ),
ucb::CommandInfo ( rtl::OUString( "cancelCheckout" ), -1, getCppuVoidType() ),
ucb::CommandInfo ( rtl::OUString( "checkIn" ), -1,
getCppuType( static_cast<ucb::TransferInfo * >( 0 ) ) ),
// Folder Only, omitted if not a folder
ucb::CommandInfo
@ -1227,46 +1459,20 @@ namespace cmis
}
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" );
aRet <<= checkOut( xEnv );
}
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() )
else if ( aCommand.Name == "cancelCheckout" )
{
string sPath = aPaths.front( );
aCmisUrl.setObjectPath( STD_TO_OUSTR( sPath ) );
aRet <<= cancelCheckOut( xEnv );
}
else
else if ( aCommand.Name == "checkin" )
{
// 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 )
ucb::CheckinArgument aArg;
if ( !( aCommand.Argument >>= aArg ) )
{
SAL_INFO( "cmisucp", "Unexpected libcmis exception: " << e.what( ) );
ucbhelper::cancelCommandExecution(
ucb::IOErrorCode_GENERAL,
uno::Sequence< uno::Any >( 0 ),
xEnv,
rtl::OUString::createFromAscii( e.what() ) );
ucbhelper::cancelCommandExecution ( getBadArgExcept(), xEnv );
}
aRet <<= checkIn( aArg, xEnv );
}
else
{

View File

@ -34,6 +34,7 @@
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/ucb/CheckinArgument.hpp>
#include <com/sun/star/ucb/ContentCreationException.hpp>
#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
#include <com/sun/star/ucb/TransferInfo.hpp>
@ -117,6 +118,16 @@ private:
const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& xEnv )
throw( com::sun::star::uno::Exception );
rtl::OUString checkIn( const com::sun::star::ucb::CheckinArgument& rArg,
const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv )
throw( com::sun::star::uno::Exception );
rtl::OUString checkOut( const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv )
throw( com::sun::star::uno::Exception );
rtl::OUString cancelCheckOut( const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv )
throw( com::sun::star::uno::Exception );
void destroy( ) throw( com::sun::star::uno::Exception );
void copyData( com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xIn,

View File

@ -81,7 +81,8 @@ enum InsertOperation
{
InsertOperation_COPY, // copy source data
InsertOperation_MOVE, // move source data
InsertOperation_LINK // create a link to source
InsertOperation_LINK, // create a link to source
InsertOperation_CHECKIN // check-in source data
};
//=========================================================================
@ -664,13 +665,21 @@ public:
* will overwrite the clashing content and all its data,
* NameClash::RENAME will generate and supply a non-clashing title.
* @see com/sun/star/ucb/NameClash.idl
* @param rMimeType contains the MIME type of the document to write.
* @param bMajorVersion tells to create a new major version for checkin operations
* @param rCommentVersion contains the comment to use for checkin operations
* @param rResultURL is a hacky way to get the update URL after the operation in
* case there was a change (introduced for the checkin operation)
*/
sal_Bool
transferContent( const Content& rSourceContent,
InsertOperation eOperation,
const ::rtl::OUString & rTitle,
const sal_Int32 nNameClashAction,
const ::rtl::OUString & rMimeType = ::rtl::OUString( ) )
const ::rtl::OUString & rMimeType = ::rtl::OUString( ),
bool bMajorVersion = false,
const ::rtl::OUString & rCommentVersion = ::rtl::OUString( ),
::rtl::OUString* pResultURL = NULL )
throw( ::com::sun::star::ucb::CommandAbortedException,
::com::sun::star::uno::RuntimeException,
::com::sun::star::uno::Exception );

View File

@ -27,6 +27,7 @@
#include <cppuhelper/weak.hxx>
#include <cppuhelper/implbase1.hxx>
#include <com/sun/star/ucb/CheckinArgument.hpp>
#include <com/sun/star/ucb/ContentCreationError.hpp>
#include <com/sun/star/ucb/XCommandEnvironment.hpp>
#include <com/sun/star/ucb/XCommandInfo.hpp>
@ -962,7 +963,10 @@ sal_Bool Content::transferContent( const Content& rSourceContent,
InsertOperation eOperation,
const rtl::OUString & rTitle,
const sal_Int32 nNameClashAction,
const rtl::OUString & rMimeType )
const rtl::OUString & rMimeType,
bool bMajorVersion,
const rtl::OUString & rVersionComment,
rtl::OUString* pResultURL )
throw( CommandAbortedException, RuntimeException, Exception )
{
Reference< XUniversalContentBroker > pBroker(
@ -971,6 +975,8 @@ sal_Bool Content::transferContent( const Content& rSourceContent,
// Execute command "globalTransfer" at UCB.
TransferCommandOperation eTransOp = TransferCommandOperation();
rtl::OUString sCommand( "globalTransfer" );
bool bCheckIn = false;
switch ( eOperation )
{
case InsertOperation_COPY:
@ -985,6 +991,12 @@ sal_Bool Content::transferContent( const Content& rSourceContent,
eTransOp = TransferCommandOperation_LINK;
break;
case InsertOperation_CHECKIN:
eTransOp = TransferCommandOperation_COPY;
sCommand = rtl::OUString( "checkin" );
bCheckIn = true;
break;
default:
ucbhelper::cancelCommandExecution(
makeAny( IllegalArgumentException(
@ -995,7 +1007,12 @@ sal_Bool Content::transferContent( const Content& rSourceContent,
m_xImpl->getEnvironment() );
// Unreachable
}
Command aCommand;
aCommand.Name = sCommand;
aCommand.Handle = -1; // n/a
if ( !bCheckIn )
{
GlobalTransferCommandArgument2 aTransferArg(
eTransOp,
rSourceContent.getURL(), // SourceURL
@ -1003,12 +1020,18 @@ sal_Bool Content::transferContent( const Content& rSourceContent,
rTitle,
nNameClashAction,
rMimeType );
Command aCommand;
aCommand.Name = rtl::OUString("globalTransfer");
aCommand.Handle = -1; // n/a
aCommand.Argument <<= aTransferArg;
}
else
{
CheckinArgument aCheckinArg( bMajorVersion, rVersionComment,
rSourceContent.getURL(), getURL(), rTitle, rMimeType );
aCommand.Argument <<= aCheckinArg;
}
pBroker->execute( aCommand, 0, m_xImpl->getEnvironment() );
Any aRet = pBroker->execute( aCommand, 0, m_xImpl->getEnvironment() );
if ( pResultURL != NULL )
aRet >>= *pResultURL;
return sal_True;
}