1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "precompiled_sd.hxx" 29 #include "controller/SlsFocusManager.hxx" 30 31 #include "SlideSorter.hxx" 32 #include "PaneDockingWindow.hxx" 33 #include "controller/SlideSorterController.hxx" 34 #include "controller/SlsCurrentSlideManager.hxx" 35 #include "controller/SlsVisibleAreaManager.hxx" 36 #include "model/SlideSorterModel.hxx" 37 #include "model/SlsPageDescriptor.hxx" 38 #include "view/SlideSorterView.hxx" 39 #include "view/SlsLayouter.hxx" 40 #include <vcl/toolbox.hxx> 41 42 #include "Window.hxx" 43 #include "sdpage.hxx" 44 45 #define UNIFY_FOCUS_AND_CURRENT_PAGE 46 47 namespace sd { namespace slidesorter { namespace controller { 48 49 FocusManager::FocusManager (SlideSorter& rSlideSorter) 50 : mrSlideSorter(rSlideSorter), 51 mnPageIndex(0), 52 mbPageIsFocused(false), 53 mbIsVerticalWrapActive(false) 54 { 55 if (mrSlideSorter.GetModel().GetPageCount() > 0) 56 mnPageIndex = 0; 57 } 58 59 60 61 62 FocusManager::~FocusManager (void) 63 { 64 } 65 66 67 68 69 void FocusManager::MoveFocus (FocusMoveDirection eDirection) 70 { 71 if (mnPageIndex >= 0 && mbPageIsFocused) 72 { 73 HideFocusIndicator (GetFocusedPageDescriptor()); 74 75 const sal_Int32 nColumnCount (mrSlideSorter.GetView().GetLayouter().GetColumnCount()); 76 const sal_Int32 nPageCount (mrSlideSorter.GetModel().GetPageCount()); 77 switch (eDirection) 78 { 79 case FMD_NONE: 80 // Nothing to be done. 81 break; 82 83 case FMD_LEFT: 84 if (mnPageIndex > 0) 85 mnPageIndex -= 1; 86 else if (mbIsVerticalWrapActive) 87 mnPageIndex = nPageCount-1; 88 break; 89 90 case FMD_RIGHT: 91 if (mnPageIndex < nPageCount-1) 92 mnPageIndex += 1; 93 else if (mbIsVerticalWrapActive) 94 mnPageIndex = 0; 95 break; 96 97 case FMD_UP: 98 { 99 const sal_Int32 nCandidate (mnPageIndex - nColumnCount); 100 if (nCandidate < 0) 101 { 102 if (mbIsVerticalWrapActive) 103 { 104 // Wrap arround to the bottom row or the one above 105 // and go to the correct column. 106 const sal_Int32 nLastIndex (nPageCount-1); 107 const sal_Int32 nLastColumn (nLastIndex % nColumnCount); 108 const sal_Int32 nCurrentColumn (mnPageIndex%nColumnCount); 109 if (nLastColumn >= nCurrentColumn) 110 { 111 // The last row contains the current column. 112 mnPageIndex = nLastIndex - (nLastColumn-nCurrentColumn); 113 } 114 else 115 { 116 // Only the second to last row contains the current column. 117 mnPageIndex = nLastIndex - nLastColumn 118 - nColumnCount 119 + nCurrentColumn; 120 } 121 } 122 } 123 else 124 { 125 // Move the focus the previous row. 126 mnPageIndex = nCandidate; 127 } 128 } 129 break; 130 131 case FMD_DOWN: 132 { 133 const sal_Int32 nCandidate (mnPageIndex + nColumnCount); 134 if (nCandidate >= nPageCount) 135 { 136 if (mbIsVerticalWrapActive) 137 { 138 // Wrap arround to the correct column. 139 mnPageIndex = mnPageIndex % nColumnCount; 140 } 141 else 142 { 143 // Do not move the focus. 144 } 145 } 146 else 147 { 148 // Move the focus to the next row. 149 mnPageIndex = nCandidate; 150 } 151 } 152 break; 153 } 154 155 if (mnPageIndex < 0) 156 { 157 OSL_ASSERT(mnPageIndex>=0); 158 mnPageIndex = 0; 159 } 160 else if (mnPageIndex >= nPageCount) 161 { 162 OSL_ASSERT(mnPageIndex<nPageCount); 163 mnPageIndex = nPageCount - 1; 164 } 165 166 if (mbPageIsFocused) 167 { 168 ShowFocusIndicator(GetFocusedPageDescriptor(), true); 169 } 170 } 171 } 172 173 174 175 176 void FocusManager::ShowFocus (const bool bScrollToFocus) 177 { 178 mbPageIsFocused = true; 179 ShowFocusIndicator(GetFocusedPageDescriptor(), bScrollToFocus); 180 } 181 182 183 184 185 void FocusManager::HideFocus (void) 186 { 187 mbPageIsFocused = false; 188 HideFocusIndicator(GetFocusedPageDescriptor()); 189 } 190 191 192 193 194 bool FocusManager::ToggleFocus (void) 195 { 196 if (mnPageIndex >= 0) 197 { 198 if (mbPageIsFocused) 199 HideFocus (); 200 else 201 ShowFocus (); 202 } 203 return mbPageIsFocused; 204 } 205 206 207 208 209 bool FocusManager::HasFocus (void) const 210 { 211 return mrSlideSorter.GetContentWindow()->HasFocus(); 212 } 213 214 215 216 217 model::SharedPageDescriptor FocusManager::GetFocusedPageDescriptor (void) const 218 { 219 return mrSlideSorter.GetModel().GetPageDescriptor(mnPageIndex); 220 } 221 222 223 224 225 sal_Int32 FocusManager::GetFocusedPageIndex (void) const 226 { 227 return mnPageIndex; 228 } 229 230 231 232 /* 233 void FocusManager::FocusPage (sal_Int32 nPageIndex) 234 { 235 if (nPageIndex != mnPageIndex) 236 { 237 // Hide the focus while switching it to the specified page. 238 FocusHider aHider (*this); 239 mnPageIndex = nPageIndex; 240 } 241 242 if (HasFocus() && !IsFocusShowing()) 243 ShowFocus(); 244 } 245 */ 246 247 248 249 void FocusManager::SetFocusedPage (const model::SharedPageDescriptor& rpDescriptor) 250 { 251 if (rpDescriptor.get() != NULL) 252 { 253 FocusHider aFocusHider (*this); 254 mnPageIndex = (rpDescriptor->GetPage()->GetPageNum()-1)/2; 255 } 256 } 257 258 259 260 261 void FocusManager::SetFocusedPage (sal_Int32 nPageIndex) 262 { 263 FocusHider aFocusHider (*this); 264 mnPageIndex = nPageIndex; 265 } 266 267 268 269 270 void FocusManager::SetFocusedPageToCurrentPage (void) 271 { 272 SetFocusedPage(mrSlideSorter.GetController().GetCurrentSlideManager()->GetCurrentSlide()); 273 } 274 275 276 277 278 bool FocusManager::IsFocusShowing (void) const 279 { 280 return HasFocus() && mbPageIsFocused; 281 } 282 283 284 285 286 void FocusManager::HideFocusIndicator (const model::SharedPageDescriptor& rpDescriptor) 287 { 288 if (rpDescriptor.get() != NULL) 289 { 290 mrSlideSorter.GetView().SetState(rpDescriptor, model::PageDescriptor::ST_Focused, false); 291 } 292 } 293 294 295 296 297 void FocusManager::ShowFocusIndicator ( 298 const model::SharedPageDescriptor& rpDescriptor, 299 const bool bScrollToFocus) 300 { 301 if (rpDescriptor.get() != NULL) 302 { 303 mrSlideSorter.GetView().SetState(rpDescriptor, model::PageDescriptor::ST_Focused, true); 304 305 if (bScrollToFocus) 306 { 307 // Scroll the focused page object into the visible area and repaint 308 // it, so that the focus indicator becomes visible. 309 mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor,true); 310 } 311 mrSlideSorter.GetView().RequestRepaint(rpDescriptor); 312 313 NotifyFocusChangeListeners(); 314 } 315 } 316 317 318 319 320 void FocusManager::AddFocusChangeListener (const Link& rListener) 321 { 322 if (::std::find (maFocusChangeListeners.begin(), maFocusChangeListeners.end(), rListener) 323 == maFocusChangeListeners.end()) 324 { 325 maFocusChangeListeners.push_back (rListener); 326 } 327 } 328 329 330 331 332 void FocusManager::RemoveFocusChangeListener (const Link& rListener) 333 { 334 maFocusChangeListeners.erase ( 335 ::std::find (maFocusChangeListeners.begin(), maFocusChangeListeners.end(), rListener)); 336 } 337 338 339 340 341 void FocusManager::SetFocusToToolBox (void) 342 { 343 HideFocus(); 344 345 if (mrSlideSorter.GetViewShell() != NULL) 346 { 347 ::Window* pParentWindow = mrSlideSorter.GetViewShell()->GetParentWindow(); 348 DockingWindow* pDockingWindow = NULL; 349 while (pParentWindow!=NULL && pDockingWindow==NULL) 350 { 351 pDockingWindow = dynamic_cast<DockingWindow*>(pParentWindow); 352 pParentWindow = pParentWindow->GetParent(); 353 } 354 if (pDockingWindow) 355 { 356 PaneDockingWindow* pPaneDockingWindow = dynamic_cast<PaneDockingWindow*>(pDockingWindow); 357 if (pPaneDockingWindow != NULL) 358 pPaneDockingWindow->GetToolBox().GrabFocus(); 359 } 360 } 361 } 362 363 364 365 366 void FocusManager::NotifyFocusChangeListeners (void) const 367 { 368 // Create a copy of the listener list to be safe when that is modified. 369 ::std::vector<Link> aListeners (maFocusChangeListeners); 370 371 // Tell the slection change listeners that the selection has changed. 372 ::std::vector<Link>::iterator iListener (aListeners.begin()); 373 ::std::vector<Link>::iterator iEnd (aListeners.end()); 374 for (; iListener!=iEnd; ++iListener) 375 { 376 iListener->Call(NULL); 377 } 378 } 379 380 381 382 383 FocusManager::FocusHider::FocusHider (FocusManager& rManager) 384 : mbFocusVisible(rManager.IsFocusShowing()) 385 , mrManager(rManager) 386 { 387 mrManager.HideFocus(); 388 } 389 390 391 392 393 FocusManager::FocusHider::~FocusHider (void) 394 { 395 if (mbFocusVisible) 396 mrManager.ShowFocus(); 397 } 398 399 } } } // end of namespace ::sd::slidesorter::controller 400 401