1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sd.hxx" 26 27 #include "ViewClipboard.hxx" 28 29 #include "DrawDocShell.hxx" 30 #include "View.hxx" 31 #include "ViewShell.hxx" 32 #include "Window.hxx" 33 34 #include "drawdoc.hxx" 35 #include "sdpage.hxx" 36 #include "sdxfer.hxx" 37 #include "sdresid.hxx" 38 #include "glob.hrc" 39 40 #include <svx/svdpagv.hxx> 41 #include <vos/mutex.hxx> 42 #include <vcl/svapp.hxx> 43 44 namespace sd { 45 46 ViewClipboard::ViewClipboard (::sd::View& rView) 47 : mrView(rView) 48 { 49 } 50 51 52 53 54 ViewClipboard::~ViewClipboard (void) 55 { 56 } 57 58 59 60 61 void ViewClipboard::HandlePageDrop (const SdTransferable& rTransferable) 62 { 63 // Determine whether to insert the given set of slides or to assign a 64 // given master page. 65 SdPage* pMasterPage = GetFirstMasterPage (rTransferable); 66 if (pMasterPage != NULL) 67 AssignMasterPage (rTransferable, pMasterPage); 68 else 69 InsertSlides (rTransferable, DetermineInsertPosition (rTransferable)); 70 } 71 72 73 74 75 SdPage* ViewClipboard::GetFirstMasterPage (const SdTransferable& rTransferable) 76 { 77 SdPage* pFirstMasterPage = NULL; 78 79 if (rTransferable.HasPageBookmarks()) 80 { 81 do 82 { 83 const List* pBookmarks = &rTransferable.GetPageBookmarks(); 84 if (pBookmarks == NULL) 85 break; 86 87 DrawDocShell* pDocShell = rTransferable.GetPageDocShell(); 88 if (pDocShell == NULL) 89 break; 90 91 SdDrawDocument* pDocument = pDocShell->GetDoc(); 92 if (pDocument == NULL) 93 break; 94 95 if (pBookmarks->Count() <= 0) 96 break; 97 98 int nBookmarkCount = pBookmarks->Count(); 99 for (int nIndex=0; nIndex<nBookmarkCount; nIndex++) 100 { 101 String sName (*(String*) pBookmarks->GetObject(nIndex)); 102 sal_Bool bIsMasterPage; 103 104 // SdPage* GetMasterSdPage(sal_uInt16 nPgNum, PageKind ePgKind); 105 // sal_uInt16 GetMasterSdPageCount(PageKind ePgKind) const; 106 107 sal_uInt16 nBMPage = pDocument->GetPageByName ( 108 sName, bIsMasterPage); 109 if ( ! bIsMasterPage) 110 { 111 // At least one regular slide: return NULL to indicate 112 // that not all bookmarks point to master pages. 113 pFirstMasterPage = NULL; 114 break; 115 } 116 else if (pFirstMasterPage == NULL) 117 { 118 // Remember the first master page for later. 119 if (nBMPage != SDRPAGE_NOTFOUND) 120 pFirstMasterPage = static_cast<SdPage*>( 121 pDocument->GetMasterPage(nBMPage)); 122 } 123 } 124 } 125 while (false); 126 } 127 128 return pFirstMasterPage; 129 } 130 131 132 133 134 void ViewClipboard::AssignMasterPage ( 135 const SdTransferable& rTransferable, 136 SdPage* pMasterPage) 137 { 138 do 139 { 140 if (pMasterPage == NULL) 141 return; 142 143 // Get the target page to which the master page is assigned. 144 SdrPageView* pPageView = mrView.GetSdrPageView(); 145 if (pPageView == NULL) 146 break; 147 148 SdPage* pPage = static_cast<SdPage*>(pPageView->GetPage()); 149 if (pPage == NULL) 150 break; 151 152 SdDrawDocument* pDocument = mrView.GetDoc(); 153 if (pDocument == NULL) 154 break; 155 156 if ( ! rTransferable.HasPageBookmarks()) 157 break; 158 159 DrawDocShell* pDataDocShell = rTransferable.GetPageDocShell(); 160 if (pDataDocShell == NULL) 161 break; 162 163 SdDrawDocument* pSourceDocument = pDataDocShell->GetDoc(); 164 if (pSourceDocument == NULL) 165 break; 166 167 // We have to remove the layout suffix from the layout name which is 168 // appended again by SetMasterPage() to the given name. Don't ask. 169 String sLayoutSuffix (RTL_CONSTASCII_STRINGPARAM(SD_LT_SEPARATOR)); 170 sLayoutSuffix.Append (SdResId(STR_LAYOUT_OUTLINE)); 171 sal_uInt16 nLength = sLayoutSuffix.Len(); 172 String sLayoutName (pMasterPage->GetLayoutName()); 173 if (String(sLayoutName, sLayoutName.Len()-nLength, nLength).Equals ( 174 sLayoutSuffix)) 175 sLayoutName = String(sLayoutName, 0, sLayoutName.Len()-nLength); 176 177 pDocument->SetMasterPage ( 178 pPage->GetPageNum() / 2, 179 sLayoutName, 180 pSourceDocument, 181 sal_False, // Exchange the master page of only the target page. 182 sal_False // Keep unused master pages. 183 ); 184 } 185 while (false); 186 } 187 188 189 190 191 sal_uInt16 ViewClipboard::DetermineInsertPosition ( 192 const SdTransferable& ) 193 { 194 SdDrawDocument* pDoc = mrView.GetDoc(); 195 sal_uInt16 nPgCnt = pDoc->GetSdPageCount( PK_STANDARD ); 196 197 // Insert position is the behind the last selected page or behind the 198 // last page when the selection is empty. 199 sal_uInt16 nInsertPos = pDoc->GetSdPageCount( PK_STANDARD ) * 2 + 1; 200 for( sal_uInt16 nPage = 0; nPage < nPgCnt; nPage++ ) 201 { 202 SdPage* pPage = pDoc->GetSdPage( nPage, PK_STANDARD ); 203 204 if( pPage->IsSelected() ) 205 nInsertPos = nPage * 2 + 3; 206 } 207 208 return nInsertPos; 209 } 210 211 212 213 214 sal_uInt16 ViewClipboard::InsertSlides ( 215 const SdTransferable& rTransferable, 216 sal_uInt16 nInsertPosition) 217 { 218 SdDrawDocument* pDoc = mrView.GetDoc(); 219 220 sal_uInt16 nInsertPgCnt = 0; 221 sal_Bool bMergeMasterPages = !rTransferable.HasSourceDoc( pDoc ); 222 223 // Prepare the insertion. 224 const List* pBookmarkList; 225 DrawDocShell* pDataDocSh; 226 if (rTransferable.HasPageBookmarks()) 227 { 228 // When the transferable contains page bookmarks then the referenced 229 // pages are inserted. 230 pBookmarkList = &rTransferable.GetPageBookmarks(); 231 pDataDocSh = rTransferable.GetPageDocShell(); 232 nInsertPgCnt = (sal_uInt16)pBookmarkList->Count(); 233 } 234 else 235 { 236 // Otherwise all pages of the document of the transferable are 237 // inserted. 238 SfxObjectShell* pShell = rTransferable.GetDocShell(); 239 pDataDocSh = (DrawDocShell*) pShell; 240 SdDrawDocument* pDataDoc = pDataDocSh->GetDoc(); 241 pBookmarkList = NULL; 242 if (pDataDoc!=NULL && pDataDoc->GetSdPageCount(PK_STANDARD)) 243 nInsertPgCnt = pDataDoc->GetSdPageCount(PK_STANDARD); 244 } 245 if (nInsertPgCnt > 0) 246 { 247 const ::vos::OGuard aGuard( Application::GetSolarMutex() ); 248 ::sd::Window* pWin = mrView.GetViewShell()->GetActiveWindow(); 249 const sal_Bool bWait = pWin && pWin->IsWait(); 250 251 if( bWait ) 252 pWin->LeaveWait(); 253 254 pDoc->InsertBookmarkAsPage( 255 const_cast<List*>(pBookmarkList), 256 NULL, 257 sal_False, 258 sal_False, 259 nInsertPosition, 260 (&rTransferable == SD_MOD()->pTransferDrag), 261 pDataDocSh, 262 sal_True, 263 bMergeMasterPages, 264 sal_False); 265 266 if( bWait ) 267 pWin->EnterWait(); 268 } 269 270 return nInsertPgCnt; 271 } 272 273 274 } // end of namespace ::sd 275