summaryrefslogtreecommitdiff
path: root/sd/source/ui/toolpanel
diff options
context:
space:
mode:
Diffstat (limited to 'sd/source/ui/toolpanel')
-rw-r--r--sd/source/ui/toolpanel/ConstrainedIterator.cxx267
-rw-r--r--sd/source/ui/toolpanel/ConstrainedIterator.hxx104
-rw-r--r--sd/source/ui/toolpanel/ControlContainer.cxx500
-rw-r--r--sd/source/ui/toolpanel/ControlContainerDescriptor.hxx139
-rw-r--r--sd/source/ui/toolpanel/ControlList.hxx59
-rwxr-xr-xsd/source/ui/toolpanel/LayoutMenu.cxx1012
-rwxr-xr-xsd/source/ui/toolpanel/LayoutMenu.hxx239
-rw-r--r--sd/source/ui/toolpanel/MethodGuard.hxx67
-rwxr-xr-xsd/source/ui/toolpanel/ScrollPanel.cxx834
-rwxr-xr-xsd/source/ui/toolpanel/SlideSorterCacheDisplay.cxx372
-rwxr-xr-xsd/source/ui/toolpanel/SubToolPanel.cxx419
-rwxr-xr-xsd/source/ui/toolpanel/TaskPaneControlFactory.cxx57
-rw-r--r--sd/source/ui/toolpanel/TaskPaneFocusManager.cxx325
-rw-r--r--sd/source/ui/toolpanel/TaskPaneFocusManager.hxx135
-rwxr-xr-xsd/source/ui/toolpanel/TaskPaneShellManager.cxx183
-rwxr-xr-xsd/source/ui/toolpanel/TaskPaneShellManager.hxx121
-rwxr-xr-xsd/source/ui/toolpanel/TaskPaneTreeNode.cxx292
-rwxr-xr-xsd/source/ui/toolpanel/TestMenu.cxx318
-rwxr-xr-xsd/source/ui/toolpanel/TestMenu.hxx84
-rwxr-xr-xsd/source/ui/toolpanel/TestPanel.cxx174
-rwxr-xr-xsd/source/ui/toolpanel/TestPanel.hxx57
-rwxr-xr-xsd/source/ui/toolpanel/TitleBar.cxx585
-rwxr-xr-xsd/source/ui/toolpanel/TitledControl.cxx432
-rwxr-xr-xsd/source/ui/toolpanel/ToolPanel.cxx113
-rw-r--r--sd/source/ui/toolpanel/ToolPanel.hxx80
-rw-r--r--sd/source/ui/toolpanel/ToolPanelDescriptor.hxx89
-rw-r--r--sd/source/ui/toolpanel/ToolPanelFactory.cxx255
-rw-r--r--sd/source/ui/toolpanel/ToolPanelUIElement.cxx134
-rw-r--r--sd/source/ui/toolpanel/ToolPanelUIElement.hxx87
-rwxr-xr-xsd/source/ui/toolpanel/ToolPanelViewShell.cxx900
-rw-r--r--sd/source/ui/toolpanel/controls/AllMasterPagesSelector.cxx208
-rw-r--r--sd/source/ui/toolpanel/controls/AllMasterPagesSelector.hxx94
-rwxr-xr-xsd/source/ui/toolpanel/controls/AnimationSchemesPanel.cxx170
-rwxr-xr-xsd/source/ui/toolpanel/controls/AnimationSchemesPanel.hxx138
-rw-r--r--sd/source/ui/toolpanel/controls/CurrentMasterPagesSelector.cxx343
-rw-r--r--sd/source/ui/toolpanel/controls/CurrentMasterPagesSelector.hxx83
-rwxr-xr-xsd/source/ui/toolpanel/controls/CustomAnimationPanel.cxx113
-rwxr-xr-xsd/source/ui/toolpanel/controls/CustomAnimationPanel.hxx81
-rwxr-xr-xsd/source/ui/toolpanel/controls/DocumentHelper.cxx552
-rw-r--r--sd/source/ui/toolpanel/controls/DocumentHelper.hxx116
-rwxr-xr-xsd/source/ui/toolpanel/controls/MasterPageContainer.cxx1220
-rwxr-xr-xsd/source/ui/toolpanel/controls/MasterPageContainer.hxx220
-rw-r--r--sd/source/ui/toolpanel/controls/MasterPageContainerFiller.cxx199
-rw-r--r--sd/source/ui/toolpanel/controls/MasterPageContainerFiller.hxx95
-rwxr-xr-xsd/source/ui/toolpanel/controls/MasterPageContainerProviders.cxx429
-rwxr-xr-xsd/source/ui/toolpanel/controls/MasterPageContainerProviders.hxx189
-rw-r--r--sd/source/ui/toolpanel/controls/MasterPageContainerQueue.cxx304
-rw-r--r--sd/source/ui/toolpanel/controls/MasterPageContainerQueue.hxx136
-rwxr-xr-xsd/source/ui/toolpanel/controls/MasterPageDescriptor.cxx423
-rwxr-xr-xsd/source/ui/toolpanel/controls/MasterPageDescriptor.hxx240
-rwxr-xr-xsd/source/ui/toolpanel/controls/MasterPageObserver.cxx426
-rwxr-xr-xsd/source/ui/toolpanel/controls/MasterPagesPanel.cxx157
-rwxr-xr-xsd/source/ui/toolpanel/controls/MasterPagesPanel.hxx72
-rwxr-xr-xsd/source/ui/toolpanel/controls/MasterPagesSelector.cxx854
-rwxr-xr-xsd/source/ui/toolpanel/controls/MasterPagesSelector.hxx235
-rw-r--r--sd/source/ui/toolpanel/controls/PreviewValueSet.cxx240
-rw-r--r--sd/source/ui/toolpanel/controls/PreviewValueSet.hxx96
-rw-r--r--sd/source/ui/toolpanel/controls/RecentMasterPagesSelector.cxx159
-rw-r--r--sd/source/ui/toolpanel/controls/RecentMasterPagesSelector.hxx76
-rw-r--r--sd/source/ui/toolpanel/controls/RecentlyUsedMasterPages.cxx501
-rw-r--r--sd/source/ui/toolpanel/controls/RecentlyUsedMasterPages.hxx128
-rwxr-xr-xsd/source/ui/toolpanel/controls/SlideTransitionPanel.cxx116
-rwxr-xr-xsd/source/ui/toolpanel/controls/SlideTransitionPanel.hxx81
-rwxr-xr-xsd/source/ui/toolpanel/controls/TableDesignPanel.cxx110
-rwxr-xr-xsd/source/ui/toolpanel/controls/TableDesignPanel.hxx81
-rwxr-xr-xsd/source/ui/toolpanel/controls/makefile.mk67
-rwxr-xr-xsd/source/ui/toolpanel/makefile.mk70
67 files changed, 17255 insertions, 0 deletions
diff --git a/sd/source/ui/toolpanel/ConstrainedIterator.cxx b/sd/source/ui/toolpanel/ConstrainedIterator.cxx
new file mode 100644
index 000000000000..261017ee3e1d
--- /dev/null
+++ b/sd/source/ui/toolpanel/ConstrainedIterator.cxx
@@ -0,0 +1,267 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+// This is a definition file of a template class. It is therefore
+// included by other files and thus has to be guarded against multiple
+// inclusion.
+
+#ifndef SD_TOOLPANEL_CONSTRAINED_ITERATOR_CXX
+#define SD_TOOLPANEL_CONSTRAINED_ITERATOR_CXX
+
+namespace sd { namespace toolpanel {
+
+
+template <class Container>
+ConstrainedIterator<Container>::value_type&
+ ConstrainedIterator<Container>::operator* (void)
+{
+ return *maIterator;
+}
+
+
+
+
+template <class Container>
+const ConstrainedIterator<Container>::value_type&
+ ConstrainedIterator<Container>::operator* (void)
+ const
+{
+ return *maIterator;
+}
+
+
+
+
+template <class Container>
+ConstrainedIterator<Container>::value_type&
+ ConstrainedIterator<Container>::operator-> (void)
+{
+ return *maIterator;
+}
+
+
+
+
+template <class Container>
+const ConstrainedIterator<Container>::value_type&
+ ConstrainedIterator<Container>::operator-> (void)
+ const
+{
+ return *maIterator;
+}
+
+
+
+
+
+template <class Container>
+ConstrainedIterator<Container>
+ ::ConstrainedIterator (void)
+ : mpContainer (NULL)
+{
+}
+
+
+
+
+template <class Container>
+ConstrainedIterator<Container>::ConstrainedIterator (
+ const Container& rContainer,
+ const Container::iterator& rIterator)
+ : mpContainer(&rContainer),
+ maIterator (rIterator),
+ mpConstraint (NULL)
+{
+ AdvanceToNextValidElement();
+}
+
+
+
+
+template <class Container>
+ConstrainedIterator<Container>::ConstrainedIterator (
+ const Container& rContainer,
+ const Container::iterator& rIterator,
+ const Constraint<Container>& rConstraint)
+ : mpContainer(&rContainer),
+ maIterator (rIterator),
+ mpConstraint (&rConstraint)
+{
+ AdvanceToNextValidElement();
+}
+
+
+
+
+template <class Container>
+ConstrainedIterator<Container>::ConstrainedIterator (
+ const ConstrainedIterator& rIterator)
+ : mpContainer (rIterator.mpContainer),
+ maIterator (rIterator.maIterator),
+ mpConstraint (rIterator.mpConstraint)
+{
+ // Everything has been done in the initializer
+}
+
+
+
+
+template <class Container>
+ConstrainedIterator<Container>&
+ ConstrainedIterator<Container>
+ ::operator= (const ConstrainedIterator& rIterator)
+{
+ mpContainer = rIterator.mpContainer;
+ maIterator = rIterator.maIterator;
+ mpConstraint = rIterator.mpConstraint;
+
+ AdvanceToNextValidElement();
+
+ return *this;
+}
+
+
+
+
+template <class Container>
+bool ConstrainedIterator<Container>::operator== (
+ const ConstrainedIterator& aIterator) const
+{
+ return ! operator!=(aIterator);
+}
+
+
+
+
+template <class Container>
+bool ConstrainedIterator<Container>::operator!= (
+ const ConstrainedIterator& aIterator) const
+{
+ return maIterator != aIterator.maIterator;
+}
+
+
+
+
+template <class Container>
+ConstrainedIterator<Container>&
+ ConstrainedIterator<Container>::operator++ (void)
+{
+ maIterator++;
+ AdvanceToNextValidElement();
+ return *this;
+}
+
+
+
+
+template <class Container>
+ConstrainedIterator<Container>
+ ConstrainedIterator<Container>::operator++ (int)
+{
+ ConstrainedIterator aIterator (*this);
+ ++(*this);
+ return aIterator;
+}
+
+
+
+
+template <class Container>
+ConstrainedIterator<Container>&
+ ConstrainedIterator<Container>::operator-- (void)
+{
+ maIterator--;
+ AdvanceToPreviousValidElement();
+ return *this;
+}
+
+
+
+
+template <class Container>
+ConstrainedIterator<Container>
+ ConstrainedIterator<Container>::operator-- (int)
+{
+ ConstrainedIterator aIterator (*this);
+ --(*this);
+ return aIterator;
+}
+
+
+
+
+template <class Container>
+ConstrainedIterator<Container>
+ ConstrainedIterator<Container>::operator+ (int nValue) const
+{
+ return ConstrainedIterator (*mpContainer, maIterator+nValue);
+}
+
+
+
+template <class Container>
+ConstrainedIterator<Container>
+ ConstrainedIterator<Container>::operator- (int nValue) const
+{
+ return ConstrainedIterator (*mpContainer, maIterator-nValue);
+}
+
+
+
+template <class Container>
+void ConstrainedIterator<Container>::AdvanceToNextValidElement (void)
+{
+ if (mpContainer!=NULL && mpConstraint!=NULL)
+ {
+ while (maIterator != mpContainer->end()
+ && ! mpConstraint->operator()(*mpContainer, maIterator))
+ ++maIterator;
+ }
+}
+
+
+
+
+template <class Container>
+void ConstrainedIterator<Container>::AdvanceToPreviousValidElement (void)
+{
+ if (mpContainer!=NULL && mpConstraint!=NULL)
+ {
+ while (maIterator != mpContainer->begin()
+ && ! mpConstraint->operator()(*mpContainer, maIterator))
+ --maIterator;
+ }
+}
+
+
+} } // end of namespace ::sd::toolpanel
+
+#endif
diff --git a/sd/source/ui/toolpanel/ConstrainedIterator.hxx b/sd/source/ui/toolpanel/ConstrainedIterator.hxx
new file mode 100644
index 000000000000..8f81ba89ebe7
--- /dev/null
+++ b/sd/source/ui/toolpanel/ConstrainedIterator.hxx
@@ -0,0 +1,104 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANEL_CONSTRAINED_ITERATOR_HXX
+#define SD_TOOLPANEL_CONSTRAINED_ITERATOR_HXX
+
+#include <iterator>
+
+namespace sd { namespace toolpanel {
+
+
+template <class Container>
+class Constraint
+{
+public:
+ virtual bool operator() (
+ const Container& rContainer,
+ const Container::iterator& rIterator) const = 0;
+};
+
+
+
+
+/** This iterator is a bidirectional iterator with something of random
+ access thrown in. It uses a constraint object to jump over
+ elements in the underlying container that do not meet the
+ constraint.
+*/
+template <class Container>
+class ConstrainedIterator
+ : public ::std::bidirectional_iterator_tag
+{
+public:
+ typedef Container::value_type value_type;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+
+ ConstrainedIterator (void);
+ ConstrainedIterator (
+ const Container& rContainer,
+ const Container::iterator& rIterator);
+ ConstrainedIterator (
+ const Container& rContainer,
+ const Container::iterator& rIterator,
+ const Constraint<Container>& pConstraint);
+ ConstrainedIterator (
+ const ConstrainedIterator& rIterator);
+
+ ConstrainedIterator& operator= (
+ const ConstrainedIterator& aIterator);
+
+ reference operator* (void);
+ const_reference operator* (void) const;
+ reference operator-> (void);
+ const_reference operator-> (void) const;
+
+ bool operator== (const ConstrainedIterator& aIterator) const;
+ bool operator!= (const ConstrainedIterator& aIterator) const;
+
+ ConstrainedIterator& operator++ (void);
+ ConstrainedIterator operator++ (int);
+ ConstrainedIterator& operator-- (void);
+ ConstrainedIterator operator-- (int);
+
+ ConstrainedIterator operator+ (int nValue) const;
+ ConstrainedIterator operator- (int nValue) const;
+
+
+private:
+ const Container* mpContainer;
+ Container::iterator maIterator;
+ const Constraint<Container>* mpConstraint;
+
+ void AdvanceToNextValidElement (void);
+ void AdvanceToPreviousValidElement (void);
+};
+
+} } // end of namespace ::sd::toolpanel
+
+#endif
diff --git a/sd/source/ui/toolpanel/ControlContainer.cxx b/sd/source/ui/toolpanel/ControlContainer.cxx
new file mode 100644
index 000000000000..cb8b6c41f5c3
--- /dev/null
+++ b/sd/source/ui/toolpanel/ControlContainer.cxx
@@ -0,0 +1,500 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "taskpane/ControlContainer.hxx"
+
+#include "taskpane/TaskPaneTreeNode.hxx"
+
+#include <vcl/window.hxx>
+#include <vcl/svapp.hxx>
+
+namespace sd { namespace toolpanel {
+
+
+ControlContainer::ControlContainer (TreeNode* pNode)
+ : mpNode(pNode),
+ mnActiveControlIndex((sal_uInt32)-1),
+ mbMultiSelection(false)
+{
+}
+
+
+
+
+ControlContainer::~ControlContainer (void)
+{
+ // Set mpNode to NULL so that no one calls it from now on.
+ mpNode = NULL;
+ DeleteChildren();
+}
+
+
+
+
+void ControlContainer::DeleteChildren (void)
+{
+ // Deleting the children may lead to calls back to the container. To
+ // prevent the container from accessing the just deleted children, the
+ // maControlList member is first cleared (by transferring its content to
+ // a local list) before the children are destroyed.
+ ControlList maList;
+ maList.swap(maControlList);
+ ControlList::iterator I;
+ ControlList::iterator Iend (maList.end());
+ for (I=maList.begin(); I!=Iend; ++I)
+ delete *I;
+
+ if (mpNode != NULL)
+ mpNode->FireStateChangeEvent(EID_ALL_CHILDREN_REMOVED);
+}
+
+
+
+sal_uInt32 ControlContainer::AddControl (::std::auto_ptr<TreeNode> pControl)
+{
+ ::osl::MutexGuard aGuard (maMutex);
+
+ pControl->GetWindow()->Show();
+ sal_uInt32 nIndex = maControlList.size();
+ maControlList.push_back (pControl.get());
+ pControl.release();
+
+ ListHasChanged ();
+
+ if (mpNode != NULL)
+ mpNode->FireStateChangeEvent(EID_CHILD_ADDED, pControl.get());
+
+ return nIndex;
+}
+
+
+
+
+void ControlContainer::SetExpansionState (
+ UINT32 nIndex,
+ ExpansionState aState)
+{
+ ::osl::MutexGuard aGuard (maMutex);
+
+ bool bResizeNecessary (false);
+
+ if (mbMultiSelection)
+ {
+ TreeNode* pControl = GetControl(nIndex);
+ switch (aState)
+ {
+ case ES_TOGGLE:
+ bResizeNecessary = pControl->Expand( ! pControl->IsExpanded());
+ break;
+
+ case ES_EXPAND:
+ bResizeNecessary = pControl->Expand(true);
+ break;
+
+ case ES_COLLAPSE:
+ bResizeNecessary = pControl->Expand(false);
+ break;
+ }
+ }
+ else
+ {
+ // When bExpansionState is true then the control to expand is the
+ // one with the given index. If bExpansionState is false and the
+ // given index points to the active control then then following
+ // control (in cyclic order) it is expanded. When there is only one
+ // control then that is always expanded.
+ do
+ {
+ // Ignore a call with an invalid index. (The seperate comparison
+ // with -1 is not strictly necessary but it is here just in
+ // case.)
+ if (nIndex>=GetControlCount() || nIndex==(sal_uInt32)-1)
+ break;
+
+ bool bExpand;
+ switch (aState)
+ {
+ default:
+ case ES_TOGGLE:
+ bExpand = ! GetControl(nIndex)->IsExpanded();
+ break;
+
+ case ES_EXPAND:
+ bExpand = true;
+ break;
+
+ case ES_COLLAPSE:
+ bExpand = false;
+ break;
+ }
+ if (bExpand)
+ {
+ // Make the specified control the active one and expand it.
+ mnActiveControlIndex = nIndex;
+ }
+ else
+ {
+ if (nIndex == mnActiveControlIndex)
+ {
+ // We have to determine a new active control since the
+ // current one is about to be collapsed. Choose the
+ // previous one for the last and the next one for all
+ // other.
+ if (mnActiveControlIndex+1 == GetControlCount())
+ mnActiveControlIndex
+ = GetPreviousIndex(mnActiveControlIndex);
+ else
+ mnActiveControlIndex
+ = GetNextIndex (mnActiveControlIndex);
+ }
+ }
+
+ // Update the expansion state of all controls.
+ for (UINT32 i=0; i<GetControlCount(); i=GetNextIndex(i))
+ {
+ TreeNode* pControl = GetControl(i);
+ bResizeNecessary |= pControl->Expand(i == mnActiveControlIndex);
+ }
+ }
+ while (false);
+ }
+
+ if (bResizeNecessary && mpNode != NULL)
+ mpNode->RequestResize();
+}
+
+
+
+
+void ControlContainer::SetExpansionState (
+ TreeNode* pControl,
+ ExpansionState aState)
+{
+ SetExpansionState (GetControlIndex(pControl), aState);
+}
+
+
+
+
+sal_uInt32 ControlContainer::GetControlIndex (TreeNode* pControlToExpand) const
+{
+ sal_uInt32 nIndex;
+ for (nIndex=0; nIndex<GetControlCount(); nIndex++)
+ {
+ TreeNode* pControl = GetControl(nIndex);
+ if (pControl == pControlToExpand)
+ break;
+ }
+ return nIndex;
+}
+
+
+
+
+sal_uInt32 ControlContainer::GetActiveControlIndex (void) const
+{
+ return mnActiveControlIndex;
+}
+
+
+
+
+void ControlContainer::ListHasChanged (void)
+{
+}
+
+
+
+
+sal_uInt32 ControlContainer::GetControlCount (void) const
+{
+ return maControlList.size();
+}
+
+
+
+
+sal_uInt32 ControlContainer::GetVisibleControlCount (void) const
+{
+ sal_uInt32 nCount (0);
+
+ UINT32 nIndex;
+ sal_uInt32 nAllCount (maControlList.size());
+ for (nIndex=0; nIndex<nAllCount; nIndex=GetNextIndex(nIndex,true))
+ {
+ if (maControlList[nIndex]->GetWindow()->IsVisible())
+ nCount += 1;
+ }
+
+ return nCount;
+}
+
+
+
+
+TreeNode* ControlContainer::GetControl (sal_uInt32 nIndex) const
+{
+ if (nIndex<maControlList.size() && nIndex!=(sal_uInt32)-1)
+ return maControlList[nIndex];
+ else
+ return NULL;
+}
+
+
+
+
+sal_uInt32 ControlContainer::GetPreviousIndex (
+ sal_uInt32 nIndex,
+ bool bIncludeHidden,
+ bool bCycle) const
+{
+ sal_uInt32 nCandidate (nIndex);
+
+ while (true)
+ {
+ if (nCandidate==0)
+ if ( ! bCycle)
+ {
+ // We have reached the head of the list of controls and must
+ // not cycle to its end.
+ nCandidate = maControlList.size();
+ break;
+ }
+ else
+ {
+ // Cycle to the end of the list.
+ nCandidate = maControlList.size() - 1;
+ }
+ else
+ // Go to the regular predecessor.
+ nCandidate -= 1;
+
+ if (nCandidate == nIndex)
+ {
+ // Made one full loop and found no valid control.
+ nCandidate = maControlList.size();
+ break;
+ }
+ else if (bIncludeHidden)
+ {
+ // Return the candidate index regardless of whether the control
+ // is hidden or not.
+ break;
+ }
+ else if (maControlList[nCandidate]->GetWindow()->IsVisible())
+ {
+ // Found a visible control.
+ break;
+ }
+
+ // The candidate does not meet our constraints so do one more loop.
+ }
+
+ return nCandidate;
+}
+
+
+
+sal_uInt32 ControlContainer::GetNextIndex (
+ sal_uInt32 nIndex,
+ bool bIncludeHidden,
+ bool bCycle) const
+{
+ sal_uInt32 nCandidate (nIndex);
+
+ while (true)
+ {
+ // Go to the regular successor.
+ nCandidate += 1;
+ if (nCandidate==maControlList.size())
+ {
+ if ( ! bCycle)
+ {
+ // We have reached the end of the list of controls and must
+ // not cycle to its head.
+ break;
+ }
+ else
+ {
+ // Cycle to the head of the list.
+ nCandidate = 0;
+ }
+ }
+
+ if (nCandidate == nIndex)
+ {
+ // Made one full loop and found no valid control.
+ nCandidate = maControlList.size();
+ break;
+ }
+ else if (bIncludeHidden)
+ {
+ // Return the candidate index regardless of whether the control
+ // is hidden or not.
+ break;
+ }
+ else if (maControlList[nCandidate]->GetWindow()->IsVisible())
+ {
+ // Found a visible control.
+ break;
+ }
+
+ // The candidate does not meet our constraints so do one more loop.
+ }
+
+ return nCandidate;
+}
+
+
+
+
+sal_uInt32 ControlContainer::GetFirstIndex (bool bIncludeHidden)
+{
+ sal_uInt32 nIndex = 0;
+
+ if (maControlList.size() == 0)
+ {
+ // The list is empty so there is no first element.
+ nIndex = maControlList.size();
+ }
+ else if ( ! bIncludeHidden
+ && ! maControlList[nIndex]->GetWindow()->IsVisible())
+ {
+ // The first element is not visible. Go the next visible one.
+ nIndex = GetNextIndex (nIndex, bIncludeHidden, false);
+ }
+
+ return nIndex;
+}
+
+
+
+
+sal_uInt32 ControlContainer::GetLastIndex (bool bIncludeHidden)
+{
+ sal_uInt32 nIndex;
+
+ if (maControlList.size() == 0)
+ {
+ // The list is empty so there is no last element.
+ nIndex = maControlList.size();
+ }
+ else
+ {
+ nIndex = maControlList.size() - 1;
+ if ( ! bIncludeHidden
+ && ! maControlList[nIndex]->GetWindow()->IsVisible())
+ {
+ // The last element is not visible. Go the previous visible one.
+ nIndex = GetPreviousIndex (nIndex, bIncludeHidden, false);
+ }
+ }
+ return nIndex;
+}
+
+
+
+
+void ControlContainer::SetMultiSelection (bool bFlag)
+{
+ mbMultiSelection = bFlag;
+}
+
+
+
+
+void ControlContainer::SetVisibilityState (
+ sal_uInt32 nControlIndex,
+ VisibilityState aState)
+{
+ TreeNode* pControl = GetControl (nControlIndex);
+ if (pControl != NULL)
+ {
+ bool bShow;
+ switch (aState)
+ {
+ default:
+ case VS_TOGGLE:
+ bShow = ! pControl->IsShowing();
+ break;
+ case VS_SHOW:
+ bShow = true;
+ break;
+ case VS_HIDE:
+ bShow = false;
+ break;
+ }
+
+ bool bControlWasExpanded = pControl->IsExpanded();
+ if (bShow != pControl->IsShowing())
+ {
+ pControl->Show (bShow);
+
+ if (bShow)
+ {
+ // If we just turned on the first control then expand it, too.
+ // If we turned on another control collapse it.
+ if (GetVisibleControlCount() == 1)
+ SetExpansionState (nControlIndex, ES_EXPAND);
+ else
+ SetExpansionState (nControlIndex, ES_COLLAPSE);
+ }
+ else
+ {
+ if (GetVisibleControlCount() > 0)
+ {
+ if (bControlWasExpanded)
+ {
+ // We turned off an expanded control. Make sure that
+ // one of the still visible ones is expanded.
+ sal_uInt32 nIndex = GetNextIndex(
+ nControlIndex,
+ false,
+ false);
+ if (nIndex == GetControlCount())
+ nIndex = GetPreviousIndex(
+ nControlIndex,
+ false,
+ false);
+ SetExpansionState (nIndex, ES_EXPAND);
+ }
+ }
+ }
+
+ if (mpNode != NULL)
+ mpNode->RequestResize();
+ }
+ }
+}
+
+
+
+
+} } // end of namespace ::sd::toolpanel
diff --git a/sd/source/ui/toolpanel/ControlContainerDescriptor.hxx b/sd/source/ui/toolpanel/ControlContainerDescriptor.hxx
new file mode 100644
index 000000000000..3557200880d2
--- /dev/null
+++ b/sd/source/ui/toolpanel/ControlContainerDescriptor.hxx
@@ -0,0 +1,139 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TASKPANE_CONTROL_CONTAINER_DESCRIPTOR_HXX
+#define SD_TASKPANE_CONTROL_CONTAINER_DESCRIPTOR_HXX
+
+#include "taskpane/ILayoutableWindow.hxx"
+#include "taskpane/TitleBar.hxx"
+#include <tools/string.hxx>
+#include <tools/gen.hxx>
+#ifndef SD_WINDOW_HXX
+#include <vcl/window.hxx>
+#endif
+#include <memory>
+
+class Window;
+
+namespace sd { namespace toolpanel {
+
+class ControlContainer;
+
+/** Collection of information the describes entries of the tool
+ panel. A descriptor owns the control it is associated with.
+*/
+class ControlContainerDescriptor
+ : public ::Window,
+ public virtual ILayoutableWindow
+{
+public:
+ /** Create a new descriptor for the given control.
+ @param rContainer
+ The container to inform about selection (caused by mouse
+ clicks or keyboard.)
+ @param pParent
+ The parent window of the new descriptor.
+ @param pControl
+ The control that is shown when being in the expanded
+ state.
+ @param rTitle
+ String that is shown as title in the title area above the
+ control.
+ @param eType
+ Type of the title bar. This specifies how the title bar
+ will be formated. For more information see TitleBar.
+
+ */
+ ControlContainerDescriptor (
+ ControlContainer& rContainer,
+ ::Window* pParent,
+ ::std::auto_ptr<ILayoutableWindow> pControl,
+ const String& rTitle,
+ TitleBar::TitleBarType eType);
+
+ virtual ~ControlContainerDescriptor (void);
+
+
+ virtual Size GetPreferredSize (void);
+ virtual int GetPreferredWidth (int nHeight);
+ virtual int GetPreferredHeight (int nWidth);
+ virtual bool IsResizable (void);
+ virtual ::Window* GetWindow (void);
+
+ virtual void Resize (void);
+ virtual void GetFocus (void);
+ virtual void LoseFocus (void);
+ virtual void MouseButtonUp (const MouseEvent& rMouseEvent);
+ virtual void KeyInput (const KeyEvent& rEvent);
+
+ void Select (bool bExpansionState);
+
+ // const Rectangle& GetTitleBarBox (void) const;
+
+ Window* GetControl (void) const;
+ const String& GetTitle (void) const;
+
+ void Expand (bool bExpanded = true);
+ void Collapse (void);
+ bool IsExpanded (void) const;
+
+ /** Ownership of the given data remains with the caller. The data
+ is thus not destroyed when the destructor of this class is
+ called.
+ */
+ void SetUserData (void* pUserData);
+ void* GetUserData (void) const;
+
+ bool IsVisible (void) const;
+ void SetVisible (bool bVisible);
+
+ using Window::GetWindow;
+ using sd::toolpanel::ILayoutableWindow::GetPreferredWidth;
+ using sd::toolpanel::ILayoutableWindow::GetPreferredHeight;
+
+private:
+ ControlContainer& mrContainer;
+ ::std::auto_ptr<TitleBar> mpTitleBar;
+ ::std::auto_ptr<ILayoutableWindow> mpControl;
+ String msTitle;
+ bool mbExpanded;
+ bool mbVisible;
+ void* mpUserData;
+ bool mnVisible;
+
+ /// Do not use! Assignment operator is not supported.
+ const ControlContainerDescriptor& operator= (
+ const ControlContainerDescriptor& aDescriptor);
+
+ void UpdateStates (void);
+
+ DECL_LINK(WindowEventListener, VclSimpleEvent*);
+};
+
+} } // end of namespace ::sd::toolpanel
+
+#endif
diff --git a/sd/source/ui/toolpanel/ControlList.hxx b/sd/source/ui/toolpanel/ControlList.hxx
new file mode 100644
index 000000000000..623a9567215f
--- /dev/null
+++ b/sd/source/ui/toolpanel/ControlList.hxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANEL_CONTROL_LIST_HXX
+#define SD_TOOLPANEL_CONTROL_LIST_HXX
+
+#include "ConstrainedIterator.hxx"
+#include "ConstrainedIterator.cxx"
+#include "TitledControl.hxx"
+
+#include <vector>
+
+namespace sd { namespace toolpanel {
+
+
+typedef ::std::vector<TitledControl*> ControlList;
+typedef ConstrainedIterator<ControlList> ControlIterator;
+
+
+class VisibilityConstraint
+ : public Constraint<ControlList>
+{
+public:
+ virtual bool operator() (
+ const ControlList& rContainer,
+ const ControlList::iterator& rIterator) const
+ {
+ return (**rIterator).GetWindow()->IsVisible();
+ }
+};
+
+
+} } // end of namespace ::sd::toolpanel
+
+#endif
diff --git a/sd/source/ui/toolpanel/LayoutMenu.cxx b/sd/source/ui/toolpanel/LayoutMenu.cxx
new file mode 100755
index 000000000000..ec4eb1e43d4d
--- /dev/null
+++ b/sd/source/ui/toolpanel/LayoutMenu.cxx
@@ -0,0 +1,1012 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "LayoutMenu.hxx"
+
+#include "TaskPaneShellManager.hxx"
+#include "pres.hxx"
+#include "drawdoc.hxx"
+#include "DrawDocShell.hxx"
+#include "sdpage.hxx"
+#include "glob.hxx"
+#include "glob.hrc"
+#include "app.hrc"
+#include "helpids.h"
+#include "res_bmp.hrc"
+#include "strings.hrc"
+#include "ViewShellBase.hxx"
+#include "DrawViewShell.hxx"
+#include "SlideSorterViewShell.hxx"
+#include "controller/SlideSorterController.hxx"
+#include "controller/SlsPageSelector.hxx"
+#include "taskpane/TaskPaneControlFactory.hxx"
+#include "taskpane/ToolPanelViewShell.hxx"
+#include "taskpane/ScrollPanel.hxx"
+#include "tools/SlotStateListener.hxx"
+#include "EventMultiplexer.hxx"
+#include "DrawController.hxx"
+#include "framework/FrameworkHelper.hxx"
+
+#include <vector>
+#include <memory>
+#include <sfx2/objface.hxx>
+#include "sdresid.hxx"
+#include <vcl/image.hxx>
+#include <svl/languageoptions.hxx>
+#include <sfx2/app.hxx>
+#include "taskpane/TitledControl.hxx"
+#include <sfx2/dispatch.hxx>
+#include <sfx2/request.hxx>
+#include <comphelper/processfactory.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/drawing/framework/XControllerManager.hpp>
+#include <com/sun/star/drawing/framework/XView.hpp>
+#include <com/sun/star/drawing/framework/ResourceId.hpp>
+
+using namespace ::sd::toolpanel;
+#define LayoutMenu
+#include "sdslots.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+using namespace ::sd::slidesorter;
+using ::sd::framework::FrameworkHelper;
+
+namespace sd { namespace toolpanel {
+
+class LayoutMenuRootFactory
+ : public ControlFactory
+{
+public:
+ LayoutMenuRootFactory (ToolPanelViewShell& i_rPanelViewShell)
+ :mrPanelViewShell(i_rPanelViewShell)
+ {
+ }
+
+protected:
+ virtual TreeNode* InternalCreateControl( ::Window& i_rParent )
+ {
+ ScrollPanel* pScrollPanel = new ScrollPanel (i_rParent);
+ ::std::auto_ptr<TreeNode> pMenu (
+ new LayoutMenu (
+ pScrollPanel,
+ mrPanelViewShell));
+ pScrollPanel->AddControl(pMenu);
+ return pScrollPanel;
+ }
+
+private:
+ ToolPanelViewShell& mrPanelViewShell;
+};
+
+
+SFX_IMPL_INTERFACE(LayoutMenu, SfxShell,
+ SdResId(STR_TASKPANELAYOUTMENU))
+{
+ SFX_POPUPMENU_REGISTRATION(SdResId(RID_TASKPANE_LAYOUTMENU_POPUP));
+}
+
+TYPEINIT1(LayoutMenu, SfxShell);
+
+struct snewfoil_value_info
+{
+ USHORT mnBmpResId;
+ USHORT mnHCBmpResId;
+ USHORT mnStrResId;
+ WritingMode meWritingMode;
+ AutoLayout maAutoLayout;
+};
+
+static snewfoil_value_info notes[] =
+{
+ {BMP_FOILN_01, BMP_FOILN_01_H, STR_AUTOLAYOUT_NOTES, WritingMode_LR_TB,
+ AUTOLAYOUT_NOTES},
+ {0, 0, 0, WritingMode_LR_TB, AUTOLAYOUT_NONE},
+};
+
+static snewfoil_value_info handout[] =
+{
+ {BMP_FOILH_01, BMP_FOILH_01_H, STR_AUTOLAYOUT_HANDOUT1, WritingMode_LR_TB,
+ AUTOLAYOUT_HANDOUT1},
+ {BMP_FOILH_02, BMP_FOILH_02_H, STR_AUTOLAYOUT_HANDOUT2, WritingMode_LR_TB,
+ AUTOLAYOUT_HANDOUT2},
+ {BMP_FOILH_03, BMP_FOILH_03_H, STR_AUTOLAYOUT_HANDOUT3, WritingMode_LR_TB,
+ AUTOLAYOUT_HANDOUT3},
+ {BMP_FOILH_04, BMP_FOILH_04_H, STR_AUTOLAYOUT_HANDOUT4, WritingMode_LR_TB,
+ AUTOLAYOUT_HANDOUT4},
+ {BMP_FOILH_06, BMP_FOILH_06_H, STR_AUTOLAYOUT_HANDOUT6, WritingMode_LR_TB,
+ AUTOLAYOUT_HANDOUT6},
+ {BMP_FOILH_09, BMP_FOILH_09_H, STR_AUTOLAYOUT_HANDOUT9, WritingMode_LR_TB,
+ AUTOLAYOUT_HANDOUT9},
+ {0, 0, 0, WritingMode_LR_TB, AUTOLAYOUT_NONE},
+};
+
+static snewfoil_value_info standard[] =
+{
+ {BMP_LAYOUT_EMPTY, BMP_LAYOUT_EMPTY_H, STR_AUTOLAYOUT_NONE, WritingMode_LR_TB, AUTOLAYOUT_NONE},
+ {BMP_LAYOUT_HEAD03, BMP_LAYOUT_HEAD03_H, STR_AUTOLAYOUT_TITLE, WritingMode_LR_TB, AUTOLAYOUT_TITLE},
+ {BMP_LAYOUT_HEAD02, BMP_LAYOUT_HEAD02_H, STR_AUTOLAYOUT_CONTENT, WritingMode_LR_TB, AUTOLAYOUT_ENUM},
+ {BMP_LAYOUT_HEAD02A, BMP_LAYOUT_HEAD02A_H, STR_AUTOLAYOUT_2CONTENT, WritingMode_LR_TB, AUTOLAYOUT_2TEXT},
+ {BMP_LAYOUT_HEAD01, BMP_LAYOUT_HEAD01_H, STR_AUTOLAYOUT_ONLY_TITLE, WritingMode_LR_TB, AUTOLAYOUT_ONLY_TITLE},
+ {BMP_LAYOUT_TEXTONLY, BMP_LAYOUT_TEXTONLY_H, STR_AUTOLAYOUT_ONLY_TEXT, WritingMode_LR_TB, AUTOLAYOUT_ONLY_TEXT},
+ {BMP_LAYOUT_HEAD03B, BMP_LAYOUT_HEAD03B_H, STR_AUTOLAYOUT_2CONTENT_CONTENT, WritingMode_LR_TB, AUTOLAYOUT_2OBJTEXT},
+ {BMP_LAYOUT_HEAD03C, BMP_LAYOUT_HEAD03C_H, STR_AUTOLAYOUT_CONTENT_2CONTENT, WritingMode_LR_TB, AUTOLAYOUT_TEXT2OBJ},
+ {BMP_LAYOUT_HEAD03A, BMP_LAYOUT_HEAD03A_H, STR_AUTOLAYOUT_2CONTENT_OVER_CONTENT,WritingMode_LR_TB, AUTOLAYOUT_2OBJOVERTEXT},
+ {BMP_LAYOUT_HEAD02B, BMP_LAYOUT_HEAD02B_H, STR_AUTOLAYOUT_CONTENT_OVER_CONTENT, WritingMode_LR_TB, AUTOLAYOUT_OBJOVERTEXT},
+ {BMP_LAYOUT_HEAD04, BMP_LAYOUT_HEAD04_H, STR_AUTOLAYOUT_4CONTENT, WritingMode_LR_TB, AUTOLAYOUT_4OBJ},
+ {BMP_LAYOUT_HEAD06, BMP_LAYOUT_HEAD06_H, STR_AUTOLAYOUT_6CONTENT, WritingMode_LR_TB, AUTOLAYOUT_6CLIPART},
+
+ // vertical
+ {BMP_LAYOUT_VERTICAL02, BMP_LAYOUT_VERTICAL02_H, STR_AL_VERT_TITLE_TEXT_CHART, WritingMode_TB_RL,AUTOLAYOUT_VERTICAL_TITLE_TEXT_CHART},
+ {BMP_LAYOUT_VERTICAL01, BMP_LAYOUT_VERTICAL01_H, STR_AL_VERT_TITLE_VERT_OUTLINE, WritingMode_TB_RL, AUTOLAYOUT_VERTICAL_TITLE_VERTICAL_OUTLINE},
+ {BMP_LAYOUT_HEAD02, BMP_LAYOUT_HEAD02_H, STR_AL_TITLE_VERT_OUTLINE, WritingMode_TB_RL, AUTOLAYOUT_TITLE_VERTICAL_OUTLINE},
+ {BMP_LAYOUT_HEAD02A, BMP_LAYOUT_HEAD02A_H, STR_AL_TITLE_VERT_OUTLINE_CLIPART, WritingMode_TB_RL, AUTOLAYOUT_TITLE_VERTICAL_OUTLINE_CLIPART},
+ {0, 0, 0, WritingMode_LR_TB, AUTOLAYOUT_NONE}
+};
+
+LayoutMenu::LayoutMenu( TreeNode* pParent, ToolPanelViewShell& i_rPanelViewShell )
+ : ValueSet (pParent->GetWindow()),
+ TreeNode(pParent),
+ DragSourceHelper(this),
+ DropTargetHelper(this),
+ mrBase( i_rPanelViewShell.GetViewShellBase() ),
+ mpShellManager (&i_rPanelViewShell.GetSubShellManager()),
+ mbUseOwnScrollBar( false ),
+ mnPreferredColumnCount(3),
+ mxListener(NULL),
+ mbSelectionUpdatePending(true),
+ mbIsMainViewChangePending(false)
+{
+ implConstruct( *mrBase.GetDocument()->GetDocSh() );
+}
+
+
+void LayoutMenu::implConstruct( DrawDocShell& rDocumentShell )
+{
+ OSL_ENSURE( mrBase.GetDocument()->GetDocSh() == &rDocumentShell,
+ "LayoutMenu::implConstruct: hmm?" );
+ // if this fires, then my assumption that the rDocumentShell parameter to our first ctor is superfluous ...
+
+ SetStyle (
+ ( GetStyle() & ~(WB_ITEMBORDER) )
+ | WB_TABSTOP
+ | WB_NO_DIRECTSELECT
+ );
+ if (mbUseOwnScrollBar)
+ SetStyle (GetStyle() | WB_VSCROLL);
+ SetExtraSpacing(2);
+ SetSelectHdl (LINK(this, LayoutMenu, ClickHandler));
+ SetPool (&rDocumentShell.GetDoc()->GetPool());
+ SetName(String(RTL_CONSTASCII_USTRINGPARAM("LayoutMenu")));
+ InvalidateContent();
+
+ Link aEventListenerLink (LINK(this,LayoutMenu,EventMultiplexerListener));
+ mrBase.GetEventMultiplexer()->AddEventListener(aEventListenerLink,
+ ::sd::tools::EventMultiplexerEvent::EID_CURRENT_PAGE
+ | ::sd::tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION
+ | ::sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
+ | ::sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
+ | ::sd::tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED
+ | ::sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_NORMAL
+ | ::sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_MASTER);
+
+ SetSmartHelpId(SmartId(HID_SD_TASK_PANE_PREVIEW_LAYOUTS));
+ SetAccessibleName(SdResId(STR_TASKPANEL_LAYOUT_MENU_TITLE));
+
+ Link aStateChangeLink (LINK(this,LayoutMenu,StateChangeHandler));
+ mxListener = new ::sd::tools::SlotStateListener(
+ aStateChangeLink,
+ Reference<frame::XDispatchProvider>(mrBase.GetController()->getFrame(), UNO_QUERY),
+ ::rtl::OUString::createFromAscii(".uno:VerticalTextState"));
+
+ // Add this new object as shell to the shell factory.
+ GetShellManager()->AddSubShell(HID_SD_TASK_PANE_PREVIEW_LAYOUTS,this,this);
+}
+
+
+
+LayoutMenu::~LayoutMenu (void)
+{
+ // Tell the shell factory that this object is no longer available.
+ if (GetShellManager() != NULL)
+ GetShellManager()->RemoveSubShell(this);
+
+ Reference<lang::XComponent> xComponent (mxListener, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+
+ Clear();
+ Link aLink (LINK(this,LayoutMenu,EventMultiplexerListener));
+ mrBase.GetEventMultiplexer()->RemoveEventListener (aLink);
+}
+
+
+
+
+::std::auto_ptr<ControlFactory> LayoutMenu::CreateControlFactory (
+ ToolPanelViewShell& i_rPanelViewShell )
+{
+ return ::std::auto_ptr<ControlFactory>(new LayoutMenuRootFactory(i_rPanelViewShell));
+}
+
+
+
+
+AutoLayout LayoutMenu::GetSelectedAutoLayout (void)
+{
+ AutoLayout aResult = AUTOLAYOUT_NONE;
+
+ if ( ! IsNoSelection() && GetSelectItemId()!=0)
+ {
+ AutoLayout* pLayout = static_cast<AutoLayout*>(GetItemData(GetSelectItemId()));
+ if (pLayout != NULL)
+ aResult = *pLayout;
+ }
+
+ return aResult;
+}
+
+
+
+
+/** The preferred size depends on the preferred number of columns, the
+ number of items, and the size of the items.
+*/
+Size LayoutMenu::GetPreferredSize (void)
+{
+ Size aItemSize = CalcItemSizePixel (Size());
+ Size aPreferredWindowSize = CalcWindowSizePixel (
+ aItemSize,
+ (USHORT)mnPreferredColumnCount,
+ (USHORT)CalculateRowCount (aItemSize,mnPreferredColumnCount));
+ return aPreferredWindowSize;
+}
+
+
+
+
+sal_Int32 LayoutMenu::GetPreferredWidth (sal_Int32 nHeight)
+{
+ sal_Int32 nPreferredWidth = 100;
+ if (GetItemCount() > 0)
+ {
+ Image aImage = GetItemImage(GetItemId(0));
+ Size aItemSize = CalcItemSizePixel (aImage.GetSizePixel());
+ if (nHeight>0 && aItemSize.Height()>0)
+ {
+ int nRowCount = nHeight / aItemSize.Height();
+ if (nRowCount <= 0)
+ nRowCount = 1;
+ int nColumnCount = (GetItemCount() + nRowCount-1) / nRowCount;
+ nPreferredWidth = nColumnCount * aItemSize.Width();
+ }
+ }
+
+ return nPreferredWidth;
+}
+
+
+
+
+sal_Int32 LayoutMenu::GetPreferredHeight (sal_Int32 nWidth)
+{
+ sal_Int32 nPreferredHeight = 200;
+ if ( ! mbUseOwnScrollBar && GetItemCount()>0)
+ {
+ Image aImage = GetItemImage(GetItemId(0));
+ Size aItemSize = CalcItemSizePixel (aImage.GetSizePixel());
+ if (nWidth>0 && aItemSize.Width()>0)
+ {
+ aItemSize.Width() += 8;
+ aItemSize.Height() += 8;
+ int nColumnCount = nWidth / aItemSize.Width();
+ if (nColumnCount <= 0)
+ nColumnCount = 1;
+ else if (nColumnCount > 4)
+ nColumnCount = 4;
+ int nRowCount = (GetItemCount() + nColumnCount-1) / nColumnCount;
+ nPreferredHeight = nRowCount * aItemSize.Height();
+ }
+ }
+ return nPreferredHeight;
+}
+
+
+
+
+sal_Int32 LayoutMenu::GetMinimumWidth (void)
+{
+ sal_Int32 nMinimumWidth = 0;
+ if (GetItemCount()>0)
+ {
+ Image aImage = GetItemImage(GetItemId(0));
+ Size aItemSize = CalcItemSizePixel (aImage.GetSizePixel());
+ nMinimumWidth = aItemSize.Width();
+ }
+ return nMinimumWidth;
+}
+
+
+
+
+bool LayoutMenu::IsResizable (void)
+{
+ return true;
+}
+
+
+
+
+void LayoutMenu::UpdateEnabledState (const MasterMode eMode)
+{
+ bool bIsEnabled (false);
+
+ ::boost::shared_ptr<ViewShell> pMainViewShell (mrBase.GetMainViewShell());
+ if (pMainViewShell)
+ {
+ switch (pMainViewShell->GetShellType())
+ {
+ case ViewShell::ST_NONE:
+ case ViewShell::ST_OUTLINE:
+ case ViewShell::ST_PRESENTATION:
+ case ViewShell::ST_TASK_PANE:
+ // The complete task pane is disabled for these values or
+ // not even visible. Disabling the LayoutMenu would be
+ // logical but unnecessary. The main disadvantage is that
+ // after re-enabling it (typically) another panel is
+ // expanded.
+ bIsEnabled = true;
+ break;
+
+ case ViewShell::ST_DRAW:
+ case ViewShell::ST_IMPRESS:
+ {
+ switch (eMode)
+ {
+ case MM_UNKNOWN:
+ {
+ ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
+ ::boost::dynamic_pointer_cast<DrawViewShell>(pMainViewShell));
+ if (pDrawViewShell)
+ bIsEnabled = pDrawViewShell->GetEditMode() != EM_MASTERPAGE;
+ break;
+ }
+ case MM_NORMAL:
+ bIsEnabled = true;
+ break;
+
+ case MM_MASTER:
+ bIsEnabled = false;
+ break;
+ }
+ break;
+ }
+
+ case ViewShell::ST_HANDOUT:
+ case ViewShell::ST_NOTES:
+ case ViewShell::ST_SLIDE_SORTER:
+ default:
+ bIsEnabled = true;
+ break;
+ }
+
+ TreeNode* pParentNode = GetParentNode();
+ if (pParentNode != NULL)
+ {
+ TitledControl* pGrandParentNode
+ = dynamic_cast<TitledControl*>(pParentNode->GetParentNode());
+ if (pGrandParentNode != NULL)
+ pGrandParentNode->SetEnabledState(bIsEnabled);
+ }
+
+ }
+}
+
+
+
+
+::Window* LayoutMenu::GetWindow (void)
+{
+ return this;
+}
+
+
+
+
+void LayoutMenu::Paint (const Rectangle& rRect)
+{
+ SetBackground (GetSettings().GetStyleSettings().GetWindowColor());
+
+ if (mbSelectionUpdatePending)
+ {
+ mbSelectionUpdatePending = false;
+ UpdateSelection();
+ }
+ ValueSet::Paint (rRect);
+
+ SetBackground (Wallpaper());
+}
+
+
+
+
+void LayoutMenu::Resize (void)
+{
+ Size aWindowSize = GetOutputSizePixel();
+ if (IsVisible() && aWindowSize.Width() > 0)
+ {
+ // Calculate the number of rows and columns.
+ if (GetItemCount() > 0)
+ {
+ Image aImage = GetItemImage(GetItemId(0));
+ Size aItemSize = CalcItemSizePixel (
+ aImage.GetSizePixel());
+ aItemSize.Width() += 8;
+ aItemSize.Height() += 8;
+ int nColumnCount = aWindowSize.Width() / aItemSize.Width();
+ if (nColumnCount < 1)
+ nColumnCount = 1;
+ else if (nColumnCount > 4)
+ nColumnCount = 4;
+
+ int nRowCount = CalculateRowCount (aItemSize, nColumnCount);
+
+ SetColCount ((USHORT)nColumnCount);
+ SetLineCount ((USHORT)nRowCount);
+ }
+ }
+
+ ValueSet::Resize ();
+}
+
+
+
+
+void LayoutMenu::MouseButtonDown (const MouseEvent& rEvent)
+{
+ // As a preparation for the context menu the item under the mouse is
+ // selected.
+ if (rEvent.IsRight())
+ {
+ ReleaseMouse();
+ USHORT nIndex = GetItemId (rEvent.GetPosPixel());
+ if (nIndex > 0)
+ SelectItem(nIndex);
+ }
+
+ ValueSet::MouseButtonDown (rEvent);
+}
+
+
+
+
+void LayoutMenu::Execute (SfxRequest& rRequest)
+{
+ switch (rRequest.GetSlot())
+ {
+ case SID_TP_APPLY_TO_SELECTED_SLIDES:
+ AssignLayoutToSelectedSlides(GetSelectedAutoLayout());
+ rRequest.Done();
+ break;
+
+ case SID_INSERTPAGE_LAYOUT_MENU:
+ // Add arguments to this slot and forward it to the main view
+ // shell.
+ InsertPageWithLayout(GetSelectedAutoLayout());
+ break;
+ }
+}
+
+
+
+
+void LayoutMenu::GetState (SfxItemSet& rItemSet)
+{
+ // Cut and paste is not supported. The SID_(CUT,COPY,PASTE) entries
+ // therefore must not show up in the context menu.
+ rItemSet.DisableItem (SID_CUT);
+ rItemSet.DisableItem (SID_COPY);
+ rItemSet.DisableItem (SID_PASTE);
+
+ // The SID_INSERTPAGE_LAYOUT_MENU slot depends on the SID_INSERTPAGE
+ // slot being supported elsewhere.
+ const SfxPoolItem* pItem = NULL;
+ const SfxItemState aState (
+ mrBase.GetViewFrame()->GetDispatcher()->QueryState(SID_INSERTPAGE, pItem));
+ if (aState == SFX_ITEM_DISABLED)
+ rItemSet.DisableItem(SID_INSERTPAGE_LAYOUT_MENU);
+}
+
+
+
+
+void LayoutMenu::InsertPageWithLayout (AutoLayout aLayout)
+{
+ ViewShell* pViewShell = mrBase.GetMainViewShell().get();
+ if (pViewShell == NULL)
+ return;
+
+ SfxViewFrame* pViewFrame = mrBase.GetViewFrame();
+ if (pViewFrame == NULL)
+ return;
+
+ SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
+ if (pDispatcher == NULL)
+ return;
+
+ // Call SID_INSERTPAGE with the right arguments. This is because
+ // the popup menu can not call this slot with arguments directly.
+ SfxRequest aRequest (CreateRequest(SID_INSERTPAGE, aLayout));
+ if (aRequest.GetArgs() != NULL)
+ {
+ pDispatcher->Execute(
+ SID_INSERTPAGE,
+ SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
+ *aRequest.GetArgs());
+ }
+ UpdateSelection();
+}
+
+
+
+
+TaskPaneShellManager* LayoutMenu::GetShellManager()
+{
+ if ( mpShellManager )
+ return mpShellManager;
+ return TreeNode::GetShellManager();
+}
+
+void LayoutMenu::InvalidateContent (void)
+{
+ // The number of items may have changed. Request a resize so that the
+ // vertical size of this control can be adapted.
+ RequestResize();
+
+ // Throw away the current set and fill the menu anew according to the
+ // current settings (this includes the support for vertical writing.)
+ Fill();
+}
+
+
+
+
+int LayoutMenu::CalculateRowCount (const Size&, int nColumnCount)
+{
+ int nRowCount = 0;
+
+ if (GetItemCount() > 0 && nColumnCount > 0)
+ {
+ nRowCount = (GetItemCount() + nColumnCount - 1) / nColumnCount;
+ // nRowCount = GetOutputSizePixel().Height() / rItemSize.Height();
+ if (nRowCount < 1)
+ nRowCount = 1;
+ }
+
+ return nRowCount;
+}
+
+
+
+
+IMPL_LINK(LayoutMenu, ClickHandler, ValueSet*, EMPTYARG)
+{
+ AssignLayoutToSelectedSlides (GetSelectedAutoLayout());
+ return 0;
+}
+
+
+
+
+/** The specified layout is assigned to the current page of the view shell
+ in the center pane.
+*/
+void LayoutMenu::AssignLayoutToSelectedSlides (AutoLayout aLayout)
+{
+ using namespace ::sd::slidesorter;
+ using namespace ::sd::slidesorter::controller;
+
+ do
+ {
+ // The view shell in the center pane has to be present.
+ ViewShell* pMainViewShell = mrBase.GetMainViewShell().get();
+ if (pMainViewShell == NULL)
+ break;
+
+ // Determine if the current view is in an invalid master page mode.
+ // The handout view is always in master page mode and therefore not
+ // invalid.
+ bool bMasterPageMode (false);
+ switch (pMainViewShell->GetShellType())
+ {
+ case ViewShell::ST_NOTES:
+ case ViewShell::ST_IMPRESS:
+ {
+ DrawViewShell* pDrawViewShell = static_cast<DrawViewShell*>(pMainViewShell);
+ if (pDrawViewShell != NULL)
+ if (pDrawViewShell->GetEditMode() == EM_MASTERPAGE)
+ bMasterPageMode = true;
+ }
+ default:
+ break;
+ }
+ if (bMasterPageMode)
+ break;
+
+ // Get a list of all selected slides and call the SID_MODIFYPAGE
+ // slot for all of them.
+ ::sd::slidesorter::SharedPageSelection pPageSelection;
+
+ // Get a list of selected pages.
+ // First we try to obtain this list from a slide sorter. This is
+ // possible only some of the view shells in the center pane. When
+ // no valid slide sorter is available then ask the main view shell
+ // for its current page.
+ SlideSorterViewShell* pSlideSorter = NULL;
+ switch (pMainViewShell->GetShellType())
+ {
+ case ViewShell::ST_IMPRESS:
+ case ViewShell::ST_NOTES:
+ case ViewShell::ST_SLIDE_SORTER:
+ pSlideSorter = SlideSorterViewShell::GetSlideSorter(mrBase);
+ break;
+ default:
+ break;
+ }
+ if (pSlideSorter != NULL)
+ {
+ // There is a slide sorter visible so get the list of selected pages from it.
+ pPageSelection = pSlideSorter->GetPageSelection();
+ }
+
+ if( (pSlideSorter == NULL) || (pPageSelection.get() == 0) || pPageSelection->empty() )
+ {
+ // No valid slide sorter available. Ask the main view shell for
+ // its current page.
+ pPageSelection.reset(new ::sd::slidesorter::SlideSorterViewShell::PageSelection());
+ pPageSelection->push_back(pMainViewShell->GetActualPage());
+ }
+
+
+ if (pPageSelection->empty())
+ break;
+
+ ::std::vector<SdPage*>::iterator iPage;
+ for (iPage=pPageSelection->begin(); iPage!=pPageSelection->end(); ++iPage)
+ {
+ if ((*iPage) == NULL)
+ continue;
+
+ // Call the SID_ASSIGN_LAYOUT slot with all the necessary parameters.
+ SfxRequest aRequest (mrBase.GetViewFrame(), SID_ASSIGN_LAYOUT);
+ aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATPAGE, ((*iPage)->GetPageNum()-1)/2));
+ aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATLAYOUT, aLayout));
+ pMainViewShell->ExecuteSlot (aRequest, BOOL(FALSE));
+ }
+ }
+ while(false);
+}
+
+
+
+
+SfxRequest LayoutMenu::CreateRequest (
+ USHORT nSlotId,
+ AutoLayout aLayout)
+{
+ SfxRequest aRequest (mrBase.GetViewFrame(), nSlotId);
+
+ do
+ {
+ SdrLayerAdmin& rLayerAdmin (mrBase.GetDocument()->GetLayerAdmin());
+ BYTE aBackground (rLayerAdmin.GetLayerID(
+ String(SdResId(STR_LAYER_BCKGRND)), FALSE));
+ BYTE aBackgroundObject (rLayerAdmin.GetLayerID(
+ String(SdResId(STR_LAYER_BCKGRNDOBJ)), FALSE));
+ ViewShell* pViewShell = mrBase.GetMainViewShell().get();
+ if (pViewShell == NULL)
+ break;
+ SdPage* pPage = pViewShell->GetActualPage();
+ if (pPage == NULL)
+ break;
+
+ SetOfByte aVisibleLayers (pPage->TRG_GetMasterPageVisibleLayers());
+
+ aRequest.AppendItem(
+ SfxStringItem (ID_VAL_PAGENAME, String()));//pPage->GetName()));
+ aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATLAYOUT, aLayout));
+ aRequest.AppendItem(
+ SfxBoolItem(ID_VAL_ISPAGEBACK, aVisibleLayers.IsSet(aBackground)));
+ aRequest.AppendItem(
+ SfxBoolItem(
+ ID_VAL_ISPAGEOBJ,
+ aVisibleLayers.IsSet(aBackgroundObject)));
+ }
+ while (false);
+
+ return aRequest;
+}
+
+
+
+
+void LayoutMenu::Fill (void)
+{
+ const bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
+ SvtLanguageOptions aLanguageOptions;
+ sal_Bool bVertical = aLanguageOptions.IsVerticalTextEnabled();
+ SdDrawDocument* pDocument = mrBase.GetDocument();
+ sal_Bool bRightToLeft = (pDocument!=NULL
+ && pDocument->GetDefaultWritingMode() == WritingMode_RL_TB);
+
+ // Get URL of the view in the center pane.
+ ::rtl::OUString sCenterPaneViewName;
+ try
+ {
+ Reference<XControllerManager> xControllerManager (
+ Reference<XWeak>(&mrBase.GetDrawController()), UNO_QUERY_THROW);
+ Reference<XResourceId> xPaneId (ResourceId::create(
+ ::comphelper::getProcessComponentContext(),
+ FrameworkHelper::msCenterPaneURL));
+ Reference<XView> xView (FrameworkHelper::Instance(mrBase)->GetView(xPaneId));
+ if (xView.is())
+ sCenterPaneViewName = xView->getResourceId()->getResourceURL();
+ }
+ catch (RuntimeException&)
+ {}
+
+ snewfoil_value_info* pInfo = NULL;
+ if (sCenterPaneViewName.equals(framework::FrameworkHelper::msNotesViewURL))
+ {
+ pInfo = notes;
+ }
+ else if (sCenterPaneViewName.equals(framework::FrameworkHelper::msHandoutViewURL))
+ {
+ pInfo = handout;
+ }
+ else if (sCenterPaneViewName.equals(framework::FrameworkHelper::msImpressViewURL)
+ || sCenterPaneViewName.equals(framework::FrameworkHelper::msSlideSorterURL))
+ {
+ pInfo = standard;
+ }
+ else
+ {
+ pInfo = NULL;
+ }
+
+ Clear();
+ int n = 0;
+ for (sal_uInt16 i=1; pInfo!=NULL&&pInfo->mnBmpResId!=0; i++,pInfo++)
+ {
+ if ((WritingMode_TB_RL != pInfo->meWritingMode) || bVertical)
+ {
+ BitmapEx aBmp (SdResId (bHighContrast
+ ? pInfo->mnHCBmpResId
+ : pInfo->mnBmpResId));
+
+ if (bRightToLeft && (WritingMode_TB_RL != pInfo->meWritingMode))
+ aBmp.Mirror (BMP_MIRROR_HORZ);
+
+ InsertItem (i, aBmp, String (SdResId (pInfo->mnStrResId)));
+ SetItemData (i, new AutoLayout(pInfo->maAutoLayout));
+ n++;
+ }
+ }
+
+ mbSelectionUpdatePending = true;
+}
+
+
+
+
+void LayoutMenu::Clear (void)
+{
+ for (USHORT nId=1; nId<=GetItemCount(); nId++)
+ delete static_cast<AutoLayout*>(GetItemData(nId));
+ ValueSet::Clear();
+}
+
+
+
+void LayoutMenu::StartDrag (sal_Int8 , const Point& )
+{
+}
+
+
+
+
+sal_Int8 LayoutMenu::AcceptDrop (const AcceptDropEvent& )
+{
+ return 0;
+}
+
+
+
+
+sal_Int8 LayoutMenu::ExecuteDrop (const ExecuteDropEvent& )
+{
+ return 0;
+}
+
+
+
+
+void LayoutMenu::Command (const CommandEvent& rEvent)
+{
+ switch (rEvent.GetCommand())
+ {
+ case COMMAND_CONTEXTMENU:
+ if ( ! SD_MOD()->GetWaterCan())
+ {
+ if (GetShellManager() != NULL)
+ GetShellManager()->MoveToTop(this);
+ if (rEvent.IsMouseEvent())
+ {
+ // Do not show the context menu when the mouse was not
+ // pressed over an item.
+ if (GetItemId(rEvent.GetMousePosPixel()) > 0)
+ mrBase.GetViewFrame()->GetDispatcher()->ExecutePopup(
+ SdResId(RID_TASKPANE_LAYOUTMENU_POPUP));
+ }
+ else
+ {
+ // When the command event was not caused by a mouse
+ // event (for example a key press instead) then show the
+ // popup menu at the center of the current item.
+ if (GetSelectItemId() != (USHORT)-1)
+ {
+ Rectangle aBBox (GetItemRect(GetSelectItemId()));
+ Point aPosition (aBBox.Center());
+ mrBase.GetViewFrame()->GetDispatcher()->ExecutePopup(
+ SdResId(RID_TASKPANE_LAYOUTMENU_POPUP),
+ this,
+ &aPosition);
+ }
+ }
+ }
+ break;
+
+ default:
+ ValueSet::Command(rEvent);
+ break;
+ }
+}
+
+
+
+
+IMPL_LINK(LayoutMenu, StateChangeHandler, ::rtl::OUString*, EMPTYARG)
+{
+ InvalidateContent();
+ return 0;
+}
+
+
+
+
+void LayoutMenu::UpdateSelection (void)
+{
+ bool bItemSelected = false;
+
+ do
+ {
+ // Get current page of main view.
+ ViewShell* pViewShell = mrBase.GetMainViewShell().get();
+ if (pViewShell == NULL)
+ break;
+
+ SdPage* pCurrentPage = pViewShell->getCurrentPage();
+ if (pCurrentPage == NULL)
+ break;
+
+ // Get layout of current page.
+ AutoLayout aLayout (pCurrentPage->GetAutoLayout());
+ if (aLayout<AUTOLAYOUT__START || aLayout>AUTOLAYOUT__END)
+ break;
+
+ // Find the entry of the menu for to the layout.
+ USHORT nItemCount (GetItemCount());
+ for (USHORT nId=1; nId<=nItemCount; nId++)
+ {
+ if (*static_cast<AutoLayout*>(GetItemData(nId)) == aLayout)
+ {
+ SelectItem(nId);
+ bItemSelected = true;
+ break;
+ }
+ }
+ }
+ while (false);
+
+ if ( ! bItemSelected)
+ SetNoSelection();
+}
+
+
+
+
+IMPL_LINK(LayoutMenu, EventMultiplexerListener, ::sd::tools::EventMultiplexerEvent*, pEvent)
+{
+ switch (pEvent->meEventId)
+ {
+ case ::sd::tools::EventMultiplexerEvent::EID_CURRENT_PAGE:
+ case ::sd::tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION:
+ if ( ! mbSelectionUpdatePending)
+ UpdateSelection();
+ break;
+
+ case ::sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED:
+ mbIsMainViewChangePending = true;
+ UpdateEnabledState(MM_UNKNOWN);
+ break;
+
+ case ::sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED:
+ HideFocus();
+ break;
+
+ case ::sd::tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED:
+ if (mbIsMainViewChangePending)
+ {
+ mbIsMainViewChangePending = false;
+ InvalidateContent();
+ }
+ break;
+
+ case ::sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_NORMAL:
+ UpdateEnabledState(MM_NORMAL);
+ break;
+
+ case ::sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_MASTER:
+ UpdateEnabledState(MM_MASTER);
+ break;
+
+ default:
+ /* Ignored */
+ break;
+ }
+
+ return 0;
+}
+
+
+
+
+void LayoutMenu::DataChanged (const DataChangedEvent& rEvent)
+{
+ Fill();
+ ValueSet::DataChanged(rEvent);
+}
+
+
+} } // end of namespace ::sd::toolpanel
diff --git a/sd/source/ui/toolpanel/LayoutMenu.hxx b/sd/source/ui/toolpanel/LayoutMenu.hxx
new file mode 100755
index 000000000000..627a363fb576
--- /dev/null
+++ b/sd/source/ui/toolpanel/LayoutMenu.hxx
@@ -0,0 +1,239 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TASKPANE_LAYOUT_MENU_HXX
+#define SD_TASKPANE_LAYOUT_MENU_HXX
+
+#include "taskpane/TaskPaneTreeNode.hxx"
+
+#ifndef _COM_SUN_STAR_FRAME_XSTATUS_LISTENER_HPP_
+#include <com/sun/star/frame/XStatusListener.hpp>
+#endif
+
+#include "glob.hxx"
+#include "pres.hxx"
+#include <vcl/ctrl.hxx>
+#include <svtools/valueset.hxx>
+#include <svtools/transfer.hxx>
+#include <sfx2/shell.hxx>
+
+
+class SfxModule;
+
+
+namespace sd {
+class DrawDocShell;
+class PaneManagerEvent;
+class ViewShellBase;
+}
+
+
+namespace sd { namespace tools {
+class EventMultiplexerEvent;
+} }
+
+
+namespace sd { namespace toolpanel {
+
+class ControlFactory;
+class ToolPanelViewShell;
+
+
+class LayoutMenu
+ : public ValueSet,
+ public TreeNode,
+ public SfxShell,
+ public DragSourceHelper,
+ public DropTargetHelper
+{
+public:
+ TYPEINFO();
+ SFX_DECL_INTERFACE(SD_IF_SDLAYOUTMENU)
+
+ /** Create a new layout menu. Depending on the given flag it
+ displays its own scroll bar or lets a surrounding window
+ handle that.
+ @param i_pParent
+ the parent node in the control tree
+ @param i_rPanelViewShell
+ the view shell of the task pane.
+ */
+ LayoutMenu (
+ TreeNode* i_pParent,
+ ToolPanelViewShell& i_rPanelViewShell);
+ virtual ~LayoutMenu (void);
+
+ static std::auto_ptr<ControlFactory> CreateControlFactory (
+ ToolPanelViewShell& i_rPanelViewShell );
+
+ /** Return a numerical value representing the currently selected
+ layout.
+ */
+ AutoLayout GetSelectedAutoLayout (void);
+
+
+ // From ILayoutableWindow
+ virtual Size GetPreferredSize (void);
+ virtual sal_Int32 GetPreferredWidth (sal_Int32 nHeight);
+ virtual sal_Int32 GetPreferredHeight (sal_Int32 nWidth);
+ virtual sal_Int32 GetMinimumWidth (void);
+ virtual bool IsResizable (void);
+ virtual ::Window* GetWindow (void);
+
+ // From ::Window
+ virtual void Paint (const Rectangle& rRect);
+ virtual void Resize (void);
+
+ /** Show a context menu when the right mouse button is pressed.
+ */
+ virtual void MouseButtonDown (const MouseEvent& rEvent);
+
+ void Execute (SfxRequest& rRequest);
+ void GetState (SfxItemSet& rItemSet);
+
+ /** The LayoutMenu does not support some main views. In this case the
+ LayoutMenu is disabled. This state is updated in this method.
+ @param eMode
+ On some occasions the edit mode is being switched when this
+ method is called can not (yet) be reliably detected. Luckily,
+ in these cases the new value is provided by some broadcaster.
+ On other occasions the edit mode is not modified and is also not
+ provided. Therefore the Unknown value.
+ */
+ enum MasterMode { MM_NORMAL, MM_MASTER, MM_UNKNOWN };
+ void UpdateEnabledState (const MasterMode eMode);
+
+ // TreeNode overridables
+ virtual TaskPaneShellManager* GetShellManager (void);
+
+ /** Call this method when the set of displayed layouts is not up-to-date
+ anymore. It will re-assemple this set according to the current
+ settings.
+ */
+ void InvalidateContent (void);
+
+ // DragSourceHelper
+ virtual void StartDrag (sal_Int8 nAction, const Point& rPosPixel);
+
+ // DropTargetHelper
+ virtual sal_Int8 AcceptDrop (const AcceptDropEvent& rEvent);
+ virtual sal_Int8 ExecuteDrop (const ExecuteDropEvent& rEvent);
+
+ /** The context menu is requested over this Command() method.
+ */
+ virtual void Command (const CommandEvent& rEvent);
+
+ /** Call Fill() when switching to or from high contrast mode so that the
+ correct set of icons is displayed.
+ */
+ virtual void DataChanged (const DataChangedEvent& rEvent);
+
+ using Window::GetWindow;
+ using ValueSet::StartDrag;
+
+private:
+ ViewShellBase& mrBase;
+
+ TaskPaneShellManager* mpShellManager;
+
+ /** Do we use our own scroll bar or is viewport handling done by
+ our parent?
+ */
+ bool mbUseOwnScrollBar;
+
+ /** If we are asked for the preferred window size, then use this
+ many columns for the calculation.
+ */
+ const int mnPreferredColumnCount;
+
+ ::com::sun::star::uno::Reference<com::sun::star::frame::XStatusListener> mxListener;
+
+ bool mbSelectionUpdatePending;
+
+ bool mbIsMainViewChangePending;
+
+ /** Calculate the number of displayed rows. This depends on the given
+ item size, the given number of columns, and the size of the
+ control. Note that this is not the number of rows managed by the
+ valueset. This number may be larger. In that case a vertical
+ scroll bar is displayed.
+ */
+ int CalculateRowCount (const Size& rItemSize, int nColumnCount);
+
+ /** Fill the value set with the layouts that are applicable to the
+ current main view shell.
+ */
+ void Fill (void);
+
+ /** Remove all items from the value set.
+ */
+ void Clear (void);
+
+ /** Assign the given layout to all selected slides of a slide sorter.
+ If no slide sorter is active then this call is ignored. The slide
+ sorter in the center pane is preferred if the choice exists.
+ */
+ void AssignLayoutToSelectedSlides (AutoLayout aLayout);
+
+ /** Insert a new page with the given layout. The page is inserted via
+ the main view shell, i.e. its SID_INSERTPAGE slot is called. It it
+ does not support this slot then inserting a new page does not take
+ place. The new page is inserted after the currently active one (the
+ one returned by ViewShell::GetActualPage().)
+ */
+ void InsertPageWithLayout (AutoLayout aLayout);
+
+ /** Create a request structure that can be used with the SID_INSERTPAGE
+ and SID_MODIFYPAGE slots. The parameters are set so that the given
+ layout is assigned to the current page of the main view shell.
+ @param nSlotId
+ Supported slots are SID_INSERTPAGE and SID_MODIFYPAGE.
+ @param aLayout
+ Layout of the page to insert or to assign.
+ */
+ SfxRequest CreateRequest (
+ USHORT nSlotId,
+ AutoLayout aLayout);
+
+ /** Select the layout that is used by the current page.
+ */
+ void UpdateSelection (void);
+
+ // internal ctor
+ void implConstruct( DrawDocShell& rDocumentShell );
+
+ /** When clicked then set the current page of the view in the center pane.
+ */
+ DECL_LINK(ClickHandler, ValueSet*);
+ DECL_LINK(RightClickHandler, MouseEvent*);
+ DECL_LINK(StateChangeHandler, ::rtl::OUString*);
+ DECL_LINK(EventMultiplexerListener, ::sd::tools::EventMultiplexerEvent*);
+};
+
+} } // end of namespace ::sd::toolpanel
+
+#endif
diff --git a/sd/source/ui/toolpanel/MethodGuard.hxx b/sd/source/ui/toolpanel/MethodGuard.hxx
new file mode 100644
index 000000000000..45b81367c8de
--- /dev/null
+++ b/sd/source/ui/toolpanel/MethodGuard.hxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_METHODGUARD_HXX
+#define SD_METHODGUARD_HXX
+
+#include <osl/mutex.hxx>
+
+//......................................................................................................................
+namespace sd { namespace toolpanel
+{
+//......................................................................................................................
+
+ //==================================================================================================================
+ //= MethodGuard
+ //==================================================================================================================
+ template < class COMPONENT >
+ class MethodGuard
+ {
+ public:
+ MethodGuard( COMPONENT& i_rComponent )
+ :m_aGuard( i_rComponent.getMutex() )
+ {
+ i_rComponent.checkDisposed();
+ }
+
+ ~MethodGuard()
+ {
+ }
+
+ inline void clear()
+ {
+ m_aGuard.clear();
+ }
+
+ private:
+ ::osl::ClearableMutexGuard m_aGuard;
+ };
+
+//......................................................................................................................
+} } // namespace sd::toolpanel
+//......................................................................................................................
+
+#endif // SD_METHODGUARD_HXX
diff --git a/sd/source/ui/toolpanel/ScrollPanel.cxx b/sd/source/ui/toolpanel/ScrollPanel.cxx
new file mode 100755
index 000000000000..6b10ed889424
--- /dev/null
+++ b/sd/source/ui/toolpanel/ScrollPanel.cxx
@@ -0,0 +1,834 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "taskpane/ScrollPanel.hxx"
+
+#include "taskpane/ControlContainer.hxx"
+#include "TaskPaneFocusManager.hxx"
+#include "taskpane/TitledControl.hxx"
+#include "AccessibleScrollPanel.hxx"
+
+#include <vcl/svapp.hxx>
+#include <svtools/valueset.hxx>
+
+namespace sd { namespace toolpanel {
+
+ScrollPanel::ScrollPanel (
+ TreeNode* pParent)
+ : Control (pParent->GetWindow(), WB_DIALOGCONTROL),
+ TreeNode(pParent),
+ maScrollWindow(this, WB_DIALOGCONTROL),
+ maVerticalScrollBar(this, WB_VERT),
+ maHorizontalScrollBar(this, WB_HORZ),
+ maScrollBarFiller(this),
+ maScrollWindowFiller(&maScrollWindow),
+ mbIsRearrangePending(true),
+ mbIsLayoutPending(true),
+ mnChildrenWidth(0),
+ mnVerticalBorder(2),
+ mnVerticalGap(3),
+ mnHorizontalBorder(2)
+{
+ Construct();
+}
+
+ScrollPanel::ScrollPanel (
+ ::Window& i_rParentWindow)
+ : Control (&i_rParentWindow, WB_DIALOGCONTROL),
+ TreeNode(NULL),
+ maScrollWindow(this, WB_DIALOGCONTROL),
+ maVerticalScrollBar(this, WB_VERT),
+ maHorizontalScrollBar(this, WB_HORZ),
+ maScrollBarFiller(this),
+ maScrollWindowFiller(&maScrollWindow),
+ mbIsRearrangePending(true),
+ mbIsLayoutPending(true),
+ mnChildrenWidth(0),
+ mnVerticalBorder(2),
+ mnVerticalGap(3),
+ mnHorizontalBorder(2)
+{
+ Construct();
+}
+
+void ScrollPanel::Construct()
+{
+ SetAccessibleName (
+ ::rtl::OUString::createFromAscii("Sub Task Panel"));
+ mpControlContainer->SetMultiSelection (true);
+
+ SetBorderStyle (WINDOW_BORDER_NORMAL);
+ SetMapMode (MapMode(MAP_PIXEL));
+
+ // To reduce flickering during repaints make the container windows
+ // transparent and rely on their children to paint the whole area.
+ SetBackground(Wallpaper());
+ maScrollWindow.SetBackground(Wallpaper());
+ maScrollWindowFiller.SetBackground(
+ Application::GetSettings().GetStyleSettings().GetWindowColor());
+
+ maScrollWindow.Show();
+
+ // Initialize the scroll bars.
+ maVerticalScrollBar.SetScrollHdl (
+ LINK(this, ScrollPanel, ScrollBarHandler));
+ maVerticalScrollBar.EnableDrag (TRUE);
+ maHorizontalScrollBar.SetScrollHdl (
+ LINK(this, ScrollPanel, ScrollBarHandler));
+ maHorizontalScrollBar.EnableDrag (TRUE);
+}
+
+
+
+
+ScrollPanel::~ScrollPanel (void)
+{
+ sal_uInt32 nCount = mpControlContainer->GetControlCount();
+ for (sal_uInt32 nIndex=0; nIndex<nCount; nIndex++)
+ {
+ TreeNode* pNode = mpControlContainer->GetControl(nIndex);
+ TreeNode* pControl = pNode;
+ // When the node has been created as TitledControl then use its
+ // control instead of pNode directly.
+ TitledControl* pTitledControl = static_cast<TitledControl*>(pNode);
+ if (pTitledControl != NULL)
+ pControl = pTitledControl->GetControl();
+
+ // Remove this object as listener from the control.
+ if (pControl != NULL && pControl->GetWindow()!=NULL)
+ {
+ pControl->GetWindow()->RemoveEventListener(
+ LINK(this,ScrollPanel,WindowEventListener));
+ }
+ }
+ mpControlContainer->DeleteChildren();
+}
+
+
+
+
+TitledControl* ScrollPanel::AddControl (
+ ::std::auto_ptr<TreeNode> pControl,
+ const String& rTitle,
+ ULONG nHelpId)
+{
+ // We are interested only in the title. The control itself is
+ // managed by the content object.
+ TitledControl* pTitledControl = new TitledControl(
+ this,
+ pControl,
+ rTitle,
+ TitledControlStandardClickHandler(GetControlContainer(), ControlContainer::ES_TOGGLE),
+ TitleBar::TBT_SUB_CONTROL_HEADLINE);
+ pTitledControl->GetTitleBar()->SetHelpId(nHelpId);
+
+ AddControl(::std::auto_ptr<TreeNode>(pTitledControl));
+
+ return pTitledControl;
+}
+
+
+
+
+void ScrollPanel::AddControl (::std::auto_ptr<TreeNode> pControl)
+{
+ if (pControl.get() != NULL)
+ {
+ // Add a window event listener which does two things:
+ // 1. Listen for controls being shown or hidden so that the layout
+ // can be adapted.
+ // 2. Track selection changes in order to make the selected elements
+ // visible.
+ const Link aWindowListener(LINK(this,ScrollPanel,WindowEventListener));
+ OSL_ASSERT(pControl->GetWindow()!=NULL);
+ pControl->GetWindow()->AddEventListener(aWindowListener);
+
+ TitledControl* pTitledControl = dynamic_cast<TitledControl*>(pControl.get());
+ if (pTitledControl != NULL)
+ {
+ OSL_ASSERT(pTitledControl->GetControl()!=NULL);
+ OSL_ASSERT(pTitledControl->GetControl()->GetWindow()!=NULL);
+ pTitledControl->GetControl()->GetWindow()->AddEventListener(aWindowListener);
+ }
+
+ FocusManager& rFocusManager (FocusManager::Instance());
+ int nControlCount (mpControlContainer->GetControlCount());
+ // Replace the old links for cycling between first and last child by
+ // current ones.
+ if (nControlCount > 0)
+ {
+ ::Window* pFirst = mpControlContainer->GetControl(0)->GetWindow();
+ ::Window* pLast = mpControlContainer->GetControl(nControlCount-1)->GetWindow();
+ rFocusManager.RemoveLinks(pFirst,pLast);
+ rFocusManager.RemoveLinks(pLast,pFirst);
+
+ rFocusManager.RegisterLink(pFirst,pControl->GetWindow(), KEY_UP);
+ rFocusManager.RegisterLink(pControl->GetWindow(),pFirst, KEY_DOWN);
+ }
+
+
+ // Add a down link only for the first control so that when entering
+ // the sub tool panel the focus is set to the first control.
+ if (nControlCount == 0)
+ rFocusManager.RegisterDownLink(GetParent(), pControl->GetWindow());
+ rFocusManager.RegisterUpLink(pControl->GetWindow(), GetParent());
+
+ pControl->GetWindow()->SetParent(&maScrollWindow);
+ mpControlContainer->AddControl (pControl);
+ mpControlContainer->SetExpansionState(
+ mpControlContainer->GetControlCount()-1,
+ ControlContainer::ES_EXPAND);
+ }
+}
+
+
+
+
+void ScrollPanel::Paint (const Rectangle& rRect)
+{
+ if (mbIsRearrangePending)
+ Rearrange();
+ if (mbIsLayoutPending)
+ LayoutChildren();
+ ::Window::Paint (rRect);
+
+ // Paint the outer border and the space between every two children.
+ Color aOriginalLineColor (maScrollWindow.GetLineColor());
+ Color aOriginalFillColor (maScrollWindow.GetFillColor());
+
+ maScrollWindow.SetLineColor ();
+ maScrollWindow.SetFillColor (
+ GetSettings().GetStyleSettings().GetWindowColor());
+
+ Size aSize (maScrollWindow.GetOutputSizePixel());
+ // Paint left and right vertical border.
+ Rectangle aVerticalArea (
+ Point(0,0),
+ Size(mnHorizontalBorder,aSize.Height()));
+ maScrollWindow.DrawRect (aVerticalArea);
+ aVerticalArea.Right() += mnHorizontalBorder + mnChildrenWidth - 1;
+ aVerticalArea.Left() = aVerticalArea.Right() + mnHorizontalBorder;
+ maScrollWindow.DrawRect (aVerticalArea);
+
+ // Paint horizontal stripes.
+ Rectangle aStripeArea (
+ Point (mnHorizontalBorder,0),
+ Size(mnChildrenWidth,0));
+ StripeList::const_iterator iStripe;
+ for (iStripe=maStripeList.begin(); iStripe!=maStripeList.end(); iStripe++)
+ {
+ aStripeArea.Top() = iStripe->first;
+ aStripeArea.Bottom() = iStripe->second;
+ if (aStripeArea.Bottom() < 0)
+ continue;
+ if (aStripeArea.Top() >= aSize.Height())
+ break;
+ maScrollWindow.DrawRect (aStripeArea);
+ }
+
+ maScrollWindow.SetLineColor (aOriginalLineColor);
+ maScrollWindow.SetFillColor (aOriginalFillColor);
+}
+
+
+
+
+void ScrollPanel::Resize (void)
+{
+ ::Window::Resize();
+ mbIsRearrangePending = true;
+ mbIsLayoutPending = true;
+}
+
+
+
+
+void ScrollPanel::RequestResize (void)
+{
+ mbIsRearrangePending = true;
+ mbIsLayoutPending = true;
+ Invalidate();
+}
+
+
+
+
+Size ScrollPanel::GetPreferredSize (void)
+{
+ return GetRequiredSize();
+}
+
+
+
+
+sal_Int32 ScrollPanel::GetPreferredWidth (sal_Int32 )
+{
+ return GetPreferredSize().Width();
+}
+
+
+
+
+sal_Int32 ScrollPanel::GetPreferredHeight (sal_Int32 )
+{
+ return GetPreferredSize().Height();
+}
+
+
+
+
+bool ScrollPanel::IsResizable (void)
+{
+ return true;
+}
+
+
+
+
+::Window* ScrollPanel::GetWindow (void)
+{
+ return this;
+}
+
+
+
+
+sal_Int32 ScrollPanel::GetMinimumWidth (void)
+{
+ return TreeNode::GetMinimumWidth();
+}
+
+
+
+
+void ScrollPanel::ExpandControl (
+ TreeNode* pControl,
+ bool bExpansionState)
+{
+ // Toggle expand status.
+ pControl->Expand (bExpansionState);
+
+ Rearrange ();
+ Invalidate ();
+}
+
+
+
+
+bool ScrollPanel::IsVerticalScrollBarVisible (void) const
+{
+ return maVerticalScrollBar.IsReallyVisible();
+}
+
+
+
+
+bool ScrollPanel::IsHorizontalScrollBarVisible (void) const
+{
+ return maHorizontalScrollBar.IsReallyVisible();
+}
+
+
+
+
+ScrollBar& ScrollPanel::GetVerticalScrollBar (void)
+{
+ return maVerticalScrollBar;
+}
+
+
+
+
+ScrollBar& ScrollPanel::GetHorizontalScrollBar (void)
+{
+ return maHorizontalScrollBar;
+}
+
+
+
+
+/** This control shows an expansion bar for every control and in a
+ separate area below that expansion area it shows all controls each
+ with its title bar. When there is not enough space then show a
+ scroll bar in the control area.
+*/
+void ScrollPanel::Rearrange (void)
+{
+ Size aRequiredSize (GetRequiredSize());
+ if (aRequiredSize.Width()>0 && aRequiredSize.Height()>0)
+ {
+ Size aAvailableSize (SetupScrollBars (aRequiredSize));
+ maScrollWindow.SetPosSizePixel(
+ Point(0,0),
+ aAvailableSize);
+
+ // Make the children at least as wide as the sub tool panel.
+ if (aRequiredSize.Width() < aAvailableSize.Width())
+ aRequiredSize.Width() = aAvailableSize.Width();
+ mnChildrenWidth = -2*mnHorizontalBorder;
+ if (maHorizontalScrollBar.IsVisible())
+ mnChildrenWidth += aRequiredSize.Width();
+ else
+ mnChildrenWidth += aAvailableSize.Width();
+
+ sal_Int32 nChildrenHeight (LayoutChildren());
+ maVerticalScrollBar.SetRangeMax (
+ nChildrenHeight + mnVerticalBorder);
+
+ mbIsRearrangePending = false;
+ }
+}
+
+
+
+
+Size ScrollPanel::GetRequiredSize (void)
+{
+ // First determine the width of the children. This is the maximum of
+ // the current window width and the individual minimum widths of the
+ // children.
+ int nChildrenWidth (GetSizePixel().Width());
+ unsigned int nCount = mpControlContainer->GetControlCount();
+ unsigned int nIndex;
+ for (nIndex=0; nIndex<nCount; nIndex++)
+ {
+ TreeNode* pChild = mpControlContainer->GetControl (nIndex);
+ int nMinimumWidth (pChild->GetMinimumWidth());
+ if (nMinimumWidth > nChildrenWidth)
+ nChildrenWidth = nMinimumWidth;
+ }
+
+ // Determine the accumulated width of all children when scaled to the
+ // minimum width.
+ nChildrenWidth -= 2*mnHorizontalBorder;
+ Size aTotalSize (nChildrenWidth,
+ 2*mnVerticalBorder + (nCount-1) * mnVerticalGap);
+ for (nIndex=0; nIndex<nCount; nIndex++)
+ {
+ TreeNode* pChild = mpControlContainer->GetControl (nIndex);
+ sal_Int32 nHeight = pChild->GetPreferredHeight(nChildrenWidth);
+ aTotalSize.Height() += nHeight;
+ }
+
+ return aTotalSize;
+}
+
+
+
+
+sal_Int32 ScrollPanel::LayoutChildren (void)
+{
+ maStripeList.clear();
+
+ Point aPosition (maScrollOffset);
+ aPosition.X() += mnHorizontalBorder;
+ maStripeList.push_back( ::std::pair<int,int>(
+ aPosition.Y(),
+ aPosition.Y() + mnVerticalBorder - 1));
+ aPosition.Y() += mnVerticalBorder;
+
+ // Place the controls one over the other.
+ unsigned int nCount (mpControlContainer->GetControlCount());
+ for (unsigned int nIndex=0; nIndex<nCount; nIndex++)
+ {
+ if (nIndex > 0)
+ {
+ maStripeList.push_back( ::std::pair<int,int>(
+ aPosition.Y(),
+ aPosition.Y() + mnVerticalGap - 1));
+ aPosition.Y() += mnVerticalGap;
+ }
+ TreeNode* pChild = mpControlContainer->GetControl (nIndex);
+ int nControlHeight = pChild->GetPreferredHeight(mnChildrenWidth);
+ pChild->GetWindow()->SetPosSizePixel(
+ aPosition,
+ Size(mnChildrenWidth, nControlHeight));
+ aPosition.Y() += nControlHeight;
+ }
+
+ // If the children do not cover their parent window completely
+ // (regarding the height) we put a filler below that is responsible for
+ // painting the remaining space.
+ int nWindowHeight = maScrollWindow.GetSizePixel().Height();
+ if (aPosition.Y() < nWindowHeight)
+ {
+ maScrollWindowFiller.SetPosSizePixel (
+ aPosition,
+ Size(mnChildrenWidth, nWindowHeight-aPosition.Y()));
+ maStripeList.push_back( ::std::pair<int,int>(
+ aPosition.Y(),
+ nWindowHeight-1));
+ // maScrollWindowFiller.Show();
+ aPosition.Y() = nWindowHeight;
+ }
+ else
+ maScrollWindowFiller.Hide();
+
+ aPosition.Y() += mnVerticalBorder;
+ mbIsLayoutPending = false;
+
+ return aPosition.Y()-maScrollOffset.Y();
+}
+
+
+
+
+Size ScrollPanel::SetupScrollBars (const Size& rRequiredSize)
+{
+ Size aWindowSize (GetSizePixel());
+ Size aScrollBarSize (
+ maVerticalScrollBar.GetSizePixel().Width(),
+ maHorizontalScrollBar.GetSizePixel().Height());
+ Size aRemainingSize (aWindowSize);
+
+ // Determine which scroll bars have to be shown.
+ bool bShowHorizontal = false;
+ if (rRequiredSize.Width() > aWindowSize.Width())
+ bShowHorizontal = true;
+ bool bShowVertical = false;
+ if (rRequiredSize.Height() > aWindowSize.Height())
+ bShowVertical = true;
+ // Showing one scroll bar may reduce the available size so that the
+ // other one has to be shown as well.
+ if (bShowHorizontal && ! bShowVertical)
+ {
+ if ((rRequiredSize.Height() + aScrollBarSize.Height())
+ > aWindowSize.Height())
+ bShowVertical = true;
+ }
+ else if (bShowVertical && ! bShowHorizontal)
+ {
+ if (GetMinimumWidth() + aScrollBarSize.Width() > aWindowSize.Width())
+ bShowHorizontal = true;
+ }
+
+ // Setup the scroll bars.
+ aRemainingSize.Width()
+ = SetupVerticalScrollBar (bShowVertical, rRequiredSize.Height());
+ aRemainingSize.Height()
+ = SetupHorizontalScrollBar (bShowHorizontal, rRequiredSize.Width());
+
+ // Place the filler.
+ if (bShowHorizontal && bShowVertical)
+ {
+ maScrollBarFiller.SetPosSizePixel (
+ Point(aWindowSize.Width(), aWindowSize.Height()),
+ aScrollBarSize);
+ maScrollBarFiller.Show();
+ }
+ else
+ maScrollBarFiller.Hide();
+
+
+ return aRemainingSize;
+}
+
+
+
+
+sal_Int32 ScrollPanel::SetupVerticalScrollBar (bool bShow, sal_Int32 nRange)
+{
+ Size aScrollBarSize (
+ maVerticalScrollBar.GetSizePixel().Width(),
+ maHorizontalScrollBar.GetSizePixel().Height());
+ Size aWindowSize (GetOutputSizePixel());
+ sal_Int32 nRemainingWidth (aWindowSize.Width());
+
+ // Setup the verical scroll bar.
+ if (bShow)
+ {
+ int nWidth = aScrollBarSize.Width();
+ int nHeight = aWindowSize.Height();
+ maVerticalScrollBar.SetPosSizePixel(
+ Point(aWindowSize.Width()-nWidth,0),
+ Size(nWidth, nHeight));
+ maVerticalScrollBar.Show();
+
+ // Set the scroll bar range and thumb size.
+ maVerticalScrollBar.SetRangeMin (0);
+ maVerticalScrollBar.SetRangeMax (
+ nRange + 2*mnVerticalBorder);
+ maVerticalScrollBar.SetVisibleSize (aWindowSize.Height());
+ // Make page size approx. 10% of visible area.
+ maVerticalScrollBar.SetLineSize (aWindowSize.Height()/10);
+ // Make page size approx. 100% of visible area.
+ maVerticalScrollBar.SetPageSize (aWindowSize.Height());
+ // Make sure that thumb is inside the valid range.
+ maVerticalScrollBar.SetThumbPos(-maScrollOffset.Y());
+ long nMinPos = maVerticalScrollBar.GetRangeMin();
+ if (maVerticalScrollBar.GetThumbPos() < nMinPos)
+ maVerticalScrollBar.SetThumbPos(nMinPos);
+ long nMaxPos = maVerticalScrollBar.GetRangeMax()
+ - maVerticalScrollBar.GetVisibleSize();
+ if (maVerticalScrollBar.GetThumbPos() >= nMaxPos)
+ maVerticalScrollBar.SetThumbPos(nMaxPos);
+ // Set offset to match thumb pos.
+ maScrollOffset.Y() = -maVerticalScrollBar.GetThumbPos();
+
+ nRemainingWidth -= aScrollBarSize.Width();
+ }
+ else
+ {
+ maVerticalScrollBar.Hide();
+ maScrollOffset.Y() = 0;
+ }
+
+ return nRemainingWidth;
+}
+
+
+
+
+sal_Int32 ScrollPanel::SetupHorizontalScrollBar (bool bShow, sal_Int32 nRange)
+{
+ Size aScrollBarSize (
+ maVerticalScrollBar.GetSizePixel().Width(),
+ maHorizontalScrollBar.GetSizePixel().Height());
+ Size aWindowSize (GetOutputSizePixel());
+ sal_Int32 nRemainingHeight (aWindowSize.Height());
+
+ // Setup the horizontal scroll bar.
+ if (bShow)
+ {
+ int nHeight = aScrollBarSize.Height();
+ int nWidth = GetOutputSizePixel().Width();
+ maHorizontalScrollBar.SetPosSizePixel(
+ Point(0, aWindowSize.Height()-nHeight),
+ Size(nWidth,nHeight));
+ maHorizontalScrollBar.Show();
+
+ // Set the scroll bar range and thumb size.
+ maHorizontalScrollBar.SetRangeMin (0);
+ maHorizontalScrollBar.SetRangeMax (
+ nRange + 2*mnHorizontalBorder);
+ maHorizontalScrollBar.SetVisibleSize (aWindowSize.Width());
+ // Make page size approx. 5% of visible area.
+ maHorizontalScrollBar.SetLineSize (aWindowSize.Width()/20+1);
+ // Make page size approx. 50% of visible area.
+ maHorizontalScrollBar.SetPageSize (aWindowSize.Width()/2+1);
+ // Make sure that thumb is inside the valid range.
+ maHorizontalScrollBar.SetThumbPos(-maScrollOffset.X());
+ long nMinPos = maHorizontalScrollBar.GetRangeMin();
+ if (maHorizontalScrollBar.GetThumbPos() < nMinPos)
+ maHorizontalScrollBar.SetThumbPos(nMinPos);
+ long nMaxPos = maHorizontalScrollBar.GetRangeMax()
+ - maHorizontalScrollBar.GetVisibleSize();
+ if (maHorizontalScrollBar.GetThumbPos() >= nMaxPos)
+ maHorizontalScrollBar.SetThumbPos(nMaxPos);
+ // Set offset to match thumb pos.
+ maScrollOffset.X() = -maHorizontalScrollBar.GetThumbPos();
+
+ nRemainingHeight -= aScrollBarSize.Height();
+ }
+ else
+ {
+ maHorizontalScrollBar.Hide();
+ maScrollOffset.X() = 0;
+ }
+
+ return nRemainingHeight;
+}
+
+
+IMPL_LINK(ScrollPanel, ScrollBarHandler, ScrollBar*, EMPTYARG)
+{
+ maScrollOffset.X() -= maHorizontalScrollBar.GetDelta();
+ maScrollOffset.Y() -= maVerticalScrollBar.GetDelta();
+
+ // Scrolling is done by moving the child windows up or down.
+ mbIsLayoutPending = true;
+ Invalidate();
+ // LayoutChildren();
+
+ return 0;
+}
+
+
+
+
+long ScrollPanel::Notify( NotifyEvent& rNEvt )
+{
+ long nRet = FALSE;
+ if( rNEvt.GetType() == EVENT_COMMAND )
+ {
+ // note: dynamic_cast is not possible as GetData() returns a void*
+ CommandEvent* pCmdEvent = reinterpret_cast< CommandEvent* >(rNEvt.GetData());
+ DBG_ASSERT( pCmdEvent!=0 &&
+ ( pCmdEvent->IsMouseEvent() == TRUE ||
+ pCmdEvent->IsMouseEvent() == FALSE ),
+ "Invalid CommandEvent" );
+ if (pCmdEvent)
+ switch (pCmdEvent->GetCommand())
+ {
+ case COMMAND_WHEEL:
+ case COMMAND_STARTAUTOSCROLL:
+ case COMMAND_AUTOSCROLL:
+ {
+ nRet = HandleScrollCommand (*pCmdEvent, &maHorizontalScrollBar, &maVerticalScrollBar);
+ break;
+ }
+ }
+ }
+
+ if( ! nRet )
+ nRet = ::Window::Notify( rNEvt );
+
+ return nRet;
+}
+
+
+
+
+::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible> ScrollPanel::CreateAccessibleObject (
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& )
+{
+ return new ::accessibility::AccessibleScrollPanel (
+ *this,
+ ::rtl::OUString::createFromAscii("Scroll Panel"),
+ ::rtl::OUString::createFromAscii("Scroll Panel"));
+}
+
+
+
+
+void ScrollPanel::MakeRectangleVisible (
+ Rectangle& aRectangle,
+ ::Window* pWindow)
+{
+ if (maVerticalScrollBar.IsVisible() && aRectangle.GetWidth()>0 && aRectangle.GetHeight()>0)
+ {
+ const Rectangle aRelativeBox (pWindow->GetWindowExtentsRelative(&maScrollWindow));
+
+ aRectangle.Move(
+ -maScrollOffset.X() + aRelativeBox.Left(),
+ -maScrollOffset.Y() + aRelativeBox.Top());
+
+ const int nVisibleHeight (maVerticalScrollBar.GetVisibleSize());
+ const int nVisibleTop (maVerticalScrollBar.GetThumbPos());
+ if (aRectangle.Bottom() >= nVisibleTop+nVisibleHeight)
+ maVerticalScrollBar.DoScroll(aRectangle.Bottom() - nVisibleHeight);
+ else if (aRectangle.Top() < nVisibleTop)
+ maVerticalScrollBar.DoScroll(aRectangle.Top());
+ }
+}
+
+
+
+
+IMPL_LINK(ScrollPanel,WindowEventListener,VclSimpleEvent*,pEvent)
+{
+ VclWindowEvent* pWindowEvent = dynamic_cast<VclWindowEvent*>(pEvent);
+ if (pWindowEvent != NULL)
+ {
+ switch (pWindowEvent->GetId())
+ {
+ case VCLEVENT_WINDOW_KEYUP:
+ case VCLEVENT_WINDOW_MOUSEBUTTONUP:
+ {
+ // Make the currently selected item visible.
+ ValueSet* pControl = dynamic_cast<ValueSet*>(pWindowEvent->GetWindow());
+ if (pControl != NULL)
+ {
+ // Get the bounding box of the currently selected item
+ // and enlarge this so that the selection frame is
+ // inside as well.
+ Rectangle aBox (pControl->GetItemRect(pControl->GetSelectItemId()));
+ aBox.Top()-=4;
+ aBox.Bottom()+=4;
+
+ MakeRectangleVisible(aBox, pControl);
+ }
+ }
+ break;
+
+ case VCLEVENT_WINDOW_MOUSEBUTTONDOWN:
+ {
+ // Make the item under the mouse visible. We need this case
+ // for right clicks that open context menus. For these we
+ // only get the mouse down event. The following mouse up
+ // event is sent to the context menu.
+ ValueSet* pControl = dynamic_cast<ValueSet*>(pWindowEvent->GetWindow());
+ if (pControl != NULL)
+ {
+ // Get the bounding box of the item at the mouse
+ // position and enlarge this so that the selection frame
+ // is inside as well.
+ MouseEvent* pMouseEvent
+ = reinterpret_cast<MouseEvent*>(pWindowEvent->GetData());
+ if (pMouseEvent != NULL)
+ {
+ Point aPosition (pMouseEvent->GetPosPixel());
+ Rectangle aBox (pControl->GetItemRect(pControl->GetItemId(aPosition)));
+ aBox.Top()-=4;
+ aBox.Bottom()+=4;
+
+ MakeRectangleVisible(aBox, pControl);
+ }
+ }
+ }
+ break;
+
+
+ case VCLEVENT_WINDOW_GETFOCUS:
+ {
+ // Move title bars into the visible area when they get the
+ // focus (::Window wise their enclosing TitledControl gets
+ // the focus.)
+ TitledControl* pTitledControl = dynamic_cast<TitledControl*>(pWindowEvent->GetWindow());
+ if (pTitledControl!=NULL && pTitledControl->GetTitleBar()!=NULL)
+ {
+ ::Window* pTitleBarWindow = pTitledControl->GetTitleBar()->GetWindow();
+ Rectangle aBox(pTitleBarWindow->GetPosPixel(),pTitleBarWindow->GetSizePixel());
+ MakeRectangleVisible(
+ aBox,
+ pTitleBarWindow);
+ }
+ }
+ break;
+
+ case VCLEVENT_WINDOW_SHOW:
+ case VCLEVENT_WINDOW_HIDE:
+ case VCLEVENT_WINDOW_ACTIVATE:
+ case VCLEVENT_WINDOW_RESIZE:
+ // Rearrange the children of the scroll panel when one of
+ // the children changes its size or visibility.
+ RequestResize();
+ break;
+ }
+ }
+ return 0;
+}
+
+
+
+
+} } // end of namespace ::sd::toolpanel
diff --git a/sd/source/ui/toolpanel/SlideSorterCacheDisplay.cxx b/sd/source/ui/toolpanel/SlideSorterCacheDisplay.cxx
new file mode 100755
index 000000000000..a032b6ef02f0
--- /dev/null
+++ b/sd/source/ui/toolpanel/SlideSorterCacheDisplay.cxx
@@ -0,0 +1,372 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "taskpane/SlideSorterCacheDisplay.hxx"
+
+#ifdef USE_SLIDE_SORTER_CACHE_DISPLAY
+
+#include "taskpane/ScrollPanel.hxx"
+#include "taskpane/TaskPaneControlFactory.hxx"
+
+#include <vcl/window.hxx>
+#include <vcl/lstbox.hxx>
+#include <vcl/button.hxx>
+
+namespace {
+
+static const Color maBackgroundColor (255,250,245);
+
+class PageCacheWindow : public ::Window
+{
+public:
+ PageCacheWindow (
+ ::Window* pParentWindow,
+ ::sd::toolpanel::SlideSorterCacheDisplay* pDisplay)
+ : ::Window(pParentWindow),
+ mpDisplay(pDisplay)
+ {
+ SetBackground(Wallpaper(maBackgroundColor));
+ }
+
+ virtual void Paint (const Rectangle& rBoundingBox)
+ { mpDisplay->Paint(rBoundingBox); ::Window::Paint(rBoundingBox); }
+ virtual void Resize (void) { mpDisplay->Resize(); ::Window::Resize(); }
+
+private:
+ ::sd::toolpanel::SlideSorterCacheDisplay* mpDisplay;
+};
+
+}
+
+
+
+namespace sd { namespace toolpanel {
+
+::std::map<const SdDrawDocument*, SlideSorterCacheDisplay*> SlideSorterCacheDisplay::maDisplays;
+
+SlideSorterCacheDisplay::SlideSorterCacheDisplay (const SdDrawDocument* pDocument)
+ : TreeNode(NULL),
+ mpWindow(NULL),
+ mnPageCount(0),
+ mnColumnCount(0),
+ mnRowCount(0),
+ maCellSize(0,0),
+ mnHorizontalBorder(0),
+ mnVerticalBorder(0)
+{
+ SlideSorterCacheDisplay::AddInstance(pDocument,this);
+}
+
+
+
+
+SlideSorterCacheDisplay::~SlideSorterCacheDisplay (void)
+{
+ if (mpWindow != NULL)
+ delete mpWindow;
+ SlideSorterCacheDisplay::RemoveInstance(this);
+}
+
+
+
+
+void SlideSorterCacheDisplay::SetParentWindow (::Window* pParentWindow)
+{
+ mpWindow = new PageCacheWindow(pParentWindow, this);
+}
+
+
+
+
+void SlideSorterCacheDisplay::Paint (const Rectangle& rBoundingBox)
+{
+ if (maCellSize.Width()>0 && maCellSize.Height()>0 && mpWindow!=NULL)
+ {
+ Color maSavedFillColor (mpWindow->GetFillColor());
+ Color maSavedLineColor (mpWindow->GetLineColor());
+ sal_Int32 nC0 = (rBoundingBox.Left() - mnHorizontalBorder) / maCellSize.Width();
+ sal_Int32 nC1 = (rBoundingBox.Right() - mnHorizontalBorder) / maCellSize.Width();
+ sal_Int32 nR0 = (rBoundingBox.Top() - mnVerticalBorder) / maCellSize.Height();
+ sal_Int32 nR1 = (rBoundingBox.Bottom() - mnVerticalBorder) / maCellSize.Height();
+ for (sal_Int32 nC=nC0; nC<=nC1; ++nC)
+ for (sal_Int32 nR=nR0; nR<=nR1; ++nR)
+ {
+ sal_Int32 nPageIndex (nC + nR*mnColumnCount);
+ if (nPageIndex < mnPageCount)
+ {
+ Rectangle aBox (GetPageBox(nPageIndex));
+ if ( ! maPageDescriptors[nPageIndex].mbVisible)
+ {
+ mpWindow->SetLineColor();
+ mpWindow->SetFillColor(maBackgroundColor);
+ mpWindow->DrawRect(aBox);
+
+ aBox.Left() += maCellSize.Width()/4;
+ aBox.Right() -= maCellSize.Width()/4;
+ aBox.Top() += maCellSize.Height()/4;
+ aBox.Bottom() -= maCellSize.Height()/4;
+ }
+
+ switch (maPageDescriptors[nPageIndex].meStatus)
+ {
+ case NONE : mpWindow->SetFillColor (Color(95,255,128)); break;
+ case RENDERING : mpWindow->SetFillColor (Color(236,125,128)); break;
+ case IN_QUEUE_PRIORITY_0 : mpWindow->SetFillColor (Color(255,243,0)); break;
+ case IN_QUEUE_PRIORITY_1 : mpWindow->SetFillColor (Color(255,199,0)); break;
+ case IN_QUEUE_PRIORITY_2 : mpWindow->SetFillColor (Color(20,255,128)); break;
+ default : mpWindow->SetFillColor (COL_BLACK); break;
+ }
+ mpWindow->SetLineColor(COL_BLACK);
+ mpWindow->DrawRect(aBox);
+
+ if ( ! maPageDescriptors[nPageIndex].mbUpToDate)
+ mpWindow->DrawLine(aBox.TopLeft(), aBox.BottomRight());
+ }
+ }
+ mpWindow->SetLineColor(maSavedLineColor);
+ mpWindow->SetFillColor(maSavedFillColor);
+ }
+}
+
+
+
+
+void SlideSorterCacheDisplay::Resize (void)
+{
+ if (mpWindow != NULL)
+ {
+ double nW = mpWindow->GetSizePixel().Width();
+ double nH = mpWindow->GetSizePixel().Height();
+ if (nH > 0)
+ {
+ double nAspect = nW / nH;
+ sal_Int32 nR = 1;
+ sal_Int32 nC = 1;
+ while (nR * nC < mnPageCount)
+ {
+ if (double(nC) / double(nR) > nAspect)
+ ++nR;
+ else
+ ++nC;
+ }
+ double nAspect2 = double(nC) / double(nR);
+
+ mnRowCount = nR;
+ mnColumnCount = nC;
+ mnHorizontalGap = 2;
+ mnVerticalGap = 2;
+ maCellSize = Size(
+ (int)((nW-(nC-1)*mnHorizontalGap) / nC),
+ (int)((nH-(nR-1)*mnVerticalGap) / nR));
+ mnHorizontalBorder = (int)(nW - nC*maCellSize.Width() - ((nC-1)*mnHorizontalGap))/2;
+ mnVerticalBorder = (int)(nH - nR*maCellSize.Height() - ((nR-1)*mnVerticalGap))/2;
+ }
+ }
+}
+
+
+
+
+SlideSorterCacheDisplay* SlideSorterCacheDisplay::Instance (const SdDrawDocument* pDocument)
+{
+ SlideSorterCacheDisplay* pDisplay = NULL;
+ ::std::map<const SdDrawDocument*, SlideSorterCacheDisplay*>::iterator iDisplay;
+ for (iDisplay=maDisplays.begin(); iDisplay!=maDisplays.end(); ++iDisplay)
+ if (iDisplay->first == pDocument)
+ pDisplay = iDisplay->second;
+
+ if (pDisplay == NULL)
+ {
+ pDisplay = new SlideSorterCacheDisplay(pDocument);
+ }
+
+ return pDisplay;
+}
+
+
+
+
+void SlideSorterCacheDisplay::SetPageCount (sal_Int32 nPageCount)
+{
+ mnPageCount = nPageCount;
+ maPageDescriptors.resize(nPageCount);
+ Resize();
+ if (mpWindow != NULL)
+ mpWindow->Invalidate();
+}
+
+
+
+
+void SlideSorterCacheDisplay::SetPageStatus (sal_Int32 nPageIndex, PageStatus eStatus)
+{
+ ProvideSize(nPageIndex);
+ maPageDescriptors[nPageIndex].meStatus = eStatus;
+ PaintPage(nPageIndex);
+}
+
+
+
+
+void SlideSorterCacheDisplay::SetPageVisibility (sal_Int32 nPageIndex, bool bVisible)
+{
+ ProvideSize(nPageIndex);
+ maPageDescriptors[nPageIndex].mbVisible = bVisible;
+ PaintPage(nPageIndex);
+}
+
+
+
+
+void SlideSorterCacheDisplay::SetUpToDate (sal_Int32 nPageIndex, bool bUpToDate)
+{
+ ProvideSize(nPageIndex);
+ maPageDescriptors[nPageIndex].mbUpToDate = bUpToDate;
+ PaintPage(nPageIndex);
+}
+
+
+
+
+Rectangle SlideSorterCacheDisplay::GetPageBox (sal_Int32 nPageIndex)
+{
+ sal_Int32 nRow = nPageIndex / mnColumnCount;
+ sal_Int32 nColumn = nPageIndex % mnColumnCount;
+ return Rectangle(
+ Point(mnHorizontalBorder + nColumn * maCellSize.Width() + nColumn*mnHorizontalGap,
+ mnVerticalBorder + nRow * maCellSize.Height() + nRow*mnVerticalGap),
+ maCellSize);
+}
+
+
+
+
+void SlideSorterCacheDisplay::AddInstance (
+ const SdDrawDocument* pDocument,
+ SlideSorterCacheDisplay* pControl)
+{
+ maDisplays[pDocument] = pControl;
+}
+
+
+
+
+void SlideSorterCacheDisplay::RemoveInstance (SlideSorterCacheDisplay* pControl)
+{
+ ::std::map<const SdDrawDocument*, SlideSorterCacheDisplay*>::iterator iDisplay;
+ for (iDisplay=maDisplays.begin(); iDisplay!=maDisplays.end(); ++iDisplay)
+ if (iDisplay->second == pControl)
+ {
+ maDisplays.erase(iDisplay);
+ break;
+ }
+}
+
+
+
+
+void SlideSorterCacheDisplay::ProvideSize (sal_Int32 nPageIndex)
+{
+ if (maPageDescriptors.size() <= (sal_uInt32)nPageIndex)
+ maPageDescriptors.resize(nPageIndex+1);
+ if (mnPageCount <= nPageIndex)
+ mnPageCount = nPageIndex;
+}
+
+
+
+
+Size SlideSorterCacheDisplay::GetPreferredSize (void)
+{
+ return Size(100,100);
+}
+
+
+
+
+sal_Int32 SlideSorterCacheDisplay::GetPreferredWidth (sal_Int32 nHeigh)
+{
+ return GetPreferredSize().Width();
+}
+
+
+
+
+sal_Int32 SlideSorterCacheDisplay::GetPreferredHeight (sal_Int32 nWidth)
+{
+ return GetPreferredSize().Height();
+}
+
+
+
+::Window* SlideSorterCacheDisplay::GetWindow (void)
+{
+ return mpWindow;
+}
+
+
+
+
+bool SlideSorterCacheDisplay::IsResizable (void)
+{
+ return true;
+}
+
+
+
+
+bool SlideSorterCacheDisplay::IsExpandable (void) const
+{
+ return true;
+}
+
+
+
+
+bool SlideSorterCacheDisplay::IsExpanded (void) const
+{
+ return true;
+}
+
+
+
+
+void SlideSorterCacheDisplay::PaintPage (sal_Int32 nPageIndex)
+{
+ if (mpWindow != NULL)
+ {
+ Paint(GetPageBox(nPageIndex));
+ }
+}
+
+
+} } // end of namespace ::sd::toolpanel
+
+#endif
diff --git a/sd/source/ui/toolpanel/SubToolPanel.cxx b/sd/source/ui/toolpanel/SubToolPanel.cxx
new file mode 100755
index 000000000000..73783b0f0a41
--- /dev/null
+++ b/sd/source/ui/toolpanel/SubToolPanel.cxx
@@ -0,0 +1,419 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "taskpane/SubToolPanel.hxx"
+
+#include "TaskPaneFocusManager.hxx"
+#include "taskpane/TitleBar.hxx"
+#include "taskpane/TitledControl.hxx"
+#include "taskpane/ControlContainer.hxx"
+#include "AccessibleTreeNode.hxx"
+#include <vcl/decoview.hxx>
+#include <vcl/svapp.hxx>
+
+namespace sd { namespace toolpanel {
+
+
+SubToolPanel::SubToolPanel (
+ TreeNode* pParent)
+ : Control (pParent->GetWindow(), WB_DIALOGCONTROL),
+ TreeNode(pParent),
+ maWindowFiller(this),
+ mbIsRearrangePending(true),
+ mbIsLayoutPending(true),
+ mnChildrenWidth(0),
+ mnVerticalBorder(0),
+ mnVerticalGap(3),
+ mnHorizontalBorder(2)
+{
+ SetAccessibleName (
+ ::rtl::OUString::createFromAscii("Sub Task Panel"));
+ mpControlContainer->SetMultiSelection (true);
+
+ SetBorderStyle (WINDOW_BORDER_NORMAL);
+ SetMapMode (MapMode(MAP_PIXEL));
+
+ // To reduce flickering during repaints make the container windows
+ // transparent and rely on their children to paint the whole area.
+ SetBackground(Wallpaper());
+ maWindowFiller.SetBackground(
+ Application::GetSettings().GetStyleSettings().GetWindowColor());
+}
+
+
+
+
+SubToolPanel::SubToolPanel (
+ Window& i_rParentWindow)
+ : Control (&i_rParentWindow, WB_DIALOGCONTROL),
+ TreeNode(NULL),
+ maWindowFiller(this),
+ mbIsRearrangePending(true),
+ mbIsLayoutPending(true),
+ mnChildrenWidth(0),
+ mnVerticalBorder(0),
+ mnVerticalGap(3),
+ mnHorizontalBorder(2)
+{
+ SetAccessibleName (
+ ::rtl::OUString::createFromAscii("Sub Task Panel"));
+ mpControlContainer->SetMultiSelection (true);
+
+ SetBorderStyle (WINDOW_BORDER_NORMAL);
+ SetMapMode (MapMode(MAP_PIXEL));
+
+ // To reduce flickering during repaints make the container windows
+ // transparent and rely on their children to paint the whole area.
+ SetBackground(Wallpaper());
+ maWindowFiller.SetBackground(
+ Application::GetSettings().GetStyleSettings().GetWindowColor());
+}
+
+
+
+
+SubToolPanel::~SubToolPanel (void)
+{
+ sal_uInt32 nCount = mpControlContainer->GetControlCount();
+ for (sal_uInt32 nIndex=0; nIndex<nCount; nIndex++)
+ {
+ TitledControl* pControl = static_cast<TitledControl*>(
+ mpControlContainer->GetControl(nIndex));
+ pControl->GetControl()->GetWindow()->RemoveEventListener(
+ LINK(this,SubToolPanel,WindowEventListener));
+ }
+ mpControlContainer->DeleteChildren();
+}
+
+
+
+
+void SubToolPanel::Paint (const Rectangle& rRect)
+{
+ if (mbIsRearrangePending)
+ Rearrange();
+ if (mbIsLayoutPending)
+ LayoutChildren();
+ ::Window::Paint (rRect);
+
+ // Paint the outer border and the space between every two children.
+ Color aOriginalLineColor (GetLineColor());
+ Color aOriginalFillColor (GetFillColor());
+
+ SetLineColor ();
+ SetFillColor (GetSettings().GetStyleSettings().GetWindowColor());
+
+ Size aSize (GetOutputSizePixel());
+ // Paint left and right vertical border.
+ Rectangle aVerticalArea (
+ Point(0,0),
+ Size(mnHorizontalBorder,aSize.Height()));
+ DrawRect (aVerticalArea);
+ aVerticalArea.Right() += mnHorizontalBorder + mnChildrenWidth - 1;
+ aVerticalArea.Left() = aVerticalArea.Right() + mnHorizontalBorder;
+ DrawRect (aVerticalArea);
+
+ // Paint horizontal stripes.
+ Rectangle aStripeArea (
+ Point (mnHorizontalBorder,0),
+ Size(mnChildrenWidth,0));
+ StripeList::const_iterator iStripe;
+ for (iStripe=maStripeList.begin(); iStripe!=maStripeList.end(); iStripe++)
+ {
+ aStripeArea.Top() = iStripe->first;
+ aStripeArea.Bottom() = iStripe->second;
+ if (aStripeArea.Bottom() < 0)
+ continue;
+ if (aStripeArea.Top() >= aSize.Height())
+ break;
+ DrawRect (aStripeArea);
+ }
+
+ SetLineColor (aOriginalLineColor);
+ SetFillColor (aOriginalFillColor);
+}
+
+
+
+
+void SubToolPanel::Resize (void)
+{
+ ::Window::Resize();
+ mbIsRearrangePending = true;
+ mbIsLayoutPending = true;
+}
+
+
+
+
+void SubToolPanel::RequestResize (void)
+{
+ mbIsRearrangePending = true;
+ mbIsLayoutPending = true;
+ Invalidate();
+}
+
+
+
+
+Size SubToolPanel::GetPreferredSize (void)
+{
+ return GetRequiredSize();
+}
+
+
+
+
+sal_Int32 SubToolPanel::GetPreferredWidth (sal_Int32 )
+{
+ return GetPreferredSize().Width();
+}
+
+
+
+
+sal_Int32 SubToolPanel::GetPreferredHeight (sal_Int32 )
+{
+ return GetPreferredSize().Height();
+}
+
+
+
+
+bool SubToolPanel::IsResizable (void)
+{
+ return true;
+}
+
+
+
+
+::Window* SubToolPanel::GetWindow (void)
+{
+ return this;
+}
+
+
+
+
+sal_Int32 SubToolPanel::GetMinimumWidth (void)
+{
+ return TreeNode::GetMinimumWidth();
+}
+
+
+
+
+void SubToolPanel::ExpandControl (
+ TreeNode* pControl,
+ bool bExpansionState)
+{
+ // Toggle expand status.
+ pControl->Expand (bExpansionState);
+
+ Rearrange ();
+ Invalidate ();
+}
+
+
+
+
+/** This control shows an expansion bar for every control and in a
+ separate area below that expansion area it shows all controls each
+ with its title bar. When there is not enough space then show a
+ scroll bar in the control area.
+*/
+void SubToolPanel::Rearrange (void)
+{
+ Size aRequiredSize (GetRequiredSize());
+ if (aRequiredSize.Width()>0 && aRequiredSize.Height()>0)
+ {
+ Size aAvailableSize (GetOutputSizePixel());
+
+ // Make the children at least as wide as the sub tool panel.
+ if (aRequiredSize.Width() < aAvailableSize.Width())
+ aRequiredSize.Width() = aAvailableSize.Width();
+ mnChildrenWidth = -2*mnHorizontalBorder;
+ mnChildrenWidth += aAvailableSize.Width();
+
+ LayoutChildren();
+
+ mbIsRearrangePending = false;
+ }
+}
+
+
+
+
+Size SubToolPanel::GetRequiredSize (void)
+{
+ // First determine the width of the children. This is the maximum of
+ // the current window width and the individual minimum widths of the
+ // children.
+ int nChildrenWidth (GetSizePixel().Width());
+ unsigned int nCount = mpControlContainer->GetControlCount();
+ unsigned int nIndex;
+ for (nIndex=0; nIndex<nCount; nIndex++)
+ {
+ TreeNode* pChild = mpControlContainer->GetControl (nIndex);
+ int nMinimumWidth (pChild->GetMinimumWidth());
+ if (nMinimumWidth > nChildrenWidth)
+ nChildrenWidth = nMinimumWidth;
+ }
+
+ // Determine the accumulated width of all children when scaled to the
+ // minimum width.
+ nChildrenWidth -= 2*mnHorizontalBorder;
+ Size aTotalSize (nChildrenWidth,
+ 2*mnVerticalBorder + (nCount-1) * mnVerticalGap);
+ for (nIndex=0; nIndex<nCount; nIndex++)
+ {
+ TreeNode* pChild = mpControlContainer->GetControl (nIndex);
+ sal_Int32 nHeight = pChild->GetPreferredHeight(nChildrenWidth);
+ aTotalSize.Height() += nHeight;
+ }
+
+ return aTotalSize;
+}
+
+
+
+
+sal_Int32 SubToolPanel::LayoutChildren (void)
+{
+ // Determine vertical space that can be distributed to sizable children.
+ unsigned int nCount (mpControlContainer->GetControlCount());
+ unsigned int nResizableCount = 0;
+ int nAvailableHeight = GetSizePixel().Height() - 2*mnVerticalBorder;
+ unsigned int nIndex;
+ for (nIndex=0; nIndex<nCount; nIndex++)
+ {
+ TreeNode* pChild = mpControlContainer->GetControl (nIndex);
+ int nControlHeight = pChild->GetPreferredHeight(mnChildrenWidth);
+ if (pChild->IsResizable())
+ nResizableCount++;
+ else
+ nAvailableHeight -= nControlHeight;
+ }
+
+ maStripeList.clear();
+
+ Point aPosition (0,0);
+ aPosition.X() += mnHorizontalBorder;
+ maStripeList.push_back( ::std::pair<int,int>(
+ aPosition.Y(),
+ aPosition.Y() + mnVerticalBorder - 1));
+ aPosition.Y() += mnVerticalBorder;
+
+ // Place the controls one over the other.
+ for (nIndex=0; nIndex<nCount; nIndex++)
+ {
+ if (nIndex > 0)
+ {
+ maStripeList.push_back( ::std::pair<int,int>(
+ aPosition.Y(),
+ aPosition.Y() + mnVerticalGap - 1));
+ aPosition.Y() += mnVerticalGap;
+ }
+ TreeNode* pChild = mpControlContainer->GetControl (nIndex);
+ int nControlHeight = pChild->GetPreferredHeight(mnChildrenWidth);
+ if (pChild->IsResizable())
+ {
+ nControlHeight = nAvailableHeight / nResizableCount;
+ nResizableCount--;
+ }
+ nAvailableHeight -= nControlHeight;
+ pChild->GetWindow()->SetPosSizePixel(
+ aPosition,
+ Size(mnChildrenWidth, nControlHeight));
+ aPosition.Y() += nControlHeight;
+ }
+
+ // If the children do not cover their parent window completely
+ // (regarding the height) we put a filler below that is responsible for
+ // painting the remaining space.
+ int nWindowHeight = GetSizePixel().Height();
+ if (aPosition.Y() < nWindowHeight)
+ {
+ maWindowFiller.SetPosSizePixel (
+ aPosition,
+ Size(mnChildrenWidth, nWindowHeight-aPosition.Y()));
+ maStripeList.push_back( ::std::pair<int,int>(
+ aPosition.Y(),
+ nWindowHeight-1));
+ // maScrollWindowFiller.Show();
+ aPosition.Y() = nWindowHeight;
+ }
+ else
+ maWindowFiller.Hide();
+
+ aPosition.Y() += mnVerticalBorder;
+ mbIsLayoutPending = false;
+
+ return aPosition.Y();
+}
+
+
+
+
+IMPL_LINK(SubToolPanel, WindowEventListener, VclSimpleEvent*, pEvent)
+{
+ if (pEvent!=NULL && pEvent->ISA(VclWindowEvent))
+ {
+ VclWindowEvent* pWindowEvent = static_cast<VclWindowEvent*>(pEvent);
+ switch (pWindowEvent->GetId())
+ {
+ case VCLEVENT_WINDOW_SHOW:
+ case VCLEVENT_WINDOW_HIDE:
+ case VCLEVENT_WINDOW_ACTIVATE:
+ case VCLEVENT_WINDOW_RESIZE:
+ RequestResize();
+ break;
+ }
+ }
+ return 0;
+}
+
+
+
+
+::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible> SubToolPanel::CreateAccessibleObject (
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& )
+{
+ return new ::accessibility::AccessibleTreeNode (
+ *this,
+ ::rtl::OUString::createFromAscii("Sub Task Panel"),
+ ::rtl::OUString::createFromAscii("Sub Task Panel"),
+ ::com::sun::star::accessibility::AccessibleRole::PANEL);
+}
+
+} } // end of namespace ::sd::toolpanel
diff --git a/sd/source/ui/toolpanel/TaskPaneControlFactory.cxx b/sd/source/ui/toolpanel/TaskPaneControlFactory.cxx
new file mode 100755
index 000000000000..4ad610df7f7f
--- /dev/null
+++ b/sd/source/ui/toolpanel/TaskPaneControlFactory.cxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "taskpane/TaskPaneControlFactory.hxx"
+
+#include <vos/diagnose.hxx>
+
+namespace sd { namespace toolpanel {
+
+ControlFactory::ControlFactory (void)
+{
+}
+
+
+
+
+ControlFactory::~ControlFactory (void)
+{
+}
+
+
+
+
+::std::auto_ptr<TreeNode> ControlFactory::CreateControl( ::Window& i_rParent )
+{
+ TreeNode* pNewNode = InternalCreateControl( i_rParent );
+ return ::std::auto_ptr<TreeNode>( pNewNode );
+}
+
+} } // end of namespace ::sd::toolpanel
diff --git a/sd/source/ui/toolpanel/TaskPaneFocusManager.cxx b/sd/source/ui/toolpanel/TaskPaneFocusManager.cxx
new file mode 100644
index 000000000000..48882d0f2f9e
--- /dev/null
+++ b/sd/source/ui/toolpanel/TaskPaneFocusManager.cxx
@@ -0,0 +1,325 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "TaskPaneFocusManager.hxx"
+
+#include <vcl/window.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/event.hxx>
+#include <hash_map>
+
+namespace {
+
+class WindowHash
+{
+public:
+ size_t operator()(const ::Window* argument) const
+ { return reinterpret_cast<unsigned long>(argument); }
+};
+
+class EventDescriptor
+{
+public:
+ EventDescriptor (const KeyCode& rKey, ::Window* pWindow)
+ : maKeyCode(rKey), mpTargetWindow(pWindow) {}
+ KeyCode maKeyCode;
+ ::Window* mpTargetWindow;
+};
+
+} // end of anonymous namespace
+
+
+
+
+namespace sd { namespace toolpanel {
+
+
+
+class FocusManager::LinkMap
+ : public ::std::hash_multimap< ::Window*, EventDescriptor, WindowHash>
+{
+};
+
+
+
+FocusManager* FocusManager::spInstance = NULL;
+
+
+FocusManager& FocusManager::Instance (void)
+{
+ if (spInstance == NULL)
+ {
+ ::vos::OGuard aGuard (::Application::GetSolarMutex());
+ if (spInstance == NULL)
+ spInstance = new FocusManager ();
+ }
+ return *spInstance;
+}
+
+
+
+
+FocusManager::FocusManager (void)
+ : mpLinks(new LinkMap())
+{
+}
+
+
+
+
+FocusManager::~FocusManager (void)
+{
+ Clear();
+}
+
+
+
+
+void FocusManager::Clear (void)
+{
+ if (mpLinks.get() != NULL)
+ {
+ while ( ! mpLinks->empty())
+ {
+ ::Window* pWindow = mpLinks->begin()->first;
+ if (pWindow == NULL)
+ {
+ mpLinks->erase(mpLinks->begin());
+ }
+ else
+ {
+ RemoveLinks(pWindow);
+ }
+ }
+ }
+}
+
+
+
+
+void FocusManager::RegisterUpLink (::Window* pSource, ::Window* pTarget)
+{
+ RegisterLink(pSource, pTarget, KEY_ESCAPE);
+}
+
+
+
+
+void FocusManager::RegisterDownLink (::Window* pSource, ::Window* pTarget)
+{
+ RegisterLink(pSource, pTarget, KEY_RETURN);
+}
+
+
+
+
+void FocusManager::RegisterLink (
+ ::Window* pSource,
+ ::Window* pTarget,
+ const KeyCode& rKey)
+{
+ OSL_ASSERT(pSource!=NULL);
+ OSL_ASSERT(pTarget!=NULL);
+
+ if (pSource==NULL || pTarget==NULL)
+ return;
+
+ // Register this focus manager as event listener at the source window.
+ if (mpLinks->equal_range(pSource).first == mpLinks->end())
+ pSource->AddEventListener (LINK (this, FocusManager, WindowEventListener));
+ mpLinks->insert(LinkMap::value_type(pSource, EventDescriptor(rKey,pTarget)));
+}
+
+
+
+
+void FocusManager::RemoveLinks (
+ ::Window* pSourceWindow,
+ ::Window* pTargetWindow)
+{
+ OSL_ASSERT(pSourceWindow!=NULL);
+ OSL_ASSERT(pTargetWindow!=NULL);
+
+ if (pSourceWindow==NULL || pTargetWindow==NULL)
+ {
+ // This method was called with invalid arguments. To avoid
+ // referencing windows that will soon be deleted we clear *all*
+ // links as an emergency fallback.
+ Clear();
+ return;
+ }
+
+ ::std::pair<LinkMap::iterator,LinkMap::iterator> aCandidates;
+ LinkMap::iterator iCandidate;
+ bool bLoop (mpLinks->size() > 0);
+ while (bLoop)
+ {
+ aCandidates = mpLinks->equal_range(pSourceWindow);
+ if (aCandidates.first == mpLinks->end())
+ {
+ // No links for the source window found -> nothing more to do.
+ bLoop = false;
+ }
+ else
+ {
+ // Set the loop control to false so that when no candidate for
+ // deletion is found the loop is left.
+ bLoop = false;
+ for (iCandidate=aCandidates.first; iCandidate!=aCandidates.second; ++iCandidate)
+ if (iCandidate->second.mpTargetWindow == pTargetWindow)
+ {
+ mpLinks->erase(iCandidate);
+ // One link erased. The iterators have become invalid so
+ // start the search for links to delete anew.
+ bLoop = true;
+ break;
+ }
+ }
+ }
+
+ RemoveUnusedEventListener(pSourceWindow);
+}
+
+
+
+
+void FocusManager::RemoveLinks (::Window* pWindow)
+{
+ OSL_ASSERT(pWindow!=NULL);
+
+ if (pWindow == NULL)
+ {
+ // This method was called with invalid arguments. To avoid
+ // referencing windows that will soon be deleted we clear *all*
+ // links as an emergency fallback.
+ Clear();
+ return;
+ }
+
+ // Make sure that we are not called back for the window.
+ pWindow->RemoveEventListener (LINK (this, FocusManager, WindowEventListener));
+
+ // Remove the links from the given window.
+ ::std::pair<LinkMap::iterator,LinkMap::iterator> aCandidates(mpLinks->equal_range(pWindow));
+ mpLinks->erase(aCandidates.first, aCandidates.second);
+
+ // Remove links to the given window.
+ bool bLinkRemoved;
+ do
+ {
+ bLinkRemoved = false;
+ LinkMap::iterator iLink;
+ for (iLink=mpLinks->begin(); iLink!=mpLinks->end(); ++iLink)
+ {
+ if (iLink->second.mpTargetWindow == pWindow)
+ {
+ RemoveUnusedEventListener(iLink->first);
+ mpLinks->erase(iLink);
+ bLinkRemoved = true;
+ break;
+ }
+ }
+ }
+ while (bLinkRemoved);
+}
+
+
+
+
+void FocusManager::RemoveUnusedEventListener (::Window* pWindow)
+{
+ OSL_ASSERT(pWindow!=NULL);
+
+ if (pWindow == NULL)
+ return;
+
+ // When there are no more links from the window to another window
+ // then remove the event listener from the window.
+ if (mpLinks->find(pWindow) == mpLinks->end())
+ pWindow->RemoveEventListener (LINK (this, FocusManager, WindowEventListener));
+}
+
+
+
+
+bool FocusManager::TransferFocus (
+ ::Window* pSourceWindow,
+ const KeyCode& rKeyCode)
+{
+ bool bSuccess (false);
+
+ OSL_ASSERT(pSourceWindow!=NULL);
+ if (pSourceWindow == NULL)
+ return bSuccess;
+
+ ::std::pair<LinkMap::iterator,LinkMap::iterator> aCandidates (
+ mpLinks->equal_range(pSourceWindow));
+ LinkMap::const_iterator iCandidate;
+ for (iCandidate=aCandidates.first; iCandidate!=aCandidates.second; ++iCandidate)
+ if (iCandidate->second.maKeyCode == rKeyCode)
+ {
+ OSL_ASSERT(iCandidate->second.mpTargetWindow != NULL);
+ iCandidate->second.mpTargetWindow->GrabFocus();
+ bSuccess = true;
+ break;
+ }
+
+ return bSuccess;
+}
+
+
+
+
+IMPL_LINK(FocusManager, WindowEventListener, VclSimpleEvent*, pEvent)
+{
+ if (pEvent!=NULL && pEvent->ISA(VclWindowEvent))
+ {
+ VclWindowEvent* pWindowEvent = static_cast<VclWindowEvent*>(pEvent);
+ switch (pWindowEvent->GetId())
+ {
+ case VCLEVENT_WINDOW_KEYINPUT:
+ {
+ ::Window* pSource = pWindowEvent->GetWindow();
+ KeyEvent* pKeyEvent = static_cast<KeyEvent*>(pWindowEvent->GetData());
+ TransferFocus(pSource, pKeyEvent->GetKeyCode());
+ }
+ break;
+
+ case VCLEVENT_OBJECT_DYING:
+ RemoveLinks(pWindowEvent->GetWindow());
+ break;
+ }
+ }
+ return 1;
+}
+
+
+} } // end of namespace ::sd::toolpanel
diff --git a/sd/source/ui/toolpanel/TaskPaneFocusManager.hxx b/sd/source/ui/toolpanel/TaskPaneFocusManager.hxx
new file mode 100644
index 000000000000..b9b28154dc5b
--- /dev/null
+++ b/sd/source/ui/toolpanel/TaskPaneFocusManager.hxx
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANEL_FOCUS_MANAGER_HXX
+#define SD_TOOLPANEL_FOCUS_MANAGER_HXX
+
+#include <tools/link.hxx>
+
+#include <memory>
+
+class KeyCode;
+class VclSimpleEvent;
+class Window;
+
+namespace sd { namespace toolpanel {
+
+/** On certain key presses the focus is moved from one window to another.
+ For this to work every window that wants its focus managed has to
+ register or be registered and tell where to put the focus on what key
+ press.
+*/
+class FocusManager
+{
+public:
+ /** Return an instance of the focus manager.
+ */
+ static FocusManager& Instance (void);
+
+ /** Register a link from one window to another so that any time the
+ specified key is pressed while the source window is focused, the
+ focus is transferred to the target window.
+ @param pSource
+ The window from which the focus will be transferred.
+ @param pTarget
+ The window to which the focus will be transferred.
+ @param rKey
+ The key for which the focus is transferred from the source
+ window to the target window.
+ */
+ void RegisterLink (
+ ::Window* pSource,
+ ::Window* pTarget,
+ const KeyCode& rKey);
+
+ /** Register a link that will move the focus from the source window to
+ the target window when the source window is focused and KEY_ESCAPE
+ is pressed.
+ @param pSource
+ The window from which the focus will be transferred.
+ @param pTarget
+ The window to which the focus will be transferred.
+ */
+ void RegisterUpLink (::Window* pSource, ::Window* pTarget);
+
+ /** Register a link that will move the focus from the source window to
+ the target window when the source window is focused and KEY_RETURN
+ is pressed.
+ @param pSource
+ The window from which the focus will be transferred.
+ @param pTarget
+ The window to which the focus will be transferred.
+ */
+ void RegisterDownLink (::Window* pSource, ::Window* pTarget);
+
+ /** Remove all links from the source window to the target window. When
+ there are links from the target window to the source window then
+ these are not touced.
+ */
+ void RemoveLinks (
+ ::Window* pSource,
+ ::Window* pTarget);
+
+ /** Let the focus manager transfer the focus from the specified source
+ window to a target window that is determined according the the
+ registered links and the given key code.
+ When there is no rule for this combination of source window and key
+ code then the focus stays where it is.
+ */
+ bool TransferFocus (::Window* pSource, const KeyCode& rCode);
+
+private:
+ static FocusManager* spInstance;
+ class LinkMap;
+ ::std::auto_ptr<LinkMap> mpLinks;
+
+ FocusManager (void);
+ ~FocusManager (void);
+
+ /** Clear the list of focus transfer links. This removes all window
+ listeners.
+ */
+ void Clear (void);
+
+ /** Remove all links from or to the given window.
+ */
+ void RemoveLinks (::Window* pWindow);
+
+ /** Unregister as event listener from the given window when there are no
+ links from this window anymore.
+ */
+ void RemoveUnusedEventListener (::Window* pWindow);
+
+ /** Listen for key events and on KEY_RETURN go down and on
+ KEY_ESCAPE go up.
+ */
+ DECL_LINK(WindowEventListener, VclSimpleEvent*);
+};
+
+} } // end of namespace ::sd::toolpanel
+
+#endif
diff --git a/sd/source/ui/toolpanel/TaskPaneShellManager.cxx b/sd/source/ui/toolpanel/TaskPaneShellManager.cxx
new file mode 100755
index 000000000000..0a9667dd2431
--- /dev/null
+++ b/sd/source/ui/toolpanel/TaskPaneShellManager.cxx
@@ -0,0 +1,183 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "TaskPaneShellManager.hxx"
+
+#include "ViewShellManager.hxx"
+#include <tools/diagnose_ex.h>
+#include <vcl/window.hxx>
+
+#include <algorithm>
+
+namespace sd { namespace toolpanel {
+
+TaskPaneShellManager::TaskPaneShellManager (
+ const ::boost::shared_ptr<ViewShellManager>& rpViewShellManager,
+ const ViewShell& rViewShell)
+ : mpViewShellManager(rpViewShellManager),
+ mrViewShell(rViewShell),
+ maSubShells()
+{
+}
+
+
+
+
+TaskPaneShellManager::~TaskPaneShellManager (void)
+{
+ while ( ! maSubShells.empty())
+ RemoveSubShell(maSubShells.begin()->second.mpShell);
+}
+
+
+
+
+SfxShell* TaskPaneShellManager::CreateShell( ShellId nId, ::Window* , FrameView* )
+{
+ SubShells::const_iterator iShell (maSubShells.find(nId));
+ if (iShell != maSubShells.end())
+ return iShell->second.mpShell;
+ else
+ return NULL;
+}
+
+
+
+
+void TaskPaneShellManager::ReleaseShell (SfxShell* )
+{
+ // Nothing to do.
+}
+
+void TaskPaneShellManager::AddSubShell (
+ ShellId nId,
+ SfxShell* pShell,
+ ::Window* pWindow)
+{
+ if (pShell != NULL)
+ {
+ maSubShells[nId] = ShellDescriptor(pShell,pWindow);
+ if (pWindow != NULL)
+ {
+ pWindow->AddEventListener(LINK(this,TaskPaneShellManager,WindowCallback));
+ if (pWindow->IsReallyVisible())
+ mpViewShellManager->ActivateSubShell(mrViewShell, nId);
+ }
+ else
+ mpViewShellManager->ActivateSubShell(mrViewShell, nId);
+ }
+}
+
+
+
+
+void TaskPaneShellManager::RemoveSubShell (const ShellId i_nShellId)
+{
+ SubShells::iterator pos = maSubShells.find( i_nShellId );
+ ENSURE_OR_RETURN_VOID( pos != maSubShells.end(), "no shell for this ID" );
+ if ( pos->second.mpWindow != NULL )
+ {
+ pos->second.mpWindow->RemoveEventListener( LINK( this, TaskPaneShellManager, WindowCallback ) );
+ }
+ mpViewShellManager->DeactivateSubShell( mrViewShell, pos->first );
+ maSubShells.erase( pos );
+}
+
+
+
+
+void TaskPaneShellManager::RemoveSubShell (const SfxShell* pShell)
+{
+ if (pShell != NULL)
+ {
+ SubShells::iterator iShell;
+ for (iShell=maSubShells.begin(); iShell!=maSubShells.end(); ++iShell)
+ if (iShell->second.mpShell == pShell)
+ {
+ if (iShell->second.mpWindow != NULL)
+ iShell->second.mpWindow->RemoveEventListener(
+ LINK(this,TaskPaneShellManager,WindowCallback));
+ mpViewShellManager->DeactivateSubShell(mrViewShell,iShell->first);
+ maSubShells.erase(iShell);
+ break;
+ }
+ }
+}
+
+
+
+
+void TaskPaneShellManager::MoveToTop (SfxShell* pShell)
+{
+ SubShells::const_iterator iShell;
+ for (iShell=maSubShells.begin(); iShell!=maSubShells.end(); ++iShell)
+ if (iShell->second.mpShell == pShell)
+ {
+ ViewShellManager::UpdateLock aLocker (mpViewShellManager);
+ mpViewShellManager->MoveSubShellToTop(mrViewShell,iShell->first);
+ mpViewShellManager->MoveToTop(mrViewShell);
+ break;
+ }
+}
+
+
+
+
+IMPL_LINK(TaskPaneShellManager, WindowCallback, VclWindowEvent*, pEvent)
+{
+ if (pEvent != NULL)
+ {
+ SubShells::const_iterator iShell;
+ ::Window* pWindow = pEvent->GetWindow();
+ for (iShell=maSubShells.begin(); iShell!=maSubShells.end(); ++iShell)
+ if (iShell->second.mpWindow == pWindow)
+ break;
+ if (iShell != maSubShells.end())
+ switch (pEvent->GetId())
+ {
+ case VCLEVENT_WINDOW_SHOW:
+ mpViewShellManager->ActivateSubShell(mrViewShell,iShell->first);
+ break;
+
+ case VCLEVENT_WINDOW_HIDE:
+ // Do not activate the sub shell. This leads to
+ // problems with shapes currently being in text edit
+ // mode: Deactivating the shell leads to leaving the
+ // text editing mode.
+ // mpViewShellManager->DeactivateSubShell(mrViewShell,iShell->first);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+} } // end of namespace ::sd::toolpanel
diff --git a/sd/source/ui/toolpanel/TaskPaneShellManager.hxx b/sd/source/ui/toolpanel/TaskPaneShellManager.hxx
new file mode 100755
index 000000000000..92e7b6b83b8d
--- /dev/null
+++ b/sd/source/ui/toolpanel/TaskPaneShellManager.hxx
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANEL_TASK_PANE_SHELL_MANAGER_HXX
+#define SD_TOOLPANEL_TASK_PANE_SHELL_MANAGER_HXX
+
+#include "ShellFactory.hxx"
+#include "ViewShellManager.hxx"
+#include <map>
+
+class FrameView;
+class SfxShell;
+class VclWindowEvent;
+class Window;
+
+namespace sd {
+class ViewShell;
+}
+
+namespace sd { namespace toolpanel {
+
+/** The TaskPaneShellManager implements the ViewShellManager::ShellFactory
+ interface. However, it does not create or delete shells. It only
+ gives the ViewShellManager access to the sub shells of the
+ ToolPanelViewShell. Life time control of the sub shells is managed by
+ the sub shells themselves.
+*/
+class TaskPaneShellManager
+ : public ShellFactory<SfxShell>
+{
+public:
+ /** Create a shell manager that manages the stacked shells for the given
+ view shell. It works together with the given view shell manager.
+ */
+ TaskPaneShellManager (
+ const ::boost::shared_ptr<ViewShellManager>& rpViewShellManager,
+ const ViewShell& rViewShell);
+ ~TaskPaneShellManager (void);
+
+ /** Return the requested sub shell.
+ @param nId
+ The id of the requested sub shell.
+ @return
+ When there is no sub shell currently registered under the given
+ id then NULL is returned.
+ */
+ virtual SfxShell* CreateShell (
+ ShellId nId,
+ ::Window* pParentWindow,
+ FrameView* pFrameView = NULL);
+
+ virtual void ReleaseShell (SfxShell* pShell);
+
+ /** Add a sub shell to the set of sub shells managed by the
+ TaskPaneShellManager. Only shells added by this method are returned
+ by CreateShell().
+ */
+ void AddSubShell (ShellId nId, SfxShell* pShell, ::Window* pWindow);
+
+ /** Remove the given shell from the set of sub shells managed by the
+ TaskPaneShellManager. Following calls to CreateShell() will return
+ NULL when this shell is requested.
+ */
+ void RemoveSubShell (const SfxShell* pShell);
+ /** removes the shell given by its ID from the set of sub shells managed by the
+ TaskPaneShellManager. Subsequent calls to CreateShell() will return
+ NULL when this shell is requested.
+ */
+ void RemoveSubShell (const ShellId i_nShellId);
+
+ /** Move the given sub-shell to the top of the local shell stack.
+ Furthermore move the view shell whose sub-shells this class manages
+ to the top of the global shell stack.
+ */
+ void MoveToTop (SfxShell* pShell);
+
+ DECL_LINK(WindowCallback,VclWindowEvent*);
+
+private:
+ ::boost::shared_ptr<ViewShellManager> mpViewShellManager;
+
+ /// The view shell whose sub-shells this class manages.
+ const ViewShell& mrViewShell;
+
+ class ShellDescriptor { public:
+ SfxShell* mpShell;
+ ::Window* mpWindow;
+ ShellDescriptor(void) : mpShell(NULL),mpWindow(NULL){}
+ ShellDescriptor(SfxShell*pShell,::Window*pWindow) : mpShell(pShell),mpWindow(pWindow){}
+ };
+ typedef ::std::map<ShellId,ShellDescriptor> SubShells;
+ SubShells maSubShells;
+};
+
+} } // end of namespace ::sd::toolpanel
+
+#endif
diff --git a/sd/source/ui/toolpanel/TaskPaneTreeNode.cxx b/sd/source/ui/toolpanel/TaskPaneTreeNode.cxx
new file mode 100755
index 000000000000..8c69e12c504d
--- /dev/null
+++ b/sd/source/ui/toolpanel/TaskPaneTreeNode.cxx
@@ -0,0 +1,292 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "taskpane/TaskPaneTreeNode.hxx"
+
+#include "taskpane/ControlContainer.hxx"
+#include "taskpane/TitledControl.hxx"
+
+#include <vector>
+#include <algorithm>
+
+namespace sd { namespace toolpanel {
+
+TreeNode::TreeNode( TreeNode* pParent)
+: mpControlContainer (new ControlContainer(this))
+, mpParent (pParent)
+, maStateChangeListeners()
+{
+}
+
+
+
+
+TreeNode::~TreeNode (void)
+{
+}
+
+
+
+
+void TreeNode::SetParentNode (TreeNode* pNewParent)
+{
+ mpParent = pNewParent;
+ GetWindow()->SetParent (pNewParent->GetWindow());
+}
+
+
+
+
+TreeNode* TreeNode::GetParentNode (void)
+{
+ return mpParent;
+}
+
+
+
+
+::Window* TreeNode::GetWindow (void)
+{
+ return NULL;
+}
+
+
+
+
+const ::Window* TreeNode::GetConstWindow (void) const
+{
+ return const_cast<TreeNode*>(this)->GetWindow();
+}
+
+
+
+
+sal_Int32 TreeNode::GetMinimumWidth (void)
+{
+ sal_Int32 nTotalMinimumWidth = 0;
+ unsigned int nCount = mpControlContainer->GetControlCount();
+ for (unsigned int nIndex=0; nIndex<nCount; nIndex++)
+ {
+ TreeNode* pChild = mpControlContainer->GetControl (nIndex);
+ sal_Int32 nMinimumWidth = pChild->GetMinimumWidth ();
+ if (nMinimumWidth > nTotalMinimumWidth)
+ nTotalMinimumWidth = nMinimumWidth;
+ }
+
+ return nTotalMinimumWidth;;
+}
+
+
+
+
+bool TreeNode::IsResizable (void)
+{
+ return false;
+}
+
+
+
+
+void TreeNode::RequestResize (void)
+{
+ if (mpParent != NULL)
+ mpParent->RequestResize();
+}
+
+
+
+
+ControlContainer& TreeNode::GetControlContainer (void)
+{
+ return *mpControlContainer.get();
+}
+
+
+
+
+bool TreeNode::Expand (bool bExpansionState)
+{
+ bool bExpansionStateChanged (false);
+
+ if (IsExpandable() && IsExpanded()!=bExpansionState)
+ {
+ if (bExpansionState)
+ GetWindow()->Show();
+ else
+ GetWindow()->Hide();
+ bExpansionStateChanged = true;
+
+ FireStateChangeEvent (EID_EXPANSION_STATE_CHANGED);
+ }
+
+ return bExpansionStateChanged;
+}
+
+
+
+
+bool TreeNode::IsExpanded (void) const
+{
+ if (GetConstWindow()!=NULL)
+ return GetConstWindow()->IsVisible();
+ else
+ return false;
+}
+
+
+
+
+bool TreeNode::IsExpandable (void) const
+{
+ return GetConstWindow()!=NULL;
+}
+
+
+
+
+void TreeNode::Show (bool bExpansionState)
+{
+ if (GetWindow() != NULL)
+ {
+ bool bWasShowing (IsShowing());
+ GetWindow()->Show (bExpansionState);
+ if (bWasShowing != bExpansionState)
+ FireStateChangeEvent (EID_SHOWING_STATE_CHANGED);
+ }
+}
+
+
+
+
+bool TreeNode::IsShowing (void) const
+{
+ const ::Window* pWindow = const_cast<TreeNode*>(this)->GetWindow();
+ if (pWindow != NULL)
+ return pWindow->IsVisible();
+ else
+ return false;
+}
+
+
+
+
+TaskPaneShellManager* TreeNode::GetShellManager (void)
+{
+ if (mpParent != NULL)
+ return mpParent->GetShellManager();
+ else
+ return NULL;
+}
+
+
+
+
+::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible> TreeNode::GetAccessibleObject (void)
+{
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible> xAccessible;
+ ::Window* pWindow = GetWindow();
+ if (pWindow != NULL)
+ {
+ xAccessible = pWindow->GetAccessible(FALSE);
+ if ( ! xAccessible.is())
+ {
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible> xParent;
+ if (pWindow!=NULL && pWindow->GetAccessibleParentWindow()!=NULL)
+ xParent = pWindow->GetAccessibleParentWindow()->GetAccessible();
+ xAccessible = CreateAccessibleObject(xParent);
+ pWindow->SetAccessible(xAccessible);
+ }
+ }
+ return xAccessible;
+}
+
+
+
+
+::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible> TreeNode::CreateAccessibleObject (
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& )
+{
+ if (GetWindow() != NULL)
+ return GetWindow()->CreateAccessible();
+ else
+ return NULL;
+}
+
+
+
+
+void TreeNode::AddStateChangeListener (const Link& rListener)
+{
+ if (::std::find (
+ maStateChangeListeners.begin(),
+ maStateChangeListeners.end(),
+ rListener) == maStateChangeListeners.end())
+ {
+ maStateChangeListeners.push_back(rListener);
+ }
+}
+
+
+
+
+void TreeNode::FireStateChangeEvent (
+ TreeNodeStateChangeEventId eEventId,
+ TreeNode* pChild) const
+{
+ TreeNodeStateChangeEvent aEvent (*this, eEventId, pChild);
+ StateChangeListenerContainer aContainerCopy(maStateChangeListeners);
+ StateChangeListenerContainer::iterator aLink (aContainerCopy.begin());
+ StateChangeListenerContainer::iterator aEnd (aContainerCopy.end());
+ while (aLink!=aEnd)
+ {
+ aLink->Call (&aEvent);
+ ++aLink;
+ }
+}
+
+
+
+TreeNodeStateChangeEvent::TreeNodeStateChangeEvent (
+ const TreeNode& rNode,
+ TreeNodeStateChangeEventId eEventId,
+ TreeNode* pChild)
+ : mrSource(rNode),
+ meEventId(eEventId),
+ mpChild(pChild)
+{
+}
+
+
+} } // end of namespace ::sd::toolpanel
diff --git a/sd/source/ui/toolpanel/TestMenu.cxx b/sd/source/ui/toolpanel/TestMenu.cxx
new file mode 100755
index 000000000000..a8f0b6df7893
--- /dev/null
+++ b/sd/source/ui/toolpanel/TestMenu.cxx
@@ -0,0 +1,318 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "TestMenu.hxx"
+
+#include "taskpane/TaskPaneControlFactory.hxx"
+
+#include <vcl/image.hxx>
+#include <vcl/svapp.hxx>
+
+namespace sd { namespace toolpanel {
+
+#ifdef SHOW_COLOR_MENU
+/** This factory class is used to create instances of ColorMenu. It can be
+ extended so that its constructor stores arguments that later are passed
+ to new ColorMenu objects.
+*/
+class ColorMenuFactory
+ : public ControlFactory
+{
+protected:
+ virtual TreeNode* InternalCreateControl( ::Window& i_rParent )
+ {
+ return new ColorMenu (&i_rParent);
+ }
+};
+
+
+ColorMenu::ColorMenu (::Window* i_pParent)
+ : Window (i_pParent),
+ TreeNode(NULL),
+ maSet (this),
+ mnPreferredColumnCount(2)
+{
+ WinBits aStyle =
+ WB_ITEMBORDER
+ | WB_DOUBLEBORDER
+ | WB_NAMEFIELD
+ | WB_FLATVALUESET
+ | WB_TABSTOP
+ | WB_VSCROLL;
+
+ maSet.SetStyle (maSet.GetStyle() | aStyle);
+ maSet.SetExtraSpacing(2);
+
+ Fill ();
+ maSet.Show();
+ i_pParent->Resize();
+}
+
+
+
+
+ColorMenu::~ColorMenu (void)
+{
+}
+
+
+::std::auto_ptr<ControlFactory> ColorMenu::CreateControlFactory (void)
+{
+ return ::std::auto_ptr<ControlFactory>(new ColorMenuFactory());
+}
+
+
+/** The preferred size depends on the preferred number of columns, the
+ number of items, and the size of the items.
+*/
+Size ColorMenu::GetPreferredSize (void)
+{
+ Size aItemSize = maSet.CalcItemSizePixel (Size());
+ Size aPreferredWindowSize = maSet.CalcWindowSizePixel (
+ aItemSize,
+ (USHORT)mnPreferredColumnCount,
+ (USHORT)CalculateRowCount (aItemSize, (USHORT)mnPreferredColumnCount));
+ return aPreferredWindowSize;
+}
+
+
+
+
+sal_Int32 ColorMenu::GetPreferredWidth (sal_Int32 nHeight)
+{
+ sal_Int32 nPreferredWidth = 0;
+ if (maSet.GetItemCount() > 0)
+ {
+ Image aImage = maSet.GetItemImage(maSet.GetItemId(0));
+ Size aItemSize = maSet.CalcItemSizePixel (aImage.GetSizePixel());
+ if (nHeight>0 && aItemSize.Height()>0)
+ {
+ int nRowCount = nHeight / aItemSize.Height();
+ if (nRowCount <= 0)
+ nRowCount = 1;
+ int nColumnCount = (maSet.GetItemCount() + nRowCount-1)
+ / nRowCount;
+ nPreferredWidth = nColumnCount * aItemSize.Width();
+ }
+ }
+
+ return nPreferredWidth;
+}
+
+
+
+
+sal_Int32 ColorMenu::GetPreferredHeight (sal_Int32 nWidth)
+{
+ sal_Int32 nPreferredHeight = 0;
+ if (maSet.GetItemCount()>0)
+ {
+ Image aImage = maSet.GetItemImage(maSet.GetItemId(0));
+ Size aItemSize = maSet.CalcItemSizePixel (aImage.GetSizePixel());
+ if (nWidth>0 && aItemSize.Width()>0)
+ {
+ int nColumnCount = nWidth / aItemSize.Width();
+ if (nColumnCount <= 0)
+ nColumnCount = 1;
+ else if (nColumnCount > 4)
+ nColumnCount = 4;
+ int nRowCount = (maSet.GetItemCount() + nColumnCount-1)
+ / nColumnCount;
+ nPreferredHeight = nRowCount * aItemSize.Height();
+ }
+ }
+ return nPreferredHeight;
+}
+
+
+
+
+bool ColorMenu::IsResizable (void)
+{
+ return true;
+}
+
+
+
+
+::Window* ColorMenu::GetWindow (void)
+{
+ return this;
+}
+
+
+
+
+void ColorMenu::Resize (void)
+{
+ ::Window::Resize();
+ Size aWindowSize = GetOutputSizePixel();
+ maSet.SetPosSizePixel (Point(0,0), aWindowSize);
+ if (IsVisible() && aWindowSize.Width() > 0)
+ {
+ // maSet.SetPosSizePixel (
+ // Point (0,0),
+ // aWindowSize);
+
+ // Calculate the number of rows and columns.
+ if (maSet.GetItemCount() > 0)
+ {
+ Image aImage = maSet.GetItemImage(maSet.GetItemId(0));
+ Size aItemSize = maSet.CalcItemSizePixel (
+ aImage.GetSizePixel());
+ int nColumnCount = aWindowSize.Width() / 30;
+ if (nColumnCount < 1)
+ nColumnCount = 1;
+ else if (nColumnCount > 4)
+ nColumnCount = 4;
+
+ USHORT nRowCount = (USHORT)CalculateRowCount (aItemSize, nColumnCount);
+
+ maSet.SetColCount ((USHORT)nColumnCount);
+ maSet.SetLineCount (nRowCount);
+ }
+ }
+
+}
+
+
+
+
+int ColorMenu::CalculateRowCount (const Size&, int nColumnCount)
+{
+ int nRowCount = 0;
+
+ if (maSet.GetItemCount()>0 && nColumnCount>0)
+ {
+ nRowCount = GetOutputSizePixel().Height() / 30;
+ if (nRowCount < 1)
+ nRowCount = 1;
+ }
+
+ return nRowCount;
+}
+
+
+
+
+void ColorMenu::Fill (void)
+{
+ const StyleSettings& rSettings (
+ Application::GetSettings().GetStyleSettings());
+ maSet.Clear();
+ maSet.SetItemWidth (30);
+ maSet.SetItemHeight (30);
+ USHORT i = 0;
+ maSet.InsertItem (++i, rSettings.GetFaceColor());
+ maSet.SetItemText (i, String::CreateFromAscii("FaceColor"));
+ maSet.InsertItem (++i, rSettings.GetCheckedColor());
+ maSet.SetItemText (i, String::CreateFromAscii("CheckedColor"));
+ maSet.InsertItem (++i, rSettings.GetLightColor());
+ maSet.SetItemText (i, String::CreateFromAscii("LightColor"));
+ maSet.InsertItem (++i, rSettings.GetLightBorderColor());
+ maSet.SetItemText (i, String::CreateFromAscii("LightBorderColor"));
+ maSet.InsertItem (++i, rSettings.GetShadowColor());
+ maSet.SetItemText (i, String::CreateFromAscii("ShadowColor"));
+ maSet.InsertItem (++i, rSettings.GetDarkShadowColor());
+ maSet.SetItemText (i, String::CreateFromAscii("DarkShadowColor"));
+ maSet.InsertItem (++i, rSettings.GetButtonTextColor());
+ maSet.SetItemText (i, String::CreateFromAscii("ButtonTextColor"));
+ maSet.InsertItem (++i, rSettings.GetRadioCheckTextColor());
+ maSet.SetItemText (i, String::CreateFromAscii("RadioCheckTextColor"));
+ maSet.InsertItem (++i, rSettings.GetGroupTextColor());
+ maSet.SetItemText (i, String::CreateFromAscii("GroupTextColor"));
+ maSet.InsertItem (++i, rSettings.GetLabelTextColor());
+ maSet.SetItemText (i, String::CreateFromAscii("LabelTextColor"));
+ maSet.InsertItem (++i, rSettings.GetInfoTextColor());
+ maSet.SetItemText (i, String::CreateFromAscii("InfoTextColor"));
+ maSet.InsertItem (++i, rSettings.GetWindowColor());
+ maSet.SetItemText (i, String::CreateFromAscii("WindowColor"));
+ maSet.InsertItem (++i, rSettings.GetWindowTextColor());
+ maSet.SetItemText (i, String::CreateFromAscii("WindowTextColor"));
+ maSet.InsertItem (++i, rSettings.GetDialogColor());
+ maSet.SetItemText (i, String::CreateFromAscii("DialogColor"));
+ maSet.InsertItem (++i, rSettings.GetDialogTextColor());
+ maSet.SetItemText (i, String::CreateFromAscii("DialogTextColor"));
+ maSet.InsertItem (++i, rSettings.GetWorkspaceColor());
+ maSet.SetItemText (i, String::CreateFromAscii("WorkspaceColor"));
+ maSet.InsertItem (++i, rSettings.GetFieldColor());
+ maSet.SetItemText (i, String::CreateFromAscii("FieldColor"));
+ maSet.InsertItem (++i, rSettings.GetFieldTextColor());
+ maSet.SetItemText (i, String::CreateFromAscii("FieldTextColor"));
+ maSet.InsertItem (++i, rSettings.GetActiveColor());
+ maSet.SetItemText (i, String::CreateFromAscii("ActiveColor"));
+ maSet.InsertItem (++i, rSettings.GetActiveColor2());
+ maSet.SetItemText (i, String::CreateFromAscii("ActiveColor2"));
+ maSet.InsertItem (++i, rSettings.GetActiveTextColor());
+ maSet.SetItemText (i, String::CreateFromAscii("ActiveTextColor"));
+ maSet.InsertItem (++i, rSettings.GetActiveBorderColor());
+ maSet.SetItemText (i, String::CreateFromAscii("ActiveBorderColor"));
+ maSet.InsertItem (++i, rSettings.GetDeactiveColor());
+ maSet.SetItemText (i, String::CreateFromAscii("DeactiveColor"));
+ maSet.InsertItem (++i, rSettings.GetDeactiveColor2());
+ maSet.SetItemText (i, String::CreateFromAscii("DeactiveColor2"));
+ maSet.InsertItem (++i, rSettings.GetDeactiveTextColor());
+ maSet.SetItemText (i, String::CreateFromAscii("DeactiveTextColor"));
+ maSet.InsertItem (++i, rSettings.GetDeactiveBorderColor());
+ maSet.SetItemText (i, String::CreateFromAscii("DeactiveBorderColor"));
+ maSet.InsertItem (++i, rSettings.GetHighlightColor());
+ maSet.SetItemText (i, String::CreateFromAscii("HighlightColor"));
+ maSet.InsertItem (++i, rSettings.GetHighlightTextColor());
+ maSet.SetItemText (i, String::CreateFromAscii("HighlightTextColor"));
+ maSet.InsertItem (++i, rSettings.GetDisableColor());
+ maSet.SetItemText (i, String::CreateFromAscii("DisableColor"));
+ maSet.InsertItem (++i, rSettings.GetHelpColor());
+ maSet.SetItemText (i, String::CreateFromAscii("HelpColor"));
+ maSet.InsertItem (++i, rSettings.GetHelpTextColor());
+ maSet.SetItemText (i, String::CreateFromAscii("HelpTextColor"));
+ maSet.InsertItem (++i, rSettings.GetMenuColor());
+ maSet.SetItemText (i, String::CreateFromAscii("MenuColor"));
+ maSet.InsertItem (++i, rSettings.GetMenuBarColor());
+ maSet.SetItemText (i, String::CreateFromAscii("MenuBarColor"));
+ maSet.InsertItem (++i, rSettings.GetMenuBorderColor());
+ maSet.SetItemText (i, String::CreateFromAscii("MenuBorderColor"));
+ maSet.InsertItem (++i, rSettings.GetMenuTextColor());
+ maSet.SetItemText (i, String::CreateFromAscii("MenuTextColor"));
+ maSet.InsertItem (++i, rSettings.GetMenuHighlightColor());
+ maSet.SetItemText (i, String::CreateFromAscii("MenuHighlightColor"));
+ maSet.InsertItem (++i, rSettings.GetMenuHighlightTextColor());
+ maSet.SetItemText (i, String::CreateFromAscii("MenuHighlightTextColor"));
+ maSet.InsertItem (++i, rSettings.GetLinkColor());
+ maSet.SetItemText (i, String::CreateFromAscii("LinkColor"));
+ maSet.InsertItem (++i, rSettings.GetVisitedLinkColor());
+ maSet.SetItemText (i, String::CreateFromAscii("VisitedLinkColor"));
+ maSet.InsertItem (++i, rSettings.GetHighlightLinkColor());
+ maSet.SetItemText (i, String::CreateFromAscii("HighlightLinkColor"));
+ maSet.InsertItem (++i, rSettings.GetFontColor());
+ maSet.SetItemText (i, String::CreateFromAscii("FontColor"));
+}
+#endif
+
+} } // end of namespace ::sd::toolpanel
diff --git a/sd/source/ui/toolpanel/TestMenu.hxx b/sd/source/ui/toolpanel/TestMenu.hxx
new file mode 100755
index 000000000000..0c4b3bfe6530
--- /dev/null
+++ b/sd/source/ui/toolpanel/TestMenu.hxx
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TASKPANE_COLOR_MENU_HXX
+#define SD_TASKPANE_COLOR_MENU_HXX
+
+#include "taskpane/TaskPaneTreeNode.hxx"
+#include <svtools/valueset.hxx>
+#include <vcl/window.hxx>
+
+#include <memory>
+
+
+namespace sd { namespace toolpanel {
+
+class ControlFactory;
+
+#ifdef SHOW_COLOR_MENU
+
+/** This demo menu shows the colors that are available from the
+ StyleSettings.
+*/
+class ColorMenu
+ : public ::Window,
+ public TreeNode
+{
+public:
+ ColorMenu (::Window* i_pParent);
+ virtual ~ColorMenu (void);
+
+ static ::std::auto_ptr<ControlFactory> CreateControlFactory (void);
+
+ // From ILayoutableWindow
+ virtual Size GetPreferredSize (void);
+ virtual sal_Int32 GetPreferredWidth (sal_Int32 nHeight);
+ virtual sal_Int32 GetPreferredHeight (sal_Int32 nWidth);
+ virtual bool IsResizable (void);
+ virtual ::Window* GetWindow (void);
+
+ // From ::Window
+ virtual void Resize (void);
+
+ using Window::GetWindow;
+
+private:
+ ValueSet maSet;
+ int mnPreferredColumnCount;
+
+ /** Depending on the given number of columns and the item size
+ calculate the number of rows that are necessary to display all
+ items.
+ */
+ int CalculateRowCount (const Size& rItemSize, int nColumnCount);
+ void Fill (void);
+};
+#endif
+
+} } // end of namespace ::sd::toolpanel
+
+#endif
diff --git a/sd/source/ui/toolpanel/TestPanel.cxx b/sd/source/ui/toolpanel/TestPanel.cxx
new file mode 100755
index 000000000000..044b40dcdb4f
--- /dev/null
+++ b/sd/source/ui/toolpanel/TestPanel.cxx
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "TestPanel.hxx"
+#include "taskpane/ScrollPanel.hxx"
+#include "taskpane/TaskPaneControlFactory.hxx"
+
+#include <vcl/lstbox.hxx>
+#include <vcl/button.hxx>
+
+namespace sd { namespace toolpanel {
+
+#ifdef SHOW_TEST_PANEL
+/** This factory class is used to create instances of TestPanel. It can be
+ extended so that its constructor stores arguments that later are passed
+ to new TestPanel objects.
+*/
+class TestPanelFactory
+ : public ControlFactory
+{
+protected:
+ virtual TreeNode* InternalCreateControl( ::Window& i_rParent )
+ {
+ return new TestPanel (i_rParent);
+ }
+};
+
+
+class Wrapper
+ : public TreeNode
+{
+public:
+ Wrapper (
+ TreeNode* pParent,
+ Size aPreferredSize,
+ ::Window* pWrappedControl,
+ bool bIsResizable)
+ : TreeNode (pParent),
+ maPreferredSize(aPreferredSize),
+ mpWrappedControl(pWrappedControl),
+ mbIsResizable(bIsResizable)
+ {
+ mpWrappedControl->Show();
+ }
+ virtual ~Wrapper (void)
+ {
+ delete mpWrappedControl;
+ }
+
+ virtual Size GetPreferredSize (void)
+ {
+ return maPreferredSize;
+ }
+ virtual sal_Int32 GetPreferredWidth (sal_Int32 )
+ {
+ return maPreferredSize.Width();
+ }
+ virtual sal_Int32 GetPreferredHeight (sal_Int32 )
+ {
+ return maPreferredSize.Height();
+ }
+ virtual ::Window* GetWindow (void)
+ {
+ return mpWrappedControl;
+ }
+ virtual bool IsResizable (void)
+ {
+ return mbIsResizable;
+ }
+ virtual bool IsExpandable (void) const
+ {
+ return false;
+ }
+ virtual bool IsExpanded (void) const
+ {
+ return true;
+ }
+
+private:
+ Size maPreferredSize;
+ ::Window* mpWrappedControl;
+ bool mbIsResizable;
+};
+
+
+TestPanel::TestPanel (::Window& i_rParent)
+ : SubToolPanel (i_rParent)
+{
+ // Create a scrollable panel with two list boxes.
+ ScrollPanel* pScrollPanel = new ScrollPanel (this);
+
+ ListBox* pBox = new ListBox (pScrollPanel->GetWindow());
+ int i;
+ for (i=1; i<=20; i++)
+ {
+ XubString aString (XubString::CreateFromAscii("Text "));
+ aString.Append (XubString::CreateFromInt32(i));
+ aString.Append (XubString::CreateFromAscii("/20"));
+ pBox->InsertEntry (aString);
+ }
+ pScrollPanel->AddControl (
+ ::std::auto_ptr<TreeNode>(new Wrapper (
+ pScrollPanel, Size (200,300), pBox, true)),
+ String::CreateFromAscii ("First ListBox"),
+ 0);
+
+ pBox = new ListBox (pScrollPanel->GetWindow());
+ for (i=1; i<=20; i++)
+ {
+ XubString aString (XubString::CreateFromAscii("More Text "));
+ aString.Append (XubString::CreateFromInt32(i));
+ aString.Append (XubString::CreateFromAscii("/20"));
+ pBox->InsertEntry (aString);
+ }
+ pScrollPanel->AddControl (
+ ::std::auto_ptr<TreeNode>(new Wrapper (
+ pScrollPanel, Size (200,300), pBox, true)),
+ String::CreateFromAscii ("Second ListBox"),
+ 0);
+
+ AddControl (::std::auto_ptr<TreeNode>(pScrollPanel));
+
+ // Add a fixed size button.
+ Button* pButton = new OKButton (this);
+ AddControl (
+ ::std::auto_ptr<TreeNode>(new Wrapper (
+ this, Size (100,30), pButton, false)),
+ String::CreateFromAscii ("Button Area"),
+ 0);
+}
+
+
+
+
+
+TestPanel::~TestPanel (void)
+{
+}
+
+std::auto_ptr<ControlFactory> TestPanel::CreateControlFactory (void)
+{
+ return std::auto_ptr<ControlFactory>(new TestPanelFactory());
+}
+#endif
+
+
+} } // end of namespace ::sd::toolpanel
diff --git a/sd/source/ui/toolpanel/TestPanel.hxx b/sd/source/ui/toolpanel/TestPanel.hxx
new file mode 100755
index 000000000000..494e5086b179
--- /dev/null
+++ b/sd/source/ui/toolpanel/TestPanel.hxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TASKPANE_TEST_PANEL_HXX
+#define SD_TASKPANE_TEST_PANEL_HXX
+
+#include "taskpane/SubToolPanel.hxx"
+
+
+namespace sd { namespace toolpanel {
+
+class ControlFactory;
+class TreeNode;
+
+#ifdef SHOW_TEST_PANEL
+
+/** This panel demonstrates how to create a panel for the task pane.
+*/
+class TestPanel
+ : public SubToolPanel
+{
+public:
+ TestPanel (::Window& i_rParent);
+ virtual ~TestPanel (void);
+
+ static std::auto_ptr<ControlFactory> CreateControlFactory (void);
+};
+
+#endif
+
+} } // end of namespace ::sd::toolpanel
+
+#endif
diff --git a/sd/source/ui/toolpanel/TitleBar.cxx b/sd/source/ui/toolpanel/TitleBar.cxx
new file mode 100755
index 000000000000..de49b7a6abb5
--- /dev/null
+++ b/sd/source/ui/toolpanel/TitleBar.cxx
@@ -0,0 +1,585 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "taskpane/TitleBar.hxx"
+
+#include "ControlContainerDescriptor.hxx"
+#include "tools/IconCache.hxx"
+#include "AccessibleTreeNode.hxx"
+#include <vcl/decoview.hxx>
+#include <vcl/window.hxx>
+#include <vcl/virdev.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include "sdresid.hxx"
+#include <vcl/bitmap.hxx>
+#include <vcl/lineinfo.hxx>
+#include <vcl/bitmapex.hxx>
+#include <tools/color.hxx>
+#include <svx/xdash.hxx>
+#include <svl/itemset.hxx>
+#include <svx/xlndsit.hxx>
+#include <svx/xlineit0.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdpool.hxx>
+#include <svtools/colorcfg.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xfillit0.hxx>
+#include "res_bmp.hrc"
+
+
+namespace sd { namespace toolpanel {
+
+const int TitleBar::snIndentationWidth = 16;
+
+TitleBar::TitleBar ( ::Window* pParent, const String& rsTitle, TitleBarType eType, bool bIsExpandable)
+: ::Window (pParent, WB_TABSTOP)
+, TreeNode(this)
+, meType(eType)
+, msTitle(rsTitle)
+, mbExpanded(false)
+, mbFocused(false)
+, mpDevice(new VirtualDevice (*this))
+, mbIsExpandable (bIsExpandable)
+{
+ EnableMapMode (FALSE);
+
+ SetBackground (Wallpaper());
+
+ // Change the mouse pointer shape so that it acts as a mouse over effect.
+ switch (meType)
+ {
+ case TBT_SUB_CONTROL_HEADLINE:
+ if (mbIsExpandable)
+ SetPointer (POINTER_REFHAND);
+ break;
+ }
+}
+
+
+
+
+TitleBar::~TitleBar (void)
+{
+}
+
+
+
+
+Size TitleBar::GetPreferredSize (void)
+{
+ int nWidth = GetOutputSizePixel().Width();
+ Rectangle aTitleBarBox (
+ CalculateTitleBarBox(
+ CalculateTextBoundingBox(nWidth, true),
+ nWidth));
+
+ return aTitleBarBox.GetSize();
+}
+
+
+
+
+sal_Int32 TitleBar::GetPreferredWidth (sal_Int32 )
+{
+ Rectangle aTitleBarBox (
+ CalculateTitleBarBox(
+ CalculateTextBoundingBox(0, true),
+ 0));
+ return aTitleBarBox.GetWidth();
+}
+
+
+
+
+sal_Int32 TitleBar::GetPreferredHeight (sal_Int32 nWidth)
+{
+ Rectangle aTitleBarBox (
+ CalculateTitleBarBox(
+ CalculateTextBoundingBox(nWidth, true),
+ nWidth));
+
+ return aTitleBarBox.GetHeight();
+}
+
+
+
+
+bool TitleBar::IsResizable (void)
+{
+ return true;
+}
+
+
+
+
+::Window* TitleBar::GetWindow (void)
+{
+ return this;
+}
+
+
+
+
+sal_Int32 TitleBar::GetMinimumWidth (void)
+{
+ return 20;
+}
+
+
+
+
+void TitleBar::Paint (const Rectangle& rBoundingBox)
+{
+ mpDevice->SetMapMode(GetMapMode());
+ mpDevice->SetOutputSize (GetOutputSizePixel());
+ mpDevice->SetSettings(GetSettings());
+ mpDevice->SetDrawMode(GetDrawMode());
+
+ switch (meType)
+ {
+ case TBT_SUB_CONTROL_HEADLINE:
+ PaintSubPanelHeadLineBar ();
+ break;
+ }
+
+ DrawOutDev (
+ Point(0,0),
+ GetOutputSizePixel(),
+ Point(0,0),
+ GetOutputSizePixel(),
+ *mpDevice);
+
+ ::Window::Paint (rBoundingBox);
+}
+
+
+
+
+bool TitleBar::Expand (bool bFlag)
+{
+ bool bExpansionStateChanged (bFlag!=IsExpanded());
+ mbExpanded = bFlag;
+ Invalidate ();
+ return bExpansionStateChanged;
+}
+
+
+
+
+bool TitleBar::IsExpanded (void) const
+{
+ return mbExpanded;
+}
+
+
+void TitleBar::SetEnabledState(bool bFlag)
+{
+ if(bFlag)
+ Enable();
+ else
+ Disable();
+ Invalidate ();
+}
+
+
+
+
+void TitleBar::GetFocus()
+{
+ mbFocused = true;
+ Invalidate();
+}
+
+
+
+
+void TitleBar::LoseFocus()
+{
+ mbFocused = false;
+ Invalidate();
+}
+
+
+
+
+bool TitleBar::HasExpansionIndicator (void) const
+{
+ bool bHasExpansionIndicator (false);
+ if (mbIsExpandable)
+ {
+ switch (meType)
+ {
+ case TBT_SUB_CONTROL_HEADLINE:
+ bHasExpansionIndicator = true;
+ break;
+ }
+ }
+ return bHasExpansionIndicator;
+}
+
+
+
+
+Image TitleBar::GetExpansionIndicator (void) const
+{
+ Image aIndicator;
+ bool bHighContrastMode (GetSettings().GetStyleSettings().GetHighContrastMode() != 0);
+ if (mbIsExpandable)
+ {
+ USHORT nResourceId = 0;
+ switch (meType)
+ {
+ case TBT_SUB_CONTROL_HEADLINE:
+ if (mbExpanded)
+ if (bHighContrastMode)
+ nResourceId = BMP_COLLAPSE_H;
+ else
+ nResourceId = BMP_COLLAPSE;
+ else
+ if (bHighContrastMode)
+ nResourceId = BMP_EXPAND_H;
+ else
+ nResourceId = BMP_EXPAND;
+
+ aIndicator = IconCache::Instance().GetIcon(nResourceId);
+ break;
+ }
+ }
+
+ return aIndicator;
+}
+
+
+
+
+void TitleBar::PaintSubPanelHeadLineBar (void)
+{
+ int nWidth (GetOutputSizePixel().Width());
+ Rectangle aTextBox (CalculateTextBoundingBox (nWidth, true));
+
+ Rectangle aTitleBarBox (CalculateTitleBarBox(aTextBox, nWidth));
+ int nVerticalOffset = -aTitleBarBox.Top();
+ aTitleBarBox.Top() += nVerticalOffset;
+ aTitleBarBox.Bottom() += nVerticalOffset;
+ aTextBox.Top() += nVerticalOffset;
+ aTextBox.Bottom() += nVerticalOffset;
+
+ PaintBackground (aTitleBarBox);
+ Rectangle aFocusBox (PaintExpansionIndicator (aTextBox));
+ PaintText (aTextBox);
+
+ aFocusBox.Union (aTextBox);
+ aFocusBox.Left() -= 2;
+ aFocusBox.Right() += 1;
+ PaintFocusIndicator (aFocusBox);
+}
+
+
+
+
+void TitleBar::PaintFocusIndicator (const Rectangle& rTextBox)
+{
+ if (mbFocused)
+ {
+ Rectangle aTextPixelBox (mpDevice->LogicToPixel (rTextBox));
+ mpDevice->EnableMapMode (FALSE);
+ Rectangle aBox (rTextBox);
+ aBox.Top() -= 1;
+ aBox.Bottom() += 1;
+
+ mpDevice->SetFillColor ();
+
+ mpDevice->DrawRect (aTextPixelBox);
+
+ LineInfo aDottedStyle (LINE_DASH);
+ aDottedStyle.SetDashCount (0);
+ aDottedStyle.SetDotCount (1);
+ aDottedStyle.SetDotLen (1);
+ aDottedStyle.SetDistance (1);
+
+ mpDevice->SetLineColor (COL_BLACK);
+ mpDevice->DrawPolyLine (Polygon(aTextPixelBox), aDottedStyle);
+ mpDevice->EnableMapMode (FALSE);
+ }
+ else
+ HideFocus ();
+}
+
+
+
+
+Rectangle TitleBar::PaintExpansionIndicator (const Rectangle& rTextBox)
+{
+ Rectangle aExpansionIndicatorArea;
+
+ if (HasExpansionIndicator())
+ {
+ Image aImage = GetExpansionIndicator();
+ int nHeight (aImage.GetSizePixel().Height());
+ if (nHeight > 0)
+ {
+ Point aPosition (
+ 0,
+ rTextBox.Top() + (GetTextHeight() - nHeight) / 2);
+ if (meType == TBT_SUB_CONTROL_HEADLINE)
+ aPosition.X() += 3;
+ mpDevice->DrawImage (aPosition, aImage);
+
+ aExpansionIndicatorArea = Rectangle (
+ aPosition, aImage.GetSizePixel());
+ }
+ }
+
+ return aExpansionIndicatorArea;
+}
+
+
+
+
+void TitleBar::PaintText (const Rectangle& rTextBox)
+{
+ mpDevice->DrawText (rTextBox, msTitle, GetTextStyle());
+}
+
+
+
+
+USHORT TitleBar::GetTextStyle (void)
+{
+ if(IsEnabled())
+ {
+ return TEXT_DRAW_LEFT
+ | TEXT_DRAW_TOP
+ | TEXT_DRAW_MULTILINE
+ | TEXT_DRAW_WORDBREAK;
+ }
+ else
+ {
+ return TEXT_DRAW_DISABLE;
+ }
+}
+
+
+
+void TitleBar::PaintBackground (const Rectangle& rTitleBarBox)
+{
+ // Fill a slightly rounded rectangle.
+ Color aFillColor (GetFillColor());
+ Color aLineColor (GetLineColor());
+
+ switch (meType)
+ {
+ case TBT_SUB_CONTROL_HEADLINE:
+ {
+ Color aColor (GetSettings().GetStyleSettings().GetDialogColor());
+ if (mbExpanded)
+ {
+ // Make the color a little bit darker.
+ aColor.SetRed(UINT8(((UINT16)aColor.GetRed()) * 8 / 10));
+ aColor.SetGreen(UINT8(((UINT16)aColor.GetGreen()) * 8 / 10));
+ aColor.SetBlue(UINT8(((UINT16)aColor.GetBlue()) * 8 / 10));
+ }
+
+ mpDevice->SetFillColor (aColor);
+ mpDevice->SetLineColor ();
+ mpDevice->DrawRect (rTitleBarBox);
+
+ // Erase the four corner pixels to make the rectangle appear
+ // rounded.
+ mpDevice->SetLineColor (
+ GetSettings().GetStyleSettings().GetWindowColor());
+ mpDevice->DrawPixel (
+ rTitleBarBox.TopLeft());
+ mpDevice->DrawPixel (
+ Point(rTitleBarBox.Right(), rTitleBarBox.Top()));
+ mpDevice->DrawPixel (
+ Point(rTitleBarBox.Left(), rTitleBarBox.Bottom()));
+ mpDevice->DrawPixel (
+ Point(rTitleBarBox.Right(), rTitleBarBox.Bottom()));
+ }
+ break;
+ }
+}
+
+
+
+
+Rectangle TitleBar::CalculateTextBoundingBox (
+ int nAvailableWidth,
+ bool bEmphasizeExpanded)
+{
+ // Show the title of expanded controls in bold font.
+ const Font& rOriginalFont (GetFont());
+ Font aFont (rOriginalFont);
+ if (bEmphasizeExpanded && mbExpanded)
+ aFont.SetWeight (WEIGHT_BOLD);
+ else
+ aFont.SetWeight (WEIGHT_NORMAL);
+ mpDevice->SetFont (aFont);
+
+ // Use the natural width of the text when no width is given.
+ if (nAvailableWidth == 0)
+ nAvailableWidth = GetTextWidth (msTitle);
+
+ Rectangle aTextBox (
+ Point(0,0),
+ Size (nAvailableWidth,
+ GetSettings().GetStyleSettings().GetTitleHeight()));
+ aTextBox.Top() += (aTextBox.GetHeight() - GetTextHeight()) / 2;
+ if (HasExpansionIndicator())
+ aTextBox.Left() += snIndentationWidth;
+ else
+ aTextBox.Left() += 3;
+ aTextBox.Right() -= 1;
+
+ aTextBox = mpDevice->GetTextRect (aTextBox, msTitle, GetTextStyle());
+
+ return aTextBox;
+}
+
+
+
+
+Rectangle TitleBar::CalculateTitleBarBox (
+ const Rectangle& rTextBox,
+ int nWidth)
+{
+ Rectangle aTitleBarBox (rTextBox);
+
+ switch (meType)
+ {
+ case TBT_SUB_CONTROL_HEADLINE:
+ aTitleBarBox.Top() -= 3;
+ aTitleBarBox.Bottom() += 3;
+ break;
+
+ }
+ aTitleBarBox.Left() = 0;
+ if (aTitleBarBox.GetWidth() < nWidth)
+ aTitleBarBox.Right() = nWidth-1;
+
+ return aTitleBarBox;
+}
+
+
+
+
+void TitleBar::MouseMove (const MouseEvent& )
+{
+}
+
+
+
+
+void TitleBar::MouseButtonDown (const MouseEvent& )
+{
+ // Do not forward to parent window so that the mouse button handler of
+ // the docking window is not invoked.
+}
+
+
+
+
+void TitleBar::MouseButtonUp (const MouseEvent& )
+{
+ // Do not forward to parent window so that the mouse button handler of
+ // the docking window is not invoked.
+}
+
+
+
+
+void TitleBar::DataChanged (const DataChangedEvent& rEvent)
+{
+ ::Window::DataChanged (rEvent);
+
+ switch (rEvent.GetType())
+ {
+ case DATACHANGED_SETTINGS:
+ if ((rEvent.GetFlags() & SETTINGS_STYLE) == 0)
+ break;
+ SetSettings(Application::GetSettings());
+ mpDevice.reset(new VirtualDevice (*this));
+
+ // fall through.
+
+ case DATACHANGED_FONTS:
+ case DATACHANGED_FONTSUBSTITUTION:
+ {
+ const StyleSettings& rStyleSettings (GetSettings().GetStyleSettings());
+
+ // Font.
+ Font aFont = rStyleSettings.GetAppFont();
+ if (IsControlFont())
+ aFont.Merge(GetControlFont());
+ SetZoomedPointFont(aFont);
+
+ // Color.
+ Color aColor;
+ if (IsControlForeground())
+ aColor = GetControlForeground();
+ else
+ aColor = rStyleSettings.GetButtonTextColor();
+ SetTextColor(aColor);
+ SetTextFillColor();
+
+ Resize();
+ Invalidate();
+ }
+ break;
+ }
+}
+
+
+
+
+String TitleBar::GetTitle (void) const
+{
+ return msTitle;
+}
+
+
+
+
+::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible > TitleBar::CreateAccessibleObject (
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& )
+{
+ return new ::accessibility::AccessibleTreeNode(
+ *this,
+ GetTitle(),
+ GetTitle(),
+ ::com::sun::star::accessibility::AccessibleRole::LABEL);
+}
+
+
+} } // end of namespace ::sd::toolpanel
diff --git a/sd/source/ui/toolpanel/TitledControl.cxx b/sd/source/ui/toolpanel/TitledControl.cxx
new file mode 100755
index 000000000000..e83e6c47c10a
--- /dev/null
+++ b/sd/source/ui/toolpanel/TitledControl.cxx
@@ -0,0 +1,432 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "taskpane/TitledControl.hxx"
+
+#include "AccessibleTreeNode.hxx"
+#include "taskpane/ControlContainer.hxx"
+#include "TaskPaneFocusManager.hxx"
+#include "taskpane/TaskPaneControlFactory.hxx"
+#include <vcl/ctrl.hxx>
+#include <vcl/svapp.hxx>
+
+
+namespace sd { namespace toolpanel {
+
+
+TitledControl::TitledControl (
+ TreeNode* pParent,
+ ::std::auto_ptr<TreeNode> pControl,
+ const String& rTitle,
+ const ClickHandler& rClickHandler,
+ TitleBar::TitleBarType eType)
+ : ::Window (pParent->GetWindow(), WB_TABSTOP),
+ TreeNode(pParent),
+ msTitle(rTitle),
+ mbVisible(true),
+ mpUserData(NULL),
+ mpClickHandler(new ClickHandler(rClickHandler))
+{
+ mpControlContainer->AddControl (::std::auto_ptr<TreeNode> (
+ new TitleBar (this, rTitle, eType, pControl->IsExpandable())));
+ pControl->SetParentNode (this);
+ mpControlContainer->AddControl (pControl);
+
+ FocusManager::Instance().RegisterDownLink( GetTitleBar()->GetWindow(), GetControl()->GetWindow() );
+ FocusManager::Instance().RegisterUpLink( GetControl()->GetWindow(), GetTitleBar()->GetWindow() );
+
+ SetBackground (Wallpaper());
+
+ GetTitleBar()->GetWindow()->Show ();
+ GetTitleBar()->GetWindow()->AddEventListener (
+ LINK(this,TitledControl,WindowEventListener));
+
+ UpdateStates ();
+}
+
+
+
+
+TitledControl::~TitledControl (void)
+{
+ GetTitleBar()->GetWindow()->RemoveEventListener (
+ LINK(this,TitledControl,WindowEventListener));
+}
+
+
+
+
+Size TitledControl::GetPreferredSize (void)
+{
+ Size aPreferredSize;
+ if (GetControl() != NULL)
+ {
+ aPreferredSize = GetControl()->GetPreferredSize();
+ if ( ! IsExpanded())
+ aPreferredSize.Height() = 0;
+ }
+ else
+ aPreferredSize = Size (GetSizePixel().Width(), 0);
+ if (aPreferredSize.Width() == 0)
+ aPreferredSize.Width() = 300;
+ aPreferredSize.Height() += GetTitleBar()->GetPreferredHeight(
+ aPreferredSize.Width());
+
+ return aPreferredSize;
+}
+
+
+
+
+sal_Int32 TitledControl::GetPreferredWidth (sal_Int32 nHeight)
+{
+ int nPreferredWidth = 0;
+ if (GetControl() != NULL)
+ nPreferredWidth = GetControl()->GetPreferredWidth(
+ nHeight - GetTitleBar()->GetWindow()->GetSizePixel().Height());
+ else
+ nPreferredWidth = GetSizePixel().Width();
+ if (nPreferredWidth == 0)
+ nPreferredWidth = 300;
+
+ return nPreferredWidth;
+}
+
+
+
+
+sal_Int32 TitledControl::GetPreferredHeight (sal_Int32 nWidth)
+{
+ int nPreferredHeight = 0;
+ if (IsExpanded() && GetControl()!=NULL)
+ nPreferredHeight = GetControl()->GetPreferredHeight(nWidth);
+ nPreferredHeight += GetTitleBar()->GetPreferredHeight(nWidth);
+
+ return nPreferredHeight;
+}
+
+
+
+
+bool TitledControl::IsResizable (void)
+{
+ return IsExpanded()
+ && GetControl()->IsResizable();
+}
+
+
+
+
+::Window* TitledControl::GetWindow (void)
+{
+ return this;
+}
+
+
+
+
+void TitledControl::Resize (void)
+{
+ Size aWindowSize (GetOutputSizePixel());
+
+ int nTitleBarHeight
+ = GetTitleBar()->GetPreferredHeight(aWindowSize.Width());
+ GetTitleBar()->GetWindow()->SetPosSizePixel (
+ Point (0,0),
+ Size (aWindowSize.Width(), nTitleBarHeight));
+
+
+ TreeNode* pControl = GetControl();
+ if (pControl != NULL
+ && pControl->GetWindow() != NULL
+ && pControl->GetWindow()->IsVisible())
+ {
+ pControl->GetWindow()->SetPosSizePixel (
+ Point (0,nTitleBarHeight),
+ Size (aWindowSize.Width(), aWindowSize.Height()-nTitleBarHeight));
+ }
+}
+
+
+
+
+void TitledControl::GetFocus (void)
+{
+ ::Window::GetFocus();
+ if (GetTitleBar() != NULL)
+ GetTitleBar()->GrabFocus();
+}
+
+
+
+
+void TitledControl::KeyInput (const KeyEvent& rEvent)
+{
+ KeyCode nCode = rEvent.GetKeyCode();
+ if (nCode == KEY_SPACE)
+ {
+ // Toggle the expansion state of the control (when toggling is
+ // supported.) The focus remains on this control.
+ GetParentNode()->GetControlContainer().SetExpansionState (
+ this,
+ ControlContainer::ES_TOGGLE);
+ }
+ else if (nCode == KEY_RETURN)
+ {
+ // Return, also called enter, enters the control and puts the
+ // focus to the first child. If the control is not yet
+ // expanded then do that first.
+ GetParentNode()->GetControlContainer().SetExpansionState (
+ this,
+ ControlContainer::ES_EXPAND);
+
+ if ( ! FocusManager::Instance().TransferFocus(this,nCode))
+ {
+ // When already expanded then put focus on first child.
+ TreeNode* pControl = GetControl();
+ if (pControl!=NULL && IsExpanded())
+ if (pControl->GetWindow() != NULL)
+ pControl->GetWindow()->GrabFocus();
+ }
+ }
+ else if (nCode == KEY_ESCAPE)
+ {
+ if ( ! FocusManager::Instance().TransferFocus(this,nCode))
+ // Put focus to parent.
+ GetParent()->GrabFocus();
+ }
+ else
+ Window::KeyInput (rEvent);
+}
+
+
+
+
+const String& TitledControl::GetTitle (void) const
+{
+ return msTitle;
+}
+
+
+
+
+bool TitledControl::Expand (bool bExpanded)
+{
+ bool bExpansionStateChanged (false);
+
+ if (IsExpandable() && IsEnabled())
+ {
+ if (GetTitleBar()->IsExpanded() != bExpanded)
+ bExpansionStateChanged |= GetTitleBar()->Expand (bExpanded);
+ // Get the control. Use the bExpanded parameter as argument to
+ // indicate that a control is created via its factory only when it
+ // is to be expanded. When it is collapsed this is not necessary.
+ TreeNode* pControl = GetControl();
+ if (pControl != NULL
+ && GetControl()->IsExpanded() != bExpanded)
+ {
+ bExpansionStateChanged |= pControl->Expand (bExpanded);
+ }
+ if (bExpansionStateChanged)
+ UpdateStates();
+ }
+
+ return bExpansionStateChanged;
+}
+
+
+
+
+bool TitledControl::IsExpandable (void) const
+{
+ const TreeNode* pControl = GetConstControl();
+ if (pControl != NULL)
+ return pControl->IsExpandable();
+ else
+ // When a control factory is given but the control has not yet been
+ // created we assume that the control is expandable.
+ return true;
+}
+
+
+
+
+bool TitledControl::IsExpanded (void) const
+{
+ const TreeNode* pControl = GetConstControl();
+ if (pControl != NULL)
+ return pControl->IsExpanded();
+ else
+ return false;
+}
+
+void TitledControl::SetEnabledState(bool bFlag)
+{
+ if (!bFlag)
+ {
+ GetParentNode()->GetControlContainer().SetExpansionState (
+ this,
+ ControlContainer::ES_COLLAPSE);
+ Disable();
+ }
+ else
+ {
+/*
+ GetParentNode()->GetControlContainer().SetExpansionState (
+ this,
+ ControlContainer::ES_EXPAND);
+*/
+ Enable();
+ }
+
+ GetTitleBar()->SetEnabledState(bFlag);
+}
+
+
+
+bool TitledControl::IsShowing (void) const
+{
+ return mbVisible;
+}
+
+
+
+
+void TitledControl::Show (bool bVisible)
+{
+ if (mbVisible != bVisible)
+ {
+ mbVisible = bVisible;
+ UpdateStates ();
+ }
+}
+
+
+
+
+void TitledControl::UpdateStates (void)
+{
+ if (mbVisible)
+ GetWindow()->Show();
+ else
+ GetWindow()->Hide();
+
+ TreeNode* pControl = GetControl();
+ if (pControl!=NULL && pControl->GetWindow() != NULL)
+ {
+ if (IsVisible() && IsExpanded())
+ pControl->GetWindow()->Show();
+ else
+ pControl->GetWindow()->Hide();
+ }
+}
+
+
+
+
+IMPL_LINK(TitledControl, WindowEventListener,
+ VclSimpleEvent*, pEvent)
+{
+ if (pEvent!=NULL && pEvent->ISA(VclWindowEvent))
+ {
+ VclWindowEvent* pWindowEvent = static_cast<VclWindowEvent*>(pEvent);
+ switch (pWindowEvent->GetId())
+ {
+ case VCLEVENT_WINDOW_MOUSEBUTTONUP:
+ if (IsEnabled())
+ (*mpClickHandler)(*this);
+ break;
+ }
+ }
+ return 0;
+}
+
+
+
+
+TreeNode* TitledControl::GetControl (void)
+{
+ return mpControlContainer->GetControl(1);
+}
+
+
+
+
+const TreeNode* TitledControl::GetConstControl () const
+{
+ return const_cast<TitledControl*>(this)->GetControl();
+}
+
+
+
+
+TitleBar* TitledControl::GetTitleBar (void)
+{
+ return static_cast<TitleBar*>(mpControlContainer->GetControl(0));
+}
+
+
+
+
+::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible> TitledControl::CreateAccessibleObject (
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& )
+{
+ return new ::accessibility::AccessibleTreeNode(
+ *this,
+ GetTitle(),
+ GetTitle(),
+ ::com::sun::star::accessibility::AccessibleRole::LIST_ITEM);
+}
+
+
+
+
+//===== TitledControlStandardClickHandler =====================================
+
+TitledControlStandardClickHandler::TitledControlStandardClickHandler (
+ ControlContainer& rControlContainer,
+ ControlContainer::ExpansionState eExpansionState)
+ : mrControlContainer(rControlContainer),
+ meExpansionState(eExpansionState)
+{
+}
+
+
+
+
+void TitledControlStandardClickHandler::operator () (TitledControl& rTitledControl)
+{
+ // Toggle expansion.
+ mrControlContainer.SetExpansionState (&rTitledControl, meExpansionState);
+}
+
+} } // end of namespace ::sd::toolpanel
diff --git a/sd/source/ui/toolpanel/ToolPanel.cxx b/sd/source/ui/toolpanel/ToolPanel.cxx
new file mode 100755
index 000000000000..6dbcae52547a
--- /dev/null
+++ b/sd/source/ui/toolpanel/ToolPanel.cxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_sd.hxx"
+
+#include "ToolPanel.hxx"
+#include "MethodGuard.hxx"
+#include <taskpane/TaskPaneTreeNode.hxx>
+
+/** === begin UNO includes === **/
+#include <com/sun/star/lang/DisposedException.hpp>
+/** === end UNO includes === **/
+
+#include <vcl/window.hxx>
+
+//......................................................................................................................
+namespace sd { namespace toolpanel
+{
+//......................................................................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::uno::UNO_SET_THROW;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::uno::RuntimeException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::lang::DisposedException;
+ using ::com::sun::star::awt::XWindow;
+ using ::com::sun::star::accessibility::XAccessible;
+ /** === end UNO using === **/
+
+ typedef MethodGuard< ToolPanel > ToolPanelGuard;
+
+ //==================================================================================================================
+ //= ToolPanel
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ ToolPanel::ToolPanel( ::std::auto_ptr< TreeNode >& i_rControl )
+ :ToolPanel_Base( m_aMutex )
+ ,m_pControl( i_rControl )
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ToolPanel::~ToolPanel()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanel::checkDisposed()
+ {
+ if ( m_pControl.get() == NULL )
+ throw DisposedException( ::rtl::OUString(), *this );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XWindow > SAL_CALL ToolPanel::getWindow() throw (RuntimeException)
+ {
+ ToolPanelGuard aGuard( *this );
+ return Reference< XWindow >( m_pControl->GetWindow()->GetComponentInterface(), UNO_QUERY_THROW );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XAccessible > SAL_CALL ToolPanel::createAccessible( const Reference< XAccessible >& i_rParentAccessible ) throw (RuntimeException)
+ {
+ ToolPanelGuard aGuard( *this );
+ Reference< XAccessible > xAccessible( m_pControl->GetWindow()->GetAccessible( FALSE ) );
+ if ( !xAccessible.is() )
+ {
+ xAccessible.set( m_pControl->CreateAccessibleObject( i_rParentAccessible ) );
+ m_pControl->GetWindow()->SetAccessible( xAccessible );
+ }
+ return xAccessible;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL ToolPanel::disposing()
+ {
+ m_pControl.reset();
+ }
+
+//......................................................................................................................
+} } // namespace sd::toolpanel
+//......................................................................................................................
diff --git a/sd/source/ui/toolpanel/ToolPanel.hxx b/sd/source/ui/toolpanel/ToolPanel.hxx
new file mode 100644
index 000000000000..2fe4a64c71be
--- /dev/null
+++ b/sd/source/ui/toolpanel/ToolPanel.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANEL_HXX
+#define SD_TOOLPANEL_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/ui/XToolPanel.hpp>
+/** === end UNO includes === **/
+
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase1.hxx>
+
+#include <memory>
+
+//......................................................................................................................
+namespace sd { namespace toolpanel
+{
+//......................................................................................................................
+
+ class TreeNode;
+
+ //==================================================================================================================
+ //= ToolPanel
+ //==================================================================================================================
+ typedef ::cppu::WeakComponentImplHelper1 < ::com::sun::star::ui::XToolPanel
+ > ToolPanel_Base;
+ class ToolPanel :public ::cppu::BaseMutex
+ ,public ToolPanel_Base
+ {
+ public:
+ ToolPanel(
+ ::std::auto_ptr< TreeNode >& i_rControl
+ );
+
+ // XToolPanel
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > SAL_CALL getWindow() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL createAccessible( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& ParentAccessible ) throw (::com::sun::star::uno::RuntimeException);
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing();
+
+ ::osl::Mutex& getMutex() { return m_aMutex; }
+ void checkDisposed();
+
+ protected:
+ ~ToolPanel();
+
+ private:
+ ::std::auto_ptr< TreeNode > m_pControl;
+ };
+
+//......................................................................................................................
+} } // namespace sd::toolpanel
+//......................................................................................................................
+
+#endif // SD_TOOLPANEL_HXX
diff --git a/sd/source/ui/toolpanel/ToolPanelDescriptor.hxx b/sd/source/ui/toolpanel/ToolPanelDescriptor.hxx
new file mode 100644
index 000000000000..4ac31ef53e23
--- /dev/null
+++ b/sd/source/ui/toolpanel/ToolPanelDescriptor.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOL_PANEL_DESCRIPTOR_HXX
+#define SD_TOOL_PANEL_DESCRIPTOR_HXX
+
+#include <tools/string.hxx>
+#include <tools/gen.hxx>
+#include <memory>
+
+class Window;
+
+namespace sd { namespace toolpanel {
+
+
+/** Collection of information the describes entries of the tool
+ panel. A descriptor owns the control it is associated with.
+*/
+class ToolPanelDescriptor
+{
+public:
+ /** Create a new descriptor for the given control.
+ @param pControl
+ */
+ ToolPanelDescriptor (::std::auto_ptr< ::Window> pControl,
+ const String& rTitle);
+
+ ~ToolPanelDescriptor (void);
+
+ /** Return the height of the title bar.
+ @return
+ The title bar height is returned in pixels.
+ */
+ int GetTitleBarHeight (void) const;
+
+
+ void SetPositionAndSize (const Point& aPosition,
+ const Size& aSize);
+ void SetPositionAndSize (const Rectangle& aBox);
+ void SetWeight (double nWeight);
+
+ Window* GetControl (void) const;
+ const String& GetTitle (void) const;
+ const Rectangle& GetTitleBox (void) const;
+ Rectangle GetPositionAndSize (void) const;
+ double GetWeight (void) const;
+
+ int GetTotalHeight (void) const;
+ int GetWindowHeight (void) const;
+
+private:
+ ::std::auto_ptr< ::Window> mpControl;
+ String msTitle;
+ Rectangle maTitleBox;
+ double mnWeight;
+ int mnTotalHeight;
+
+ /// Do not use! Assignment operator is not supported.
+ const ToolPanelDescriptor& operator= (
+ const ToolPanelDescriptor& aDescriptor);
+};
+
+} } // end of namespace ::sd::toolpanel
+
+#endif
diff --git a/sd/source/ui/toolpanel/ToolPanelFactory.cxx b/sd/source/ui/toolpanel/ToolPanelFactory.cxx
new file mode 100644
index 000000000000..db4602c991d0
--- /dev/null
+++ b/sd/source/ui/toolpanel/ToolPanelFactory.cxx
@@ -0,0 +1,255 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_sd.hxx"
+
+#include "taskpane/ToolPanelViewShell.hxx"
+#include "framework/FrameworkHelper.hxx"
+#include "PaneChildWindows.hxx"
+#include "ViewShellBase.hxx"
+#include "app.hrc"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/ui/XUIElementFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+/** === end UNO includes === **/
+
+#include <sfx2/frame.hxx>
+#include <vcl/svapp.hxx>
+#include <vos/mutex.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <cppuhelper/implbase3.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+
+//......................................................................................................................
+namespace sd { namespace toolpanel
+{
+//......................................................................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::uno::UNO_SET_THROW;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::uno::RuntimeException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::uno::XComponentContext;
+ using ::com::sun::star::ui::XUIElementFactory;
+ using ::com::sun::star::ui::XUIElement;
+ using ::com::sun::star::beans::PropertyValue;
+ using ::com::sun::star::container::NoSuchElementException;
+ using ::com::sun::star::lang::IllegalArgumentException;
+ using ::com::sun::star::lang::XServiceInfo;
+ using ::com::sun::star::lang::XInitialization;
+ using ::com::sun::star::frame::XFrame;
+ using ::com::sun::star::awt::XWindow;
+ /** === end UNO using === **/
+
+ //==================================================================================================================
+ //= ToolPanelFactory
+ //==================================================================================================================
+ typedef ::cppu::WeakImplHelper3 < XUIElementFactory
+ , XServiceInfo
+ , XInitialization
+ > ToolPanelFactory_Base;
+ class ToolPanelFactory : public ToolPanelFactory_Base
+ {
+ public:
+ ToolPanelFactory( const Reference< XComponentContext >& i_rContext );
+
+ // XUIElementFactory
+ virtual Reference< XUIElement > SAL_CALL createUIElement( const ::rtl::OUString& ResourceURL, const Sequence< PropertyValue >& Args ) throw (NoSuchElementException, IllegalArgumentException, RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (RuntimeException);
+ virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException);
+ virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException);
+
+ protected:
+ virtual ~ToolPanelFactory();
+
+ private:
+ const Reference< XComponentContext > m_xContext;
+ };
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XInterface > SAL_CALL ToolPanelFactory_createInstance( const Reference< XComponentContext >& i_rContext )
+ {
+ return Reference< XInterface >( *new ToolPanelFactory( i_rContext ) );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::rtl::OUString ToolPanelFactory_getImplementationName() throw(RuntimeException)
+ {
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.drawing.ToolPanelFactory" ) );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL ToolPanelFactory_getSupportedServiceNames (void)
+ throw (RuntimeException)
+ {
+ const ::rtl::OUString sServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DefaultToolPanelFactory" ) );
+ return Sequence< ::rtl::OUString >( &sServiceName, 1 );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ToolPanelFactory::ToolPanelFactory( const Reference< XComponentContext >& i_rContext )
+ :m_xContext( i_rContext )
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ToolPanelFactory::~ToolPanelFactory()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XUIElement > SAL_CALL ToolPanelFactory::createUIElement( const ::rtl::OUString& i_rResourceURL, const Sequence< PropertyValue >& i_rArgs ) throw (NoSuchElementException, IllegalArgumentException, RuntimeException)
+ {
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+
+ const PanelId ePanelId( toolpanel::GetStandardPanelId( i_rResourceURL ) );
+ if ( ePanelId == PID_UNKNOWN )
+ throw NoSuchElementException( i_rResourceURL, *this );
+
+ const ::comphelper::NamedValueCollection aArgs( i_rArgs );
+ const Reference< XFrame > xDocFrame( aArgs.getOrDefault( "Frame", Reference< XFrame >() ) );
+ const Reference< XWindow > xParentWindow( aArgs.getOrDefault( "ParentWindow", Reference< XWindow >() ) );
+ if ( !xDocFrame.is() || !xParentWindow.is() )
+ throw IllegalArgumentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "For creating a standard tool panel, a Frame and a Parent window are needed." ) ),
+ *this,
+ 2
+ );
+
+ // look up the Sfx(View)Frame for the given XFrame
+ SfxViewFrame* pViewFrame = NULL;
+ for ( SfxFrame* pFrame = SfxFrame::GetFirst();
+ pFrame != NULL;
+ pFrame = SfxFrame::GetNext( *pFrame )
+ )
+ {
+ if ( pFrame->GetFrameInterface() == xDocFrame )
+ {
+ pViewFrame = pFrame->GetCurrentViewFrame();
+ break;
+ }
+ }
+
+ if ( !pViewFrame || !pViewFrame->HasChildWindow( SID_TASKPANE ) )
+ throw IllegalArgumentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Illegal frame." ) ),
+ *this,
+ 2
+ );
+
+ // retrieve the task pane
+ ToolPanelChildWindow* pToolPanelWindow( dynamic_cast< ToolPanelChildWindow* >( pViewFrame->GetChildWindow( SID_TASKPANE ) ) );
+ if ( !pToolPanelWindow )
+ throw IllegalArgumentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No Impress document, or no Impress Task Pane." ) ),
+ *this,
+ 2
+ );
+
+ // retrieve the ViewShellBase, and the view shell of the task pane
+ ViewShellBase* pViewShellBase = dynamic_cast< ViewShellBase* >( pViewFrame->GetViewShell() );
+ ::boost::shared_ptr< framework::FrameworkHelper > pFrameworkHelper;
+ if ( pViewShellBase )
+ pFrameworkHelper = framework::FrameworkHelper::Instance( *pViewShellBase );
+ ::boost::shared_ptr< ViewShell > pViewShell;
+ if ( pFrameworkHelper.get() )
+ pViewShell = pFrameworkHelper->GetViewShell( framework::FrameworkHelper::msRightPaneURL );
+ ToolPanelViewShell* pToolPanelShell = dynamic_cast< ToolPanelViewShell* >( pViewShell.get() );
+
+ if ( !pToolPanelShell )
+ throw IllegalArgumentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Wrong document type." ) ),
+ *this,
+ 2
+ );
+
+ ::Window* pParentWindow = VCLUnoHelper::GetWindow( xParentWindow );
+ if ( !pParentWindow || !pToolPanelShell->IsPanelAnchorWindow( *pParentWindow ) )
+ throw IllegalArgumentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unsupported parent window." ) ),
+ *this,
+ 2
+ );
+
+ return pToolPanelShell->CreatePanelUIElement( xDocFrame, i_rResourceURL );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL ToolPanelFactory::getImplementationName( ) throw (RuntimeException)
+ {
+ return ToolPanelFactory_getImplementationName();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Bool SAL_CALL ToolPanelFactory::supportsService( const ::rtl::OUString& i_rServiceName ) throw (RuntimeException)
+ {
+ const Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() );
+ for ( const ::rtl::OUString* pSupported = aSupported.getConstArray();
+ pSupported != aSupported.getConstArray() + aSupported.getLength();
+ ++pSupported
+ )
+ if ( *pSupported == i_rServiceName )
+ return sal_True;
+
+ return sal_False;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL ToolPanelFactory::getSupportedServiceNames( ) throw (RuntimeException)
+ {
+ return ToolPanelFactory_getSupportedServiceNames();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL ToolPanelFactory::initialize( const Sequence< Any >& i_rArguments ) throw (Exception, RuntimeException)
+ {
+ ::comphelper::NamedValueCollection aArgs( i_rArguments );
+ (void)aArgs;
+ // TODO
+ }
+
+//......................................................................................................................
+} } // namespace sd::toolpanel
+//......................................................................................................................
diff --git a/sd/source/ui/toolpanel/ToolPanelUIElement.cxx b/sd/source/ui/toolpanel/ToolPanelUIElement.cxx
new file mode 100644
index 000000000000..e81f683bcfa7
--- /dev/null
+++ b/sd/source/ui/toolpanel/ToolPanelUIElement.cxx
@@ -0,0 +1,134 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_sd.hxx"
+
+#include "ToolPanelUIElement.hxx"
+#include "MethodGuard.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/ui/UIElementType.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+/** === end UNO includes === **/
+
+#include <tools/diagnose_ex.h>
+
+//......................................................................................................................
+namespace sd { namespace toolpanel
+{
+//......................................................................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::uno::UNO_SET_THROW;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::uno::RuntimeException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::frame::XFrame;
+ using ::com::sun::star::lang::XComponent;
+ using ::com::sun::star::ui::XToolPanel;
+ using ::com::sun::star::lang::DisposedException;
+ /** === end UNO using === **/
+ namespace UIElementType = ::com::sun::star::ui::UIElementType;
+
+ typedef MethodGuard< ToolPanelUIElement > UIElementMethodGuard;
+
+ //==================================================================================================================
+ //= ToolPanelUIElement
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ ToolPanelUIElement::ToolPanelUIElement( const Reference< XFrame >& i_rFrame, const ::rtl::OUString& i_rResourceURL,
+ const Reference< XToolPanel >& i_rToolPanel )
+ :ToolPanelUIElement_Base( m_aMutex )
+ ,m_xFrame( i_rFrame )
+ ,m_sResourceURL( i_rResourceURL )
+ ,m_xToolPanel( i_rToolPanel )
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ToolPanelUIElement::~ToolPanelUIElement()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void ToolPanelUIElement::checkDisposed()
+ {
+ if ( !m_xToolPanel.is() )
+ throw DisposedException( ::rtl::OUString(), *this );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XFrame > SAL_CALL ToolPanelUIElement::getFrame() throw (RuntimeException)
+ {
+ UIElementMethodGuard aGuard( *this );
+ return m_xFrame;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL ToolPanelUIElement::getResourceURL() throw (RuntimeException)
+ {
+ UIElementMethodGuard aGuard( *this );
+ return m_sResourceURL;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Int16 SAL_CALL ToolPanelUIElement::getType() throw (RuntimeException)
+ {
+ UIElementMethodGuard aGuard( *this );
+ return UIElementType::TOOLPANEL;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XInterface > SAL_CALL ToolPanelUIElement::getRealInterface( ) throw (RuntimeException)
+ {
+ UIElementMethodGuard aGuard( *this );
+ return m_xToolPanel.get();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL ToolPanelUIElement::disposing()
+ {
+ try
+ {
+ Reference< XComponent > xPanelComponent( m_xToolPanel, UNO_QUERY_THROW );
+ xPanelComponent->dispose();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+//......................................................................................................................
+} } // namespace sd::toolpanel
+//......................................................................................................................
diff --git a/sd/source/ui/toolpanel/ToolPanelUIElement.hxx b/sd/source/ui/toolpanel/ToolPanelUIElement.hxx
new file mode 100644
index 000000000000..0a74b7bd449e
--- /dev/null
+++ b/sd/source/ui/toolpanel/ToolPanelUIElement.hxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANELUIELEMENT_HXX
+#define SD_TOOLPANELUIELEMENT_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/ui/XUIElement.hpp>
+#include <com/sun/star/ui/XToolPanel.hpp>
+/** === end UNO includes === **/
+
+#include <cppuhelper/compbase1.hxx>
+#include <cppuhelper/basemutex.hxx>
+
+#include <memory>
+
+//......................................................................................................................
+namespace sd { namespace toolpanel
+{
+//......................................................................................................................
+
+ class TreeNode;
+
+ //==================================================================================================================
+ //= ToolPanelUIElement
+ //==================================================================================================================
+ typedef ::cppu::WeakComponentImplHelper1 < ::com::sun::star::ui::XUIElement
+ > ToolPanelUIElement_Base;
+ class ToolPanelUIElement :public ::cppu::BaseMutex
+ ,public ToolPanelUIElement_Base
+ {
+ public:
+ ToolPanelUIElement(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& i_rFrame,
+ const ::rtl::OUString& i_rResourceURL,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XToolPanel >& i_rToolPanel
+ );
+
+ // XUIElement
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > SAL_CALL getFrame() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getResourceURL() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int16 SAL_CALL getType() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getRealInterface( ) throw (::com::sun::star::uno::RuntimeException);
+
+ void checkDisposed();
+ ::osl::Mutex& getMutex() { return m_aMutex; }
+
+ protected:
+ virtual ~ToolPanelUIElement();
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing();
+
+ private:
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > m_xFrame;
+ const ::rtl::OUString m_sResourceURL;
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XToolPanel > m_xToolPanel;
+ };
+
+//......................................................................................................................
+} } // namespace sd::toolpanel
+//......................................................................................................................
+
+#endif // SD_TOOLPANELUIELEMENT_HXX
diff --git a/sd/source/ui/toolpanel/ToolPanelViewShell.cxx b/sd/source/ui/toolpanel/ToolPanelViewShell.cxx
new file mode 100755
index 000000000000..c62faf29ca50
--- /dev/null
+++ b/sd/source/ui/toolpanel/ToolPanelViewShell.cxx
@@ -0,0 +1,900 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "taskpane/ToolPanelViewShell.hxx"
+
+#include "TaskPaneShellManager.hxx"
+#include "TaskPaneFocusManager.hxx"
+#include "taskpane/TaskPaneControlFactory.hxx"
+#include "controls/MasterPagesPanel.hxx"
+#include "LayoutMenu.hxx"
+#include "DrawDocShell.hxx"
+#include "controls/TableDesignPanel.hxx"
+#include "controls/CustomAnimationPanel.hxx"
+#include "controls/SlideTransitionPanel.hxx"
+#include "controls/MasterPagesSelector.hxx"
+#include "ToolPanel.hxx"
+#include "ToolPanelUIElement.hxx"
+#include "PaneDockingWindow.hxx"
+#include "FrameView.hxx"
+#include "Window.hxx"
+#include "sdmod.hxx"
+#include "app.hrc"
+#include "glob.hrc"
+#include "res_bmp.hrc"
+#include "helpids.h"
+#include "strings.hrc"
+#include "sdresid.hxx"
+#include "framework/FrameworkHelper.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/drawing/framework/XResourceId.hpp>
+#include <com/sun/star/drawing/framework/ResourceActivationMode.hpp>
+#include <com/sun/star/drawing/framework/AnchorBindingMode.hpp>
+#include <com/sun/star/drawing/framework/ResourceActivationMode.hpp>
+#include <com/sun/star/drawing/XDrawSubController.hpp>
+/** === end UNO includes === **/
+
+#include <svtools/toolpanel/toolpanel.hxx>
+#include <svtools/toolpanel/toolpaneldeck.hxx>
+#include <svx/dlgctrl.hxx>
+#include <sfx2/taskpane.hxx>
+#include <sfx2/imagemgr.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/msg.hxx>
+#include <sfx2/objface.hxx>
+#include <svx/colrctrl.hxx>
+#include <svx/xtable.hxx>
+#include <vcl/dockwin.hxx>
+#include "sdtreelb.hxx"
+#include "DrawViewShell.hxx"
+#include "drawdoc.hxx"
+#include "ViewShellBase.hxx"
+#include <svx/ruler.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/toolbox.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/confignode.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/componentcontext.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/basemutex.hxx>
+
+#include <vector>
+
+using namespace ::sd::toolpanel;
+
+#define ToolPanelViewShell
+#include "sdslots.hxx"
+
+/** === begin UNO using === **/
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::XInterface;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::UNO_SET_THROW;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::makeAny;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Type;
+using ::com::sun::star::accessibility::XAccessible;
+using ::com::sun::star::drawing::XDrawSubController;
+using ::com::sun::star::frame::XFrame;
+using ::com::sun::star::drawing::framework::XResourceId;
+using ::com::sun::star::drawing::framework::XConfigurationChangeListener;
+using ::com::sun::star::drawing::framework::ConfigurationChangeEvent;
+using ::com::sun::star::lang::EventObject;
+using ::com::sun::star::lang::DisposedException;
+using ::com::sun::star::drawing::framework::XConfigurationControllerBroadcaster;
+using ::com::sun::star::drawing::framework::XConfigurationController;
+using ::com::sun::star::drawing::framework::XConfiguration;
+using ::com::sun::star::drawing::framework::AnchorBindingMode_DIRECT;
+using ::com::sun::star::ui::XUIElement;
+using ::com::sun::star::ui::XToolPanel;
+using ::com::sun::star::drawing::framework::ResourceActivationMode_REPLACE;
+/** === end UNO using === **/
+
+using ::sd::framework::FrameworkHelper;
+
+namespace sd { namespace toolpanel {
+
+// =====================================================================================================================
+// = misc helper
+// =====================================================================================================================
+// ---------------------------------------------------------------------------------------------------------------------
+PanelId GetStandardPanelId( const ::rtl::OUString& i_rTaskPanelResourceURL, const bool i_bIgnoreUnknown )
+{
+ PanelId ePanelId( PID_UNKNOWN );
+
+ if ( i_rTaskPanelResourceURL.equals( FrameworkHelper::msMasterPagesTaskPanelURL ) )
+ {
+ ePanelId = PID_MASTER_PAGES;
+ }
+ else if ( i_rTaskPanelResourceURL.equals( FrameworkHelper::msLayoutTaskPanelURL ) )
+ {
+ ePanelId = PID_LAYOUT;
+ }
+ else if ( i_rTaskPanelResourceURL.equals( FrameworkHelper::msTableDesignPanelURL ) )
+ {
+ ePanelId = PID_TABLE_DESIGN;
+ }
+ else if ( i_rTaskPanelResourceURL.equals( FrameworkHelper::msCustomAnimationTaskPanelURL ) )
+ {
+ ePanelId = PID_CUSTOM_ANIMATION;
+ }
+ else if ( i_rTaskPanelResourceURL.equals( FrameworkHelper::msSlideTransitionTaskPanelURL ) )
+ {
+ ePanelId = PID_SLIDE_TRANSITION;
+ }
+ else
+ {
+ OSL_ENSURE( i_bIgnoreUnknown, "GetStandardPanelId: cannot translate the given resource URL!" );
+ (void)i_bIgnoreUnknown;
+ }
+
+ return ePanelId;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+PanelId GetStandardPanelId( const ::rtl::OUString& i_rTaskPanelResourceURL )
+{
+ return GetStandardPanelId( i_rTaskPanelResourceURL, false );
+}
+
+// =====================================================================================================================
+// = ConfigurationListener - declaration
+// =====================================================================================================================
+typedef ::cppu::WeakImplHelper1 < XConfigurationChangeListener
+ > ConfigurationListener_Base;
+
+class ConfigurationListener :public ::cppu::BaseMutex
+ ,public ConfigurationListener_Base
+{
+public:
+ ConfigurationListener( ToolPanelViewShell_Impl& i_rShellImpl );
+
+ // XConfigurationChangeListener
+ virtual void SAL_CALL notifyConfigurationChange( const ConfigurationChangeEvent& aEvent ) throw (RuntimeException);
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);
+
+ // XComponent equivalents (not available per UNO interface)
+ void dispose();
+
+protected:
+ ~ConfigurationListener();
+
+ void impl_checkDisposed_throw()
+ {
+ if ( !m_pShellImpl )
+ throw DisposedException( ::rtl::OUString(), *this );
+ }
+
+private:
+ ToolPanelViewShell_Impl* m_pShellImpl;
+};
+
+// =====================================================================================================================
+// = ToolPanelViewShell_Impl - declaration
+// =====================================================================================================================
+/** Inner implementation class of ToolPanelViewShell.
+*/
+class ToolPanelViewShell_Impl :public ::boost::noncopyable
+ ,public ::svt::IToolPanelDeckListener
+ ,public ::sfx2::IToolPanelCompare
+{
+public:
+ static const size_t mnInvalidId = static_cast< size_t >( -1 );
+
+ ToolPanelViewShell_Impl( ToolPanelViewShell& i_rPanelViewShell, ::Window& i_rPanelDeckParent );
+ ~ToolPanelViewShell_Impl();
+
+ ToolPanelViewShell& GetAntiImpl() { return m_rPanelViewShell; }
+
+ /** Here the panels are created that are shown in the task pane.
+ */
+ void Setup();
+
+ /** clean up the instance
+ */
+ void Cleanup();
+
+ /** activates the panel which has the given resource URL
+ */
+ void ActivatePanelByResource( const ::rtl::OUString& i_rPanelResourceURL );
+
+ /** de-activates the panel given by its resource URL, bypassing the configuration controller
+
+ If the panel is not active currently, nothing happens.
+ */
+ void DeactivatePanelByResource( const ::rtl::OUString& i_rPanelResourceURL );
+
+ /** provides access to the the VCL window of the panel deck
+ */
+ ::sfx2::ModuleTaskPane& GetTaskPane() { return *m_pTaskPane; }
+ const ::sfx2::ModuleTaskPane& GetTaskPane() const { return *m_pTaskPane; }
+
+ ::svt::ToolPanelDeck& GetToolPanelDeck() { return GetTaskPane().GetPanelDeck(); }
+ const ::svt::ToolPanelDeck& GetToolPanelDeck() const { return GetTaskPane().GetPanelDeck(); }
+
+ Reference< XAccessible >
+ CreateAccessible( ::sd::Window& i_rWindow );
+
+ void ConnectToDockingWindow();
+
+private:
+ // IToolPanelDeckListener overridables
+ virtual void PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition );
+ virtual void PanelRemoved( const size_t i_nPosition );
+ virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive );
+ virtual void LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter );
+ virtual void Dying();
+
+ // IToolPanelCompare overridables
+ virtual short compareToolPanelsURLs( const ::rtl::OUString& i_rLHS, const ::rtl::OUString& i_rRHS ) const;
+
+private:
+ struct InitialPanel
+ {
+ ::rtl::OUString sPanelResourceURL;
+ bool bActivateDirectly;
+ InitialPanel()
+ :sPanelResourceURL()
+ ,bActivateDirectly( true )
+ {
+ }
+ };
+ InitialPanel impl_determineInitialPanel();
+ ::rtl::OUString impl_getPanelURL( const ::boost::optional< size_t >& i_rPanel );
+
+private:
+ ToolPanelViewShell& m_rPanelViewShell;
+ ::boost::scoped_ptr< ::sfx2::ModuleTaskPane > m_pTaskPane;
+ ::std::auto_ptr< ::sfx2::TaskPaneController > m_pTaskPaneController;
+ ::rtl::Reference< ConfigurationListener > m_pConfigListener;
+ bool m_bInitialized;
+};
+
+// =====================================================================================================================
+// = ConfigurationListener - implementation
+// =====================================================================================================================
+// ---------------------------------------------------------------------------------------------------------------------
+ConfigurationListener::ConfigurationListener( ToolPanelViewShell_Impl& i_rShellImpl )
+ :m_pShellImpl( &i_rShellImpl )
+{
+ ::boost::shared_ptr< FrameworkHelper > pFrameworkHelper( FrameworkHelper::Instance( i_rShellImpl.GetAntiImpl().GetViewShellBase() ) );
+ Reference< XConfigurationControllerBroadcaster > xBroadcaster;
+ if ( pFrameworkHelper.get() )
+ xBroadcaster.set( pFrameworkHelper->GetConfigurationController().get() );
+ ENSURE_OR_THROW( pFrameworkHelper.get(), "no access to the config controller" );
+
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ xBroadcaster->addConfigurationChangeListener( this, ::rtl::OUString(), Any() );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+ConfigurationListener::~ConfigurationListener()
+{
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void SAL_CALL ConfigurationListener::notifyConfigurationChange( const ConfigurationChangeEvent& i_rEvent ) throw (RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ impl_checkDisposed_throw();
+
+ // is this an event we're interested in?
+ if ( i_rEvent.Type != FrameworkHelper::msResourceActivationEvent )
+ return;
+
+ // is this a resource we're interested in? Must be anchored in the task pane ...
+ Reference< XResourceId > xAnchorId;
+ if ( i_rEvent.ResourceId.is() )
+ xAnchorId = i_rEvent.ResourceId->getAnchor();
+ if ( !xAnchorId.is() )
+ return;
+ const ::rtl::OUString sAnchorURL( xAnchorId->getResourceURL() );
+ if ( sAnchorURL != FrameworkHelper::msTaskPaneURL )
+ return;
+
+ m_pShellImpl->ActivatePanelByResource( i_rEvent.ResourceId->getResourceURL() );
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void SAL_CALL ConfigurationListener::disposing( const EventObject& i_rEvent ) throw (RuntimeException)
+{
+ (void)i_rEvent;
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ impl_checkDisposed_throw();
+ }
+
+ dispose();
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ConfigurationListener::dispose()
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_pShellImpl = NULL;
+}
+
+// =====================================================================================================================
+// = ToolPanelViewShell
+// =====================================================================================================================
+// ---------------------------------------------------------------------------------------------------------------------
+SFX_IMPL_INTERFACE(ToolPanelViewShell, SfxShell, SdResId(STR_TASKPANEVIEWSHELL))
+{
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+TYPEINIT1(ToolPanelViewShell, ViewShell);
+
+// ---------------------------------------------------------------------------------------------------------------------
+ToolPanelViewShell_Impl::InitialPanel ToolPanelViewShell_Impl::impl_determineInitialPanel()
+{
+ InitialPanel aPanelToActivate;
+ if ( GetAntiImpl().GetViewShellBase().GetDocShell()->GetDocumentType() == DOCUMENT_TYPE_DRAW )
+ // for Draw, rely on SFX's default handling, which is to activate the previously active panel
+ return aPanelToActivate;
+
+ // Default to Layout panel, but check whether the requested configuration already contains a tool panel, in this case,
+ // use that one.
+ aPanelToActivate.sPanelResourceURL = FrameworkHelper::msLayoutTaskPanelURL;
+ aPanelToActivate.bActivateDirectly = false;
+ try
+ {
+ ::boost::shared_ptr< FrameworkHelper > pFrameworkHelper( FrameworkHelper::Instance( m_rPanelViewShell.GetViewShellBase() ) );
+ const Reference< XResourceId > xToolPanelId( pFrameworkHelper->CreateResourceId( FrameworkHelper::msTaskPaneURL, FrameworkHelper::msRightPaneURL ) );
+ Reference< XConfigurationController > xCC( pFrameworkHelper->GetConfigurationController(), UNO_QUERY_THROW );
+ Reference< XConfiguration > xConfiguration( xCC->getRequestedConfiguration(), UNO_QUERY_THROW );
+ Sequence< Reference< XResourceId > > aViewIds( xConfiguration->getResources(
+ FrameworkHelper::CreateResourceId( FrameworkHelper::msTaskPaneURL, FrameworkHelper::msRightPaneURL ),
+ FrameworkHelper::msTaskPanelURLPrefix, AnchorBindingMode_DIRECT ) );
+
+ if ( aViewIds.getLength() > 0 )
+ {
+ const ::rtl::OUString sResourceURL( aViewIds[0]->getResourceURL() );
+ PanelId nRequestedPanel = GetStandardPanelId( sResourceURL );
+ if ( nRequestedPanel != PID_UNKNOWN )
+ {
+ aPanelToActivate.sPanelResourceURL = sResourceURL;
+ aPanelToActivate.bActivateDirectly = true;
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return aPanelToActivate;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell_Impl::Setup()
+{
+ if ( m_bInitialized )
+ return;
+ m_bInitialized = true;
+
+ // initially activate a panel
+ const InitialPanel aInitialPanel = impl_determineInitialPanel();
+ if ( aInitialPanel.sPanelResourceURL.getLength() )
+ {
+ if ( aInitialPanel.bActivateDirectly )
+ {
+ ActivatePanelByResource( aInitialPanel.sPanelResourceURL );
+ }
+ else
+ {
+ ::boost::shared_ptr< FrameworkHelper > pFrameworkHelper( FrameworkHelper::Instance( GetAntiImpl().GetViewShellBase() ) );
+ pFrameworkHelper->RequestTaskPanel( aInitialPanel.sPanelResourceURL );
+ }
+ }
+
+ // listen at the configuration
+ m_pConfigListener.set( new ConfigurationListener( *this ) );
+
+ m_pTaskPane->Show();
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell_Impl::Cleanup()
+{
+ if ( m_bInitialized )
+ {
+ if ( m_pConfigListener.is() )
+ m_pConfigListener->dispose();
+ }
+ GetToolPanelDeck().RemoveListener( *this );
+ m_pTaskPaneController.reset();
+ m_pTaskPane.reset();
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell_Impl::ActivatePanelByResource( const ::rtl::OUString& i_rResourceURL )
+{
+ // determine position of the requested panel
+ ::boost::optional< size_t > aPanelPos = GetTaskPane().GetPanelPos( i_rResourceURL );
+ OSL_ENSURE( !!aPanelPos, "ToolPanelViewShell_Impl::ActivatePanelByResource: illegal panel resource, or illegal panel deck setup!" );
+ if ( !!aPanelPos )
+ GetToolPanelDeck().ActivatePanel( *aPanelPos );
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell_Impl::DeactivatePanelByResource( const ::rtl::OUString& i_rPanelResourceURL )
+{
+ // determine position of the requested panel
+ ::boost::optional< size_t > aPanelPos = GetTaskPane().GetPanelPos( i_rPanelResourceURL );
+ OSL_ENSURE( !!aPanelPos, "ToolPanelViewShell_Impl::DeactivatePanelByResource: illegal panel resource, or illegal panel deck setup!" );
+ if ( !!aPanelPos )
+ {
+ if ( GetToolPanelDeck().GetActivePanel() == *aPanelPos )
+ GetToolPanelDeck().ActivatePanel( ::boost::optional< size_t >() );
+ }
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell::Initialize()
+{
+ mpImpl->Setup();
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+ToolPanelViewShell::ToolPanelViewShell( SfxViewFrame* pFrame, ViewShellBase& rViewShellBase, ::Window* pParentWindow,
+ FrameView* pFrameViewArgument )
+ :ViewShell(pFrame, pParentWindow, rViewShellBase)
+ ,mpImpl( new ToolPanelViewShell_Impl( *this, *mpContentWindow.get() ) )
+ ,mpSubShellManager()
+ ,mnMenuId(0)
+{
+ meShellType = ST_TASK_PANE;
+
+ mpContentWindow->SetCenterAllowed( false );
+ pParentWindow->SetStyle( pParentWindow->GetStyle() | WB_DIALOGCONTROL );
+
+ GetParentWindow()->SetBackground( Wallpaper() );
+ mpContentWindow->SetBackground( Wallpaper() );
+
+ GetParentWindow()->SetHelpId(HID_SD_TASK_PANE);
+
+ mpImpl->ConnectToDockingWindow();
+
+ SetPool( &GetDoc()->GetPool() );
+
+ if ( pFrameViewArgument )
+ mpFrameView = pFrameViewArgument;
+ else
+ mpFrameView = new FrameView( GetDoc() );
+ GetFrameView()->Connect();
+
+ // Hide or delete unused controls that we have inherited from the
+ // ViewShell base class.
+ mpHorizontalScrollBar.reset();
+ mpVerticalScrollBar.reset();
+ mpScrollBarBox.reset();
+ mpHorizontalRuler.reset();
+ mpVerticalRuler.reset();
+
+ SetName( String( RTL_CONSTASCII_USTRINGPARAM( "ToolPanelViewShell" ) ) );
+
+ // For accessibility we have to shortly hide the content window. This
+ // triggers the construction of a new accessibility object for the new
+ // view shell. (One is created earlier while the construtor of the base
+ // class is executed. At that time the correct accessibility object can
+ // not be constructed.)
+ if ( mpContentWindow.get() )
+ {
+ mpContentWindow->Hide();
+ mpContentWindow->Show();
+ }
+
+ // Register the shell manager as factory at the ViewShellManager.
+ mpSubShellManager.reset( new TaskPaneShellManager(
+ GetViewShellBase().GetViewShellManager(),
+ *this
+ ) );
+ GetViewShellBase().GetViewShellManager()->AddSubShellFactory( this, mpSubShellManager );
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+ToolPanelViewShell::~ToolPanelViewShell()
+{
+ mpImpl->Cleanup();
+
+ // reset our impl before destroying the panel deck, to ensure the hidden panels are properly
+ // disposed/destroyed, too
+ mpImpl.reset();
+ GetViewShellBase().GetViewShellManager()->RemoveSubShellFactory(this, mpSubShellManager);
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+// static
+void ToolPanelViewShell::RegisterControls()
+{
+ SfxModule* pModule = SD_MOD();
+ controls::MasterPagesSelector::RegisterInterface( pModule );
+ LayoutMenu::RegisterInterface( pModule );
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell::ArrangeGUIElements()
+{
+ ViewShell::ArrangeGUIElements();
+
+ Initialize();
+
+ mpImpl->GetTaskPane().SetPosSizePixel( Point(), maViewSize );
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell::GetFocus()
+{
+ Invalidate();
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell::LoseFocus()
+{
+ Invalidate();
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell::KeyInput( const KeyEvent& i_rKeyEvent )
+{
+ const KeyCode nCode = i_rKeyEvent.GetKeyCode();
+ if ( nCode == KEY_RETURN )
+ {
+ if ( !mpImpl->GetTaskPane().HasChildPathFocus() )
+ mpImpl->GetTaskPane().GrabFocus();
+ }
+ else
+ ViewShell::KeyInput( i_rKeyEvent, NULL );
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+SdPage* ToolPanelViewShell::GetActualPage()
+{
+ return NULL;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+SdPage* ToolPanelViewShell::getCurrentPage() const
+{
+ return NULL;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell::Execute( SfxRequest& )
+{
+ OSL_ENSURE( false, "ToolPanelViewShell::Execute: not to be called! (right?)" );
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell::GetState( SfxItemSet& )
+{
+ OSL_ENSURE( false, "ToolPanelViewShell::GetState: not to be called! (right?)" );
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+TaskPaneShellManager& ToolPanelViewShell::GetSubShellManager() const
+{
+ return *mpSubShellManager.get();
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+DockingWindow* ToolPanelViewShell::GetDockingWindow()
+{
+ ::Window* pParentWindow = GetParentWindow();
+ DockingWindow* pDockingWindow = NULL;
+ while (pParentWindow!=NULL && pDockingWindow==NULL)
+ {
+ pDockingWindow = dynamic_cast<DockingWindow*>(pParentWindow);
+ pParentWindow = pParentWindow->GetParent();
+ }
+ return pDockingWindow;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+Reference< XAccessible > ToolPanelViewShell::CreateAccessibleDocumentView( ::sd::Window* i_pWindow )
+{
+ ENSURE_OR_RETURN( i_pWindow, "ToolPanelViewShell::CreateAccessibleDocumentView: illegal window!", NULL );
+ return mpImpl->CreateAccessible( *i_pWindow );
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+Reference< XDrawSubController > ToolPanelViewShell::CreateSubController()
+{
+ // This view shell is not designed to be the main view shell and thus
+ // does not support a UNO sub controller.
+ return Reference< XDrawSubController >();
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+bool ToolPanelViewShell::RelocateToParentWindow( ::Window* pParentWindow )
+{
+ ::Window* pOldParentWindow = GetParentWindow();
+ FocusManager::Instance().RemoveLinks( pOldParentWindow, &mpImpl->GetTaskPane() );
+ FocusManager::Instance().RemoveLinks( &mpImpl->GetTaskPane(), pOldParentWindow );
+
+ PaneDockingWindow* pDockingWindow = dynamic_cast< PaneDockingWindow* >( GetDockingWindow() );
+ if ( pDockingWindow != NULL )
+ {
+ pDockingWindow->SetEndDockingHdl( Link() );
+ }
+
+ ViewShell::RelocateToParentWindow(pParentWindow);
+
+ mpImpl->ConnectToDockingWindow();
+
+ Resize();
+
+ return true;
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+bool ToolPanelViewShell::IsPanelAnchorWindow( const ::Window& i_rWindow ) const
+{
+ return &mpImpl->GetToolPanelDeck().GetPanelWindowAnchor() == &i_rWindow;
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+namespace
+{
+ typedef std::auto_ptr< ControlFactory > (*ControlFactoryFactory)( ToolPanelViewShell& i_rToolPanelShell );
+
+ struct PanelFactory
+ {
+ ControlFactoryFactory pFactory;
+ ULONG nHelpID;
+ PanelFactory( const ControlFactoryFactory i_pFactory, const ULONG i_nHelpID )
+ :pFactory( i_pFactory )
+ ,nHelpID( i_nHelpID )
+ {
+ }
+ };
+
+ const PanelFactory lcl_describePanel( const PanelId i_ePanelId )
+ {
+ switch ( i_ePanelId )
+ {
+ case PID_MASTER_PAGES:
+ return PanelFactory( &controls::MasterPagesPanel::CreateControlFactory, HID_SD_SLIDE_DESIGNS );
+ case PID_LAYOUT:
+ return PanelFactory( &LayoutMenu::CreateControlFactory, HID_SD_SLIDE_LAYOUTS );
+ case PID_TABLE_DESIGN:
+ return PanelFactory( &controls::TableDesignPanel::CreateControlFactory, HID_SD_TABLE_DESIGN );
+ case PID_CUSTOM_ANIMATION:
+ return PanelFactory( &controls::CustomAnimationPanel::CreateControlFactory, HID_SD_CUSTOM_ANIMATIONS );
+ case PID_SLIDE_TRANSITION:
+ return PanelFactory( &controls::SlideTransitionPanel::CreateControlFactory, HID_SD_SLIDE_TRANSITIONS );
+ default:
+ break;
+ }
+ throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "illegal panel ID" ) ), NULL );
+ }
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+Reference< XUIElement > ToolPanelViewShell::CreatePanelUIElement( const Reference< XFrame >& i_rDocFrame, const ::rtl::OUString& i_rPanelResourceURL )
+{
+ const PanelId ePanelId( GetStandardPanelId( i_rPanelResourceURL ) );
+ ENSURE_OR_RETURN( ePanelId != PID_UNKNOWN, "ToolPanelViewShell::CreatePanelUIElement: illegal panel URL!", NULL );
+
+ // a TreeNode which will resemble the panel
+ const PanelFactory aPanelFactory( lcl_describePanel( ePanelId ) );
+ ::std::auto_ptr< ControlFactory > pControlFactory( (*aPanelFactory.pFactory)( *this ) );
+ ::std::auto_ptr< TreeNode > pNode( pControlFactory->CreateControl( mpImpl->GetToolPanelDeck().GetPanelWindowAnchor() ) );
+ ENSURE_OR_THROW( ( pNode.get() != NULL ) && ( pNode->GetWindow() != NULL ),
+ "illegal node returned by the control factory" );
+ pNode->GetWindow()->SetHelpId( aPanelFactory.nHelpID );
+
+ // create an XToolPanel
+ Reference< XToolPanel > xPanel( new ToolPanel( pNode ) );
+
+ // create an XUIElement providing this panel
+ const Reference< XUIElement > xUIElement( new ToolPanelUIElement( i_rDocFrame, i_rPanelResourceURL, xPanel ) );
+
+ return xUIElement;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell::ActivatePanel( const ::rtl::OUString& i_rPanelResourceURL )
+{
+ OSL_ENSURE( i_rPanelResourceURL.indexOf( FrameworkHelper::msTaskPanelURLPrefix ) < 0,
+ "ToolPanelViewShell::ActivatePanel: for drawing-framework-controller panels, please use FrameworkHelper::RequestTaskPanel!" );
+ mpImpl->ActivatePanelByResource( i_rPanelResourceURL );
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell::DeactivatePanel( const ::rtl::OUString& i_rPanelResourceURL )
+{
+ mpImpl->DeactivatePanelByResource( i_rPanelResourceURL );
+}
+
+// =====================================================================================================================
+// = ToolPanelViewShell_Impl - implementation
+// =====================================================================================================================
+// ---------------------------------------------------------------------------------------------------------------------
+ToolPanelViewShell_Impl::ToolPanelViewShell_Impl( ToolPanelViewShell& i_rPanelViewShell, ::Window& i_rPanelDeckParent )
+ :m_rPanelViewShell( i_rPanelViewShell )
+ ,m_pTaskPane( new ::sfx2::ModuleTaskPane( i_rPanelDeckParent, i_rPanelViewShell.GetViewShellBase().GetViewFrame()->GetFrame().GetFrameInterface(), *this ) )
+ ,m_bInitialized( false )
+{
+ const String sPaneTitle( SdResId( STR_RIGHT_PANE_TITLE ) );
+ GetToolPanelDeck().SetAccessibleName( sPaneTitle );
+ GetToolPanelDeck().SetAccessibleDescription( sPaneTitle );
+
+ GetToolPanelDeck().AddListener( *this );
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+ToolPanelViewShell_Impl::~ToolPanelViewShell_Impl()
+{
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell_Impl::PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition )
+{
+ // not interested in
+ (void)i_pPanel;
+ (void)i_nPosition;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell_Impl::PanelRemoved( const size_t i_nPosition )
+{
+ // not interested in
+ (void)i_nPosition;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+::rtl::OUString ToolPanelViewShell_Impl::impl_getPanelURL( const ::boost::optional< size_t >& i_rPanel )
+{
+ ::rtl::OUString sPanelURL;
+ if ( !!i_rPanel )
+ {
+ sPanelURL = GetTaskPane().GetPanelResourceURL( *i_rPanel );
+ const PanelId ePanelId( GetStandardPanelId( sPanelURL, true ) );
+ if ( ePanelId == PID_UNKNOWN )
+ sPanelURL = ::rtl::OUString();
+ }
+ return sPanelURL;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell_Impl::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive )
+{
+ // update the configuration controller, since this change in the active panel might have been triggered by means other
+ // than the drawing framework, so it does not yet know about it.
+
+ const ::rtl::OUString sOldPanelURL( impl_getPanelURL( i_rOldActive ) );
+ const ::rtl::OUString sNewPanelURL( impl_getPanelURL( i_rNewActive ) );
+
+ const ::boost::shared_ptr< FrameworkHelper > pFrameworkHelper( FrameworkHelper::Instance( GetAntiImpl().GetViewShellBase() ) );
+ if ( sNewPanelURL.getLength() )
+ {
+ // activate the resource belonging to the new panel. This will automatically de-activate the previously active
+ // panel resource (since ResourceActivationMode_REPLACE is used)
+ pFrameworkHelper->RequestTaskPanel( sNewPanelURL );
+ }
+ else if ( sOldPanelURL.getLength() )
+ {
+ // there is no new active panel, or it is not one of our standard panels, i.e. it is not covered by the
+ // resource framework. => Deactivate the old resource.
+ try
+ {
+ Reference< XConfigurationController > xConfigController( pFrameworkHelper->GetConfigurationController(), UNO_QUERY_THROW );
+ xConfigController->requestResourceDeactivation(
+ pFrameworkHelper->CreateResourceId(
+ sOldPanelURL,
+ FrameworkHelper::msTaskPaneURL,
+ FrameworkHelper::msRightPaneURL
+ )
+ );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell_Impl::LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter )
+{
+ // not interested in
+ (void)i_rNewLayouter;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell_Impl::Dying()
+{
+ // not interested in
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+short ToolPanelViewShell_Impl::compareToolPanelsURLs( const ::rtl::OUString& i_rLHS, const ::rtl::OUString& i_rRHS ) const
+{
+ const PanelId eLHS( GetStandardPanelId( i_rLHS, true ) );
+ const PanelId eRHS( GetStandardPanelId( i_rRHS, true ) );
+ if ( eLHS < eRHS )
+ return -1;
+ if ( eLHS == eRHS )
+ return 0;
+ return 1;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+void ToolPanelViewShell_Impl::ConnectToDockingWindow()
+{
+ m_pTaskPaneController.reset();
+ DockingWindow* pDockingWindow( GetAntiImpl().GetDockingWindow() );
+ if ( pDockingWindow )
+ {
+ PaneDockingWindow* pPaneDockingWindow = dynamic_cast< PaneDockingWindow* >( pDockingWindow );
+ OSL_ENSURE( pPaneDockingWindow, "ToolPanelViewShell_Impl::ConnectToDockingWindow: unsupported docking window type!" );
+ if ( pPaneDockingWindow != NULL )
+ m_pTaskPaneController.reset( new ::sfx2::TaskPaneController( GetTaskPane(), *pPaneDockingWindow ) );
+ }
+
+ // Tell the focus manager that we want to pass the focus to our
+ // child.
+ FocusManager::Instance().RegisterDownLink( GetAntiImpl().GetParentWindow(), &GetTaskPane() );
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+Reference< XAccessible > ToolPanelViewShell_Impl::CreateAccessible( ::sd::Window& i_rWindow )
+{
+ Reference< XAccessible > xAccessible( GetToolPanelDeck().GetAccessible( FALSE ) );
+ if ( !xAccessible.is() )
+ {
+ // determine the XAccessible which is the parent of the to-be-created object
+ ::Window* pAccessibleParent = i_rWindow.GetAccessibleParentWindow();
+ OSL_ENSURE( pAccessibleParent, "ToolPanelViewShell_Impl::CreateAccessible: illegal accessible parent provided by the sd::Window!" );
+ GetToolPanelDeck().SetAccessibleParentWindow( pAccessibleParent );
+
+ xAccessible = GetToolPanelDeck().GetAccessible( TRUE );
+ ENSURE_OR_RETURN( xAccessible.is(), "ToolPanelViewShell_Impl::CreateAccessible: illegal ToolPanelDeck accessible!", NULL );
+ OSL_ENSURE( xAccessible->getAccessibleContext().is()
+ && xAccessible->getAccessibleContext()->getAccessibleParent() == pAccessibleParent->GetAccessible(),
+ "ToolPanelViewShell_Impl::CreateAccessible: illegal parenthood!" );
+ }
+ return xAccessible;
+}
+
+} } // end of namespace ::sd::toolpanel
diff --git a/sd/source/ui/toolpanel/controls/AllMasterPagesSelector.cxx b/sd/source/ui/toolpanel/controls/AllMasterPagesSelector.cxx
new file mode 100644
index 000000000000..86abd44e3a83
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/AllMasterPagesSelector.cxx
@@ -0,0 +1,208 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "AllMasterPagesSelector.hxx"
+#include "PreviewValueSet.hxx"
+#include "app.hrc"
+#include "MasterPageContainer.hxx"
+#include "MasterPageDescriptor.hxx"
+#include <tools/link.hxx>
+#include <set>
+
+namespace {
+
+using namespace sd::toolpanel::controls;
+
+int GetURLPriority (const SharedMasterPageDescriptor& rpDescriptor)
+{
+ int nPriority (0);
+ switch (rpDescriptor->GetURLClassification())
+ {
+ case MasterPageDescriptor::URLCLASS_USER: nPriority = 0; break;
+ case MasterPageDescriptor::URLCLASS_LAYOUT: nPriority = 1; break;
+ case MasterPageDescriptor::URLCLASS_PRESENTATION: nPriority = 2; break;
+ case MasterPageDescriptor::URLCLASS_OTHER: nPriority = 3; break;
+ case MasterPageDescriptor::URLCLASS_UNKNOWN: nPriority = 4; break;
+ default:
+ case MasterPageDescriptor::URLCLASS_UNDETERMINED: nPriority = 5; break;
+ }
+ return nPriority;
+}
+
+
+class MasterPageDescriptorOrder
+{
+public:
+ bool operator() (const sd::toolpanel::controls::SharedMasterPageDescriptor& rp1,
+ const sd::toolpanel::controls::SharedMasterPageDescriptor& rp2)
+ {
+ if (rp1->meOrigin == MasterPageContainer::DEFAULT)
+ return true;
+ else if (rp2->meOrigin == MasterPageContainer::DEFAULT)
+ return false;
+ else if (rp1->GetURLClassification() == rp2->GetURLClassification())
+ return rp1->mnTemplateIndex < rp2->mnTemplateIndex;
+ else
+ return GetURLPriority(rp1) < GetURLPriority(rp2);
+ }
+};
+
+} // end of anonymous namespace
+
+
+
+namespace sd { namespace toolpanel { namespace controls {
+
+class AllMasterPagesSelector::SortedMasterPageDescriptorList
+ : public ::std::set<SharedMasterPageDescriptor,MasterPageDescriptorOrder>
+{
+public:
+ SortedMasterPageDescriptorList (void) {}
+};
+
+
+
+
+AllMasterPagesSelector::AllMasterPagesSelector (
+ TreeNode* pParent,
+ SdDrawDocument& rDocument,
+ ViewShellBase& rBase,
+ DrawViewShell& rViewShell,
+ const ::boost::shared_ptr<MasterPageContainer>& rpContainer)
+ : MasterPagesSelector(pParent, rDocument, rBase, rpContainer),
+ mrViewShell(rViewShell),
+ mpSortedMasterPages(new SortedMasterPageDescriptorList())
+{
+ SetName (String(RTL_CONSTASCII_USTRINGPARAM("AllMasterPagesSelector")));
+ MasterPagesSelector::Fill();
+}
+
+
+
+
+AllMasterPagesSelector::~AllMasterPagesSelector (void)
+{
+}
+
+
+
+
+void AllMasterPagesSelector::Fill (ItemList& rItemList)
+{
+ if (mpSortedMasterPages->empty())
+ UpdateMasterPageList();
+ UpdatePageSet(rItemList);
+}
+
+
+
+
+void AllMasterPagesSelector::NotifyContainerChangeEvent (
+ const MasterPageContainerChangeEvent& rEvent)
+{
+ switch (rEvent.meEventType)
+ {
+ case MasterPageContainerChangeEvent::CHILD_ADDED:
+ AddItem(rEvent.maChildToken);
+ MasterPagesSelector::Fill();
+ break;
+
+ case MasterPageContainerChangeEvent::INDEX_CHANGED:
+ case MasterPageContainerChangeEvent::INDEXES_CHANGED:
+ mpSortedMasterPages->clear();
+ MasterPagesSelector::Fill();
+ break;
+
+ default:
+ MasterPagesSelector::NotifyContainerChangeEvent(rEvent);
+ break;
+ }
+}
+
+
+
+
+void AllMasterPagesSelector::UpdateMasterPageList (void)
+{
+ mpSortedMasterPages->clear();
+ int nTokenCount = mpContainer->GetTokenCount();
+ for (int i=0; i<nTokenCount; i++)
+ AddItem(mpContainer->GetTokenForIndex(i));
+}
+
+
+
+
+void AllMasterPagesSelector::AddItem (MasterPageContainer::Token aToken)
+{
+ switch (mpContainer->GetOriginForToken(aToken))
+ {
+ case MasterPageContainer::DEFAULT:
+ case MasterPageContainer::TEMPLATE:
+ // Templates are added only when coming from the
+ // MasterPageContainerFiller so that they have an id which
+ // defines their place in the list. Templates (pre) loaded from
+ // RecentlyUsedMasterPages are ignored (they will be loaded
+ // later by the MasterPageContainerFiller.)
+ if (mpContainer->GetTemplateIndexForToken(aToken) >= 0)
+ mpSortedMasterPages->insert(mpContainer->GetDescriptorForToken(aToken));
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+
+
+void AllMasterPagesSelector::UpdatePageSet (ItemList& rItemList)
+{
+ SortedMasterPageDescriptorList::const_iterator iDescriptor;
+ SortedMasterPageDescriptorList::const_iterator iEnd (mpSortedMasterPages->end());
+ for (iDescriptor=mpSortedMasterPages->begin(); iDescriptor!=iEnd; ++iDescriptor)
+ rItemList.push_back((*iDescriptor)->maToken);
+}
+
+
+
+
+void AllMasterPagesSelector::GetState (SfxItemSet& rItemSet)
+{
+ MasterPagesSelector::GetState(rItemSet);
+
+ if (rItemSet.GetItemState(SID_TP_EDIT_MASTER) == SFX_ITEM_AVAILABLE)
+ rItemSet.DisableItem(SID_TP_EDIT_MASTER);
+}
+
+
+
+
+} } } // end of namespace ::sd::toolpanel::control
diff --git a/sd/source/ui/toolpanel/controls/AllMasterPagesSelector.hxx b/sd/source/ui/toolpanel/controls/AllMasterPagesSelector.hxx
new file mode 100644
index 000000000000..e937958dbbf0
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/AllMasterPagesSelector.hxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANEL_CONTROLS_ALL_MASTER_PAGES_SELECTOR_HXX
+#define SD_TOOLPANEL_CONTROLS_ALL_MASTER_PAGES_SELECTOR_HXX
+
+#include "MasterPagesSelector.hxx"
+
+#include <memory>
+
+namespace sd { namespace toolpanel { namespace controls {
+
+
+/** Show a list of all available master pages so that the user can assign
+ them to the document.
+*/
+class AllMasterPagesSelector
+ : public MasterPagesSelector
+{
+public:
+ AllMasterPagesSelector (
+ TreeNode* pParent,
+ SdDrawDocument& rDocument,
+ ViewShellBase& rBase,
+ DrawViewShell& rViewShell,
+ const ::boost::shared_ptr<MasterPageContainer>& rpContainer);
+ virtual ~AllMasterPagesSelector (void);
+
+ /** Scan the set of templates for the ones whose first master pages are
+ shown by this control and store them in the MasterPageContainer.
+ */
+ virtual void Fill (ItemList& rItemList);
+
+ virtual void GetState (SfxItemSet& rItemSet);
+
+protected:
+ virtual void NotifyContainerChangeEvent (const MasterPageContainerChangeEvent& rEvent);
+
+private:
+ DrawViewShell& mrViewShell;
+
+ /** The list of master pages displayed by this class.
+ */
+ class SortedMasterPageDescriptorList;
+ ::std::auto_ptr<SortedMasterPageDescriptorList> mpSortedMasterPages;
+
+ void AddTemplate (const TemplateEntry& rEntry);
+
+ /** This filter returns <TRUE/> when the master page specified by the
+ given file name belongs to the set of Impress master pages.
+ */
+ bool FileFilter (const String& sFileName);
+
+ void AddItem (MasterPageContainer::Token aToken);
+
+ /** Add all items in the internal master page list into the given list.
+ */
+ void UpdatePageSet (ItemList& rItemList);
+
+ /** Update the internal list of master pages that are to show in the
+ control.
+ */
+ void UpdateMasterPageList (void);
+
+ using sd::toolpanel::controls::MasterPagesSelector::Fill;
+};
+
+} } } // end of namespace ::sd::toolpanel::controls
+
+#endif
diff --git a/sd/source/ui/toolpanel/controls/AnimationSchemesPanel.cxx b/sd/source/ui/toolpanel/controls/AnimationSchemesPanel.cxx
new file mode 100755
index 000000000000..730fc74795f2
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/AnimationSchemesPanel.cxx
@@ -0,0 +1,170 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AnimationSchemesPanel.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+#include "AnimationSchemesPanel.hxx"
+
+#include "strings.hrc"
+#include "sdresid.hxx"
+#include <com/sun/star/frame/XModel.hpp>
+
+namespace sd
+{
+
+ class ViewShellBase;
+ extern ::Window * createAnimationSchemesPanel( ::Window* pParent, ViewShellBase& rBase );
+
+namespace toolpanel { namespace controls {
+
+
+AnimationSchemesPanel::AnimationSchemesPanel(TreeNode* pParent, ViewShellBase& rBase)
+ : SubToolPanel (pParent),
+ maPreferredSize( 100, 200 )
+{
+ mpWrappedControl = createAnimationSchemesPanel( pParent->GetWindow(), rBase );
+ mpWrappedControl->Show();
+}
+
+AnimationSchemesPanel::~AnimationSchemesPanel()
+{
+ delete mpWrappedControl;
+}
+
+Size AnimationSchemesPanel::GetPreferredSize()
+{
+ return maPreferredSize;
+}
+sal_Int32 AnimationSchemesPanel::GetPreferredWidth(sal_Int32 )
+{
+ return maPreferredSize.Width();
+}
+sal_Int32 AnimationSchemesPanel::GetPreferredHeight(sal_Int32 )
+{
+ return maPreferredSize.Height();
+}
+::Window* AnimationSchemesPanel::GetWindow()
+{
+ return mpWrappedControl;
+}
+bool AnimationSchemesPanel::IsResizable()
+{
+ return true;
+}
+bool AnimationSchemesPanel::IsExpandable() const
+{
+ return true;
+}
+
+
+} } } // end of namespace ::sd::toolpanel::controls
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+#include "AnimationSchemesPanel.hxx"
+
+#include "strings.hrc"
+#include "sdresid.hxx"
+#include <com/sun/star/frame/XModel.hpp>
+
+namespace sd
+{
+
+ class ViewShellBase;
+ extern ::Window * createAnimationSchemesPanel( ::Window* pParent, ViewShellBase& rBase );
+
+namespace toolpanel { namespace controls {
+
+
+AnimationSchemesPanel::AnimationSchemesPanel(TreeNode* pParent, ViewShellBase& rBase)
+ : SubToolPanel (pParent),
+ maPreferredSize( 100, 200 )
+{
+ mpWrappedControl = createAnimationSchemesPanel( pParent->GetWindow(), rBase );
+ mpWrappedControl->Show();
+}
+
+AnimationSchemesPanel::~AnimationSchemesPanel()
+{
+ delete mpWrappedControl;
+}
+
+Size AnimationSchemesPanel::GetPreferredSize()
+{
+ return maPreferredSize;
+}
+sal_Int32 AnimationSchemesPanel::GetPreferredWidth(sal_Int32 )
+{
+ return maPreferredSize.Width();
+}
+sal_Int32 AnimationSchemesPanel::GetPreferredHeight(sal_Int32 )
+{
+ return maPreferredSize.Height();
+}
+::Window* AnimationSchemesPanel::GetWindow()
+{
+ return mpWrappedControl;
+}
+bool AnimationSchemesPanel::IsResizable()
+{
+ return true;
+}
+bool AnimationSchemesPanel::IsExpandable() const
+{
+ return true;
+}
+
+
+} } } // end of namespace ::sd::toolpanel::controls
diff --git a/sd/source/ui/toolpanel/controls/AnimationSchemesPanel.hxx b/sd/source/ui/toolpanel/controls/AnimationSchemesPanel.hxx
new file mode 100755
index 000000000000..dd3388fb0342
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/AnimationSchemesPanel.hxx
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AnimationSchemesPanel.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TASKPANE_CONTROLS_ANIMATION_SCHEMES_PANEL_HXX
+#define SD_TASKPANE_CONTROLS_ANIMATION_SCHEMES_PANEL_HXX
+
+#include "taskpane/SubToolPanel.hxx"
+
+namespace sd {
+class ViewShellBase;
+}
+
+namespace sd { namespace toolpanel {
+class TreeNode;
+} }
+
+namespace sd { namespace toolpanel { namespace controls {
+
+class AnimationSchemesPanel
+ : public SubToolPanel
+{
+public:
+ AnimationSchemesPanel (
+ TreeNode* pParent,
+ ViewShellBase& rBase);
+ virtual ~AnimationSchemesPanel (void);
+
+ virtual Size GetPreferredSize (void);
+ virtual sal_Int32 GetPreferredWidth (sal_Int32 nHeigh);
+ virtual sal_Int32 GetPreferredHeight (sal_Int32 nWidth);
+ virtual ::Window* GetWindow (void);
+ virtual bool IsResizable (void);
+ virtual bool IsExpandable (void) const;
+
+ using Window::GetWindow;
+
+private:
+ Size maPreferredSize;
+ ::Window* mpWrappedControl;
+};
+
+} } } // end of namespace ::sd::toolpanel::controls
+
+#endif
+#ifndef SD_TASKPANE_CONTROLS_ANIMATION_SCHEMES_PANEL_HXX
+#define SD_TASKPANE_CONTROLS_ANIMATION_SCHEMES_PANEL_HXX
+
+#include "taskpane/SubToolPanel.hxx"
+
+namespace sd {
+class ViewShellBase;
+}
+
+namespace sd { namespace toolpanel {
+class TreeNode;
+} }
+
+namespace sd { namespace toolpanel { namespace controls {
+
+class AnimationSchemesPanel
+ : public SubToolPanel
+{
+public:
+ AnimationSchemesPanel (
+ TreeNode* pParent,
+ ViewShellBase& rBase);
+ virtual ~AnimationSchemesPanel (void);
+
+ virtual Size GetPreferredSize (void);
+ virtual sal_Int32 GetPreferredWidth (sal_Int32 nHeigh);
+ virtual sal_Int32 GetPreferredHeight (sal_Int32 nWidth);
+ virtual ::Window* GetWindow (void);
+ virtual bool IsResizable (void);
+ virtual bool IsExpandable (void) const;
+
+ using Window::GetWindow;
+
+private:
+ Size maPreferredSize;
+ ::Window* mpWrappedControl;
+};
+
+} } } // end of namespace ::sd::toolpanel::controls
+
+#endif
diff --git a/sd/source/ui/toolpanel/controls/CurrentMasterPagesSelector.cxx b/sd/source/ui/toolpanel/controls/CurrentMasterPagesSelector.cxx
new file mode 100644
index 000000000000..7f4149d7e6fd
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/CurrentMasterPagesSelector.cxx
@@ -0,0 +1,343 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "CurrentMasterPagesSelector.hxx"
+#include "PreviewValueSet.hxx"
+#include "ViewShellBase.hxx"
+#include "DrawViewShell.hxx"
+#include "drawdoc.hxx"
+#include "sdpage.hxx"
+#include "MasterPageContainer.hxx"
+#include "MasterPageDescriptor.hxx"
+#include "EventMultiplexer.hxx"
+#include "app.hrc"
+#include "DrawDocShell.hxx"
+#include "DrawViewShell.hxx"
+#include "res_bmp.hrc"
+#include "sdresid.hxx"
+
+#include <vcl/image.hxx>
+#include <svx/svdmodel.hxx>
+#include <sfx2/request.hxx>
+
+#include <set>
+
+
+using namespace ::com::sun::star;
+
+namespace sd { namespace toolpanel { namespace controls {
+
+
+CurrentMasterPagesSelector::CurrentMasterPagesSelector (
+ TreeNode* pParent,
+ SdDrawDocument& rDocument,
+ ViewShellBase& rBase,
+ const ::boost::shared_ptr<MasterPageContainer>& rpContainer)
+ : MasterPagesSelector (pParent, rDocument, rBase, rpContainer)
+{
+ SetName(String(RTL_CONSTASCII_USTRINGPARAM("CurrentMasterPagesSelector")));
+
+ // For this master page selector only we change the default action for
+ // left clicks.
+ mnDefaultClickAction = SID_TP_APPLY_TO_SELECTED_SLIDES;
+
+ Link aLink (LINK(this,CurrentMasterPagesSelector,EventMultiplexerListener));
+ rBase.GetEventMultiplexer()->AddEventListener(aLink,
+ sd::tools::EventMultiplexerEvent::EID_CURRENT_PAGE
+ | sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_NORMAL
+ | sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_MASTER
+ | sd::tools::EventMultiplexerEvent::EID_PAGE_ORDER
+ | sd::tools::EventMultiplexerEvent::EID_SHAPE_CHANGED
+ | sd::tools::EventMultiplexerEvent::EID_SHAPE_INSERTED
+ | sd::tools::EventMultiplexerEvent::EID_SHAPE_REMOVED);
+}
+
+
+
+
+CurrentMasterPagesSelector::~CurrentMasterPagesSelector (void)
+{
+ if (mrDocument.GetDocSh() != NULL)
+ {
+ EndListening(*mrDocument.GetDocSh());
+ }
+ else
+ {
+ OSL_ASSERT(mrDocument.GetDocSh() != NULL);
+ }
+
+ Link aLink (LINK(this,CurrentMasterPagesSelector,EventMultiplexerListener));
+ mrBase.GetEventMultiplexer()->RemoveEventListener(aLink);
+}
+
+
+
+
+void CurrentMasterPagesSelector::LateInit (void)
+{
+ MasterPagesSelector::LateInit();
+ MasterPagesSelector::Fill();
+ if (mrDocument.GetDocSh() != NULL)
+ {
+ StartListening(*mrDocument.GetDocSh());
+ }
+ else
+ {
+ OSL_ASSERT(mrDocument.GetDocSh() != NULL);
+ }
+}
+
+
+
+
+void CurrentMasterPagesSelector::Fill (ItemList& rItemList)
+{
+ USHORT nPageCount = mrDocument.GetMasterSdPageCount(PK_STANDARD);
+ SdPage* pMasterPage;
+ // Remember the names of the master pages that have been inserted to
+ // avoid double insertion.
+ ::std::set<String> aMasterPageNames;
+ for (USHORT nIndex=0; nIndex<nPageCount; nIndex++)
+ {
+ pMasterPage = mrDocument.GetMasterSdPage (nIndex, PK_STANDARD);
+ if (pMasterPage == NULL)
+ continue;
+
+ // Use the name of the master page to avoid duplicate entries.
+ String sName (pMasterPage->GetName());
+ if (aMasterPageNames.find(sName)!=aMasterPageNames.end())
+ continue;
+ aMasterPageNames.insert (sName);
+
+ // Look up the master page in the container and, when it is not yet
+ // in it, insert it.
+ MasterPageContainer::Token aToken = mpContainer->GetTokenForPageObject(pMasterPage);
+ if (aToken == MasterPageContainer::NIL_TOKEN)
+ {
+ SharedMasterPageDescriptor pDescriptor (new MasterPageDescriptor(
+ MasterPageContainer::MASTERPAGE,
+ nIndex,
+ String(),
+ pMasterPage->GetName(),
+ String(),
+ pMasterPage->IsPrecious(),
+ ::boost::shared_ptr<PageObjectProvider>(new ExistingPageProvider(pMasterPage)),
+ ::boost::shared_ptr<PreviewProvider>(new PagePreviewProvider())));
+ aToken = mpContainer->PutMasterPage(pDescriptor);
+ }
+
+ rItemList.push_back(aToken);
+ }
+}
+
+
+
+
+ResId CurrentMasterPagesSelector::GetContextMenuResId (void) const
+{
+ return SdResId(RID_TASKPANE_CURRENT_MASTERPAGESSELECTOR_POPUP);
+}
+
+
+
+
+void CurrentMasterPagesSelector::UpdateSelection (void)
+{
+ // Iterate over all pages and for the selected ones put the name of
+ // their master page into a set.
+ USHORT nPageCount = mrDocument.GetSdPageCount(PK_STANDARD);
+ SdPage* pPage;
+ ::std::set<String> aNames;
+ USHORT nIndex;
+ bool bLoop (true);
+ for (nIndex=0; nIndex<nPageCount && bLoop; nIndex++)
+ {
+ pPage = mrDocument.GetSdPage (nIndex, PK_STANDARD);
+ if (pPage != NULL && pPage->IsSelected())
+ {
+ if ( ! pPage->TRG_HasMasterPage())
+ {
+ // One of the pages has no master page. This is an
+ // indicator for that this method is called in the middle of
+ // a document change and that the model is not in a valid
+ // state. Therefore we stop update the selection and wait
+ // for another call to UpdateSelection when the model is
+ // valid again.
+ bLoop = false;
+ }
+ else
+ {
+ SdrPage& rMasterPage (pPage->TRG_GetMasterPage());
+ SdPage* pMasterPage = static_cast<SdPage*>(&rMasterPage);
+ if (pMasterPage != NULL)
+ aNames.insert (pMasterPage->GetName());
+ }
+ }
+ }
+
+ // Find the items for the master pages in the set.
+ USHORT nItemCount (mpPageSet->GetItemCount());
+ for (nIndex=1; nIndex<=nItemCount && bLoop; nIndex++)
+ {
+ String sName (mpPageSet->GetItemText (nIndex));
+ if (aNames.find(sName) != aNames.end())
+ {
+ mpPageSet->SelectItem (nIndex);
+ }
+ }
+}
+
+
+
+
+void CurrentMasterPagesSelector::Execute (SfxRequest& rRequest)
+{
+ switch (rRequest.GetSlot())
+ {
+ case SID_DELETE_MASTER_PAGE:
+ {
+ // Check once again that the master page can safely be deleted,
+ // i.e. is not used.
+ SdPage* pMasterPage = GetSelectedMasterPage();
+ if (pMasterPage != NULL
+ && mrDocument.GetMasterPageUserCount(pMasterPage) > 0)
+ {
+ // Removing the precious flag so that the following call to
+ // RemoveUnnessesaryMasterPages() will remove this master page.
+ pMasterPage->SetPrecious(false);
+ mrDocument.RemoveUnnecessaryMasterPages(pMasterPage, FALSE, TRUE);
+ }
+ }
+ break;
+
+ default:
+ MasterPagesSelector::Execute(rRequest);
+ break;
+ }
+}
+
+
+
+
+void CurrentMasterPagesSelector::GetState (SfxItemSet& rItemSet)
+{
+ // Disable the SID_DELTE_MASTER slot when there is only one master page.
+ if (rItemSet.GetItemState(SID_DELETE_MASTER_PAGE) == SFX_ITEM_AVAILABLE
+ && mrDocument.GetMasterPageUserCount(GetSelectedMasterPage()) > 0)
+ {
+ rItemSet.DisableItem(SID_DELETE_MASTER_PAGE);
+ }
+
+ ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
+ ::boost::dynamic_pointer_cast<DrawViewShell>(mrBase.GetMainViewShell()));
+ if (rItemSet.GetItemState(SID_TP_EDIT_MASTER) == SFX_ITEM_AVAILABLE
+ && pDrawViewShell
+ && pDrawViewShell->GetEditMode() == EM_MASTERPAGE)
+ {
+ rItemSet.DisableItem (SID_TP_EDIT_MASTER);
+ }
+
+ MasterPagesSelector::GetState(rItemSet);
+}
+
+
+
+
+
+
+IMPL_LINK(CurrentMasterPagesSelector,EventMultiplexerListener,
+ sd::tools::EventMultiplexerEvent*,pEvent)
+{
+ if (pEvent != NULL)
+ {
+ switch (pEvent->meEventId)
+ {
+ case sd::tools::EventMultiplexerEvent::EID_CURRENT_PAGE:
+ case sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_NORMAL:
+ case sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_MASTER:
+ case sd::tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION:
+ UpdateSelection();
+ break;
+
+ case sd::tools::EventMultiplexerEvent::EID_PAGE_ORDER:
+ // This is tricky. If a master page is removed, moved, or
+ // added we have to wait until both the notes master page
+ // and the standard master page have been removed, moved,
+ // or added. We do this by looking at the number of master
+ // pages which has to be odd in the consistent state (the
+ // handout master page is always present). If the number is
+ // even we ignore the hint.
+ if (mrBase.GetDocument()->GetMasterPageCount()%2 == 1)
+ MasterPagesSelector::Fill();
+ break;
+
+ case sd::tools::EventMultiplexerEvent::EID_SHAPE_CHANGED:
+ case sd::tools::EventMultiplexerEvent::EID_SHAPE_INSERTED:
+ case sd::tools::EventMultiplexerEvent::EID_SHAPE_REMOVED:
+ InvalidatePreview((const SdPage*)pEvent->mpUserData);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+
+
+void CurrentMasterPagesSelector::Notify (SfxBroadcaster&, const SfxHint& rHint)
+{
+ const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
+ if (pSimpleHint != NULL)
+ {
+ if (pSimpleHint->GetId() == SFX_HINT_DOCCHANGED)
+ {
+ // Is the edit view visible in the center pane?
+ ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
+ ::boost::dynamic_pointer_cast<DrawViewShell>(mrBase.GetMainViewShell()));
+ if (pDrawViewShell.get() != NULL)
+ {
+ // Is the edit view in master page mode?
+ if (pDrawViewShell->GetEditMode() == EM_MASTERPAGE)
+ {
+ // Mark the currently edited master page as precious.
+ SdPage* pCurrentMasterPage = pDrawViewShell->getCurrentPage();
+ if (pCurrentMasterPage != NULL)
+ pCurrentMasterPage->SetPrecious(true);
+ }
+ }
+ }
+ }
+}
+
+
+
+
+} } } // end of namespace ::sd::toolpanel::controls
diff --git a/sd/source/ui/toolpanel/controls/CurrentMasterPagesSelector.hxx b/sd/source/ui/toolpanel/controls/CurrentMasterPagesSelector.hxx
new file mode 100644
index 000000000000..ee3503d9787d
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/CurrentMasterPagesSelector.hxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANEL_CONTROLS_CURRENT_MASTER_PAGES_SELECTOR_HXX
+#define SD_TOOLPANEL_CONTROLS_CURRENT_MASTER_PAGES_SELECTOR_HXX
+
+#include "MasterPagesSelector.hxx"
+#include <com/sun/star/lang/XComponent.hpp>
+
+namespace sd { namespace tools { class EventMultiplexerEvent; } }
+
+
+namespace sd { namespace toolpanel { namespace controls {
+
+
+/** Show the master pages currently used by a SdDrawDocument.
+*/
+class CurrentMasterPagesSelector
+ : public MasterPagesSelector,
+ public SfxListener
+{
+public:
+ CurrentMasterPagesSelector (
+ TreeNode* pParent,
+ SdDrawDocument& rDocument,
+ ViewShellBase& rBase,
+ const ::boost::shared_ptr<MasterPageContainer>& rpContainer);
+ virtual ~CurrentMasterPagesSelector (void);
+
+ virtual void LateInit (void);
+
+ /** Set the selection so that the master page is selected that is
+ used by the currently selected page of the document in the
+ center pane.
+ */
+ virtual void UpdateSelection (void);
+
+ /** Copy all master pages that are to be shown into the given list.
+ */
+ virtual void Fill (ItemList& rItemList);
+
+ using sd::toolpanel::controls::MasterPagesSelector::Fill;
+
+protected:
+ virtual ResId GetContextMenuResId (void) const;
+ virtual void Execute (SfxRequest& rRequest);
+ virtual void GetState (SfxItemSet& rItemSet);
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent>
+ mxListener;
+
+ DECL_LINK(EventMultiplexerListener,sd::tools::EventMultiplexerEvent*);
+ void Notify (SfxBroadcaster&, const SfxHint& rHint);
+};
+
+} } } // end of namespace ::sd::toolpanel::controls
+
+#endif
diff --git a/sd/source/ui/toolpanel/controls/CustomAnimationPanel.cxx b/sd/source/ui/toolpanel/controls/CustomAnimationPanel.cxx
new file mode 100755
index 000000000000..e7edf109cffd
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/CustomAnimationPanel.cxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "CustomAnimationPanel.hxx"
+
+#include "taskpane/TaskPaneControlFactory.hxx"
+#include "taskpane/ToolPanelViewShell.hxx"
+
+#include "strings.hrc"
+#include "sdresid.hxx"
+
+namespace sd
+{
+
+ class ViewShellBase;
+ extern ::Window * createCustomAnimationPanel( ::Window* pParent, ViewShellBase& rBase );
+
+namespace toolpanel { namespace controls {
+
+
+CustomAnimationPanel::CustomAnimationPanel(Window& i_rParentWindow, ToolPanelViewShell& i_rPanelViewShell)
+ :SubToolPanel( i_rParentWindow )
+ ,m_pPanelViewShell( &i_rPanelViewShell )
+{
+ mpWrappedControl = createCustomAnimationPanel( &i_rParentWindow, i_rPanelViewShell.GetViewShellBase() );
+ mpWrappedControl->Show();
+}
+
+CustomAnimationPanel::~CustomAnimationPanel()
+{
+ delete mpWrappedControl;
+}
+
+std::auto_ptr< ControlFactory > CustomAnimationPanel::CreateControlFactory( ToolPanelViewShell& i_rToolPanelShell )
+{
+ return std::auto_ptr< ControlFactory >(
+ new RootControlFactoryWithArg< CustomAnimationPanel, ToolPanelViewShell >( i_rToolPanelShell ) );
+}
+
+TaskPaneShellManager* CustomAnimationPanel::GetShellManager()
+{
+ if ( m_pPanelViewShell )
+ return &m_pPanelViewShell->GetSubShellManager();
+ return SubToolPanel::GetShellManager();
+}
+
+Size CustomAnimationPanel::GetPreferredSize()
+{
+ return maPreferredSize;
+}
+sal_Int32 CustomAnimationPanel::GetPreferredWidth(sal_Int32 )
+{
+ return maPreferredSize.Width();
+}
+sal_Int32 CustomAnimationPanel::GetPreferredHeight(sal_Int32 )
+{
+ return maPreferredSize.Height();
+}
+::Window* CustomAnimationPanel::GetWindow()
+{
+ return mpWrappedControl;
+}
+bool CustomAnimationPanel::IsResizable()
+{
+ return true;
+}
+bool CustomAnimationPanel::IsExpandable() const
+{
+ return true;
+}
+
+
+
+
+::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible> CustomAnimationPanel::CreateAccessibleObject (
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& )
+{
+ if (GetWindow() != NULL)
+ return GetWindow()->GetAccessible();
+ else
+ return NULL;
+}
+
+} } } // end of namespace ::sd::toolpanel::controls
diff --git a/sd/source/ui/toolpanel/controls/CustomAnimationPanel.hxx b/sd/source/ui/toolpanel/controls/CustomAnimationPanel.hxx
new file mode 100755
index 000000000000..864ba637b94d
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/CustomAnimationPanel.hxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANEL_CONTROLS_CUSTOM_ANIMATION_PANEL_HXX
+#define SD_TOOLPANEL_CONTROLS_CUSTOM_ANIMATION_PANEL_HXX
+
+#include "taskpane/SubToolPanel.hxx"
+
+namespace sd {
+class ViewShellBase;
+}
+
+namespace sd { namespace toolpanel {
+class TreeNode;
+class ControlFactory;
+class ToolPanelViewShell;
+} }
+
+namespace sd { namespace toolpanel { namespace controls {
+
+class CustomAnimationPanel
+ : public SubToolPanel
+{
+public:
+ CustomAnimationPanel (
+ Window& i_rParentWindow,
+ ToolPanelViewShell& i_rPanelViewShell);
+ virtual ~CustomAnimationPanel (void);
+
+ static std::auto_ptr<ControlFactory> CreateControlFactory (ToolPanelViewShell& i_rPanelViewShell);
+
+ // TreeNode overridables
+ virtual TaskPaneShellManager* GetShellManager();
+
+ // ILayoutableWindow overridables
+ virtual Size GetPreferredSize (void);
+ virtual sal_Int32 GetPreferredWidth (sal_Int32 nHeigh);
+ virtual sal_Int32 GetPreferredHeight (sal_Int32 nWidth);
+ virtual ::Window* GetWindow (void);
+ virtual bool IsResizable (void);
+ virtual bool IsExpandable (void) const;
+
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible > CreateAccessibleObject (
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent);
+
+ using Window::GetWindow;
+private:
+ Size maPreferredSize;
+ ::Window* mpWrappedControl;
+ ToolPanelViewShell* m_pPanelViewShell;
+};
+
+} } } // end of namespace ::sd::toolpanel::controls
+
+#endif
diff --git a/sd/source/ui/toolpanel/controls/DocumentHelper.cxx b/sd/source/ui/toolpanel/controls/DocumentHelper.cxx
new file mode 100755
index 000000000000..b9040e72283f
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/DocumentHelper.cxx
@@ -0,0 +1,552 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "DocumentHelper.hxx"
+
+#include "drawdoc.hxx"
+#include "DrawDocShell.hxx"
+#include "sdpage.hxx"
+#include "glob.hxx"
+#include "unmovss.hxx"
+#include "strings.hrc"
+#include "sdresid.hxx"
+#include "undoback.hxx"
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPages.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include "stlpool.hxx"
+#include <svx/xfillit0.hxx>
+#include <tools/diagnose_ex.h>
+
+using namespace ::com::sun::star;
+
+namespace sd { namespace toolpanel { namespace controls {
+
+SdPage* DocumentHelper::CopyMasterPageToLocalDocument (
+ SdDrawDocument& rTargetDocument,
+ SdPage* pMasterPage)
+{
+ SdPage* pNewMasterPage = NULL;
+
+ do
+ {
+ if (pMasterPage == NULL)
+ break;
+
+ // Check the presence of the source document.
+ SdDrawDocument* pSourceDocument = static_cast<SdDrawDocument*>(
+ pMasterPage->GetModel());
+ if (pSourceDocument == NULL)
+ break;
+
+ // When the given master page already belongs to the target document
+ // then there is nothing more to do.
+ if (pSourceDocument == &rTargetDocument)
+ {
+ pNewMasterPage = pMasterPage;
+ break;
+ }
+
+ // Test if the master pages of both the slide and its notes page are
+ // present. This is not the case when we are called during the
+ // creation of the slide master page because then the notes master
+ // page is not there.
+ USHORT nSourceMasterPageCount = pSourceDocument->GetMasterPageCount();
+ if (nSourceMasterPageCount%2 == 0)
+ // There should be 1 handout page + n slide masters + n notes
+ // masters = 2*n+1. An even value indicates that a new slide
+ // master but not yet the notes master has been inserted.
+ break;
+ USHORT nIndex = pMasterPage->GetPageNum();
+ if (nSourceMasterPageCount <= nIndex+1)
+ break;
+ // Get the slide master page.
+ if (pMasterPage != static_cast<SdPage*>(
+ pSourceDocument->GetMasterPage(nIndex)))
+ break;
+ // Get the notes master page.
+ SdPage* pNotesMasterPage = static_cast<SdPage*>(
+ pSourceDocument->GetMasterPage(nIndex+1));
+ if (pNotesMasterPage == NULL)
+ break;
+
+
+ // Check if a master page with the same name as that of the given
+ // master page already exists.
+ bool bPageExists (false);
+ USHORT nMasterPageCount(rTargetDocument.GetMasterSdPageCount(PK_STANDARD));
+ for (USHORT nMaster=0; nMaster<nMasterPageCount; nMaster++)
+ {
+ SdPage* pCandidate = static_cast<SdPage*>(
+ rTargetDocument.GetMasterSdPage (nMaster, PK_STANDARD));
+ if (pMasterPage!=NULL
+ && pCandidate->GetName().CompareTo(pMasterPage->GetName())==0)
+ {
+ bPageExists = true;
+ pNewMasterPage = pCandidate;
+ break;
+ }
+ }
+ if (bPageExists)
+ break;
+
+ // Create a new slide (and its notes page.)
+ uno::Reference<drawing::XDrawPagesSupplier> xSlideSupplier (
+ rTargetDocument.getUnoModel(), uno::UNO_QUERY);
+ if ( ! xSlideSupplier.is())
+ break;
+ uno::Reference<drawing::XDrawPages> xSlides (
+ xSlideSupplier->getDrawPages(), uno::UNO_QUERY);
+ if ( ! xSlides.is())
+ break;
+ xSlides->insertNewByIndex (xSlides->getCount());
+
+ // Set a layout.
+ SdPage* pSlide = rTargetDocument.GetSdPage(
+ rTargetDocument.GetSdPageCount(PK_STANDARD)-1,
+ PK_STANDARD);
+ if (pSlide == NULL)
+ break;
+ pSlide->SetAutoLayout(AUTOLAYOUT_TITLE, TRUE);
+
+ // Create a copy of the master page and the associated notes
+ // master page and insert them into our document.
+ pNewMasterPage = AddMasterPage(rTargetDocument, pMasterPage);
+ if (pNewMasterPage==NULL)
+ break;
+ SdPage* pNewNotesMasterPage
+ = AddMasterPage(rTargetDocument, pNotesMasterPage);
+ if (pNewNotesMasterPage==NULL)
+ break;
+
+ // Make the connection from the new slide to the master page
+ // (and do the same for the notes page.)
+ rTargetDocument.SetMasterPage (
+ rTargetDocument.GetSdPageCount(PK_STANDARD)-1,
+ pNewMasterPage->GetName(),
+ &rTargetDocument,
+ FALSE, // Connect the new master page with the new slide but
+ // do not modify other (master) pages.
+ TRUE);
+ }
+ while (false);
+
+ // We are not interested in any automatisms for our modified internal
+ // document.
+ rTargetDocument.SetChanged (sal_False);
+
+ return pNewMasterPage;
+}
+
+
+
+
+SdPage* DocumentHelper::GetSlideForMasterPage (SdPage* pMasterPage)
+{
+ SdPage* pCandidate = NULL;
+
+ SdDrawDocument* pDocument = NULL;
+ if (pMasterPage != NULL)
+ pDocument = dynamic_cast<SdDrawDocument*>(pMasterPage->GetModel());
+
+ // Iterate over all pages and check if it references the given master
+ // page.
+ if (pDocument!=NULL && pDocument->GetSdPageCount(PK_STANDARD) > 0)
+ {
+ // In most cases a new slide has just been inserted so start with
+ // the last page.
+ USHORT nPageIndex (pDocument->GetSdPageCount(PK_STANDARD)-1);
+ bool bFound (false);
+ while ( ! bFound)
+ {
+ pCandidate = pDocument->GetSdPage(
+ nPageIndex,
+ PK_STANDARD);
+ if (pCandidate != NULL)
+ {
+ if (static_cast<SdPage*>(&pCandidate->TRG_GetMasterPage())
+ == pMasterPage)
+ {
+ bFound = true;
+ break;
+ }
+ }
+
+ if (nPageIndex == 0)
+ break;
+ else
+ nPageIndex --;
+ }
+
+ // If no page was found that refernced the given master page reset
+ // the pointer that is returned.
+ if ( ! bFound)
+ pCandidate = NULL;
+ }
+
+ return pCandidate;
+}
+
+
+
+
+SdPage* DocumentHelper::AddMasterPage (
+ SdDrawDocument& rTargetDocument,
+ SdPage* pMasterPage)
+{
+ SdPage* pClonedMasterPage = NULL;
+
+ if (pMasterPage!=NULL)
+ {
+ try
+ {
+ // Duplicate the master page.
+ pClonedMasterPage = static_cast<SdPage*>(pMasterPage->Clone());
+
+ // Copy the necessary styles.
+ SdDrawDocument* pSourceDocument
+ = static_cast<SdDrawDocument*>(pMasterPage->GetModel());
+ if (pSourceDocument != NULL)
+ ProvideStyles (*pSourceDocument, rTargetDocument, pClonedMasterPage);
+
+ // Copy the precious flag.
+ pClonedMasterPage->SetPrecious(pMasterPage->IsPrecious());
+
+ // Now that the styles are available we can insert the cloned
+ // master page.
+ rTargetDocument.InsertMasterPage (pClonedMasterPage);
+ }
+ catch (uno::Exception& rException)
+ {
+ pClonedMasterPage = NULL;
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ catch (::std::exception rException)
+ {
+ pClonedMasterPage = NULL;
+ OSL_TRACE ("caught general exception");
+ }
+ catch (...)
+ {
+ pClonedMasterPage = NULL;
+ OSL_TRACE ("caught general exception");
+ }
+ }
+
+ return pClonedMasterPage;
+}
+
+
+
+
+void DocumentHelper::ProvideStyles (
+ SdDrawDocument& rSourceDocument,
+ SdDrawDocument& rTargetDocument,
+ SdPage* pPage)
+{
+ // Get the layout name of the given page.
+ String sLayoutName (pPage->GetLayoutName());
+ sLayoutName.Erase (sLayoutName.SearchAscii (SD_LT_SEPARATOR));
+
+ // Copy the style sheet from source to target document.
+ SdStyleSheetPool* pSourceStyleSheetPool =
+ static_cast<SdStyleSheetPool*>(rSourceDocument.GetStyleSheetPool());
+ SdStyleSheetPool* pTargetStyleSheetPool =
+ static_cast<SdStyleSheetPool*>(rTargetDocument.GetStyleSheetPool());
+ SdStyleSheetVector aCreatedStyles;
+ pTargetStyleSheetPool->CopyLayoutSheets (
+ sLayoutName,
+ *pSourceStyleSheetPool,
+ aCreatedStyles);
+
+ // Add an undo action for the copied style sheets.
+ if( !aCreatedStyles.empty() )
+ {
+ SfxUndoManager* pUndoManager = rTargetDocument.GetDocSh()->GetUndoManager();
+ if (pUndoManager != NULL)
+ {
+ SdMoveStyleSheetsUndoAction* pMovStyles =
+ new SdMoveStyleSheetsUndoAction (
+ &rTargetDocument,
+ aCreatedStyles,
+ TRUE);
+ pUndoManager->AddUndoAction (pMovStyles);
+ }
+ }
+}
+
+
+
+
+void DocumentHelper::AssignMasterPageToPageList (
+ SdDrawDocument& rTargetDocument,
+ SdPage* pMasterPage,
+ const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList)
+{
+ do
+ {
+ if (pMasterPage == NULL && pMasterPage->IsMasterPage())
+ break;
+
+ // Make the layout name by stripping ouf the layout postfix from the
+ // layout name of the given master page.
+ String sFullLayoutName (pMasterPage->GetLayoutName());
+ String sBaseLayoutName (sFullLayoutName);
+ sBaseLayoutName.Erase (sBaseLayoutName.SearchAscii (SD_LT_SEPARATOR));
+
+ if (rpPageList->empty())
+ break;
+
+ // Create a second list that contains only the valid pointers to
+ // pages for which an assignment is necessary.
+ ::std::vector<SdPage*>::const_iterator iPage;
+ ::std::vector<SdPage*> aCleanedList;
+ for (iPage=rpPageList->begin(); iPage!=rpPageList->end(); ++iPage)
+ {
+ OSL_ASSERT(*iPage!=NULL && (*iPage)->GetModel() == &rTargetDocument);
+ if (*iPage != NULL
+ && (*iPage)->GetLayoutName().CompareTo(sFullLayoutName)!=0)
+ {
+ aCleanedList.push_back(*iPage);
+ }
+ }
+ if (aCleanedList.size() == 0)
+ break;
+
+ SfxUndoManager* pUndoMgr = rTargetDocument.GetDocSh()->GetUndoManager();
+ if( pUndoMgr )
+ pUndoMgr->EnterListAction(String(SdResId(STR_UNDO_SET_PRESLAYOUT)), String());
+
+ SdPage* pMasterPageInDocument = ProvideMasterPage(rTargetDocument,pMasterPage,rpPageList);
+ if (pMasterPageInDocument == NULL)
+ break;
+
+ // Assign the master pages to the given list of pages.
+ for (iPage=aCleanedList.begin();
+ iPage!=aCleanedList.end();
+ ++iPage)
+ {
+ AssignMasterPageToPage (
+ pMasterPageInDocument,
+ sBaseLayoutName,
+ *iPage);
+ }
+
+ if( pUndoMgr )
+ pUndoMgr->LeaveListAction();
+ }
+ while (false);
+}
+
+
+
+
+SdPage* DocumentHelper::AddMasterPage (
+ SdDrawDocument& rTargetDocument,
+ SdPage* pMasterPage,
+ USHORT nInsertionIndex)
+{
+ SdPage* pClonedMasterPage = NULL;
+
+ if (pMasterPage!=NULL)
+ {
+ // Duplicate the master page.
+ pClonedMasterPage = static_cast<SdPage*>(pMasterPage->Clone());
+
+ // Copy the precious flag.
+ pClonedMasterPage->SetPrecious(pMasterPage->IsPrecious());
+
+ // Copy the necessary styles.
+ SdDrawDocument* pSourceDocument
+ = static_cast<SdDrawDocument*>(pMasterPage->GetModel());
+ if (pSourceDocument != NULL)
+ {
+ ProvideStyles (*pSourceDocument, rTargetDocument, pClonedMasterPage);
+
+ // Now that the styles are available we can insert the cloned
+ // master page.
+ rTargetDocument.InsertMasterPage (pClonedMasterPage, nInsertionIndex);
+
+ // Adapt the size of the new master page to that of the pages in
+ // the document.
+ Size aNewSize (rTargetDocument.GetSdPage(0, pMasterPage->GetPageKind())->GetSize());
+ Rectangle aBorders (
+ pClonedMasterPage->GetLftBorder(),
+ pClonedMasterPage->GetUppBorder(),
+ pClonedMasterPage->GetRgtBorder(),
+ pClonedMasterPage->GetLwrBorder());
+ pClonedMasterPage->ScaleObjects(aNewSize, aBorders, TRUE);
+ pClonedMasterPage->SetSize(aNewSize);
+ pClonedMasterPage->CreateTitleAndLayout(TRUE);
+ }
+ }
+
+ return pClonedMasterPage;
+}
+
+
+
+
+/** In here we have to handle three cases:
+ 1. pPage is a normal slide. We can use SetMasterPage to assign the
+ master pages to it.
+ 2. pPage is a master page that is used by at least one slide. We can
+ assign the master page to these slides.
+ 3. pPage is a master page that is currently not used by any slide.
+ We can delete that page and add copies of the given master pages
+ instead.
+
+ For points 2 and 3 where one master page A is assigned to another B we have
+ to keep in mind that the master page that page A has already been
+ inserted into the target document.
+*/
+void DocumentHelper::AssignMasterPageToPage (
+ SdPage* pMasterPage,
+ const String& rsBaseLayoutName,
+ SdPage* pPage)
+{
+ // Leave early when the parameters are invalid.
+ if (pPage == NULL || pMasterPage == NULL)
+ return;
+ SdDrawDocument* pDocument = dynamic_cast<SdDrawDocument*>(pPage->GetModel());
+ if (pDocument == NULL)
+ return;
+
+ if ( ! pPage->IsMasterPage())
+ {
+ // 1. Remove the background object (so that that, if it exists, does
+ // not override the new master page) and assign the master page to
+ // the regular slide.
+ pDocument->GetDocSh()->GetUndoManager()->AddUndoAction(
+ new SdBackgroundObjUndoAction(
+ *pDocument, *pPage, pPage->getSdrPageProperties().GetItemSet()),
+ TRUE);
+ pPage->getSdrPageProperties().PutItem(XFillStyleItem(XFILL_NONE));
+
+ pDocument->SetMasterPage (
+ (pPage->GetPageNum()-1)/2,
+ rsBaseLayoutName,
+ pDocument,
+ FALSE,
+ FALSE);
+ }
+ else
+ {
+ // Find first slide that uses the master page.
+ SdPage* pSlide = NULL;
+ USHORT nPageCount = pDocument->GetSdPageCount(PK_STANDARD);
+ for (USHORT nPage=0; nPage<nPageCount&&pSlide==NULL; nPage++)
+ {
+ SdrPage* pCandidate = pDocument->GetSdPage(nPage,PK_STANDARD);
+ if (pCandidate != NULL
+ && pCandidate->TRG_HasMasterPage()
+ && &(pCandidate->TRG_GetMasterPage()) == pPage)
+ {
+ pSlide = static_cast<SdPage*>(pCandidate);
+ }
+ }
+
+ if (pSlide != NULL)
+ {
+ // 2. Assign the given master pages to the first slide that was
+ // found above that uses the master page.
+ pDocument->SetMasterPage (
+ (pSlide->GetPageNum()-1)/2,
+ rsBaseLayoutName,
+ pDocument,
+ FALSE,
+ FALSE);
+ }
+ else
+ {
+ // 3. Replace the master page A by a copy of the given master
+ // page B.
+ pDocument->RemoveUnnecessaryMasterPages (
+ pPage, FALSE);
+ }
+ }
+}
+
+
+
+
+SdPage* DocumentHelper::ProvideMasterPage (
+ SdDrawDocument& rTargetDocument,
+ SdPage* pMasterPage,
+ const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList)
+{
+ SdPage* pMasterPageInDocument = NULL;
+
+ // Get notes master page.
+ SdDrawDocument* pSourceDocument = static_cast<SdDrawDocument*>(pMasterPage->GetModel());
+ SdPage* pNotesMasterPage = static_cast<SdPage*>(
+ pSourceDocument->GetMasterPage (pMasterPage->GetPageNum()+1));
+ if (pNotesMasterPage != NULL)
+ {
+ // When the given master page or its associated notes master page do
+ // not already belong to the document we have to create copies of
+ // them and insert them into the document.
+
+ // Determine the position where the new master pages are inserted.
+ // By default they are inserted at the end. When we assign to a
+ // master page then insert after the last of the (selected) pages.
+ USHORT nInsertionIndex = rTargetDocument.GetMasterPageCount();
+ if (rpPageList->front()->IsMasterPage())
+ {
+ nInsertionIndex = rpPageList->back()->GetPageNum();
+ }
+
+ if (pMasterPage->GetModel() != &rTargetDocument)
+ {
+ pMasterPageInDocument = AddMasterPage (rTargetDocument, pMasterPage, nInsertionIndex);
+ if( rTargetDocument.IsUndoEnabled() )
+ rTargetDocument.AddUndo(
+ rTargetDocument.GetSdrUndoFactory().CreateUndoNewPage(*pMasterPageInDocument));
+ }
+ else
+ pMasterPageInDocument = pMasterPage;
+ if (pNotesMasterPage->GetModel() != &rTargetDocument)
+ {
+ SdPage* pClonedNotesMasterPage
+ = AddMasterPage (rTargetDocument, pNotesMasterPage, nInsertionIndex+1);
+ if( rTargetDocument.IsUndoEnabled() )
+ rTargetDocument.AddUndo(
+ rTargetDocument.GetSdrUndoFactory().CreateUndoNewPage(*pClonedNotesMasterPage));
+ }
+ }
+ return pMasterPageInDocument;
+}
+
+
+
+
+
+} } } // end of namespace ::sd::toolpanel::controls
diff --git a/sd/source/ui/toolpanel/controls/DocumentHelper.hxx b/sd/source/ui/toolpanel/controls/DocumentHelper.hxx
new file mode 100644
index 000000000000..2ff1c8aa575a
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/DocumentHelper.hxx
@@ -0,0 +1,116 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANEL_CONTROLS_DCUMENT_HELPER_HXX
+#define SD_TOOLPANEL_CONTROLS_DCUMENT_HELPER_HXX
+
+#include <tools/solar.h>
+#include <boost/shared_ptr.hpp>
+#include <vector>
+
+class SdDrawDocument;
+class SdPage;
+class String;
+
+namespace sd { namespace toolpanel { namespace controls {
+
+/** A collection of methods supporting the handling of master pages.
+*/
+class DocumentHelper
+{
+public:
+ /** Return a copy of the given master page in the given document.
+ */
+ static SdPage* CopyMasterPageToLocalDocument (
+ SdDrawDocument& rTargetDocument,
+ SdPage* pMasterPage);
+
+ /** Return and, when not yet present, create a slide that uses the given
+ masster page.
+ */
+ static SdPage* GetSlideForMasterPage (SdPage* pMasterPage);
+
+ /** Copy the styles used by the given page from the source document to
+ the target document.
+ */
+ static void ProvideStyles (
+ SdDrawDocument& rSourceDocument,
+ SdDrawDocument& rTargetDocument,
+ SdPage* pPage);
+
+ /** Assign the given master page to the list of pages.
+ @param rTargetDocument
+ The document that is the owner of the pages in rPageList.
+ @param pMasterPage
+ This master page will usually be a member of the list of all
+ available master pages as provided by the MasterPageContainer.
+ @param rPageList
+ The pages to which to assign the master page. These pages may
+ be slides or master pages themselves.
+ */
+ static void AssignMasterPageToPageList (
+ SdDrawDocument& rTargetDocument,
+ SdPage* pMasterPage,
+ const ::boost::shared_ptr<std::vector<SdPage*> >& rPageList);
+
+private:
+ static SdPage* AddMasterPage (
+ SdDrawDocument& rTargetDocument,
+ SdPage* pMasterPage);
+ static SdPage* AddMasterPage (
+ SdDrawDocument& rTargetDocument,
+ SdPage* pMasterPage,
+ USHORT nInsertionIndex);
+ static SdPage* ProvideMasterPage (
+ SdDrawDocument& rTargetDocument,
+ SdPage* pMasterPage,
+ const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList);
+
+ /** Assign the given master page to the given page.
+ @param pMasterPage
+ In contrast to AssignMasterPageToPageList() this page is assumed
+ to be in the target document, i.e. the same document that pPage
+ is in. The caller will usually call AddMasterPage() to create a
+ clone of a master page in a another document to create it.
+ @param rsBaseLayoutName
+ The layout name of the given master page. It is given so that
+ it has not to be created on every call. It could be generated
+ from the given master page, though.
+ @param pPage
+ The page to which to assign the master page. It can be a slide
+ or a master page itself.
+ */
+ static void AssignMasterPageToPage (
+ SdPage* pMasterPage,
+ const String& rsBaseLayoutName,
+ SdPage* pPage);
+};
+
+
+} } } // end of namespace ::sd::toolpanel::controls
+
+#endif
diff --git a/sd/source/ui/toolpanel/controls/MasterPageContainer.cxx b/sd/source/ui/toolpanel/controls/MasterPageContainer.cxx
new file mode 100755
index 000000000000..80a094ec1a66
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/MasterPageContainer.cxx
@@ -0,0 +1,1220 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "MasterPageContainer.hxx"
+
+#include "MasterPageDescriptor.hxx"
+#include "MasterPageContainerFiller.hxx"
+#include "MasterPageContainerQueue.hxx"
+#include "TemplateScanner.hxx"
+#include "tools/AsynchronousTask.hxx"
+#include "strings.hrc"
+#include <algorithm>
+#include <list>
+#include <set>
+
+#include "unomodel.hxx"
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <comphelper/processfactory.hxx>
+#include <tools/urlobj.hxx>
+#include <sfx2/app.hxx>
+#include <svx/svdpage.hxx>
+#include "DrawDocShell.hxx"
+#include "drawdoc.hxx"
+#include "sdpage.hxx"
+#include <svl/itemset.hxx>
+#include <svl/eitem.hxx>
+#include "sdresid.hxx"
+#include "tools/TimerBasedTaskExecution.hxx"
+#include "pres.hxx"
+#include <osl/mutex.hxx>
+#include <boost/weak_ptr.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::sd::toolpanel::controls;
+
+namespace {
+
+typedef ::std::vector<SharedMasterPageDescriptor> MasterPageContainerType;
+
+} // end of anonymous namespace
+
+
+namespace sd { namespace toolpanel { namespace controls {
+
+
+/** Inner implementation class of the MasterPageContainer.
+*/
+class MasterPageContainer::Implementation
+ : public SdGlobalResource,
+ public MasterPageContainerFiller::ContainerAdapter,
+ public MasterPageContainerQueue::ContainerAdapter
+{
+public:
+ mutable ::osl::Mutex maMutex;
+
+ static ::boost::weak_ptr<Implementation> mpInstance;
+ MasterPageContainerType maContainer;
+
+ static ::boost::shared_ptr<Implementation> Instance (void);
+
+ void LateInit (void);
+ void AddChangeListener (const Link& rLink);
+ void RemoveChangeListener (const Link& rLink);
+ void UpdatePreviewSizePixel (void);
+ Size GetPreviewSizePixel (PreviewSize eSize) const;
+
+ bool HasToken (Token aToken) const;
+ const SharedMasterPageDescriptor GetDescriptor (MasterPageContainer::Token aToken) const;
+ SharedMasterPageDescriptor GetDescriptor (MasterPageContainer::Token aToken);
+ virtual Token PutMasterPage (const SharedMasterPageDescriptor& rDescriptor);
+ void InvalidatePreview (Token aToken);
+ Image GetPreviewForToken (
+ Token aToken,
+ PreviewSize ePreviewSize);
+ PreviewState GetPreviewState (Token aToken) const;
+ bool RequestPreview (Token aToken);
+
+ Reference<frame::XModel> GetModel (void);
+ SdDrawDocument* GetDocument (void);
+
+ void FireContainerChange (
+ MasterPageContainerChangeEvent::EventType eType,
+ Token aToken,
+ bool bNotifyAsynchronously = false);
+
+ virtual bool UpdateDescriptor (
+ const SharedMasterPageDescriptor& rpDescriptor,
+ bool bForcePageObject,
+ bool bForcePreview,
+ bool bSendEvents);
+
+ void ReleaseDescriptor (Token aToken);
+
+ /** Called by the MasterPageContainerFiller to notify that all master
+ pages from template documents have been added.
+ */
+ virtual void FillingDone (void);
+
+private:
+ Implementation (void);
+ virtual ~Implementation (void);
+
+ class Deleter { public:
+ void operator() (Implementation* pObject) { delete pObject; }
+ };
+ friend class Deleter;
+
+ enum InitializationState { NOT_INITIALIZED, INITIALIZING, INITIALIZED } meInitializationState;
+
+ ::boost::scoped_ptr<MasterPageContainerQueue> mpRequestQueue;
+ ::com::sun::star::uno::Reference<com::sun::star::frame::XModel> mxModel;
+ SdDrawDocument* mpDocument;
+ PreviewRenderer maPreviewRenderer;
+ /** Remember whether the first page object has already been used to
+ determine the correct size ratio.
+ */
+ bool mbFirstPageObjectSeen;
+
+ // The widths for the previews contain two pixels for the border that is
+ // painted arround the preview.
+ static const int SMALL_PREVIEW_WIDTH = 72 + 2;
+ static const int LARGE_PREVIEW_WIDTH = 2*72 + 2;
+
+ /** This substition of page preview shows "Preparing preview" and is
+ shown as long as the actual previews are not being present.
+ */
+ Image maLargePreviewBeingCreated;
+ Image maSmallPreviewBeingCreated;
+
+ /** This substition of page preview is shown when a preview can not be
+ created and thus is not available.
+ */
+ Image maLargePreviewNotAvailable;
+ Image maSmallPreviewNotAvailable;
+
+ ::std::vector<Link> maChangeListeners;
+
+ // We have to remember the tasks for initialization and filling in case
+ // a MasterPageContainer object is destroyed before these tasks have
+ // been completed.
+ ::boost::weak_ptr<sd::tools::TimerBasedTaskExecution> mpFillerTask;
+
+ Size maSmallPreviewSizePixel;
+ Size maLargePreviewSizePixel;
+ bool mbPageRatioKnown;
+
+ bool mbContainerCleaningPending;
+
+ typedef ::std::pair<MasterPageContainerChangeEvent::EventType,Token> EventData;
+ DECL_LINK(AsynchronousNotifyCallback, EventData*);
+ ::sd::DrawDocShell* LoadDocument (
+ const String& sFileName,
+ SfxObjectShellLock& rxDocumentShell);
+
+ Image GetPreviewSubstitution (USHORT nId, PreviewSize ePreviewSize);
+
+ void CleanContainer (void);
+};
+
+
+
+
+//===== MasterPageContainer ===================================================
+
+::boost::weak_ptr<MasterPageContainer::Implementation>
+ MasterPageContainer::Implementation::mpInstance;
+static const MasterPageContainer::Token NIL_TOKEN (-1);
+
+
+
+
+::boost::shared_ptr<MasterPageContainer::Implementation>
+ MasterPageContainer::Implementation::Instance (void)
+{
+ ::boost::shared_ptr<MasterPageContainer::Implementation> pInstance;
+
+ if (Implementation::mpInstance.expired())
+ {
+ ::osl::GetGlobalMutex aMutexFunctor;
+ ::osl::MutexGuard aGuard (aMutexFunctor());
+ if (Implementation::mpInstance.expired())
+ {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ pInstance = ::boost::shared_ptr<MasterPageContainer::Implementation>(
+ new MasterPageContainer::Implementation(),
+ MasterPageContainer::Implementation::Deleter());
+ SdGlobalResourceContainer::Instance().AddResource(pInstance);
+ Implementation::mpInstance = pInstance;
+ }
+ else
+ pInstance = ::boost::shared_ptr<MasterPageContainer::Implementation>(
+ Implementation::mpInstance);
+ }
+ else
+ {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ pInstance = ::boost::shared_ptr<MasterPageContainer::Implementation>(
+ Implementation::mpInstance);
+ }
+
+ DBG_ASSERT (pInstance.get()!=NULL,
+ "MasterPageContainer::Implementation::Instance(): instance is NULL");
+ return pInstance;
+}
+
+
+
+
+MasterPageContainer::MasterPageContainer (void)
+ : mpImpl(Implementation::Instance()),
+ mePreviewSize(SMALL)
+{
+ mpImpl->LateInit();
+}
+
+
+
+
+MasterPageContainer::~MasterPageContainer (void)
+{
+}
+
+
+
+
+void MasterPageContainer::AddChangeListener (const Link& rLink)
+{
+ mpImpl->AddChangeListener(rLink);
+}
+
+
+
+
+void MasterPageContainer::RemoveChangeListener (const Link& rLink)
+{
+ mpImpl->RemoveChangeListener(rLink);
+}
+
+
+
+
+void MasterPageContainer::SetPreviewSize (PreviewSize eSize)
+{
+ mePreviewSize = eSize;
+ mpImpl->FireContainerChange(
+ MasterPageContainerChangeEvent::SIZE_CHANGED,
+ NIL_TOKEN);
+}
+
+
+
+
+MasterPageContainer::PreviewSize MasterPageContainer::GetPreviewSize (void) const
+{
+ return mePreviewSize;
+}
+
+
+
+
+Size MasterPageContainer::GetPreviewSizePixel (void) const
+{
+ return mpImpl->GetPreviewSizePixel(mePreviewSize);
+}
+
+
+
+
+MasterPageContainer::Token MasterPageContainer::PutMasterPage (
+ const SharedMasterPageDescriptor& rDescriptor)
+{
+ return mpImpl->PutMasterPage(rDescriptor);
+}
+
+
+
+
+void MasterPageContainer::AcquireToken (Token aToken)
+{
+ SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
+ if (pDescriptor.get() != NULL)
+ {
+ ++pDescriptor->mnUseCount;
+ }
+}
+
+
+
+
+void MasterPageContainer::ReleaseToken (Token aToken)
+{
+ SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
+ if (pDescriptor.get() != NULL)
+ {
+ OSL_ASSERT(pDescriptor->mnUseCount>0);
+ --pDescriptor->mnUseCount;
+ if (pDescriptor->mnUseCount <= 0)
+ {
+ switch (pDescriptor->meOrigin)
+ {
+ case DEFAULT:
+ case TEMPLATE:
+ default:
+ break;
+
+ case MASTERPAGE:
+ mpImpl->ReleaseDescriptor(aToken);
+ break;
+ }
+ }
+ }
+}
+
+
+
+
+int MasterPageContainer::GetTokenCount (void) const
+{
+ const ::osl::MutexGuard aGuard (mpImpl->maMutex);
+
+ return mpImpl->maContainer.size();
+}
+
+
+
+
+bool MasterPageContainer::HasToken (Token aToken) const
+{
+ const ::osl::MutexGuard aGuard (mpImpl->maMutex);
+
+ return mpImpl->HasToken(aToken);
+}
+
+
+
+
+MasterPageContainer::Token MasterPageContainer::GetTokenForIndex (int nIndex)
+{
+ const ::osl::MutexGuard aGuard (mpImpl->maMutex);
+
+ Token aResult (NIL_TOKEN);
+ if (HasToken(nIndex))
+ aResult = mpImpl->maContainer[nIndex]->maToken;
+ return aResult;
+}
+
+
+
+
+MasterPageContainer::Token MasterPageContainer::GetTokenForURL (
+ const String& sURL)
+{
+ const ::osl::MutexGuard aGuard (mpImpl->maMutex);
+
+ Token aResult (NIL_TOKEN);
+ if (sURL.Len() > 0)
+ {
+ MasterPageContainerType::iterator iEntry (
+ ::std::find_if (
+ mpImpl->maContainer.begin(),
+ mpImpl->maContainer.end(),
+ MasterPageDescriptor::URLComparator(sURL)));
+ if (iEntry != mpImpl->maContainer.end())
+ aResult = (*iEntry)->maToken;
+ }
+ return aResult;
+}
+
+
+
+
+MasterPageContainer::Token MasterPageContainer::GetTokenForStyleName (const String& sStyleName)
+{
+ const ::osl::MutexGuard aGuard (mpImpl->maMutex);
+
+ Token aResult (NIL_TOKEN);
+ if (sStyleName.Len() > 0)
+ {
+ MasterPageContainerType::iterator iEntry (
+ ::std::find_if (
+ mpImpl->maContainer.begin(),
+ mpImpl->maContainer.end(),
+ MasterPageDescriptor::StyleNameComparator(sStyleName)));
+ if (iEntry != mpImpl->maContainer.end())
+ aResult = (*iEntry)->maToken;
+ }
+ return aResult;
+}
+
+
+
+
+MasterPageContainer::Token MasterPageContainer::GetTokenForPageObject (
+ const SdPage* pPage)
+{
+ const ::osl::MutexGuard aGuard (mpImpl->maMutex);
+
+ Token aResult (NIL_TOKEN);
+ if (pPage != NULL)
+ {
+ MasterPageContainerType::iterator iEntry (
+ ::std::find_if (
+ mpImpl->maContainer.begin(),
+ mpImpl->maContainer.end(),
+ MasterPageDescriptor::PageObjectComparator(pPage)));
+ if (iEntry != mpImpl->maContainer.end())
+ aResult = (*iEntry)->maToken;
+ }
+ return aResult;
+}
+
+
+
+
+String MasterPageContainer::GetURLForToken (
+ MasterPageContainer::Token aToken)
+{
+ const ::osl::MutexGuard aGuard (mpImpl->maMutex);
+
+ SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
+ if (pDescriptor.get() != NULL)
+ return pDescriptor->msURL;
+ else
+ return String();
+}
+
+
+
+
+String MasterPageContainer::GetPageNameForToken (
+ MasterPageContainer::Token aToken)
+{
+ const ::osl::MutexGuard aGuard (mpImpl->maMutex);
+
+ SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
+ if (pDescriptor.get() != NULL)
+ return pDescriptor->msPageName;
+ else
+ return String();
+}
+
+
+
+
+String MasterPageContainer::GetStyleNameForToken (
+ MasterPageContainer::Token aToken)
+{
+ const ::osl::MutexGuard aGuard (mpImpl->maMutex);
+
+ SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
+ if (pDescriptor.get() != NULL)
+ return pDescriptor->msStyleName;
+ else
+ return String();
+}
+
+
+
+
+SdPage* MasterPageContainer::GetPageObjectForToken (
+ MasterPageContainer::Token aToken,
+ bool bLoad)
+{
+ const ::osl::MutexGuard aGuard (mpImpl->maMutex);
+
+ SdPage* pPageObject = NULL;
+ SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
+ if (pDescriptor.get() != NULL)
+ {
+ pPageObject = pDescriptor->mpMasterPage;
+ if (pPageObject == NULL)
+ {
+ // The page object is not (yet) present. Call
+ // UpdateDescriptor() to trigger the PageObjectProvider() to
+ // provide it.
+ if (bLoad)
+ mpImpl->GetModel();
+ if (mpImpl->UpdateDescriptor(pDescriptor,bLoad,false, true))
+ pPageObject = pDescriptor->mpMasterPage;
+ }
+ }
+ return pPageObject;
+}
+
+
+
+
+MasterPageContainer::Origin MasterPageContainer::GetOriginForToken (Token aToken)
+{
+ const ::osl::MutexGuard aGuard (mpImpl->maMutex);
+
+ SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
+ if (pDescriptor.get() != NULL)
+ return pDescriptor->meOrigin;
+ else
+ return UNKNOWN;
+}
+
+
+
+
+sal_Int32 MasterPageContainer::GetTemplateIndexForToken (Token aToken)
+{
+ const ::osl::MutexGuard aGuard (mpImpl->maMutex);
+
+ SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
+ if (pDescriptor.get() != NULL)
+ return pDescriptor->mnTemplateIndex;
+ else
+ return -1;
+}
+
+
+
+
+SharedMasterPageDescriptor MasterPageContainer::GetDescriptorForToken (
+ MasterPageContainer::Token aToken)
+{
+ const ::osl::MutexGuard aGuard (mpImpl->maMutex);
+
+ return mpImpl->GetDescriptor(aToken);
+}
+
+
+
+void MasterPageContainer::InvalidatePreview (MasterPageContainer::Token aToken)
+{
+ mpImpl->InvalidatePreview(aToken);
+}
+
+
+
+
+Image MasterPageContainer::GetPreviewForToken (MasterPageContainer::Token aToken)
+{
+ return mpImpl->GetPreviewForToken(aToken,mePreviewSize);
+}
+
+
+
+
+MasterPageContainer::PreviewState MasterPageContainer::GetPreviewState (Token aToken)
+{
+ return mpImpl->GetPreviewState(aToken);
+}
+
+
+
+
+bool MasterPageContainer::RequestPreview (Token aToken)
+{
+ return mpImpl->RequestPreview(aToken);
+}
+
+
+
+
+//==== Implementation ================================================
+
+MasterPageContainer::Implementation::Implementation (void)
+ : maMutex(),
+ maContainer(),
+ meInitializationState(NOT_INITIALIZED),
+ mpRequestQueue(NULL),
+ mxModel(NULL),
+ mpDocument(NULL),
+ maPreviewRenderer(),
+ mbFirstPageObjectSeen(false),
+ maLargePreviewBeingCreated(),
+ maSmallPreviewBeingCreated(),
+ maLargePreviewNotAvailable(),
+ maSmallPreviewNotAvailable(),
+ maChangeListeners(),
+ maSmallPreviewSizePixel(),
+ maLargePreviewSizePixel(),
+ mbPageRatioKnown(false),
+ mbContainerCleaningPending(true)
+
+{
+ UpdatePreviewSizePixel();
+}
+
+
+
+
+MasterPageContainer::Implementation::~Implementation (void)
+{
+ // When the initializer or filler tasks are still running then we have
+ // to stop them now in order to prevent them from calling us back.
+ tools::TimerBasedTaskExecution::ReleaseTask(mpFillerTask);
+
+ mpRequestQueue.reset();
+
+ uno::Reference<util::XCloseable> xCloseable (mxModel, uno::UNO_QUERY);
+ if (xCloseable.is())
+ {
+ try
+ {
+ xCloseable->close(true);
+ }
+ catch (::com::sun::star::util::CloseVetoException aException)
+ {
+ }
+ }
+ mxModel = NULL;
+}
+
+
+
+
+void MasterPageContainer::Implementation::LateInit (void)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ if (meInitializationState == NOT_INITIALIZED)
+ {
+ meInitializationState = INITIALIZING;
+
+ OSL_ASSERT(Instance().get()==this);
+ mpRequestQueue.reset(MasterPageContainerQueue::Create(
+ ::boost::shared_ptr<MasterPageContainerQueue::ContainerAdapter>(Instance())));
+
+ mpFillerTask = ::sd::tools::TimerBasedTaskExecution::Create(
+ ::boost::shared_ptr<tools::AsynchronousTask>(new MasterPageContainerFiller(*this)),
+ 5,
+ 50);
+
+ meInitializationState = INITIALIZED;
+ }
+}
+
+
+
+
+void MasterPageContainer::Implementation::AddChangeListener (const Link& rLink)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ ::std::vector<Link>::iterator iListener (
+ ::std::find(maChangeListeners.begin(),maChangeListeners.end(),rLink));
+ if (iListener == maChangeListeners.end())
+ maChangeListeners.push_back(rLink);
+
+}
+
+
+
+
+void MasterPageContainer::Implementation::RemoveChangeListener (const Link& rLink)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ ::std::vector<Link>::iterator iListener (
+ ::std::find(maChangeListeners.begin(),maChangeListeners.end(),rLink));
+ if (iListener != maChangeListeners.end())
+ maChangeListeners.erase(iListener);
+}
+
+
+
+
+void MasterPageContainer::Implementation::UpdatePreviewSizePixel (void)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ // The default aspect ratio is 4:3
+ int nWidth (4);
+ int nHeight (3);
+
+ // Search for the first entry with an existing master page.
+ MasterPageContainerType::const_iterator iDescriptor;
+ MasterPageContainerType::const_iterator iContainerEnd(maContainer.end());
+ for (iDescriptor=maContainer.begin(); iDescriptor!=iContainerEnd; ++iDescriptor)
+ if (*iDescriptor!=NULL && (*iDescriptor)->mpMasterPage != NULL)
+ {
+ Size aPageSize ((*iDescriptor)->mpMasterPage->GetSize());
+ nWidth = aPageSize.Width();
+ nHeight = aPageSize.Height();
+ mbFirstPageObjectSeen = true;
+ break;
+ }
+
+ maSmallPreviewSizePixel.Width() = SMALL_PREVIEW_WIDTH;
+ maLargePreviewSizePixel.Width() = LARGE_PREVIEW_WIDTH;
+
+ int nNewSmallHeight ((maSmallPreviewSizePixel.Width()-2) * nHeight / nWidth + 2);
+ int nNewLargeHeight ((maLargePreviewSizePixel.Width()-2) * nHeight / nWidth + 2);
+
+ if (nNewSmallHeight!=maSmallPreviewSizePixel.Height()
+ || nNewLargeHeight!=maLargePreviewSizePixel.Height())
+ {
+ maSmallPreviewSizePixel.Height() = nNewSmallHeight;
+ maLargePreviewSizePixel.Height() = nNewLargeHeight;
+ FireContainerChange(
+ MasterPageContainerChangeEvent::SIZE_CHANGED,
+ NIL_TOKEN);
+ }
+}
+
+
+
+
+Size MasterPageContainer::Implementation::GetPreviewSizePixel (PreviewSize eSize) const
+{
+ if (eSize == SMALL)
+ return maSmallPreviewSizePixel;
+ else
+ return maLargePreviewSizePixel;
+}
+
+
+
+
+IMPL_LINK(MasterPageContainer::Implementation,AsynchronousNotifyCallback, EventData*, pData)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ if (pData != NULL)
+ {
+ FireContainerChange(pData->first, pData->second, false);
+ delete pData;
+ }
+
+ return 0;
+}
+
+
+
+
+MasterPageContainer::Token MasterPageContainer::Implementation::PutMasterPage (
+ const SharedMasterPageDescriptor& rpDescriptor)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ Token aResult (NIL_TOKEN);
+
+ // Get page object and preview when that is inexpensive.
+ UpdateDescriptor(rpDescriptor,false,false, false);
+
+ // Look up the new MasterPageDescriptor and either insert it or update
+ // an already existing one.
+ MasterPageContainerType::iterator aEntry (
+ ::std::find_if (
+ maContainer.begin(),
+ maContainer.end(),
+ MasterPageDescriptor::AllComparator(rpDescriptor)));
+ if (aEntry == maContainer.end())
+ {
+ // Insert a new MasterPageDescriptor.
+ bool bIgnore (rpDescriptor->mpPageObjectProvider.get()==NULL
+ && rpDescriptor->msURL.getLength()==0);
+
+ if ( ! bIgnore)
+ {
+ if (mbContainerCleaningPending)
+ CleanContainer();
+
+ aResult = maContainer.size();
+ rpDescriptor->SetToken(aResult);
+
+ // Templates are precious, i.e. we lock them so that they will
+ // not be destroyed when (temporarily) no one references them.
+ // They will only be deleted when the container is destroyed.
+ switch (rpDescriptor->meOrigin)
+ {
+ case TEMPLATE:
+ case DEFAULT:
+ ++rpDescriptor->mnUseCount;
+ break;
+
+ default:
+ break;
+ }
+
+ maContainer.push_back(rpDescriptor);
+ aEntry = maContainer.end()-1;
+
+ FireContainerChange(MasterPageContainerChangeEvent::CHILD_ADDED,aResult);
+ }
+ }
+ else
+ {
+ // Update an existing MasterPageDescriptor.
+ aResult = (*aEntry)->maToken;
+ ::std::auto_ptr<std::vector<MasterPageContainerChangeEvent::EventType> > pEventTypes(
+ (*aEntry)->Update(*rpDescriptor));
+ if (pEventTypes.get()!=NULL && pEventTypes->size()>0)
+ {
+ // One or more aspects of the descriptor have changed. Send
+ // appropriate events to the listeners.
+ UpdateDescriptor(*aEntry,false,false, true);
+
+ std::vector<MasterPageContainerChangeEvent::EventType>::const_iterator iEventType;
+ for (iEventType=pEventTypes->begin(); iEventType!=pEventTypes->end(); ++iEventType)
+ {
+ FireContainerChange(
+ *iEventType,
+ (*aEntry)->maToken,
+ false);
+ }
+ }
+ }
+
+ return aResult;
+}
+
+
+
+
+bool MasterPageContainer::Implementation::HasToken (Token aToken) const
+{
+ return aToken>=0
+ && (unsigned)aToken<maContainer.size()
+ && maContainer[aToken].get()!=NULL;
+}
+
+
+
+
+const SharedMasterPageDescriptor MasterPageContainer::Implementation::GetDescriptor (
+ Token aToken) const
+{
+ if (aToken>=0 && (unsigned)aToken<maContainer.size())
+ return maContainer[aToken];
+ else
+ return SharedMasterPageDescriptor();
+}
+
+
+
+
+SharedMasterPageDescriptor MasterPageContainer::Implementation::GetDescriptor (Token aToken)
+{
+ if (aToken>=0 && (unsigned)aToken<maContainer.size())
+ return maContainer[aToken];
+ else
+ return SharedMasterPageDescriptor();
+}
+
+
+
+
+void MasterPageContainer::Implementation::InvalidatePreview (Token aToken)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ SharedMasterPageDescriptor pDescriptor (GetDescriptor(aToken));
+ if (pDescriptor.get() != NULL)
+ {
+ pDescriptor->maSmallPreview = Image();
+ pDescriptor->maLargePreview = Image();
+ RequestPreview(aToken);
+ }
+}
+
+
+
+
+Image MasterPageContainer::Implementation::GetPreviewForToken (
+ MasterPageContainer::Token aToken,
+ PreviewSize ePreviewSize)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ Image aPreview;
+ PreviewState ePreviewState (GetPreviewState(aToken));
+
+ SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken);
+
+ // When the preview is missing but inexpensively creatable then do that
+ // now.
+ if (pDescriptor.get()!=NULL)
+ {
+ if (ePreviewState == PS_CREATABLE)
+ if (UpdateDescriptor(pDescriptor, false,false, true))
+ if (pDescriptor->maLargePreview.GetSizePixel().Width() != 0)
+ ePreviewState = PS_AVAILABLE;
+
+ switch (ePreviewState)
+ {
+ case PS_AVAILABLE:
+ aPreview = pDescriptor->GetPreview(ePreviewSize);
+ break;
+
+ case PS_PREPARING:
+ aPreview = GetPreviewSubstitution(
+ STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION,
+ ePreviewSize);
+ break;
+
+ case PS_CREATABLE:
+ aPreview = GetPreviewSubstitution(
+ STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION,
+ ePreviewSize);
+ break;
+
+ case PS_NOT_AVAILABLE:
+ aPreview = GetPreviewSubstitution(
+ STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION,
+ ePreviewSize);
+ if (ePreviewSize == SMALL)
+ pDescriptor->maSmallPreview = aPreview;
+ else
+ pDescriptor->maLargePreview = aPreview;
+ break;
+ }
+ }
+
+ return aPreview;
+}
+
+
+
+
+MasterPageContainer::PreviewState MasterPageContainer::Implementation::GetPreviewState (
+ Token aToken) const
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ PreviewState eState (PS_NOT_AVAILABLE);
+
+ SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken);
+ if (pDescriptor.get() != NULL)
+ {
+ if (pDescriptor->maLargePreview.GetSizePixel().Width() != 0)
+ eState = PS_AVAILABLE;
+ else if (pDescriptor->mpPreviewProvider.get() != NULL)
+ {
+ // The preview does not exist but can be created. When that is
+ // not expensive then do it at once.
+ if (mpRequestQueue->HasRequest(aToken))
+ eState = PS_PREPARING;
+ else
+ eState = PS_CREATABLE;
+ }
+ else
+ eState = PS_NOT_AVAILABLE;
+ }
+
+ return eState;
+}
+
+
+
+
+bool MasterPageContainer::Implementation::RequestPreview (Token aToken)
+{
+ SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken);
+ if (pDescriptor.get() != NULL)
+ return mpRequestQueue->RequestPreview(pDescriptor);
+ else
+ return false;
+}
+
+
+
+
+Reference<frame::XModel> MasterPageContainer::Implementation::GetModel (void)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ if ( ! mxModel.is())
+ {
+ // Get the desktop a s service factory.
+ ::rtl::OUString sDesktopServiceName (
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop"));
+ uno::Reference<frame::XComponentLoader> xDesktop (
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ sDesktopServiceName),
+ uno::UNO_QUERY);
+
+ // Create a new model.
+ ::rtl::OUString sModelServiceName (
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.presentation.PresentationDocument"));
+ mxModel = uno::Reference<frame::XModel>(
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ sModelServiceName),
+ uno::UNO_QUERY);
+
+ // Initialize the model.
+ uno::Reference<frame::XLoadable> xLoadable (mxModel,uno::UNO_QUERY);
+ if (xLoadable.is())
+ xLoadable->initNew();
+
+ // Use its tunnel to get a pointer to its core implementation.
+ uno::Reference<lang::XUnoTunnel> xUnoTunnel (mxModel, uno::UNO_QUERY);
+ if (xUnoTunnel.is())
+ {
+ mpDocument = reinterpret_cast<SdXImpressDocument*>(
+ xUnoTunnel->getSomething(
+ SdXImpressDocument::getUnoTunnelId()))->GetDoc();
+ }
+
+ // Create a default page.
+ uno::Reference<drawing::XDrawPagesSupplier> xSlideSupplier (mxModel, uno::UNO_QUERY);
+ if (xSlideSupplier.is())
+ {
+ uno::Reference<drawing::XDrawPages> xSlides (
+ xSlideSupplier->getDrawPages(), uno::UNO_QUERY);
+ if (xSlides.is())
+ {
+ sal_Int32 nIndex (0);
+ uno::Reference<drawing::XDrawPage> xNewPage (xSlides->insertNewByIndex(nIndex));
+ uno::Reference<beans::XPropertySet> xProperties(xNewPage, uno::UNO_QUERY);
+ if (xProperties.is())
+ xProperties->setPropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Layout")),
+ makeAny((sal_Int16)AUTOLAYOUT_TITLE));
+ }
+ }
+ }
+ return mxModel;
+}
+
+
+
+
+SdDrawDocument* MasterPageContainer::Implementation::GetDocument (void)
+{
+ GetModel();
+ return mpDocument;
+}
+
+
+
+
+Image MasterPageContainer::Implementation::GetPreviewSubstitution (
+ USHORT nId,
+ PreviewSize ePreviewSize)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ Image aPreview;
+
+ switch (nId)
+ {
+ case STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION:
+ {
+ Image& rPreview (ePreviewSize==SMALL
+ ? maSmallPreviewBeingCreated
+ : maLargePreviewBeingCreated);
+ if (rPreview.GetSizePixel().Width() == 0)
+ {
+ rPreview = maPreviewRenderer.RenderSubstitution(
+ ePreviewSize==SMALL ? maSmallPreviewSizePixel : maLargePreviewSizePixel,
+ SdResId(STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION));
+ }
+ aPreview = rPreview;
+ }
+ break;
+
+ case STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION:
+ {
+ Image& rPreview (ePreviewSize==SMALL
+ ? maSmallPreviewNotAvailable
+ : maLargePreviewNotAvailable);
+ if (rPreview.GetSizePixel().Width() == 0)
+ {
+ rPreview = maPreviewRenderer.RenderSubstitution(
+ ePreviewSize==SMALL ? maSmallPreviewSizePixel : maLargePreviewSizePixel,
+ SdResId(STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION));
+ }
+ aPreview = rPreview;
+ }
+ break;
+ }
+
+ return aPreview;
+}
+
+
+
+
+void MasterPageContainer::Implementation::CleanContainer (void)
+{
+ // Remove the empty elements at the end of the container. The empty
+ // elements in the middle can not be removed because that would
+ // invalidate the references still held by others.
+ int nIndex (maContainer.size()-1);
+ while (nIndex>=0 && maContainer[nIndex].get()==NULL)
+ --nIndex;
+ maContainer.resize(++nIndex);
+}
+
+
+
+
+void MasterPageContainer::Implementation::FireContainerChange (
+ MasterPageContainerChangeEvent::EventType eType,
+ Token aToken,
+ bool bNotifyAsynchronously)
+{
+ if (bNotifyAsynchronously)
+ {
+ Application::PostUserEvent(
+ LINK(this,Implementation,AsynchronousNotifyCallback),
+ new EventData(eType,aToken));
+ }
+ else
+ {
+ ::std::vector<Link> aCopy(maChangeListeners.begin(),maChangeListeners.end());
+ ::std::vector<Link>::iterator iListener;
+ MasterPageContainerChangeEvent aEvent;
+ aEvent.meEventType = eType;
+ aEvent.maChildToken = aToken;
+ for (iListener=aCopy.begin(); iListener!=aCopy.end(); ++iListener)
+ iListener->Call(&aEvent);
+ }
+}
+
+
+
+
+bool MasterPageContainer::Implementation::UpdateDescriptor (
+ const SharedMasterPageDescriptor& rpDescriptor,
+ bool bForcePageObject,
+ bool bForcePreview,
+ bool bSendEvents)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ // We have to create the page object when the preview provider needs it
+ // and the caller needs the preview.
+ bForcePageObject |= (bForcePreview
+ && rpDescriptor->mpPreviewProvider->NeedsPageObject()
+ && rpDescriptor->mpMasterPage==NULL);
+
+ // Define a cost threshold so that an update or page object or preview
+ // that is at least this cost are made at once. Updates with higher cost
+ // are scheduled for later.
+ sal_Int32 nCostThreshold (mpRequestQueue->IsEmpty() ? 5 : 0);
+
+ // Update the page object (which may be used for the preview update).
+ if (bForcePageObject)
+ GetDocument();
+ bool bPageObjectModified (rpDescriptor->UpdatePageObject(
+ (bForcePageObject ? -1 : nCostThreshold),
+ mpDocument));
+ if (bPageObjectModified && bSendEvents)
+ FireContainerChange(
+ MasterPageContainerChangeEvent::DATA_CHANGED,
+ rpDescriptor->maToken);
+ if (bPageObjectModified && ! mbFirstPageObjectSeen)
+ UpdatePreviewSizePixel();
+
+ // Update the preview.
+ bool bPreviewModified (rpDescriptor->UpdatePreview(
+ (bForcePreview ? -1 : nCostThreshold),
+ maSmallPreviewSizePixel,
+ maLargePreviewSizePixel,
+ maPreviewRenderer));
+
+ if (bPreviewModified && bSendEvents)
+ FireContainerChange(
+ MasterPageContainerChangeEvent::PREVIEW_CHANGED,
+ rpDescriptor->maToken);
+
+ return bPageObjectModified || bPreviewModified;
+}
+
+
+
+
+void MasterPageContainer::Implementation::ReleaseDescriptor (Token aToken)
+{
+ if (aToken>=0 && (unsigned)aToken<maContainer.size())
+ {
+ maContainer[aToken].reset();
+ mbContainerCleaningPending = true;
+ }
+}
+
+
+
+
+void MasterPageContainer::Implementation::FillingDone (void)
+{
+ mpRequestQueue->ProcessAllRequests();
+}
+
+
+
+} } } // end of namespace ::sd::toolpanel::controls
diff --git a/sd/source/ui/toolpanel/controls/MasterPageContainer.hxx b/sd/source/ui/toolpanel/controls/MasterPageContainer.hxx
new file mode 100755
index 000000000000..60f760f63e34
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/MasterPageContainer.hxx
@@ -0,0 +1,220 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANEL_CONTROLS_MASTER_PAGE_CONTAINER_HXX
+#define SD_TOOLPANEL_CONTROLS_MASTER_PAGE_CONTAINER_HXX
+
+#include "MasterPageContainerProviders.hxx"
+
+#include <osl/mutex.hxx>
+#include <tools/string.hxx>
+#include <vcl/image.hxx>
+#include <memory>
+#include "PreviewRenderer.hxx"
+#include <com/sun/star/frame/XModel.hpp>
+#include <vcl/timer.hxx>
+#include "tools/SdGlobalResourceContainer.hxx"
+
+#include <boost/shared_ptr.hpp>
+
+class SdPage;
+class SdDrawDocument;
+class SfxObjectShellLock;
+
+namespace sd {
+class DrawDocShell;
+}
+
+namespace sd { namespace toolpanel { namespace controls {
+
+class MasterPageDescriptor;
+
+/** This container manages the master pages used by the MasterPagesSelector
+ controls. It uses internally a singleton implementation object.
+ Therefore, all MasterPageContainer object operator on the same set of
+ master pages. Each MasterPageContainer, however, has its own
+ PreviewSize value and thus can independantly switch between large and
+ small previews.
+
+ The container maintains its own document to store master page objects.
+
+ For each master page container stores its URL, preview bitmap, page
+ name, and, if available, the page object.
+
+ Entries are accessed via a Token, which is mostly a numerical index but
+ whose values do not neccessarily have to be consecutive.
+*/
+class MasterPageContainer
+{
+public:
+ typedef int Token;
+ static const Token NIL_TOKEN = -1;
+
+ MasterPageContainer (void);
+ virtual ~MasterPageContainer (void);
+
+ void AddChangeListener (const Link& rLink);
+ void RemoveChangeListener (const Link& rLink);
+
+ enum PreviewSize { SMALL, LARGE };
+ /** There are two different preview sizes, a small one and a large one.
+ Which one is used by the called container can be changed with this
+ method.
+ When the preview size is changed then all change listeners are
+ notified of this.
+ */
+ void SetPreviewSize (PreviewSize eSize);
+
+ /** Returns the preview size.
+ */
+ PreviewSize GetPreviewSize (void) const;
+
+ /** Return the preview size in pixels.
+ */
+ Size GetPreviewSizePixel (void) const;
+
+ enum PreviewState { PS_AVAILABLE, PS_CREATABLE, PS_PREPARING, PS_NOT_AVAILABLE };
+ PreviewState GetPreviewState (Token aToken);
+
+ /** This method is typically called for entries in the container for
+ which GetPreviewState() returns OS_CREATABLE. The creation of the
+ preview is then scheduled to be executed asynchronously at a later
+ point in time. When the preview is available the change listeners
+ will be notified.
+ */
+ bool RequestPreview (Token aToken);
+
+ /** Each entry of the container is either the first page of a template
+ document or is a master page of an Impress document.
+ */
+ enum Origin {
+ MASTERPAGE, // Master page of a document.
+ TEMPLATE, // First page of a template file.
+ DEFAULT, // Empty master page with default style.
+ UNKNOWN
+ };
+
+ /** Put the master page identified and described by the given parameters
+ into the container. When there already is a master page with the
+ given URL, page name, or object pointer (when that is not NULL) then
+ the existing entry is replaced/updated by the given one. Otherwise
+ a new entry is inserted.
+ */
+ Token PutMasterPage (const ::boost::shared_ptr<MasterPageDescriptor>& rDescriptor);
+ void AcquireToken (Token aToken);
+ void ReleaseToken (Token aToken);
+
+ /** This and the GetTokenForIndex() methods can be used to iterate over
+ all members of the container.
+ */
+ int GetTokenCount (void) const;
+
+ /** Determine whether the container has a member for the given token.
+ */
+ bool HasToken (Token aToken) const;
+
+ /** Return a token for an index in the range
+ 0 <= index < GetTokenCount().
+ */
+ Token GetTokenForIndex (int nIndex);
+
+ Token GetTokenForURL (const String& sURL);
+ Token GetTokenForStyleName (const String& sStyleName);
+ Token GetTokenForPageObject (const SdPage* pPage);
+
+ String GetURLForToken (Token aToken);
+ String GetPageNameForToken (Token aToken);
+ String GetStyleNameForToken (Token aToken);
+ SdPage* GetPageObjectForToken (Token aToken, bool bLoad=true);
+ Origin GetOriginForToken (Token aToken);
+ sal_Int32 GetTemplateIndexForToken (Token aToken);
+ ::boost::shared_ptr<MasterPageDescriptor> GetDescriptorForToken (Token aToken);
+
+ void InvalidatePreview (Token aToken);
+
+ /** Return a preview for the specified token. When the preview is not
+ present then the PreviewProvider associated with the token is
+ executed only when that is not expensive. It is the responsibility
+ of the caller to call RequestPreview() to do the same
+ (asynchronously) for expensive PreviewProviders.
+ Call GetPreviewState() to find out if that is necessary.
+ @param aToken
+ This token specifies for which master page to return the prview.
+ Tokens are returned for example by the GetTokenFor...() methods.
+ @return
+ The returned image is the requested preview or a substitution.
+ */
+ Image GetPreviewForToken (Token aToken);
+
+private:
+ class Implementation;
+ ::boost::shared_ptr<Implementation> mpImpl;
+ PreviewSize mePreviewSize;
+
+ /** Retrieve the preview of the document specified by the given URL.
+ */
+ static BitmapEx LoadPreviewFromURL (const ::rtl::OUString& aURL);
+};
+
+
+
+
+/** For some changes to the set of master pages in a MasterPageContainer or
+ to the data stored for each master page one or more events are sent to
+ registered listeners.
+ Each event has an event type and a token that tells the listener where
+ the change took place.
+*/
+class MasterPageContainerChangeEvent
+{
+public:
+ enum EventType {
+ // A master page was added to the container.
+ CHILD_ADDED,
+ // A master page was removed from the container.
+ CHILD_REMOVED,
+ // The preview of a master page has changed.
+ PREVIEW_CHANGED,
+ // The size of a preview has changed.
+ SIZE_CHANGED,
+ // Some of the data stored for a master page has changed.
+ DATA_CHANGED,
+ // The TemplateIndex of a master page has changed.
+ INDEX_CHANGED,
+ // More than one entries changed their TemplateIndex
+ INDEXES_CHANGED
+ } meEventType;
+
+ // Token of the container entry whose data changed or which was added or
+ // removed.
+ MasterPageContainer::Token maChildToken;
+};
+
+
+} } } // end of namespace ::sd::toolpanel::controls
+
+#endif
diff --git a/sd/source/ui/toolpanel/controls/MasterPageContainerFiller.cxx b/sd/source/ui/toolpanel/controls/MasterPageContainerFiller.cxx
new file mode 100644
index 000000000000..23663b4822ef
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/MasterPageContainerFiller.cxx
@@ -0,0 +1,199 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "MasterPageContainerFiller.hxx"
+
+#include "MasterPageDescriptor.hxx"
+#include "MasterPageContainerProviders.hxx"
+#include "TemplateScanner.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::sd::toolpanel::controls;
+
+
+namespace sd { namespace toolpanel { namespace controls {
+
+MasterPageContainerFiller::MasterPageContainerFiller (ContainerAdapter& rpAdapter)
+ : mrContainerAdapter(rpAdapter),
+ meState(INITIALIZE_TEMPLATE_SCANNER),
+ mpScannerTask(),
+ mpLastAddedEntry(NULL),
+ mnIndex(1)
+{
+ // Add one entry for the default master page. We use temporarily the
+ // DefaultPagePreviewProvider to prevent the rendering (and the
+ // expensive creation) of the default page. It is replaced later on by
+ // another.
+ SharedMasterPageDescriptor pDescriptor (new MasterPageDescriptor(
+ MasterPageContainer::DEFAULT,
+ 0,
+ String(),
+ String(),
+ String(),
+ false,
+ ::boost::shared_ptr<PageObjectProvider>(new DefaultPageObjectProvider()),
+ ::boost::shared_ptr<PreviewProvider>(new PagePreviewProvider())));
+ mrContainerAdapter.PutMasterPage(pDescriptor);
+}
+
+
+
+
+MasterPageContainerFiller::~MasterPageContainerFiller (void)
+{
+}
+
+
+
+
+void MasterPageContainerFiller::RunNextStep (void)
+{
+ switch (meState)
+ {
+ case INITIALIZE_TEMPLATE_SCANNER:
+ mpScannerTask.reset(new TemplateScanner());
+ meState = SCAN_TEMPLATE;
+ break;
+
+ case SCAN_TEMPLATE:
+ meState = ScanTemplate();
+ break;
+
+ case ADD_TEMPLATE:
+ meState = AddTemplate();
+ break;
+
+ case DONE:
+ case ERROR:
+ default:
+ break;
+ }
+
+ // When the state has just been set to DONE or ERROR then tell the
+ // container that no more templates will be coming and stop the
+ // scanning.
+ switch (meState)
+ {
+ case DONE:
+ case ERROR:
+ if (mpScannerTask.get() != NULL)
+ {
+ mrContainerAdapter.FillingDone();
+ mpScannerTask.reset();
+ }
+ default:
+ break;
+ }
+}
+
+
+
+
+bool MasterPageContainerFiller::HasNextStep (void)
+{
+ switch (meState)
+ {
+ case DONE:
+ case ERROR:
+ return false;
+
+ default:
+ return true;
+ }
+}
+
+
+
+
+MasterPageContainerFiller::State MasterPageContainerFiller::ScanTemplate (void)
+{
+ State eState (ERROR);
+
+ if (mpScannerTask.get() != NULL)
+ {
+ if (mpScannerTask->HasNextStep())
+ {
+ mpScannerTask->RunNextStep();
+ if (mpScannerTask->GetLastAddedEntry() != mpLastAddedEntry)
+ {
+ mpLastAddedEntry = mpScannerTask->GetLastAddedEntry();
+ if (mpLastAddedEntry != NULL)
+ eState = ADD_TEMPLATE;
+ else
+ eState = SCAN_TEMPLATE;
+ }
+ else
+ eState = SCAN_TEMPLATE;
+ }
+ else
+ eState = DONE;
+ }
+
+ return eState;
+}
+
+
+
+
+MasterPageContainerFiller::State MasterPageContainerFiller::AddTemplate (void)
+{
+ if (mpLastAddedEntry != NULL)
+ {
+ SharedMasterPageDescriptor pDescriptor (new MasterPageDescriptor(
+ MasterPageContainer::TEMPLATE,
+ mnIndex,
+ mpLastAddedEntry->msPath,
+ mpLastAddedEntry->msTitle,
+ String(),
+ false,
+ ::boost::shared_ptr<PageObjectProvider>(
+ new TemplatePageObjectProvider(mpLastAddedEntry->msPath)),
+ ::boost::shared_ptr<PreviewProvider>(
+ new TemplatePreviewProvider(mpLastAddedEntry->msPath))));
+ // For user supplied templates we use a different preview provider:
+ // The preview in the document shows not only shapes on the master
+ // page but also shapes on the foreground. This is misleading and
+ // therefore these previews are discarded and created directly from
+ // the page objects.
+ if (pDescriptor->GetURLClassification() == MasterPageDescriptor::URLCLASS_USER)
+ pDescriptor->mpPreviewProvider = ::boost::shared_ptr<PreviewProvider>(
+ new PagePreviewProvider());
+
+ mrContainerAdapter.PutMasterPage(pDescriptor);
+ ++mnIndex;
+ }
+
+ return SCAN_TEMPLATE;
+}
+
+
+
+} } } // end of namespace ::sd::toolpanel::controls
diff --git a/sd/source/ui/toolpanel/controls/MasterPageContainerFiller.hxx b/sd/source/ui/toolpanel/controls/MasterPageContainerFiller.hxx
new file mode 100644
index 000000000000..c8ba61fef378
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/MasterPageContainerFiller.hxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANEL_CONTROLS_MASTER_PAGE_CONTAINER_FILLER_HXX
+#define SD_TOOLPANEL_CONTROLS_MASTER_PAGE_CONTAINER_FILLER_HXX
+
+#include "MasterPageContainer.hxx"
+#include "MasterPageDescriptor.hxx"
+#include "tools/AsynchronousTask.hxx"
+
+namespace sd {
+class TemplateScanner;
+class TemplateEntry;
+}
+
+namespace sd { namespace toolpanel { namespace controls {
+
+/** Fill a MasterPageContainer with information about the available master
+ pages. These are provided by one default page and from the existing
+ Impress templates. This is done asynchronously.
+*/
+class MasterPageContainerFiller
+ : public ::sd::tools::AsynchronousTask
+{
+public:
+ class ContainerAdapter
+ {
+ public:
+ virtual MasterPageContainer::Token PutMasterPage (
+ const SharedMasterPageDescriptor& rpDescriptor) = 0;
+ /** This method is called when all Impress templates have been added
+ to the container via the PutMasterPage() method.
+ */
+ virtual void FillingDone (void) = 0;
+ };
+
+ MasterPageContainerFiller (ContainerAdapter& rContainerAdapter);
+ virtual ~MasterPageContainerFiller (void);
+
+ /** Run the next step of the task. After HasNextStep() returns false
+ this method should ignore further calls.
+ */
+ virtual void RunNextStep (void);
+
+ /** Return <TRUE/> when there is at least one more step to execute.
+ When the task has been executed completely then <FALSE/> is
+ returned.
+ */
+ virtual bool HasNextStep (void);
+
+private:
+ ContainerAdapter& mrContainerAdapter;
+ // Remember what the next step has to do.
+ enum State {
+ INITIALIZE_TEMPLATE_SCANNER,
+ SCAN_TEMPLATE,
+ ADD_TEMPLATE,
+ ERROR,
+ DONE
+ } meState;
+ ::std::auto_ptr<TemplateScanner> mpScannerTask;
+ const TemplateEntry* mpLastAddedEntry;
+ int mnIndex;
+
+ State ScanTemplate (void);
+ State AddTemplate (void);
+};
+
+} } } // end of namespace ::sd::toolpanel::controls
+
+#endif
diff --git a/sd/source/ui/toolpanel/controls/MasterPageContainerProviders.cxx b/sd/source/ui/toolpanel/controls/MasterPageContainerProviders.cxx
new file mode 100755
index 000000000000..61483f278a4f
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/MasterPageContainerProviders.cxx
@@ -0,0 +1,429 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "MasterPageContainerProviders.hxx"
+
+#include "DrawDocShell.hxx"
+#include "drawdoc.hxx"
+#include "PreviewRenderer.hxx"
+#include <comphelper/processfactory.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <unotools/ucbstreamhelper.hxx>
+#include <vcl/image.hxx>
+#include <vcl/pngread.hxx>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <tools/diagnose_ex.h>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::sd::toolpanel::controls;
+
+
+namespace sd { namespace toolpanel { namespace controls {
+
+
+//===== PagePreviewProvider ===================================================
+
+PagePreviewProvider::PagePreviewProvider (void)
+{
+}
+
+
+
+
+Image PagePreviewProvider::operator () (
+ int nWidth,
+ SdPage* pPage,
+ ::sd::PreviewRenderer& rRenderer)
+{
+ Image aPreview;
+
+ if (pPage != NULL)
+ {
+ // Use the given renderer to create a preview of the given page
+ // object.
+ aPreview = rRenderer.RenderPage(
+ pPage,
+ nWidth,
+ String::CreateFromAscii(""),
+ false);
+ }
+
+ return aPreview;
+}
+
+
+
+
+int PagePreviewProvider::GetCostIndex (void)
+{
+ return 5;
+}
+
+
+
+
+bool PagePreviewProvider::NeedsPageObject (void)
+{
+ return true;
+}
+
+
+
+
+//===== TemplatePreviewProvider ===============================================
+
+TemplatePreviewProvider::TemplatePreviewProvider (const ::rtl::OUString& rsURL)
+ : msURL(rsURL)
+{
+}
+
+
+
+
+Image TemplatePreviewProvider::operator() (
+ int nWidth,
+ SdPage* pPage,
+ ::sd::PreviewRenderer& rRenderer)
+{
+ // Unused parameters.
+ (void)nWidth;
+ (void)pPage;
+ (void)rRenderer;
+
+ // Load the thumbnail from a template document.
+ uno::Reference<io::XInputStream> xIStream;
+
+ uno::Reference< lang::XMultiServiceFactory > xServiceManager (
+ ::comphelper::getProcessServiceFactory());
+ if (xServiceManager.is())
+ {
+ try
+ {
+ uno::Reference<lang::XSingleServiceFactory> xStorageFactory(
+ xServiceManager->createInstance(
+ ::rtl::OUString::createFromAscii(
+ "com.sun.star.embed.StorageFactory")),
+ uno::UNO_QUERY);
+
+ if (xStorageFactory.is())
+ {
+ 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(
+ ::rtl::OUString::createFromAscii("Thumbnails"),
+ embed::ElementModes::READ));
+ if (xStorage.is())
+ {
+ uno::Reference<io::XStream> xThumbnailCopy (
+ xStorage->cloneStreamElement(
+ ::rtl::OUString::createFromAscii(
+ "thumbnail.png")));
+ if (xThumbnailCopy.is())
+ xIStream = xThumbnailCopy->getInputStream();
+ }
+ }
+ }
+ catch (uno::Exception& rException)
+ {
+ OSL_TRACE (
+ "caught exception while trying to access Thumbnail/thumbnail.png of %s: %s",
+ ::rtl::OUStringToOString(msURL,
+ RTL_TEXTENCODING_UTF8).getStr(),
+ ::rtl::OUStringToOString(rException.Message,
+ RTL_TEXTENCODING_UTF8).getStr());
+ }
+
+ 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(
+ ::rtl::OUString::createFromAscii("Thumbnail"),
+ embed::ElementModes::READ));
+ if (xStorage.is())
+ {
+ uno::Reference<io::XStream> xThumbnailCopy (
+ xStorage->cloneStreamElement(
+ ::rtl::OUString::createFromAscii(
+ "thumbnail.png")));
+ if (xThumbnailCopy.is())
+ xIStream = xThumbnailCopy->getInputStream();
+ }
+ }
+ }
+ catch (uno::Exception& rException)
+ {
+ OSL_TRACE (
+ "caught exception while trying to access Thumbnails/thumbnail.png of %s: %s",
+ ::rtl::OUStringToOString(msURL,
+ RTL_TEXTENCODING_UTF8).getStr(),
+ ::rtl::OUStringToOString(rException.Message,
+ RTL_TEXTENCODING_UTF8).getStr());
+ }
+ }
+ }
+ catch (uno::Exception& rException)
+ {
+ OSL_TRACE (
+ "caught exception while trying to access tuhmbnail of %s: %s",
+ ::rtl::OUStringToOString(msURL,
+ RTL_TEXTENCODING_UTF8).getStr(),
+ ::rtl::OUStringToOString(rException.Message,
+ RTL_TEXTENCODING_UTF8).getStr());
+ }
+ }
+
+ // Extract the image from the stream.
+ BitmapEx aThumbnail;
+ if (xIStream.is())
+ {
+ ::std::auto_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;
+}
+
+
+
+
+int TemplatePreviewProvider::GetCostIndex (void)
+{
+ return 10;
+}
+
+
+
+
+bool TemplatePreviewProvider::NeedsPageObject (void)
+{
+ return false;
+}
+
+
+
+
+//===== TemplatePageObjectProvider =============================================
+
+TemplatePageObjectProvider::TemplatePageObjectProvider (const ::rtl::OUString& rsURL)
+ : msURL(rsURL),
+ mxDocumentShell()
+{
+}
+
+
+
+
+SdPage* TemplatePageObjectProvider::operator() (SdDrawDocument* pContainerDocument)
+{
+ // Unused parameters.
+ (void)pContainerDocument;
+
+ SdPage* pPage = NULL;
+
+ mxDocumentShell = NULL;
+ ::sd::DrawDocShell* pDocumentShell = NULL;
+ try
+ {
+ // Load the template document and return its first page.
+ pDocumentShell = LoadDocument (msURL);
+ if (pDocumentShell != NULL)
+ {
+ SdDrawDocument* pDocument = pDocumentShell->GetDoc();
+ if (pDocument != NULL)
+ {
+ pPage = pDocument->GetMasterSdPage(0, PK_STANDARD);
+ // In order to make the newly loaded master page deletable
+ // when copied into documents it is marked as no "precious".
+ // When it is modified then it is marked as "precious".
+ if (pPage != NULL)
+ pPage->SetPrecious(false);
+ }
+ }
+ }
+ catch (uno::RuntimeException)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ pPage = NULL;
+ }
+
+ return pPage;
+}
+
+
+
+
+::sd::DrawDocShell* TemplatePageObjectProvider::LoadDocument (const ::rtl::OUString& sFileName)
+{
+ SfxApplication* pSfxApp = SFX_APP();
+ SfxItemSet* pSet = new SfxAllItemSet (pSfxApp->GetPool());
+ pSet->Put (SfxBoolItem (SID_TEMPLATE, TRUE));
+ pSet->Put (SfxBoolItem (SID_PREVIEW, TRUE));
+ if (pSfxApp->LoadTemplate (mxDocumentShell, sFileName, TRUE, pSet))
+ {
+ mxDocumentShell = NULL;
+ }
+ SfxObjectShell* pShell = mxDocumentShell;
+ return PTR_CAST(::sd::DrawDocShell,pShell);
+}
+
+
+
+
+int TemplatePageObjectProvider::GetCostIndex (void)
+{
+ return 20;
+}
+
+
+
+
+bool TemplatePageObjectProvider::operator== (const PageObjectProvider& rProvider)
+{
+ const TemplatePageObjectProvider* pTemplatePageObjectProvider
+ = dynamic_cast<const TemplatePageObjectProvider*>(&rProvider);
+ if (pTemplatePageObjectProvider != NULL)
+ return (msURL == pTemplatePageObjectProvider->msURL);
+ else
+ return false;
+}
+
+
+
+
+//===== DefaultPageObjectProvider ==============================================
+
+DefaultPageObjectProvider::DefaultPageObjectProvider (void)
+{
+}
+
+
+
+
+SdPage* DefaultPageObjectProvider::operator () (SdDrawDocument* pContainerDocument)
+{
+ SdPage* pLocalMasterPage = NULL;
+ if (pContainerDocument != NULL)
+ {
+ sal_Int32 nIndex (0);
+ SdPage* pLocalSlide = pContainerDocument->GetSdPage((USHORT)nIndex, PK_STANDARD);
+ if (pLocalSlide!=NULL && pLocalSlide->TRG_HasMasterPage())
+ pLocalMasterPage = dynamic_cast<SdPage*>(&pLocalSlide->TRG_GetMasterPage());
+ }
+
+ if (pLocalMasterPage == NULL)
+ {
+ DBG_ASSERT(false, "can not create master page for slide");
+ }
+
+ return pLocalMasterPage;
+}
+
+
+
+
+int DefaultPageObjectProvider::GetCostIndex (void)
+{
+ return 15;
+}
+
+
+
+
+bool DefaultPageObjectProvider::operator== (const PageObjectProvider& rProvider)
+{
+ return (dynamic_cast<const DefaultPageObjectProvider*>(&rProvider) != NULL);
+}
+
+
+
+
+//===== ExistingPageProvider ==================================================
+
+ExistingPageProvider::ExistingPageProvider (SdPage* pPage)
+ : mpPage(pPage)
+{
+}
+
+
+
+
+SdPage* ExistingPageProvider::operator() (SdDrawDocument* pDocument)
+{
+ (void)pDocument; // Unused parameter.
+
+ return mpPage;
+}
+
+
+
+
+int ExistingPageProvider::GetCostIndex (void)
+{
+ return 0;
+}
+
+
+
+
+bool ExistingPageProvider::operator== (const PageObjectProvider& rProvider)
+{
+ const ExistingPageProvider* pExistingPageProvider
+ = dynamic_cast<const ExistingPageProvider*>(&rProvider);
+ if (pExistingPageProvider != NULL)
+ return (mpPage == pExistingPageProvider->mpPage);
+ else
+ return false;
+}
+
+
+} } } // end of namespace ::sd::toolpanel::controls
diff --git a/sd/source/ui/toolpanel/controls/MasterPageContainerProviders.hxx b/sd/source/ui/toolpanel/controls/MasterPageContainerProviders.hxx
new file mode 100755
index 000000000000..071b23cdbb16
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/MasterPageContainerProviders.hxx
@@ -0,0 +1,189 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANEL_CONTROLS_MASTER_PAGE_CONTAINER_PROVIDERS_HXX
+#define SD_TOOLPANEL_CONTROLS_MASTER_PAGE_CONTAINER_PROVIDERS_HXX
+
+#include <rtl/ustring.hxx>
+#include <sfx2/objsh.hxx>
+
+class Image;
+class SdDrawDocument;
+class SdPage;
+namespace sd { class PreviewRenderer; }
+namespace sd { class DrawDocShell; }
+
+
+namespace sd { namespace toolpanel { namespace controls {
+
+
+/** Interface for a provider of page objects. It is used by the
+ MasterPageDescriptor to create master page objects on demand.
+*/
+class PageObjectProvider
+{
+public:
+ /** Return a master page either by returning an already existing one, by
+ creating a new page, or by loading a document.
+ @param pDocument
+ The document of the MasterPageContainer. It may be used to
+ create new pages.
+ */
+ virtual SdPage* operator() (SdDrawDocument* pDocument) = 0;
+
+ /** An abstract value for the expected cost of providing a master page
+ object.
+ @return
+ A value of 0 represents for the lowest cost, i.e. an almost
+ immediate return. Positive values stand for higher costs.
+ Negative values are not supported.
+ */
+ virtual int GetCostIndex (void) = 0;
+
+ virtual bool operator== (const PageObjectProvider& rProvider) = 0;
+};
+
+
+
+
+class PreviewProvider
+{
+public:
+ /** Create a preview image in the specified width.
+ @param nWidth
+ Requested width of the preview. The calling method can cope
+ with other sizes as well but the resulting image quality is
+ better when the returned image has the requested size.
+ @param pPage
+ Page object for which a preview is requested. This may be NULL
+ when the page object is expensive to get and the PreviewProvider
+ does not need this object (NeedsPageObject() returns false.)
+ @param rRenderer
+ This PreviewRenderer may be used by the PreviewProvider to
+ create a preview image.
+ */
+ virtual Image operator() (int nWidth, SdPage* pPage, ::sd::PreviewRenderer& rRenderer) = 0;
+
+ /** Return a value that indicates how expensive the creation of a
+ preview image is. The higher the returned value the more expensive
+ is the preview creation. Return 0 when the preview is already
+ present and can be returned immediately.
+ */
+ virtual int GetCostIndex (void) = 0;
+
+ /** Return whether the page object passed is necessary to create a
+ preview.
+ */
+ virtual bool NeedsPageObject (void) = 0;
+};
+
+
+
+
+/** Provide previews of existing page objects by rendering them.
+*/
+class PagePreviewProvider : public PreviewProvider
+{
+public:
+ PagePreviewProvider (void);
+ virtual Image operator () (int nWidth, SdPage* pPage, ::sd::PreviewRenderer& rRenderer);
+ virtual int GetCostIndex (void);
+ virtual bool NeedsPageObject (void);
+private:
+};
+
+
+
+
+/** Provide master page objects for template documents for which only the
+ URL is given.
+*/
+class TemplatePageObjectProvider : public PageObjectProvider
+{
+public:
+ TemplatePageObjectProvider (const ::rtl::OUString& rsURL);
+ virtual ~TemplatePageObjectProvider (void) {};
+ virtual SdPage* operator () (SdDrawDocument* pDocument);
+ virtual int GetCostIndex (void);
+ virtual bool operator== (const PageObjectProvider& rProvider);
+private:
+ ::rtl::OUString msURL;
+ SfxObjectShellLock mxDocumentShell;
+ ::sd::DrawDocShell* LoadDocument (const ::rtl::OUString& sFileName);
+};
+
+
+
+
+/** Provide previews for template documents by loading the thumbnails from
+ the documents.
+*/
+class TemplatePreviewProvider : public PreviewProvider
+{
+public:
+ TemplatePreviewProvider (const ::rtl::OUString& rsURL);
+ virtual ~TemplatePreviewProvider (void) {};
+ virtual Image operator() (int nWidth, SdPage* pPage, ::sd::PreviewRenderer& rRenderer);
+ virtual int GetCostIndex (void);
+ virtual bool NeedsPageObject (void);
+private:
+ ::rtl::OUString msURL;
+};
+
+
+
+
+/** Create an empty default master page.
+*/
+class DefaultPageObjectProvider : public PageObjectProvider
+{
+public:
+ DefaultPageObjectProvider (void);
+ virtual SdPage* operator () (SdDrawDocument* pDocument);
+ virtual int GetCostIndex (void);
+ virtual bool operator== (const PageObjectProvider& rProvider);
+};
+
+
+
+/** This implementation of the PageObjectProvider simply returns an already
+ existing master page object.
+*/
+class ExistingPageProvider : public ::sd::toolpanel::controls::PageObjectProvider
+{
+public:
+ ExistingPageProvider (SdPage* pPage);
+ virtual SdPage* operator() (SdDrawDocument* pDocument);
+ virtual int GetCostIndex (void);
+ virtual bool operator== (const PageObjectProvider& rProvider);
+private:
+ SdPage* mpPage;
+};
+
+} } } // end of namespace ::sd::toolpanel::controls
+
+#endif
diff --git a/sd/source/ui/toolpanel/controls/MasterPageContainerQueue.cxx b/sd/source/ui/toolpanel/controls/MasterPageContainerQueue.cxx
new file mode 100644
index 000000000000..35b02497575e
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/MasterPageContainerQueue.cxx
@@ -0,0 +1,304 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "MasterPageContainerQueue.hxx"
+
+#include "tools/IdleDetection.hxx"
+
+#include <set>
+
+namespace sd { namespace toolpanel { namespace controls {
+
+const sal_Int32 MasterPageContainerQueue::snDelayedCreationTimeout (15);
+const sal_Int32 MasterPageContainerQueue::snDelayedCreationTimeoutWhenNotIdle (100);
+const sal_Int32 MasterPageContainerQueue::snMasterPagePriorityBoost (5);
+const sal_Int32 MasterPageContainerQueue::snWaitForMoreRequestsPriorityThreshold (-10);
+sal_uInt32 MasterPageContainerQueue::snWaitForMoreRequestsCount(15);
+
+//===== MasterPageContainerQueue::PreviewCreationRequest ======================
+
+class MasterPageContainerQueue::PreviewCreationRequest
+{
+public:
+ PreviewCreationRequest (const SharedMasterPageDescriptor& rpDescriptor, int nPriority)
+ : mpDescriptor(rpDescriptor),
+ mnPriority(nPriority)
+ {}
+ SharedMasterPageDescriptor mpDescriptor;
+ int mnPriority;
+ class Compare {public:
+ bool operator() (const PreviewCreationRequest& r1,const PreviewCreationRequest& r2)
+ {
+ if (r1.mnPriority != r2.mnPriority)
+ {
+ // Prefer requests with higher priority.
+ return r1.mnPriority > r2.mnPriority;
+ }
+ else
+ {
+ // Prefer tokens that have been earlier created (those with lower
+ // value).
+ return r1.mpDescriptor->maToken < r2.mpDescriptor->maToken;
+ }
+ }
+ };
+ class CompareToken {public:
+ MasterPageContainer::Token maToken;
+ CompareToken(MasterPageContainer::Token aToken) : maToken(aToken) {}
+ bool operator() (const PreviewCreationRequest& rRequest)
+ { return maToken==rRequest.mpDescriptor->maToken; }
+ };
+};
+
+
+
+
+//===== MasterPageContainerQueue::RequestQueue ================================
+
+class MasterPageContainerQueue::RequestQueue
+ : public ::std::set<PreviewCreationRequest,PreviewCreationRequest::Compare>
+{
+public:
+ RequestQueue (void) {}
+};
+
+
+
+
+//===== MasterPageContainerQueue ==============================================
+
+MasterPageContainerQueue* MasterPageContainerQueue::Create (
+ const ::boost::weak_ptr<ContainerAdapter>& rpContainer)
+{
+ MasterPageContainerQueue* pQueue = new MasterPageContainerQueue(rpContainer);
+ pQueue->LateInit();
+ return pQueue;
+}
+
+
+
+
+MasterPageContainerQueue::MasterPageContainerQueue (
+ const ::boost::weak_ptr<ContainerAdapter>& rpContainer)
+ : mpWeakContainer(rpContainer),
+ mpRequestQueue(new RequestQueue()),
+ maDelayedPreviewCreationTimer(),
+ mnRequestsServedCount(0)
+{
+}
+
+
+
+
+MasterPageContainerQueue::~MasterPageContainerQueue (void)
+{
+ maDelayedPreviewCreationTimer.Stop();
+ while ( ! mpRequestQueue->empty())
+ mpRequestQueue->erase(mpRequestQueue->begin());
+}
+
+
+
+
+void MasterPageContainerQueue::LateInit (void)
+{
+ // Set up the timer for the delayed creation of preview bitmaps.
+ maDelayedPreviewCreationTimer.SetTimeout (snDelayedCreationTimeout);
+ Link aLink (LINK(this,MasterPageContainerQueue,DelayedPreviewCreation));
+ maDelayedPreviewCreationTimer.SetTimeoutHdl(aLink);
+}
+
+
+
+
+bool MasterPageContainerQueue::RequestPreview (const SharedMasterPageDescriptor& rpDescriptor)
+{
+ bool bSuccess (false);
+ if (rpDescriptor.get() != NULL
+ && rpDescriptor->maLargePreview.GetSizePixel().Width() == 0)
+ {
+ sal_Int32 nPriority (CalculatePriority(rpDescriptor));
+
+ // Add a new or replace an existing request.
+ RequestQueue::iterator iRequest (::std::find_if(
+ mpRequestQueue->begin(),
+ mpRequestQueue->end(),
+ PreviewCreationRequest::CompareToken(rpDescriptor->maToken)));
+ // When a request for the same token exists then the lowest of the
+ // two priorities is used.
+ if (HasRequest(rpDescriptor->maToken))
+ if (iRequest->mnPriority < nPriority)
+ {
+ mpRequestQueue->erase(iRequest);
+ iRequest = mpRequestQueue->end();
+ }
+
+ // Add a new request when none exists (or has just been erased).
+ if (iRequest == mpRequestQueue->end())
+ {
+ mpRequestQueue->insert(PreviewCreationRequest(rpDescriptor,nPriority));
+ maDelayedPreviewCreationTimer.Start();
+ bSuccess = true;
+ }
+ }
+ return bSuccess;
+}
+
+
+
+
+sal_Int32 MasterPageContainerQueue::CalculatePriority (
+ const SharedMasterPageDescriptor& rpDescriptor) const
+{
+ sal_Int32 nPriority;
+
+ // The cost is used as a starting value.
+ int nCost (0);
+ if (rpDescriptor->mpPreviewProvider.get() != NULL)
+ {
+ nCost = rpDescriptor->mpPreviewProvider->GetCostIndex();
+ if (rpDescriptor->mpPreviewProvider->NeedsPageObject())
+ if (rpDescriptor->mpPageObjectProvider.get() != NULL)
+ nCost += rpDescriptor->mpPageObjectProvider->GetCostIndex();
+ }
+
+ // Its negative value is used so that requests with a low cost are
+ // preferred over those with high costs.
+ nPriority = -nCost;
+
+ // Add a term that introduces an order based on the appearance in the
+ // AllMasterPagesSelector.
+ nPriority -= rpDescriptor->maToken / 3;
+
+ // Process requests for the CurrentMasterPagesSelector first.
+ if (rpDescriptor->meOrigin == MasterPageContainer::MASTERPAGE)
+ nPriority += snMasterPagePriorityBoost;
+
+ return nPriority;
+}
+
+
+
+
+IMPL_LINK(MasterPageContainerQueue, DelayedPreviewCreation, Timer*, pTimer)
+{
+ bool bIsShowingFullScreenShow (false);
+ bool bWaitForMoreRequests (false);
+
+ do
+ {
+ if (mpRequestQueue->size() == 0)
+ break;
+
+ // First check whether the system is idle.
+ sal_Int32 nIdleState (tools::IdleDetection::GetIdleState());
+ if (nIdleState != tools::IdleDetection::IDET_IDLE)
+ {
+ if ((nIdleState&tools::IdleDetection::IDET_FULL_SCREEN_SHOW_ACTIVE) != 0)
+ bIsShowingFullScreenShow = true;
+ break;
+ }
+
+ PreviewCreationRequest aRequest (*mpRequestQueue->begin());
+
+ // Check if the request should really be processed right now.
+ // Reasons to not do it are when its cost is high and not many other
+ // requests have been inserted into the queue that would otherwise
+ // be processed first.
+ if (aRequest.mnPriority < snWaitForMoreRequestsPriorityThreshold
+ && (mnRequestsServedCount+mpRequestQueue->size() < snWaitForMoreRequestsCount))
+ {
+ // Wait for more requests before this one is processed. Note
+ // that the queue processing is not started anew when this
+ // method is left. That is done when the next request is
+ // inserted.
+ bWaitForMoreRequests = true;
+ break;
+ }
+
+ mpRequestQueue->erase(mpRequestQueue->begin());
+
+ if (aRequest.mpDescriptor.get() != NULL)
+ {
+ mnRequestsServedCount += 1;
+ if ( ! mpWeakContainer.expired())
+ {
+ ::boost::shared_ptr<ContainerAdapter> pContainer (mpWeakContainer);
+ if (pContainer.get() != NULL)
+ pContainer->UpdateDescriptor(aRequest.mpDescriptor,false,true,true);
+ }
+ }
+ }
+ while (false);
+
+ if (mpRequestQueue->size() > 0 && ! bWaitForMoreRequests)
+ {
+ int nTimeout (snDelayedCreationTimeout);
+ if (bIsShowingFullScreenShow)
+ nTimeout = snDelayedCreationTimeoutWhenNotIdle;
+ maDelayedPreviewCreationTimer.SetTimeout(nTimeout);
+ pTimer->Start();
+ }
+
+ return 0;
+}
+
+
+
+
+bool MasterPageContainerQueue::HasRequest (MasterPageContainer::Token aToken) const
+{
+ RequestQueue::iterator iRequest (::std::find_if(
+ mpRequestQueue->begin(),
+ mpRequestQueue->end(),
+ PreviewCreationRequest::CompareToken(aToken)));
+ return (iRequest != mpRequestQueue->end());
+}
+
+
+
+
+bool MasterPageContainerQueue::IsEmpty (void) const
+{
+ return mpRequestQueue->empty();
+}
+
+
+
+
+void MasterPageContainerQueue::ProcessAllRequests (void)
+{
+ snWaitForMoreRequestsCount = 0;
+ if (mpRequestQueue->size() > 0)
+ maDelayedPreviewCreationTimer.Start();
+}
+
+
+} } } // end of namespace ::sd::toolpanel::controls
diff --git a/sd/source/ui/toolpanel/controls/MasterPageContainerQueue.hxx b/sd/source/ui/toolpanel/controls/MasterPageContainerQueue.hxx
new file mode 100644
index 000000000000..3e8d31e67c1b
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/MasterPageContainerQueue.hxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANEL_CONTROLS_MASTER_PAGE_CONTAINER_QUEUE_HXX
+#define SD_TOOLPANEL_CONTROLS_MASTER_PAGE_CONTAINER_QUEUE_HXX
+
+#include "MasterPageContainer.hxx"
+#include "MasterPageDescriptor.hxx"
+
+#include <boost/scoped_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+
+namespace sd { namespace toolpanel { namespace controls {
+
+
+/** The queue stores and processes all requests from a MasterPageContainer
+ for the creation of previews.
+ The order of request processing and its timing is controlled by a
+ heuristic that uses values given with each request and which is
+ controlled by various parameters that are described below.
+*/
+class MasterPageContainerQueue
+{
+public:
+ class ContainerAdapter { public:
+ virtual bool UpdateDescriptor (
+ const SharedMasterPageDescriptor& rpDescriptor,
+ bool bForcePageObject,
+ bool bForcePreview,
+ bool bSendEvents) = 0;
+ };
+
+ static MasterPageContainerQueue* Create (
+ const ::boost::weak_ptr<ContainerAdapter>& rpContainer);
+ virtual ~MasterPageContainerQueue (void);
+
+ /** This method is typically called for entries in the container for
+ which GetPreviewState() returns OS_CREATABLE. The creation of the
+ preview is then scheduled to be executed asynchronously at a later
+ point in time. When the preview is available the change listeners
+ will be notified.
+ */
+ bool RequestPreview (const SharedMasterPageDescriptor& rDescriptor);
+
+ /** Return <TRUE/> when there is a request currently in the queue for
+ the given token.
+ */
+ bool HasRequest (MasterPageContainer::Token aToken) const;
+
+ /** Return <TRUE/> when there is at least one request in the queue.
+ */
+ bool IsEmpty (void) const;
+
+ /** After this call the queue does not wait anymore for requests with
+ higher priority when only a small number of requests with lower
+ priority are present. This method should be called when all
+ templates are inserted into the MasterPageContainer.
+ */
+ void ProcessAllRequests (void);
+
+private:
+ ::boost::weak_ptr<ContainerAdapter> mpWeakContainer;
+ class PreviewCreationRequest;
+ class RequestQueue;
+ ::boost::scoped_ptr<RequestQueue> mpRequestQueue;
+ Timer maDelayedPreviewCreationTimer;
+ sal_uInt32 mnRequestsServedCount;
+
+ // There are a couple of values that define various aspects of the
+ // heuristic that defines the order and timing in which requests for
+ // preview creation are processed.
+
+ /** The time to wait (in milliseconds) between the creation of previews.
+ */
+ static const sal_Int32 snDelayedCreationTimeout;
+
+ /** The time to wait when the system is not idle.
+ */
+ static const sal_Int32 snDelayedCreationTimeoutWhenNotIdle;
+
+ /** Requests for previews of master pages in a document have their
+ priority increased by this value.
+ */
+ static const sal_Int32 snMasterPagePriorityBoost;
+
+ /** When only requests which a priority lower than this threshold exist
+ and not many requests have been made yet then wait with processing
+ them until more requests are present.
+ */
+ static const sal_Int32 snWaitForMoreRequestsPriorityThreshold;
+
+ /** When only requests which a priority lower than a threshold exist
+ and not more requests than this number have been made or already
+ processed then wait with processing them until more requests are
+ present.
+ */
+ static sal_uInt32 snWaitForMoreRequestsCount;
+
+ MasterPageContainerQueue (const ::boost::weak_ptr<ContainerAdapter>& rpContainer);
+ void LateInit (void);
+
+ /** Calculate the priority that defines the order in which requests
+ are processed.
+ */
+ sal_Int32 CalculatePriority (const SharedMasterPageDescriptor& rDescriptor) const;
+
+ DECL_LINK(DelayedPreviewCreation, Timer *);
+};
+
+} } } // end of namespace ::sd::toolpanel::controls
+
+#endif
diff --git a/sd/source/ui/toolpanel/controls/MasterPageDescriptor.cxx b/sd/source/ui/toolpanel/controls/MasterPageDescriptor.cxx
new file mode 100755
index 000000000000..6871883d65f5
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/MasterPageDescriptor.cxx
@@ -0,0 +1,423 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "MasterPageDescriptor.hxx"
+
+#include "DocumentHelper.hxx"
+#include "sdpage.hxx"
+#include <tools/urlobj.hxx>
+
+namespace sd { namespace toolpanel { namespace controls {
+
+
+//===== MasterPageDescriptor ==================================================
+
+MasterPageDescriptor::MasterPageDescriptor (
+ MasterPageContainer::Origin eOrigin,
+ const sal_Int32 nTemplateIndex,
+ const String& rsURL,
+ const String& rsPageName,
+ const String& rsStyleName,
+ const bool bIsPrecious,
+ const ::boost::shared_ptr<PageObjectProvider>& rpPageObjectProvider,
+ const ::boost::shared_ptr<PreviewProvider>& rpPreviewProvider)
+ : maToken(MasterPageContainer::NIL_TOKEN),
+ meOrigin(eOrigin),
+ msURL(INetURLObject(rsURL).GetMainURL(INetURLObject::DECODE_UNAMBIGUOUS)),
+ msPageName(rsPageName),
+ msStyleName(rsStyleName),
+ mbIsPrecious(bIsPrecious),
+ mpMasterPage(NULL),
+ mpSlide(NULL),
+ maSmallPreview(),
+ maLargePreview(),
+ mpPreviewProvider(rpPreviewProvider),
+ mpPageObjectProvider(rpPageObjectProvider),
+ mnTemplateIndex(nTemplateIndex),
+ meURLClassification(URLCLASS_UNDETERMINED),
+ mnUseCount(0)
+{
+}
+
+
+
+
+MasterPageDescriptor::MasterPageDescriptor (const MasterPageDescriptor& rDescriptor)
+ : maToken(rDescriptor.maToken),
+ meOrigin(rDescriptor.meOrigin),
+ msURL(rDescriptor.msURL),
+ msPageName(rDescriptor.msPageName),
+ msStyleName(rDescriptor.msStyleName),
+ mbIsPrecious(rDescriptor.mbIsPrecious),
+ mpMasterPage(rDescriptor.mpMasterPage),
+ mpSlide(rDescriptor.mpSlide),
+ maSmallPreview(rDescriptor.maSmallPreview),
+ maLargePreview(rDescriptor.maLargePreview),
+ mpPreviewProvider(rDescriptor.mpPreviewProvider),
+ mpPageObjectProvider(rDescriptor.mpPageObjectProvider),
+ mnTemplateIndex(rDescriptor.mnTemplateIndex),
+ meURLClassification(rDescriptor.meURLClassification),
+ mnUseCount(rDescriptor.mnUseCount)
+{
+}
+
+
+
+
+MasterPageDescriptor::~MasterPageDescriptor (void)
+{
+}
+
+
+
+
+void MasterPageDescriptor::SetToken (MasterPageContainer::Token aToken)
+{
+ maToken = aToken;
+}
+
+
+
+
+Image MasterPageDescriptor::GetPreview (MasterPageContainer::PreviewSize eSize)
+{
+ if (eSize == MasterPageContainer::SMALL)
+ return maSmallPreview;
+ else
+ return maLargePreview;
+}
+
+
+
+
+::std::auto_ptr<std::vector<MasterPageContainerChangeEvent::EventType> >
+ MasterPageDescriptor::Update (
+ const MasterPageDescriptor& rDescriptor)
+{
+ bool bDataChanged (false);
+ bool bIndexChanged (false);
+ bool bPreviewChanged (false);
+
+ if (meOrigin==MasterPageContainer::UNKNOWN
+ && rDescriptor.meOrigin!=MasterPageContainer::UNKNOWN)
+ {
+ meOrigin = rDescriptor.meOrigin;
+ bIndexChanged = true;
+ }
+
+ if (msURL.getLength()==0 && rDescriptor.msURL.getLength()!=0)
+ {
+ msURL = rDescriptor.msURL;
+ bDataChanged = true;
+ }
+
+ if (msPageName.getLength()==0 && rDescriptor.msPageName.getLength()!=0)
+ {
+ msPageName = rDescriptor.msPageName;
+ bDataChanged = true;
+ }
+
+ if (msStyleName.getLength()==0 && rDescriptor.msStyleName.getLength()!=0)
+ {
+ msStyleName = rDescriptor.msStyleName;
+ bDataChanged = true;
+ }
+
+ if (mpPageObjectProvider.get()==NULL && rDescriptor.mpPageObjectProvider.get()!=NULL)
+ {
+ mpPageObjectProvider = rDescriptor.mpPageObjectProvider;
+ bDataChanged = true;
+ }
+
+ if (mpPreviewProvider.get()==NULL && rDescriptor.mpPreviewProvider.get()!=NULL)
+ {
+ mpPreviewProvider = rDescriptor.mpPreviewProvider;
+ bPreviewChanged = true;
+ }
+
+ if (mnTemplateIndex<0 && rDescriptor.mnTemplateIndex>=0)
+ {
+ mnTemplateIndex = rDescriptor.mnTemplateIndex;
+ bIndexChanged = true;
+ }
+
+ // Prepare the list of event types that will be returned.
+ ::std::auto_ptr<std::vector<MasterPageContainerChangeEvent::EventType> > pResult;
+ if (bDataChanged || bIndexChanged || bPreviewChanged)
+ {
+ pResult.reset(new std::vector<MasterPageContainerChangeEvent::EventType>());
+ if (bDataChanged)
+ pResult->push_back(MasterPageContainerChangeEvent::DATA_CHANGED);
+ if (bIndexChanged)
+ pResult->push_back(MasterPageContainerChangeEvent::INDEX_CHANGED);
+ if (bPreviewChanged)
+ pResult->push_back(MasterPageContainerChangeEvent::PREVIEW_CHANGED);
+ }
+
+ return pResult;
+}
+
+
+
+
+bool MasterPageDescriptor::UpdatePageObject (
+ sal_Int32 nCostThreshold,
+ SdDrawDocument* pDocument)
+{
+ bool bModified (false);
+
+ // Update the page object when that is not yet known.
+ if (mpMasterPage == NULL
+ && mpPageObjectProvider.get()!=NULL
+ && (nCostThreshold<0 || mpPageObjectProvider->GetCostIndex()<=nCostThreshold))
+ {
+ // Note that pDocument may be NULL.
+
+ SdPage* pPage = (*mpPageObjectProvider)(pDocument);
+ if (meOrigin == MasterPageContainer::MASTERPAGE)
+ {
+ mpMasterPage = pPage;
+ if (mpMasterPage != NULL)
+ mpMasterPage->SetPrecious(mbIsPrecious);
+ }
+ else
+ {
+ // Master pages from templates are copied into the local document.
+ if (pDocument != NULL)
+ mpMasterPage = DocumentHelper::CopyMasterPageToLocalDocument(*pDocument,pPage);
+ mpSlide = DocumentHelper::GetSlideForMasterPage(mpMasterPage);
+ }
+
+ if (mpMasterPage != NULL)
+ {
+ // Update page name and style name.
+ if (msPageName.getLength() == 0)
+ msPageName = mpMasterPage->GetName();
+ msStyleName = mpMasterPage->GetName();
+
+ // Delete an existing substitution. The next request for a preview
+ // will create the real one.
+ maSmallPreview = Image();
+ maLargePreview = Image();
+ mpPreviewProvider = ::boost::shared_ptr<PreviewProvider>(new PagePreviewProvider());
+ }
+ else
+ {
+ DBG_ASSERT(false, "UpdatePageObject: master page is NULL");
+ }
+
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+
+
+
+bool MasterPageDescriptor::UpdatePreview (
+ sal_Int32 nCostThreshold,
+ const Size& rSmallSize,
+ const Size& rLargeSize,
+ ::sd::PreviewRenderer& rRenderer)
+{
+ bool bModified (false);
+
+ // Update the preview when that is not yet known.
+ if (maLargePreview.GetSizePixel().Width()==0
+ && mpPreviewProvider.get()!=NULL
+ && (nCostThreshold<0 || mpPreviewProvider->GetCostIndex()<=nCostThreshold))
+ {
+ SdPage* pPage = mpSlide;
+ if (pPage == NULL)
+ {
+ pPage = mpMasterPage;
+ }
+ maLargePreview = (*mpPreviewProvider)(
+ rLargeSize.Width(),
+ pPage,
+ rRenderer);
+ if (maLargePreview.GetSizePixel().Width() > 0)
+ {
+ // Create the small preview by scaling the large one down.
+ maSmallPreview = rRenderer.ScaleBitmap(
+ maLargePreview.GetBitmapEx(),
+ rSmallSize.Width());
+ // The large preview may not have the desired width. Scale it
+ // accrodingly.
+ if (maLargePreview.GetSizePixel().Width() != rLargeSize.Width())
+ maLargePreview = rRenderer.ScaleBitmap(
+ maLargePreview.GetBitmapEx(),
+ rLargeSize.Width());
+ bModified = true;
+ }
+ }
+
+ return bModified;
+}
+
+
+
+
+MasterPageDescriptor::URLClassification MasterPageDescriptor::GetURLClassification (void)
+{
+ if (meURLClassification == URLCLASS_UNDETERMINED)
+ {
+ if (msURL.getLength() == 0)
+ meURLClassification = URLCLASS_UNKNOWN;
+ else if (msURL.indexOf(::rtl::OUString::createFromAscii("presnt"))>=0)
+ {
+ meURLClassification = URLCLASS_PRESENTATION;
+ }
+ else if (msURL.indexOf(::rtl::OUString::createFromAscii("layout"))>=0)
+ {
+ meURLClassification = URLCLASS_LAYOUT;
+ }
+ else if (msURL.indexOf(::rtl::OUString::createFromAscii("educate"))>=0)
+ {
+ meURLClassification = URLCLASS_OTHER;
+ }
+ else
+ {
+ meURLClassification = URLCLASS_USER;
+ }
+ }
+
+ return meURLClassification;
+}
+
+
+
+//===== URLComparator =========================================================
+
+MasterPageDescriptor::URLComparator::URLComparator (const ::rtl::OUString& sURL)
+ : msURL(sURL)
+{
+}
+
+
+
+
+bool MasterPageDescriptor::URLComparator::operator() (
+ const SharedMasterPageDescriptor& rDescriptor)
+{
+ if (rDescriptor.get() == NULL)
+ return false;
+ else
+ return rDescriptor->msURL.equals(msURL);
+}
+
+
+
+
+// ===== StyleNameComparator ==================================================
+
+MasterPageDescriptor::StyleNameComparator::StyleNameComparator (const ::rtl::OUString& sStyleName)
+ : msStyleName(sStyleName)
+{
+}
+
+
+
+
+bool MasterPageDescriptor::StyleNameComparator::operator() (
+ const SharedMasterPageDescriptor& rDescriptor)
+{
+ if (rDescriptor.get() == NULL)
+ return false;
+ else
+ return rDescriptor->msStyleName.equals(msStyleName);
+}
+
+
+
+
+//===== PageObjectComparator ==================================================
+
+MasterPageDescriptor::PageObjectComparator::PageObjectComparator (const SdPage* pPageObject)
+ : mpMasterPage(pPageObject)
+{
+}
+
+
+
+
+bool MasterPageDescriptor::PageObjectComparator::operator() (
+ const SharedMasterPageDescriptor& rDescriptor)
+{
+ if (rDescriptor.get() == NULL)
+ return false;
+ else
+ return rDescriptor->mpMasterPage==mpMasterPage;
+}
+
+
+
+
+//===== AllComparator =========================================================
+
+MasterPageDescriptor::AllComparator::AllComparator(const SharedMasterPageDescriptor& rDescriptor)
+ : mpDescriptor(rDescriptor)
+{
+}
+
+
+
+
+bool MasterPageDescriptor::AllComparator::operator() (const SharedMasterPageDescriptor&rDescriptor)
+{
+ if (rDescriptor.get() == NULL)
+ return false;
+ else
+ {
+ // Take URL, page name, style name, and page object into account
+ // when comparing two descriptors. When two descriptors are
+ // identical in any of these values then their are thought of as
+ // equivalent. Only the Origin has to be the same in both
+ // descriptors.
+ return
+ mpDescriptor->meOrigin == rDescriptor->meOrigin
+ && (
+ (mpDescriptor->msURL.getLength()>0
+ && mpDescriptor->msURL.equals(rDescriptor->msURL))
+ || (mpDescriptor->msPageName.getLength()>0
+ && mpDescriptor->msPageName.equals(rDescriptor->msPageName))
+ || (mpDescriptor->msStyleName.getLength()>0
+ && mpDescriptor->msStyleName.equals(rDescriptor->msStyleName))
+ || (mpDescriptor->mpMasterPage!=NULL
+ && mpDescriptor->mpMasterPage==rDescriptor->mpMasterPage)
+ || (mpDescriptor->mpPageObjectProvider.get()!=NULL
+ && rDescriptor->mpPageObjectProvider.get()!=NULL
+ && mpDescriptor->mpPageObjectProvider==rDescriptor->mpPageObjectProvider));
+ }
+}
+
+
+} } } // end of namespace ::sd::toolpanel::controls
diff --git a/sd/source/ui/toolpanel/controls/MasterPageDescriptor.hxx b/sd/source/ui/toolpanel/controls/MasterPageDescriptor.hxx
new file mode 100755
index 000000000000..0303989e3379
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/MasterPageDescriptor.hxx
@@ -0,0 +1,240 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANEL_CONTROLS_MASTER_PAGE_DESCRIPTOR_HXX
+#define SD_TOOLPANEL_CONTROLS_MASTER_PAGE_DESCRIPTOR_HXX
+
+#include "MasterPageContainer.hxx"
+#include <boost/shared_ptr.hpp>
+
+namespace sd { namespace toolpanel { namespace controls {
+
+class PageObjectProvider;
+class PreviewProvider;
+
+class MasterPageDescriptor;
+typedef ::boost::shared_ptr<MasterPageDescriptor> SharedMasterPageDescriptor;
+
+/** A collection of data that is stored for every master page in the
+ MasterpageContainer.
+*/
+class MasterPageDescriptor
+{
+public:
+ MasterPageDescriptor (
+ MasterPageContainer::Origin eOrigin,
+ const sal_Int32 nTemplateIndex,
+ const String& rURL,
+ const String& rPageName,
+ const String& rStyleName,
+ const bool bIsPrecious,
+ const ::boost::shared_ptr<PageObjectProvider>& rpPageObjectProvider,
+ const ::boost::shared_ptr<PreviewProvider>& rpPreviewProvider);
+ MasterPageDescriptor (const MasterPageDescriptor& rDescriptor);
+ ~MasterPageDescriptor (void);
+
+ void SetToken (MasterPageContainer::Token aToken);
+
+ /** Update the called MasterPageDescriptor object with values from the
+ given one. Only those values are updated that have default values
+ in the called object and that have non-default values in the given
+ one.
+ @return
+ Returns a list of event types for which event notifications have
+ to be sent to listeners. The list may be empty or NULL.
+ */
+ ::std::auto_ptr<std::vector<MasterPageContainerChangeEvent::EventType> >
+ Update (
+ const MasterPageDescriptor& rDescriptor);
+
+ /** This convenience method returns either a small or a large preview,
+ depending on the given size specifier.
+ Note that the previews are not created when they are not present.
+ @return
+ The returned preview may be empty.
+ */
+ Image GetPreview (MasterPageContainer::PreviewSize ePreviewSize);
+
+ /** Use the PreviewProvider to get access to a preview of the master
+ page.
+
+ Note that this is only done, when either bForce is <TRUE/> or
+ the PreviewProvider::GetCostIndex() returns 0.
+
+ The small preview is created by scaling the large one, not by
+ calling PreviewProvider::operator() a second time.
+
+ It is the responsibility of the caller to call UpdatePageObject()
+ before calling this method when the PreviewProvider can only work
+ when the master page object is present, i.e. its NeedsPageObject()
+ method returns <TRUE/>.
+
+ @param nCostThreshold
+ When this is zero or positive then the preview is created only
+ when the preview provider has a cost equal to or smaller than
+ this threshold. A negative value forces the preview to be
+ created, regardless of the cost.
+ @param rSmallSize
+ Size of the small preview.
+ @param rLargeSize
+ Size of the large preview.
+ @param rRenderer
+ A PreviewRenderer object that may be used to create a preview.
+ @return
+ When the previews are successfully provided then <TRUE/> is
+ returned.
+ */
+ bool UpdatePreview (
+ sal_Int32 nCostThreshold,
+ const Size& rSmallSize,
+ const Size& rLargeSize,
+ ::sd::PreviewRenderer& rRenderer);
+
+ /** Use the PageObjectProvider to get access to the master page object.
+
+ Note that this is only done, when either bForce is <TRUE/> or the
+ PreviewProvider::GetCostIndex() returns 0.
+
+ @param nCostThreshold
+ When this is zero or positive then the page object is created
+ only when the page object provider has a cost equal to or
+ smaller than this threshold. A negative value forces the
+ page object be created, regardless of the cost.
+ @param pDocument
+ This document of the MasterPageContainer may be used to create
+ a page object with or store one in.
+ @return
+ When the master page object is successfully provided then
+ <TRUE/> is returned.
+ */
+ bool UpdatePageObject (
+ sal_Int32 nCostThreshold,
+ SdDrawDocument* pDocument);
+
+ enum URLClassification {
+ URLCLASS_USER,
+ URLCLASS_LAYOUT,
+ URLCLASS_PRESENTATION,
+ URLCLASS_OTHER,
+ URLCLASS_UNKNOWN,
+ URLCLASS_UNDETERMINED
+ };
+
+ URLClassification GetURLClassification (void);
+
+ /** The Token under which the MasterPageContainer gives access to the
+ object.
+ */
+ MasterPageContainer::Token maToken;
+
+ /** A rough specification of the origin of the master page.
+ */
+ MasterPageContainer::Origin meOrigin;
+
+ /** The URL is not empty for master pages loaded from a template
+ document.
+ */
+ ::rtl::OUString msURL;
+
+ /** Taken from the title of the template file.
+ */
+ ::rtl::OUString msPageName;
+
+ /** Taken from the master page object.
+ */
+ ::rtl::OUString msStyleName;
+
+ const bool mbIsPrecious;
+
+ /** The actual master page.
+ */
+ SdPage* mpMasterPage;
+
+ /** A slide that uses the master page.
+ */
+ SdPage* mpSlide;
+
+ /** A small (the default size) preview of the master page. May be
+ empty. When this smaller preview is not empty then the larger one
+ is not empty, too.
+ */
+ Image maSmallPreview;
+
+ /** A large preview of the master page. May be empty. When this larger
+ preview is not empty then the smaller one is not empty, too.
+ */
+ Image maLargePreview;
+
+ /** The prewview provider. May be empty. May be replaced during the
+ lifetime of a MasterPageDescriptor object.
+ */
+ ::boost::shared_ptr<PreviewProvider> mpPreviewProvider;
+
+ /** The master page provider. May be empty. May be replaced during
+ the lifetime of a MasterPageDescriptor object.
+ */
+ ::boost::shared_ptr<PageObjectProvider> mpPageObjectProvider;
+
+ /** This index represents the order in which templates are provided via
+ the TemplateScanner. It defines the order in which the entries in
+ the AllMasterPagesSelector are displayed. The default value is -1.
+ */
+ sal_Int32 mnTemplateIndex;
+
+ URLClassification meURLClassification;
+
+ sal_Int32 mnUseCount;
+
+ class URLComparator { public:
+ ::rtl::OUString msURL;
+ URLComparator (const ::rtl::OUString& sURL);
+ bool operator() (const SharedMasterPageDescriptor& rDescriptor);
+ };
+ class StyleNameComparator { public:
+ ::rtl::OUString msStyleName;
+ StyleNameComparator (const ::rtl::OUString& sStyleName);
+ bool operator() (const SharedMasterPageDescriptor& rDescriptor);
+ };
+ class PageObjectComparator { public:
+ const SdPage* mpMasterPage;
+ PageObjectComparator (const SdPage* pPageObject);
+ bool operator() (const SharedMasterPageDescriptor& rDescriptor);
+ };
+ class AllComparator { public:
+ AllComparator(const SharedMasterPageDescriptor& rDescriptor);
+ bool operator() (const SharedMasterPageDescriptor& rDescriptor);
+ private:
+ SharedMasterPageDescriptor mpDescriptor;
+ };
+
+
+};
+
+
+} } } // end of namespace ::sd::toolpanel::controls
+
+#endif
diff --git a/sd/source/ui/toolpanel/controls/MasterPageObserver.cxx b/sd/source/ui/toolpanel/controls/MasterPageObserver.cxx
new file mode 100755
index 000000000000..2ba0cc678403
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/MasterPageObserver.cxx
@@ -0,0 +1,426 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "MasterPageObserver.hxx"
+
+#include <algorithm>
+#include "drawdoc.hxx"
+#include "sdpage.hxx"
+#include <hash_map>
+#include <set>
+#include <vector>
+#include <svl/lstner.hxx>
+#include <osl/doublecheckedlocking.h>
+#include <osl/getglobalmutex.hxx>
+
+
+namespace sd {
+
+class MasterPageObserver::Implementation
+ : public SfxListener
+{
+public:
+ /** The single instance of this class. It is created on demand when
+ Instance() is called for the first time.
+ */
+ static MasterPageObserver* mpInstance;
+
+ /** The master page observer will listen to events of this document and
+ detect changes of the use of master pages.
+ */
+ void RegisterDocument (SdDrawDocument& rDocument);
+
+ /** The master page observer will stop to listen to events of this
+ document.
+ */
+ void UnregisterDocument (SdDrawDocument& rDocument);
+
+ /** Add a listener that is informed of master pages that are newly
+ assigned to slides or become unassigned.
+ @param rEventListener
+ The event listener to call for future events. Call
+ RemoveEventListener() before the listener is destroyed.
+ */
+ void AddEventListener (const Link& rEventListener);
+
+ /** Remove the given listener from the list of listeners.
+ @param rEventListener
+ After this method returns the given listener is not called back
+ from this object. Passing a listener that has not
+ been registered before is safe and is silently ignored.
+ */
+ void RemoveEventListener (const Link& rEventListener);
+
+ /** Return a set of the names of master pages for the given document.
+ This convenience method exists because this set is part of the
+ internal data structure and thus takes no time to create.
+ */
+ inline MasterPageObserver::MasterPageNameSet GetMasterPageNames (
+ SdDrawDocument& rDocument);
+
+private:
+ ::std::vector<Link> maListeners;
+
+ struct DrawDocHash {
+ size_t operator()(SdDrawDocument* argument) const
+ { return reinterpret_cast<unsigned long>(argument); }
+ };
+ typedef ::std::hash_map<SdDrawDocument*,
+ MasterPageObserver::MasterPageNameSet,
+ DrawDocHash>
+ MasterPageContainer;
+ MasterPageContainer maUsedMasterPages;
+
+ virtual void Notify(
+ SfxBroadcaster& rBroadcaster,
+ const SfxHint& rHint);
+
+ void AnalyzeUsedMasterPages (SdDrawDocument& rDocument);
+
+ void SendEvent (MasterPageObserverEvent& rEvent);
+};
+
+MasterPageObserver* MasterPageObserver::Implementation::mpInstance = NULL;
+
+
+
+//===== MasterPageObserver ====================================================
+
+MasterPageObserver& MasterPageObserver::Instance (void)
+{
+ if (Implementation::mpInstance == NULL)
+ {
+ ::osl::GetGlobalMutex aMutexFunctor;
+ ::osl::MutexGuard aGuard (aMutexFunctor());
+ if (Implementation::mpInstance == NULL)
+ {
+ MasterPageObserver* pInstance = new MasterPageObserver ();
+ SdGlobalResourceContainer::Instance().AddResource (
+ ::std::auto_ptr<SdGlobalResource>(pInstance));
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ Implementation::mpInstance = pInstance;
+ }
+ }
+ else
+ {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+
+ DBG_ASSERT(Implementation::mpInstance!=NULL,
+ "MasterPageObserver::Instance(): instance is NULL");
+ return *Implementation::mpInstance;
+}
+
+
+
+
+void MasterPageObserver::RegisterDocument (SdDrawDocument& rDocument)
+{
+ mpImpl->RegisterDocument (rDocument);
+}
+
+
+
+
+void MasterPageObserver::UnregisterDocument (SdDrawDocument& rDocument)
+{
+ mpImpl->UnregisterDocument (rDocument);
+}
+
+
+
+
+void MasterPageObserver::AddEventListener (const Link& rEventListener)
+{
+
+ mpImpl->AddEventListener (rEventListener);
+}
+
+
+
+
+void MasterPageObserver::RemoveEventListener (const Link& rEventListener)
+{
+ mpImpl->RemoveEventListener (rEventListener);
+}
+
+
+
+
+MasterPageObserver::MasterPageObserver (void)
+ : mpImpl (new Implementation())
+{}
+
+
+
+
+MasterPageObserver::~MasterPageObserver (void)
+{}
+
+
+
+
+//===== MasterPageObserver::Implementation ====================================
+
+void MasterPageObserver::Implementation::RegisterDocument (
+ SdDrawDocument& rDocument)
+{
+ // Gather the names of all the master pages in the given document.
+ MasterPageContainer::data_type aMasterPageSet;
+ USHORT nMasterPageCount = rDocument.GetMasterSdPageCount(PK_STANDARD);
+ for (USHORT nIndex=0; nIndex<nMasterPageCount; nIndex++)
+ {
+ SdPage* pMasterPage = rDocument.GetMasterSdPage (nIndex, PK_STANDARD);
+ if (pMasterPage != NULL)
+ aMasterPageSet.insert (pMasterPage->GetName());
+ }
+
+ maUsedMasterPages[&rDocument] = aMasterPageSet;
+
+ StartListening (rDocument);
+}
+
+
+
+
+void MasterPageObserver::Implementation::UnregisterDocument (
+ SdDrawDocument& rDocument)
+{
+ EndListening (rDocument);
+
+ MasterPageContainer::iterator aMasterPageDescriptor(maUsedMasterPages.find(&rDocument));
+ if(aMasterPageDescriptor != maUsedMasterPages.end())
+ maUsedMasterPages.erase(aMasterPageDescriptor);
+}
+
+
+
+
+void MasterPageObserver::Implementation::AddEventListener (
+ const Link& rEventListener)
+{
+ if (::std::find (
+ maListeners.begin(),
+ maListeners.end(),
+ rEventListener) == maListeners.end())
+ {
+ maListeners.push_back (rEventListener);
+
+ // Tell the new listener about all the master pages that are
+ // currently in use.
+ typedef ::std::vector<String> StringList;
+ StringList aNewMasterPages;
+ StringList aRemovedMasterPages;
+ MasterPageContainer::iterator aDocumentIterator;
+ for (aDocumentIterator=maUsedMasterPages.begin();
+ aDocumentIterator!=maUsedMasterPages.end();
+ ++aDocumentIterator)
+ {
+ ::std::set<String>::reverse_iterator aNameIterator;
+ for (aNameIterator=aDocumentIterator->second.rbegin();
+ aNameIterator!=aDocumentIterator->second.rend();
+ ++aNameIterator)
+ {
+ MasterPageObserverEvent aEvent (
+ MasterPageObserverEvent::ET_MASTER_PAGE_EXISTS,
+ *aDocumentIterator->first,
+ *aNameIterator);
+ SendEvent (aEvent);
+ }
+ }
+ }
+}
+
+
+
+
+void MasterPageObserver::Implementation::RemoveEventListener (
+ const Link& rEventListener)
+{
+ maListeners.erase (
+ ::std::find (
+ maListeners.begin(),
+ maListeners.end(),
+ rEventListener));
+}
+
+
+
+
+MasterPageObserver::MasterPageNameSet
+ MasterPageObserver::Implementation::GetMasterPageNames (
+ SdDrawDocument& rDocument)
+{
+ MasterPageContainer::iterator aMasterPageDescriptor (
+ maUsedMasterPages.find(&rDocument));
+ if (aMasterPageDescriptor != maUsedMasterPages.end())
+ return aMasterPageDescriptor->second;
+ else
+ // Not found so return an empty set.
+ return MasterPageObserver::MasterPageNameSet();
+}
+
+
+
+
+void MasterPageObserver::Implementation::Notify(
+ SfxBroadcaster& rBroadcaster,
+ const SfxHint& rHint)
+{
+ if (rHint.ISA(SdrHint))
+ {
+ SdrHint& rSdrHint (*PTR_CAST(SdrHint,&rHint));
+ switch (rSdrHint.GetKind())
+ {
+ case HINT_PAGEORDERCHG:
+ // Process the modified set of pages only when the number of
+ // standard and notes master pages are equal. This test
+ // filters out events that are sent in between the insertion
+ // of a new standard master page and a new notes master
+ // page.
+ if (rBroadcaster.ISA(SdDrawDocument))
+ {
+ SdDrawDocument& rDocument (
+ static_cast<SdDrawDocument&>(rBroadcaster));
+ if (rDocument.GetMasterSdPageCount(PK_STANDARD)
+ == rDocument.GetMasterSdPageCount(PK_NOTES))
+ {
+ AnalyzeUsedMasterPages (rDocument);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+
+
+void MasterPageObserver::Implementation::AnalyzeUsedMasterPages (
+ SdDrawDocument& rDocument)
+{
+ // Create a set of names of the master pages used by the given document.
+ USHORT nMasterPageCount = rDocument.GetMasterSdPageCount(PK_STANDARD);
+ ::std::set<String> aCurrentMasterPages;
+ for (USHORT nIndex=0; nIndex<nMasterPageCount; nIndex++)
+ {
+ SdPage* pMasterPage = rDocument.GetMasterSdPage (nIndex, PK_STANDARD);
+ if (pMasterPage != NULL)
+ aCurrentMasterPages.insert (pMasterPage->GetName());
+ OSL_TRACE("currently used master page %d is %s",
+ nIndex,
+ ::rtl::OUStringToOString(pMasterPage->GetName(),
+ RTL_TEXTENCODING_UTF8).getStr());
+ }
+
+ typedef ::std::vector<String> StringList;
+ StringList aNewMasterPages;
+ StringList aRemovedMasterPages;
+ MasterPageContainer::iterator aOldMasterPagesDescriptor (
+ maUsedMasterPages.find(&rDocument));
+ if (aOldMasterPagesDescriptor != maUsedMasterPages.end())
+ {
+ StringList::iterator I;
+
+ ::std::set<String>::iterator J;
+ int i=0;
+ for (J=aOldMasterPagesDescriptor->second.begin();
+ J!=aOldMasterPagesDescriptor->second.end();
+ ++J)
+ OSL_TRACE("old used master page %d is %s",
+ i++,
+ ::rtl::OUStringToOString(*J,
+ RTL_TEXTENCODING_UTF8).getStr());
+
+ // Send events about the newly used master pages.
+ ::std::set_difference (
+ aCurrentMasterPages.begin(),
+ aCurrentMasterPages.end(),
+ aOldMasterPagesDescriptor->second.begin(),
+ aOldMasterPagesDescriptor->second.end(),
+ ::std::back_insert_iterator<StringList>(aNewMasterPages));
+ for (I=aNewMasterPages.begin(); I!=aNewMasterPages.end(); ++I)
+ {
+ OSL_TRACE(" added master page %s",
+ ::rtl::OUStringToOString(*I,
+ RTL_TEXTENCODING_UTF8).getStr());
+
+ MasterPageObserverEvent aEvent (
+ MasterPageObserverEvent::ET_MASTER_PAGE_ADDED,
+ rDocument,
+ *I);
+ SendEvent (aEvent);
+ }
+
+ // Send events about master pages that are not used any longer.
+ ::std::set_difference (
+ aOldMasterPagesDescriptor->second.begin(),
+ aOldMasterPagesDescriptor->second.end(),
+ aCurrentMasterPages.begin(),
+ aCurrentMasterPages.end(),
+ ::std::back_insert_iterator<StringList>(aRemovedMasterPages));
+ for (I=aRemovedMasterPages.begin(); I!=aRemovedMasterPages.end(); ++I)
+ {
+ OSL_TRACE(" removed master page %s",
+ ::rtl::OUStringToOString(*I,
+ RTL_TEXTENCODING_UTF8).getStr());
+
+ MasterPageObserverEvent aEvent (
+ MasterPageObserverEvent::ET_MASTER_PAGE_REMOVED,
+ rDocument,
+ *I);
+ SendEvent (aEvent);
+ }
+
+ // Store the new list of master pages.
+ aOldMasterPagesDescriptor->second = aCurrentMasterPages;
+ }
+}
+
+
+
+
+void MasterPageObserver::Implementation::SendEvent (
+ MasterPageObserverEvent& rEvent)
+{
+ ::std::vector<Link>::iterator aLink (maListeners.begin());
+ ::std::vector<Link>::iterator aEnd (maListeners.end());
+ while (aLink!=aEnd)
+ {
+ aLink->Call (&rEvent);
+ ++aLink;
+ }
+}
+
+
+} // end of namespace sd
diff --git a/sd/source/ui/toolpanel/controls/MasterPagesPanel.cxx b/sd/source/ui/toolpanel/controls/MasterPagesPanel.cxx
new file mode 100755
index 000000000000..8dab51e93a58
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/MasterPagesPanel.cxx
@@ -0,0 +1,157 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "MasterPagesPanel.hxx"
+#include "taskpane/ScrollPanel.hxx"
+#include "CurrentMasterPagesSelector.hxx"
+#include "RecentMasterPagesSelector.hxx"
+#include "AllMasterPagesSelector.hxx"
+#include "taskpane/ToolPanelViewShell.hxx"
+#include "taskpane/TaskPaneControlFactory.hxx"
+#include "taskpane/TitledControl.hxx"
+#include "../TaskPaneShellManager.hxx"
+
+#include "DrawViewShell.hxx"
+#include "ViewShellBase.hxx"
+
+#include "strings.hrc"
+#include "sdresid.hxx"
+#include "helpids.h"
+#include <svtools/valueset.hxx>
+
+namespace sd { namespace toolpanel { namespace controls {
+
+
+MasterPagesPanel::MasterPagesPanel (::Window& i_rParentWindow, ToolPanelViewShell& i_rPanelViewShell)
+ :ScrollPanel (i_rParentWindow)
+ ,m_pPanelViewShell( &i_rPanelViewShell )
+{
+ impl_construct( m_pPanelViewShell->GetViewShellBase() );
+}
+
+void MasterPagesPanel::impl_construct( ViewShellBase& rBase )
+{
+ SdDrawDocument* pDocument = rBase.GetDocument();
+ ::std::auto_ptr<controls::MasterPagesSelector> pSelector;
+ TitledControl* pTitledControl;
+
+ ::boost::shared_ptr<MasterPageContainer> pContainer (new MasterPageContainer());
+
+ // Create a panel with the master pages that are in use by the currently
+ // edited document.
+ DrawViewShell* pDrawViewShell = dynamic_cast<DrawViewShell*>(rBase.GetMainViewShell().get());
+ pSelector.reset(new controls::CurrentMasterPagesSelector (
+ this,
+ *pDocument,
+ rBase,
+ pContainer));
+ pSelector->LateInit();
+ pSelector->SetSmartHelpId( SmartId(HID_SD_TASK_PANE_PREVIEW_CURRENT) );
+ GetShellManager()->AddSubShell(
+ HID_SD_TASK_PANE_PREVIEW_CURRENT,
+ pSelector.get(),
+ pSelector->GetWindow());
+ pTitledControl = AddControl (
+ ::std::auto_ptr<TreeNode>(pSelector.release()),
+ SdResId(STR_TASKPANEL_CURRENT_MASTER_PAGES_TITLE),
+ HID_SD_CURRENT_MASTERS);
+
+ // Create a panel with the most recently used master pages.
+ pSelector.reset(new controls::RecentMasterPagesSelector (
+ this,
+ *pDocument,
+ rBase,
+ pContainer));
+ pSelector->LateInit();
+ pSelector->SetSmartHelpId( SmartId(HID_SD_TASK_PANE_PREVIEW_RECENT) );
+ GetShellManager()->AddSubShell(
+ HID_SD_TASK_PANE_PREVIEW_RECENT,
+ pSelector.get(),
+ pSelector->GetWindow());
+ pTitledControl = AddControl (
+ ::std::auto_ptr<TreeNode>(pSelector.release()),
+ SdResId(STR_TASKPANEL_RECENT_MASTER_PAGES_TITLE),
+ HID_SD_RECENT_MASTERS);
+
+ // Create a panel with all available master pages.
+ pSelector.reset(new controls::AllMasterPagesSelector (
+ this,
+ *pDocument,
+ rBase,
+ *pDrawViewShell,
+ pContainer));
+ pSelector->LateInit();
+ pSelector->SetSmartHelpId( SmartId(HID_SD_TASK_PANE_PREVIEW_ALL) );
+ GetShellManager()->AddSubShell(
+ HID_SD_TASK_PANE_PREVIEW_ALL,
+ pSelector.get(),
+ pSelector->GetWindow());
+ pTitledControl = AddControl (
+ ::std::auto_ptr<TreeNode>(pSelector.release()),
+ SdResId(STR_TASKPANEL_ALL_MASTER_PAGES_TITLE),
+ HID_SD_ALL_MASTERS);
+}
+
+
+
+
+
+MasterPagesPanel::~MasterPagesPanel (void)
+{
+ TaskPaneShellManager* pShellManager( GetShellManager() );
+ OSL_ENSURE( pShellManager, "MasterPagesPanel::~MasterPagesPanel: no shell manager anymore - cannot remove sub shells!" );
+ if ( pShellManager )
+ {
+ pShellManager->RemoveSubShell( HID_SD_TASK_PANE_PREVIEW_CURRENT );
+ pShellManager->RemoveSubShell( HID_SD_TASK_PANE_PREVIEW_RECENT );
+ pShellManager->RemoveSubShell( HID_SD_TASK_PANE_PREVIEW_ALL );
+ }
+}
+
+
+
+
+TaskPaneShellManager* MasterPagesPanel::GetShellManager()
+{
+ if ( m_pPanelViewShell )
+ return &m_pPanelViewShell->GetSubShellManager();
+ return TreeNode::GetShellManager();
+}
+
+
+
+
+std::auto_ptr< ControlFactory > MasterPagesPanel::CreateControlFactory( ToolPanelViewShell& i_rToolPanelShell )
+{
+ return std::auto_ptr< ControlFactory >(
+ new RootControlFactoryWithArg< MasterPagesPanel, ToolPanelViewShell >( i_rToolPanelShell ) );
+}
+
+} } } // end of namespace ::sd::toolpanel::controls
diff --git a/sd/source/ui/toolpanel/controls/MasterPagesPanel.hxx b/sd/source/ui/toolpanel/controls/MasterPagesPanel.hxx
new file mode 100755
index 000000000000..932007802ebf
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/MasterPagesPanel.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TASKPANE_CONTROLS_MASTER_PAGES_PANEL_HXX
+#define SD_TASKPANE_CONTROLS_MASTER_PAGES_PANEL_HXX
+
+#include "taskpane/ScrollPanel.hxx"
+
+namespace sd {
+class ViewShellBase;
+}
+
+namespace sd { namespace toolpanel {
+class ControlFactory;
+class TreeNode;
+class ToolPanelViewShell;
+} }
+
+namespace sd { namespace toolpanel { namespace controls {
+
+/** The master pages panel combines three master page related panels into
+ one. This has the benefit that creation of the task pane becomes a
+ little bit simpler and that common scroll bars can be displayed.
+*/
+class MasterPagesPanel
+ : public ScrollPanel
+{
+public:
+ MasterPagesPanel (
+ ::Window& i_rParentWindow,
+ ToolPanelViewShell& i_rPanelViewShell);
+ virtual ~MasterPagesPanel (void);
+
+ // TreeNode overridables
+ virtual TaskPaneShellManager* GetShellManager (void);
+
+ static std::auto_ptr<ControlFactory> CreateControlFactory (ToolPanelViewShell& i_rToolPanelShell);
+
+private:
+ void impl_construct( ViewShellBase& rBase );
+
+private:
+ ToolPanelViewShell* m_pPanelViewShell;
+};
+
+} } } // end of namespace ::sd::toolpanel::controls
+
+#endif
diff --git a/sd/source/ui/toolpanel/controls/MasterPagesSelector.cxx b/sd/source/ui/toolpanel/controls/MasterPagesSelector.cxx
new file mode 100755
index 000000000000..b321dbf8dd14
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/MasterPagesSelector.cxx
@@ -0,0 +1,854 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "MasterPagesSelector.hxx"
+
+#include "MasterPageContainer.hxx"
+#include "DocumentHelper.hxx"
+#include "pres.hxx"
+#include "drawdoc.hxx"
+#include "DrawDocShell.hxx"
+#include "sdpage.hxx"
+#include "glob.hxx"
+#include "glob.hrc"
+#include "app.hrc"
+#include "res_bmp.hrc"
+#include "strings.hrc"
+#include "DrawViewShell.hxx"
+#include "DrawController.hxx"
+#include "SlideSorterViewShell.hxx"
+#include "PreviewValueSet.hxx"
+#include "ViewShellBase.hxx"
+#include "../TaskPaneShellManager.hxx"
+#include "taskpane/TitledControl.hxx"
+#include "taskpane/ControlContainer.hxx"
+#include "controller/SlideSorterController.hxx"
+#include "controller/SlsPageSelector.hxx"
+#include <sfx2/objface.hxx>
+#include "sdresid.hxx"
+#include "TemplateScanner.hxx"
+#ifndef _SD_DRAWVIEW_HXX
+#include "drawview.hxx"
+#endif
+#include <vcl/image.hxx>
+#include <svl/languageoptions.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/mnumgr.hxx>
+#include <svl/itemset.hxx>
+#include <svl/eitem.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svxids.hrc>
+#include "FrameView.hxx"
+#include "sdpage.hxx"
+#include "stlpool.hxx"
+#include "unmovss.hxx"
+#include <sfx2/request.hxx>
+#include <svl/itempool.hxx>
+
+using namespace ::sd::toolpanel::controls;
+#define MasterPagesSelector
+#include "sdslots.hxx"
+
+using namespace ::com::sun::star::text;
+
+
+
+namespace sd { namespace toolpanel { namespace controls {
+
+
+SFX_IMPL_INTERFACE(MasterPagesSelector, SfxShell,
+ SdResId(STR_MASTERPAGESSELECTOR))
+{
+ SFX_POPUPMENU_REGISTRATION( SdResId(RID_TASKPANE_MASTERPAGESSELECTOR_POPUP) );
+}
+
+TYPEINIT1(MasterPagesSelector, SfxShell);
+
+
+
+MasterPagesSelector::MasterPagesSelector (
+ TreeNode* pParent,
+ SdDrawDocument& rDocument,
+ ViewShellBase& rBase,
+ const ::boost::shared_ptr<MasterPageContainer>& rpContainer)
+ : TreeNode (pParent),
+ SfxShell(),
+ maMutex(),
+ mpContainer(rpContainer),
+ mrDocument(rDocument),
+ mpPageSet (new PreviewValueSet(pParent)),
+ mrBase(rBase),
+ mnDefaultClickAction(SID_TP_APPLY_TO_ALL_SLIDES),
+ maPreviewUpdateQueue(),
+ maCurrentItemList(),
+ maTokenToValueSetIndex(),
+ maLockedMasterPages()
+{
+ SetPool (&rDocument.GetPool());
+
+ mpPageSet->SetSelectHdl (
+ LINK(this, MasterPagesSelector, ClickHandler));
+ mpPageSet->SetRightMouseClickHandler (
+ LINK(this, MasterPagesSelector, RightClickHandler));
+ mpPageSet->SetContextMenuCallback (
+ LINK(this, MasterPagesSelector, ContextMenuCallback));
+ mpPageSet->SetStyle(mpPageSet->GetStyle() | WB_NO_DIRECTSELECT);
+ mpPageSet->SetPreviewSize(mpContainer->GetPreviewSizePixel());
+ mpPageSet->Show();
+
+ Link aChangeListener (LINK(this,MasterPagesSelector,ContainerChangeListener));
+ mpContainer->AddChangeListener(aChangeListener);
+}
+
+
+
+
+MasterPagesSelector::~MasterPagesSelector (void)
+{
+ Clear();
+ mpPageSet.reset();
+ UpdateLocks(ItemList());
+
+ if (GetShellManager() != NULL)
+ GetShellManager()->RemoveSubShell (this);
+
+ Link aChangeListener (LINK(this,MasterPagesSelector,ContainerChangeListener));
+ mpContainer->RemoveChangeListener(aChangeListener);
+}
+
+
+
+
+void MasterPagesSelector::LateInit (void)
+{
+}
+
+
+
+
+sal_Int32 MasterPagesSelector::GetPreferredWidth (sal_Int32 nHeight)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ return mpPageSet->GetPreferredWidth (nHeight);
+}
+
+
+
+
+sal_Int32 MasterPagesSelector::GetPreferredHeight (sal_Int32 nWidth)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ return mpPageSet->GetPreferredHeight (nWidth);
+}
+
+
+
+
+Size MasterPagesSelector::GetPreferredSize (void)
+{
+ int nPreferredWidth = GetPreferredWidth(
+ mpPageSet->GetOutputSizePixel().Height());
+ int nPreferredHeight = GetPreferredHeight(nPreferredWidth);
+ return Size (nPreferredWidth, nPreferredHeight);
+
+}
+
+
+
+
+void MasterPagesSelector::UpdateLocks (const ItemList& rItemList)
+{
+ ItemList aNewLockList;
+
+ // In here we first lock the master pages in the given list and then
+ // release the locks acquired in a previous call to this method. When
+ // this were done the other way round the lock count of some master
+ // pages might drop temporarily to 0 and would lead to unnecessary
+ // deletion and re-creation of MasterPageDescriptor objects.
+
+ // Lock the master pages in the given list.
+ ItemList::const_iterator iItem;
+ for (iItem=rItemList.begin(); iItem!=rItemList.end(); ++iItem)
+ {
+ mpContainer->AcquireToken(*iItem);
+ aNewLockList.push_back(*iItem);
+ }
+
+ // Release the previously locked master pages.
+ ItemList::const_iterator iPage;
+ ItemList::const_iterator iEnd (maLockedMasterPages.end());
+ for (iPage=maLockedMasterPages.begin(); iPage!=iEnd; ++iPage)
+ mpContainer->ReleaseToken(*iPage);
+
+ maLockedMasterPages.swap(aNewLockList);
+}
+
+
+
+
+void MasterPagesSelector::Fill (void)
+{
+ ::std::auto_ptr<ItemList> pItemList (new ItemList());
+
+ Fill(*pItemList);
+
+ UpdateLocks(*pItemList);
+ UpdateItemList(pItemList);
+}
+
+
+
+
+ResId MasterPagesSelector::GetContextMenuResId (void) const
+{
+ return SdResId(RID_TASKPANE_MASTERPAGESSELECTOR_POPUP);
+}
+
+
+
+
+IMPL_LINK(MasterPagesSelector, ClickHandler, PreviewValueSet*, EMPTYARG)
+{
+ // We use the framework to assign the clicked-on master page because we
+ // so use the same mechanism as the context menu does (where we do not
+ // have the option to call the assignment method directly.)
+ if (GetShellManager() != NULL)
+ GetShellManager()->MoveToTop (this);
+
+ SfxViewFrame* pViewFrame = mrBase.GetViewFrame();
+ if (pViewFrame != NULL)
+ {
+ SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
+ if (pDispatcher != NULL)
+ pDispatcher->Execute(mnDefaultClickAction);
+ }
+
+ return 0;
+}
+
+
+
+
+IMPL_LINK(MasterPagesSelector, RightClickHandler, MouseEvent*, pEvent)
+{
+ // Here we only prepare the display of the context menu: the item under
+ // the mouse is selected. The actual display of the context menu is
+ // done in ContextMenuCallback which is called indirectly through
+ // PreviewValueSet::Command().
+ mpPageSet->GrabFocus ();
+ mpPageSet->ReleaseMouse();
+ if (GetDispatcher() != NULL && pEvent != NULL)
+ {
+ USHORT nIndex = mpPageSet->GetItemId (pEvent->GetPosPixel());
+ if (nIndex > 0)
+ mpPageSet->SelectItem (nIndex);
+ }
+ return 0;
+}
+
+
+
+
+IMPL_LINK(MasterPagesSelector, ContextMenuCallback, CommandEvent*, pEvent)
+{
+ // Use the currently selected item and show the popup menu in its
+ // center.
+ if (GetShellManager() != NULL)
+ GetShellManager()->MoveToTop (this);
+ const USHORT nIndex = mpPageSet->GetSelectItemId();
+ if (nIndex > 0 && pEvent!=NULL)
+ {
+ // The position of the upper left corner of the context menu is
+ // taken either from the mouse position (when the command was sent
+ // as reaction to a right click) or in the center of the selected
+ // item (when the command was sent as reaction to Shift+F10.)
+ Point aPosition (pEvent->GetMousePosPixel());
+ if ( ! pEvent->IsMouseEvent())
+ {
+ Rectangle aBBox (mpPageSet->GetItemRect(nIndex));
+ aPosition = aBBox.Center();
+ }
+
+ const ResId aPopupResId (GetContextMenuResId());
+ mrBase.GetViewFrame()->GetDispatcher()->ExecutePopup(
+ aPopupResId,
+ mpPageSet.get(),
+ &aPosition);
+ }
+
+ return 0;
+}
+
+
+
+
+IMPL_LINK(MasterPagesSelector, ContainerChangeListener, MasterPageContainerChangeEvent*, pEvent)
+{
+ if (pEvent)
+ NotifyContainerChangeEvent(*pEvent);
+ return 0;
+}
+
+
+
+
+SdPage* MasterPagesSelector::GetSelectedMasterPage (void)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ SdPage* pMasterPage = NULL;
+ USHORT nIndex = mpPageSet->GetSelectItemId();
+ UserData* pData = GetUserData(nIndex);
+ if (pData != NULL)
+ {
+ pMasterPage = mpContainer->GetPageObjectForToken(pData->second);
+ }
+ return pMasterPage;
+}
+
+
+
+
+/** Assemble a list of all slides of the document and pass it to
+ AssignMasterPageToPageList().
+*/
+void MasterPagesSelector::AssignMasterPageToAllSlides (SdPage* pMasterPage)
+{
+ do
+ {
+ if (pMasterPage == NULL)
+ break;
+
+ USHORT nPageCount = mrDocument.GetSdPageCount(PK_STANDARD);
+ if (nPageCount == 0)
+ break;
+
+ // Get a list of all pages. As a little optimization we only
+ // include pages that do not already have the given master page
+ // assigned.
+ String sFullLayoutName (pMasterPage->GetLayoutName());
+ ::sd::slidesorter::SharedPageSelection pPageList (
+ new ::sd::slidesorter::SlideSorterViewShell::PageSelection());
+ for (USHORT nPageIndex=0; nPageIndex<nPageCount; nPageIndex++)
+ {
+ SdPage* pPage = mrDocument.GetSdPage (nPageIndex, PK_STANDARD);
+ if (pPage != NULL
+ && pPage->GetLayoutName().CompareTo(sFullLayoutName)!=0)
+ {
+ pPageList->push_back (pPage);
+ }
+ }
+
+ AssignMasterPageToPageList(pMasterPage, pPageList);
+ }
+ while (false);
+}
+
+
+
+
+/** Assemble a list of the currently selected slides (selected in a visible
+ slide sorter) and pass it to AssignMasterPageToPageList().
+*/
+void MasterPagesSelector::AssignMasterPageToSelectedSlides (
+ SdPage* pMasterPage)
+{
+ do
+ {
+ using namespace ::std;
+ using namespace ::sd::slidesorter;
+ using namespace ::sd::slidesorter::controller;
+
+ if (pMasterPage == NULL)
+ break;
+
+ // Find a visible slide sorter.
+ SlideSorterViewShell* pSlideSorter = SlideSorterViewShell::GetSlideSorter(mrBase);
+ if (pSlideSorter == NULL)
+ break;
+
+ // Get a list of selected pages.
+ ::sd::slidesorter::SharedPageSelection pPageSelection = pSlideSorter->GetPageSelection();
+ if (pPageSelection->empty())
+ break;
+
+ AssignMasterPageToPageList(pMasterPage, pPageSelection);
+
+ // Restore the previous selection.
+ pSlideSorter->SetPageSelection(pPageSelection);
+ }
+ while (false);
+}
+
+
+
+
+void MasterPagesSelector::AssignMasterPageToPageList (
+ SdPage* pMasterPage,
+ const ::sd::slidesorter::SharedPageSelection& rPageList)
+{
+ DocumentHelper::AssignMasterPageToPageList(mrDocument, pMasterPage, rPageList);
+}
+
+
+
+
+void MasterPagesSelector::NotifyContainerChangeEvent (const MasterPageContainerChangeEvent& rEvent)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ switch (rEvent.meEventType)
+ {
+ case MasterPageContainerChangeEvent::SIZE_CHANGED:
+ mpPageSet->SetPreviewSize(mpContainer->GetPreviewSizePixel());
+ UpdateAllPreviews();
+ break;
+
+ case MasterPageContainerChangeEvent::PREVIEW_CHANGED:
+ {
+ int nIndex (GetIndexForToken(rEvent.maChildToken));
+ if (nIndex >= 0)
+ {
+ mpPageSet->SetItemImage (
+ (USHORT)nIndex,
+ mpContainer->GetPreviewForToken(rEvent.maChildToken));
+ mpPageSet->Invalidate(mpPageSet->GetItemRect((USHORT)nIndex));
+ }
+ }
+ break;
+
+ case MasterPageContainerChangeEvent::DATA_CHANGED:
+ {
+ InvalidateItem(rEvent.maChildToken);
+ Fill();
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+
+
+MasterPagesSelector::UserData* MasterPagesSelector::CreateUserData (
+ int nIndex,
+ MasterPageContainer::Token aToken) const
+{
+ return new UserData(nIndex,aToken);
+}
+
+
+
+
+MasterPagesSelector::UserData* MasterPagesSelector::GetUserData (int nIndex) const
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ if (nIndex>0 && nIndex<=mpPageSet->GetItemCount())
+ return reinterpret_cast<UserData*>(mpPageSet->GetItemData((USHORT)nIndex));
+ else
+ return NULL;
+}
+
+
+
+
+void MasterPagesSelector::SetUserData (int nIndex, UserData* pData)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ if (nIndex>0 && nIndex<=mpPageSet->GetItemCount())
+ {
+ UserData* pOldData = GetUserData(nIndex);
+ if (pOldData!=NULL && pOldData!=pData)
+ delete pOldData;
+ mpPageSet->SetItemData((USHORT)nIndex, pData);
+ }
+}
+
+
+
+
+bool MasterPagesSelector::IsResizable (void)
+{
+ return false;
+}
+
+
+
+
+::Window* MasterPagesSelector::GetWindow (void)
+{
+ return mpPageSet.get();
+}
+
+
+
+
+sal_Int32 MasterPagesSelector::GetMinimumWidth (void)
+{
+ return mpContainer->GetPreviewSizePixel().Width() + 2*3;
+}
+
+
+
+
+void MasterPagesSelector::UpdateSelection (void)
+{
+}
+
+
+
+
+void MasterPagesSelector::Execute (SfxRequest& rRequest)
+{
+ switch (rRequest.GetSlot())
+ {
+ case SID_TP_APPLY_TO_ALL_SLIDES:
+ mrBase.SetBusyState (true);
+ AssignMasterPageToAllSlides (GetSelectedMasterPage());
+ mrBase.SetBusyState (false);
+ break;
+
+ case SID_TP_APPLY_TO_SELECTED_SLIDES:
+ mrBase.SetBusyState (true);
+ AssignMasterPageToSelectedSlides (GetSelectedMasterPage());
+ mrBase.SetBusyState (false);
+ break;
+
+ case SID_TP_USE_FOR_NEW_PRESENTATIONS:
+ DBG_ASSERT (false,
+ "Using slides as default for new presentations"
+ " is not yet implemented");
+ break;
+
+ case SID_TP_SHOW_SMALL_PREVIEW:
+ case SID_TP_SHOW_LARGE_PREVIEW:
+ {
+ mrBase.SetBusyState (true);
+ mpContainer->SetPreviewSize(
+ rRequest.GetSlot()==SID_TP_SHOW_SMALL_PREVIEW
+ ? MasterPageContainer::SMALL
+ : MasterPageContainer::LARGE);
+ mrBase.SetBusyState (false);
+ break;
+ }
+
+ case SID_TP_EDIT_MASTER:
+ {
+ using namespace ::com::sun::star;
+ uno::Reference<drawing::XDrawPage> xSelectedMaster (
+ GetSelectedMasterPage()->getUnoPage(), uno::UNO_QUERY);
+ SfxViewFrame* pViewFrame = mrBase.GetViewFrame();
+ if (pViewFrame != NULL && xSelectedMaster.is())
+ {
+ SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
+ if (pDispatcher != NULL)
+ {
+ USHORT nIndex = mpPageSet->GetSelectItemId();
+ pDispatcher->Execute(SID_MASTERPAGE, SFX_CALLMODE_SYNCHRON);
+ mpPageSet->SelectItem (nIndex);
+ mrBase.GetDrawController().setCurrentPage(xSelectedMaster);
+ }
+ }
+ break;
+ }
+
+ case SID_CUT:
+ case SID_COPY:
+ case SID_PASTE:
+ // Cut, copy, and paste are not supported and thus are ignored.
+ break;
+ }
+}
+
+
+
+
+void MasterPagesSelector::GetState (SfxItemSet& rItemSet)
+{
+ if (mpContainer->GetPreviewSize() == MasterPageContainer::SMALL)
+ rItemSet.DisableItem (SID_TP_SHOW_SMALL_PREVIEW);
+ else
+ rItemSet.DisableItem (SID_TP_SHOW_LARGE_PREVIEW);
+
+ // Cut and paste is not supported so do not show the menu entries.
+ rItemSet.DisableItem (SID_CUT);
+ rItemSet.DisableItem (SID_COPY);
+ rItemSet.DisableItem (SID_PASTE);
+}
+
+
+
+
+void MasterPagesSelector::SetItem (
+ USHORT nIndex,
+ MasterPageContainer::Token aToken)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ RemoveTokenToIndexEntry(nIndex,aToken);
+
+ if (nIndex > 0)
+ {
+ if (aToken != MasterPageContainer::NIL_TOKEN)
+ {
+ Image aPreview (mpContainer->GetPreviewForToken(aToken));
+ MasterPageContainer::PreviewState eState (mpContainer->GetPreviewState(aToken));
+
+ if (aPreview.GetSizePixel().Width()>0)
+ {
+ if (mpPageSet->GetItemPos(nIndex) != VALUESET_ITEM_NOTFOUND)
+ {
+ mpPageSet->SetItemImage(nIndex,aPreview);
+ mpPageSet->SetItemText(nIndex, mpContainer->GetPageNameForToken(aToken));
+ }
+ else
+ {
+ mpPageSet->InsertItem (
+ nIndex,
+ aPreview,
+ mpContainer->GetPageNameForToken(aToken),
+ nIndex);
+ }
+ SetUserData(nIndex, CreateUserData(nIndex,aToken));
+
+ AddTokenToIndexEntry(nIndex,aToken);
+ }
+
+ if (eState == MasterPageContainer::PS_CREATABLE)
+ mpContainer->RequestPreview(aToken);
+ }
+ else
+ {
+ mpPageSet->RemoveItem(nIndex);
+ }
+ }
+
+}
+
+
+
+
+void MasterPagesSelector::AddTokenToIndexEntry (
+ USHORT nIndex,
+ MasterPageContainer::Token aToken)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ maTokenToValueSetIndex[aToken] = nIndex;
+}
+
+
+
+
+void MasterPagesSelector::RemoveTokenToIndexEntry (
+ USHORT nIndex,
+ MasterPageContainer::Token aNewToken)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ UserData* pData = GetUserData(nIndex);
+ if (pData != NULL)
+ {
+ // Get the token that the index pointed to previously.
+ MasterPageContainer::Token aOldToken (pData->second);
+
+ if (aNewToken != aOldToken
+ && nIndex == GetIndexForToken(aOldToken))
+ {
+ maTokenToValueSetIndex[aOldToken] = 0;
+ }
+ }
+}
+
+
+
+
+void MasterPagesSelector::InvalidatePreview (const SdPage* pPage)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ for (USHORT nIndex=1; nIndex<=mpPageSet->GetItemCount(); nIndex++)
+ {
+ UserData* pData = GetUserData(nIndex);
+ if (pData != NULL)
+ {
+ MasterPageContainer::Token aToken (pData->second);
+ if (pPage == mpContainer->GetPageObjectForToken(aToken,false))
+ {
+ mpContainer->InvalidatePreview(aToken);
+ mpContainer->RequestPreview(aToken);
+ break;
+ }
+ }
+ }
+}
+
+void MasterPagesSelector::UpdateAllPreviews (void)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ for (USHORT nIndex=1; nIndex<=mpPageSet->GetItemCount(); nIndex++)
+ {
+ UserData* pData = GetUserData(nIndex);
+ if (pData != NULL)
+ {
+ MasterPageContainer::Token aToken (pData->second);
+ mpPageSet->SetItemImage(
+ nIndex,
+ mpContainer->GetPreviewForToken(aToken));
+ if (mpContainer->GetPreviewState(aToken) == MasterPageContainer::PS_CREATABLE)
+ mpContainer->RequestPreview(aToken);
+ }
+ }
+ mpPageSet->Rearrange(true);
+}
+
+
+
+
+void MasterPagesSelector::ClearPageSet (void)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ for (USHORT nIndex=1; nIndex<=mpPageSet->GetItemCount(); nIndex++)
+ {
+ UserData* pData = GetUserData(nIndex);
+ if (pData != NULL)
+ delete pData;
+ }
+ mpPageSet->Clear();
+}
+
+
+
+
+void MasterPagesSelector::SetSmartHelpId( const SmartId& aId, SmartIdUpdateMode aMode )
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ mpPageSet->SetSmartHelpId( aId, aMode );
+}
+
+
+
+
+sal_Int32 MasterPagesSelector::GetIndexForToken (MasterPageContainer::Token aToken) const
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ TokenToValueSetIndex::const_iterator iIndex (maTokenToValueSetIndex.find(aToken));
+ if (iIndex != maTokenToValueSetIndex.end())
+ return iIndex->second;
+ else
+ return -1;
+}
+
+
+
+
+void MasterPagesSelector::Clear (void)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ ClearPageSet();
+}
+
+
+
+
+void MasterPagesSelector::InvalidateItem (MasterPageContainer::Token aToken)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ ItemList::iterator iItem;
+ for (iItem=maCurrentItemList.begin(); iItem!=maCurrentItemList.end(); ++iItem)
+ {
+ if (*iItem == aToken)
+ {
+ *iItem = MasterPageContainer::NIL_TOKEN;
+ break;
+ }
+ }
+}
+
+
+
+
+void MasterPagesSelector::UpdateItemList (::std::auto_ptr<ItemList> pNewItemList)
+{
+ const ::osl::MutexGuard aGuard (maMutex);
+
+ ItemList::const_iterator iNewItem (pNewItemList->begin());
+ ItemList::const_iterator iCurrentItem (maCurrentItemList.begin());
+ ItemList::const_iterator iNewEnd (pNewItemList->end());
+ ItemList::const_iterator iCurrentEnd (maCurrentItemList.end());
+ USHORT nIndex (1);
+
+ // Update existing items.
+ for ( ; iNewItem!=iNewEnd && iCurrentItem!=iCurrentEnd; ++iNewItem, ++iCurrentItem,++nIndex)
+ {
+ if (*iNewItem != *iCurrentItem)
+ {
+ SetItem(nIndex,*iNewItem);
+ }
+ }
+
+ // Append new items.
+ for ( ; iNewItem!=iNewEnd; ++iNewItem,++nIndex)
+ {
+ SetItem(nIndex,*iNewItem);
+ }
+
+ // Remove trailing items.
+ for ( ; iCurrentItem!=iCurrentEnd; ++iCurrentItem,++nIndex)
+ {
+ SetItem(nIndex,MasterPageContainer::NIL_TOKEN);
+ }
+
+ maCurrentItemList.swap(*pNewItemList);
+
+ mpPageSet->Rearrange();
+ if (GetParentNode() != NULL)
+ GetParentNode()->RequestResize();
+}
+
+
+
+
+
+} } } // end of namespace ::sd::toolpanel::controls
diff --git a/sd/source/ui/toolpanel/controls/MasterPagesSelector.hxx b/sd/source/ui/toolpanel/controls/MasterPagesSelector.hxx
new file mode 100755
index 000000000000..a2df51f2bd4b
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/MasterPagesSelector.hxx
@@ -0,0 +1,235 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TASKPANE_CONTROLS_MASTER_PAGES_SELECTOR_HXX
+#define SD_TASKPANE_CONTROLS_MASTER_PAGES_SELECTOR_HXX
+
+#include "taskpane/TaskPaneTreeNode.hxx"
+#include "MasterPageContainer.hxx"
+#include "SlideSorterViewShell.hxx"
+
+#include "pres.hxx"
+#include <sfx2/shell.hxx>
+#include <vcl/image.hxx>
+#include "glob.hxx"
+#include <osl/mutex.hxx>
+
+#include <queue>
+
+class MouseEvent;
+class SdDrawDocument;
+class SdPage;
+class SfxModule;
+
+namespace sd {
+class DrawViewShell;
+class TemplateEntry;
+class TemplateDir;
+class ViewShellBase;
+}
+
+namespace sd { namespace toolpanel { namespace controls {
+
+class PreviewValueSet;
+
+/** Base class of a menu that lets the user select from a list of
+ templates or designs that are loaded from files.
+*/
+class MasterPagesSelector
+ : public TreeNode,
+ public SfxShell
+{
+public:
+ TYPEINFO();
+ SFX_DECL_INTERFACE(SD_IF_SDMASTERPAGESSELECTOR)
+
+ MasterPagesSelector (
+ TreeNode* pParent,
+ SdDrawDocument& rDocument,
+ ViewShellBase& rBase,
+ const ::boost::shared_ptr<MasterPageContainer>& rpContainer);
+ virtual ~MasterPagesSelector (void);
+
+ virtual void LateInit (void);
+
+ /** Return the height that this control needs to show all of its lines.
+ */
+ long GetRequiredHeight (int nWidth) const;
+
+ /** The given master page, either the master page of a slide or a notes
+ page, is cloned and inserted into mrDocument. The necessary styles
+ are copied as well.
+ */
+ static SdPage* AddMasterPage (
+ SdDrawDocument* pTargetDocument,
+ SdPage* pMasterPage,
+ USHORT nInsertionIndex);
+
+ virtual Size GetPreferredSize (void);
+ virtual sal_Int32 GetPreferredWidth (sal_Int32 nHeight);
+ virtual sal_Int32 GetPreferredHeight (sal_Int32 nWidth);
+ virtual bool IsResizable (void);
+ virtual ::Window* GetWindow (void);
+ virtual sal_Int32 GetMinimumWidth (void);
+
+ virtual void Execute (SfxRequest& rRequest);
+ virtual void GetState (SfxItemSet& rItemSet);
+
+ /** Update the selection of previews according to whatever
+ influences them appart from mouse and keyboard. If, for
+ example, the current page of the main pane changes, then call
+ this method at the CurrentMasterPagesSelector to select the
+ previews of the master pages that are assigned to the new
+ current page.
+
+ The default implementation of this method ignores the call. This is
+ used by e.g. the RecentMasterPagesSelector because it does not show
+ the currently used master pages by default and thus is not
+ influenced by its changes.
+ */
+ virtual void UpdateSelection (void);
+
+ void FillPageSet (void);
+
+ /** Make the selector empty. This method clear the value set from any
+ entries. Overload this method to add functionality, especially to
+ destroy objects set as data items at the value set.
+ */
+ void ClearPageSet (void);
+
+ void SetSmartHelpId( const SmartId& aId, SmartIdUpdateMode aMode = SMART_SET_SMART );
+
+ /** Mark the preview that belongs to the given index as not up-to-date
+ anymore with respect to page content or preview size.
+ The implementation of this method will either sunchronously or
+ asynchronously call UpdatePreview().
+ @param nIndex
+ Index into the value set control that is used for displaying the
+ previews.
+ */
+ void InvalidatePreview (const SdPage* pPage);
+
+ void UpdateAllPreviews (void);
+
+protected:
+ mutable ::osl::Mutex maMutex;
+ ::boost::shared_ptr<MasterPageContainer> mpContainer;
+
+ SdDrawDocument& mrDocument;
+ ::std::auto_ptr<PreviewValueSet> mpPageSet;
+ bool mbSmallPreviewSize;
+ ViewShellBase& mrBase;
+ /** Slot that is executed as default action when the left mouse button is
+ clicked over a master page.
+ */
+ sal_uInt16 mnDefaultClickAction;
+ /** Pages with pointers in this queue have their previews updated
+ eventually. Filled by InvalidatePreview() and operated upon by
+ UpdatePreviews().
+ */
+ ::std::queue<USHORT> maPreviewUpdateQueue;
+
+ virtual SdPage* GetSelectedMasterPage (void);
+
+ /** Assign the given master page to all slides of the document.
+ @param pMasterPage
+ The master page to assign to all slides.
+ */
+ void AssignMasterPageToAllSlides (SdPage* pMasterPage);
+
+ /** Assign the given master page to all slides that are selected in a
+ slide sorter that is displayed in the lef or center pane. When both
+ panes display a slide sorter then the one in the center pane is
+ used.
+ */
+ void AssignMasterPageToSelectedSlides (SdPage* pMasterPage);
+
+ virtual void AssignMasterPageToPageList (
+ SdPage* pMasterPage,
+ const ::sd::slidesorter::SharedPageSelection& rPageList);
+
+ virtual void NotifyContainerChangeEvent (const MasterPageContainerChangeEvent& rEvent);
+
+ typedef ::std::pair<int, MasterPageContainer::Token> UserData;
+ UserData* CreateUserData (int nIndex, MasterPageContainer::Token aToken) const;
+ UserData* GetUserData (int nIndex) const;
+ void SetUserData (int nIndex, UserData* pData);
+
+ virtual sal_Int32 GetIndexForToken (MasterPageContainer::Token aToken) const;
+ typedef ::std::vector<MasterPageContainer::Token> ItemList;
+ void UpdateItemList (::std::auto_ptr<ItemList> pList);
+ void Clear (void);
+ /** Invalidate the specified item so that on the next Fill() this item
+ is updated.
+ */
+ void InvalidateItem (MasterPageContainer::Token aToken);
+
+ // For every item in the ValueSet we store its associated token. This
+ // allows a faster access and easier change tracking.
+ ItemList maCurrentItemList;
+ typedef ::std::map<MasterPageContainer::Token,sal_Int32> TokenToValueSetIndex;
+ TokenToValueSetIndex maTokenToValueSetIndex;
+
+ ItemList maLockedMasterPages;
+ /** Lock master pages in the given list and release locks that where
+ previously aquired.
+ */
+ void UpdateLocks (const ItemList& rItemList);
+
+ void Fill (void);
+ virtual void Fill (ItemList& rItemList) = 0;
+
+ /** Give derived classes the oportunity to provide their own context
+ menu. If they do then they probably have to provide their own
+ Execute() and GetState() methods as well.
+ */
+ virtual ResId GetContextMenuResId (void) const;
+
+private:
+ /** The offset between ValueSet index and MasterPageContainer::Token
+ last seen. This value is used heuristically to speed up the lookup
+ of an index for a token.
+ */
+ DECL_LINK(ClickHandler, PreviewValueSet*);
+ DECL_LINK(RightClickHandler, MouseEvent*);
+ DECL_LINK(ContextMenuCallback, CommandEvent*);
+ DECL_LINK(ContainerChangeListener, MasterPageContainerChangeEvent*);
+
+ void SetItem (
+ USHORT nIndex,
+ MasterPageContainer::Token aToken);
+ void AddTokenToIndexEntry (
+ USHORT nIndex,
+ MasterPageContainer::Token aToken);
+ void RemoveTokenToIndexEntry (
+ USHORT nIndex,
+ MasterPageContainer::Token aToken);
+};
+
+} } } // end of namespace ::sd::toolpanel::controls
+
+#endif
diff --git a/sd/source/ui/toolpanel/controls/PreviewValueSet.cxx b/sd/source/ui/toolpanel/controls/PreviewValueSet.cxx
new file mode 100644
index 000000000000..a1f29dfee044
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/PreviewValueSet.cxx
@@ -0,0 +1,240 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "PreviewValueSet.hxx"
+#include <vcl/image.hxx>
+#include "taskpane/TaskPaneTreeNode.hxx"
+
+namespace sd { namespace toolpanel { namespace controls {
+
+
+PreviewValueSet::PreviewValueSet (TreeNode* pParent)
+ : ValueSet (pParent->GetWindow(), WB_TABSTOP),
+ mpParent(pParent),
+ maPreviewSize(10,10),
+ mnBorderWidth(3),
+ mnBorderHeight(3),
+ mnMaxColumnCount(-1)
+{
+ SetStyle (
+ GetStyle()
+ & ~(WB_ITEMBORDER)// | WB_MENUSTYLEVALUESET)
+ // | WB_FLATVALUESET);
+ );
+
+ SetColCount(2);
+ // SetLineCount(1);
+ SetExtraSpacing (2);
+}
+
+
+
+
+PreviewValueSet::~PreviewValueSet (void)
+{
+}
+
+
+
+
+void PreviewValueSet::SetPreviewSize (const Size& rSize)
+{
+ maPreviewSize = rSize;
+}
+
+
+
+
+void PreviewValueSet::SetRightMouseClickHandler (const Link& rLink)
+{
+ maRightMouseClickHandler = rLink;
+}
+
+
+
+
+void PreviewValueSet::MouseButtonDown (const MouseEvent& rEvent)
+{
+ if (rEvent.IsRight())
+ maRightMouseClickHandler.Call(reinterpret_cast<void*>(
+ &const_cast<MouseEvent&>(rEvent)));
+ else
+ ValueSet::MouseButtonDown (rEvent);
+
+}
+
+
+
+
+void PreviewValueSet::Paint (const Rectangle& rRect)
+{
+ SetBackground (GetSettings().GetStyleSettings().GetWindowColor());
+
+ ValueSet::Paint (rRect);
+
+ SetBackground (Wallpaper());
+}
+
+
+
+
+void PreviewValueSet::Resize (void)
+{
+ ValueSet::Resize ();
+
+ Size aWindowSize (GetOutputSizePixel());
+ if (aWindowSize.Width()>0 && aWindowSize.Height()>0)
+ {
+ Rearrange();
+ }
+}
+
+
+
+
+void PreviewValueSet::Command (const CommandEvent& rEvent)
+{
+ switch (rEvent.GetCommand())
+ {
+ case COMMAND_CONTEXTMENU:
+ {
+ CommandEvent aNonConstEventCopy (rEvent);
+ maContextMenuCallback.Call(&aNonConstEventCopy);
+ }
+ break;
+
+ default:
+ ValueSet::Command(rEvent);
+ break;
+ }
+}
+
+
+
+
+void PreviewValueSet::Rearrange (bool bForceRequestResize)
+{
+ USHORT nOldColumnCount (GetColCount());
+ USHORT nOldRowCount (GetLineCount());
+
+ USHORT nNewColumnCount (CalculateColumnCount (
+ GetOutputSizePixel().Width()));
+ USHORT nNewRowCount (CalculateRowCount (nNewColumnCount));
+
+ SetColCount(nNewColumnCount);
+ SetLineCount(nNewRowCount);
+
+ if (bForceRequestResize
+ || nOldColumnCount != nNewColumnCount
+ || nOldRowCount != nNewRowCount)
+ mpParent->RequestResize();
+}
+
+
+
+
+void PreviewValueSet::SetContextMenuCallback (const Link& rLink)
+{
+ maContextMenuCallback = rLink;
+}
+
+
+
+
+USHORT PreviewValueSet::CalculateColumnCount (int nWidth) const
+{
+ int nColumnCount = 0;
+ if (nWidth > 0)
+ {
+ nColumnCount = nWidth / (maPreviewSize.Width() + 2*mnBorderWidth);
+ if (nColumnCount < 1)
+ nColumnCount = 1;
+ else if (mnMaxColumnCount>0 && nColumnCount>mnMaxColumnCount)
+ nColumnCount = mnMaxColumnCount;
+ }
+ return (USHORT)nColumnCount;
+}
+
+
+
+
+USHORT PreviewValueSet::CalculateRowCount (USHORT nColumnCount) const
+{
+ int nRowCount = 0;
+ int nItemCount = GetItemCount();
+ if (nColumnCount > 0)
+ {
+ nRowCount = (nItemCount+nColumnCount-1) / nColumnCount;
+ if (nRowCount < 1)
+ nRowCount = 1;
+ }
+
+ return (USHORT)nRowCount;
+}
+
+
+
+
+sal_Int32 PreviewValueSet::GetPreferredWidth (sal_Int32 nHeight)
+{
+ int nPreferredWidth (maPreviewSize.Width() + 2*mnBorderWidth);
+
+ // Get height of each row.
+ int nItemHeight (maPreviewSize.Height() + 2*mnBorderHeight);
+
+ // Calculate the row- and column count and from the later the preferred
+ // width.
+ int nRowCount = nHeight / nItemHeight;
+ if (nRowCount > 0)
+ {
+ int nColumnCount = (GetItemCount()+nRowCount-1) / nRowCount;
+ if (nColumnCount > 0)
+ nPreferredWidth = (maPreviewSize.Width() + 2*mnBorderWidth)
+ * nColumnCount;
+ }
+
+ return nPreferredWidth;
+}
+
+
+
+
+sal_Int32 PreviewValueSet::GetPreferredHeight (sal_Int32 nWidth)
+{
+ int nRowCount (CalculateRowCount(CalculateColumnCount(nWidth)));
+ int nItemHeight (maPreviewSize.Height());
+
+ return nRowCount * (nItemHeight + 2*mnBorderHeight);
+}
+
+
+
+
+} } } // end of namespace ::sd::toolpanel::controls
diff --git a/sd/source/ui/toolpanel/controls/PreviewValueSet.hxx b/sd/source/ui/toolpanel/controls/PreviewValueSet.hxx
new file mode 100644
index 000000000000..69fa7e272330
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/PreviewValueSet.hxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANEL_PREVIEW_VALUE_SET_HXX
+#define SD_TOOLPANEL_PREVIEW_VALUE_SET_HXX
+
+#include <svtools/valueset.hxx>
+
+
+namespace sd { namespace toolpanel {
+class TreeNode;
+} }
+
+namespace sd { namespace toolpanel { namespace controls {
+
+
+/** Adapt the svtools valueset to the needs of the master page controlls.
+*/
+class PreviewValueSet
+ : public ValueSet
+{
+public:
+ PreviewValueSet (TreeNode* pParent);
+ ~PreviewValueSet (void);
+
+ void SetRightMouseClickHandler (const Link& rLink);
+ virtual void Paint (const Rectangle& rRect);
+ virtual void Resize (void);
+
+ /** When a request for the display of a context menu is made to this
+ method then that request is forwarded via the ContextMenuCallback.
+ This way the owning class can handle the context menu without having
+ to be derived from this class.
+ Use SetContextMenuCallback to set or rest the handler.
+ */
+ virtual void Command (const CommandEvent& rEvent);
+
+ void SetPreviewSize (const Size& rSize);
+
+ sal_Int32 GetPreferredWidth (sal_Int32 nHeight);
+ sal_Int32 GetPreferredHeight (sal_Int32 nWidth);
+
+ /** Set the number of rows and columns according to the current number
+ of items. Call this method when new items have been inserted.
+ */
+ void Rearrange (bool bForceRequestResize = false);
+
+ /** Set the callback function to which requests for context menus are
+ forewarded. Call with an empty Link to reset the callback
+ function.
+ */
+ void SetContextMenuCallback (const Link& rLink);
+
+protected:
+ virtual void MouseButtonDown (const MouseEvent& rEvent);
+
+private:
+ Link maRightMouseClickHandler;
+ Link maContextMenuCallback;
+ TreeNode* mpParent;
+ Size maPreviewSize;
+ const int mnBorderWidth;
+ const int mnBorderHeight;
+ const int mnMaxColumnCount;
+
+ USHORT CalculateColumnCount (int nWidth) const;
+ USHORT CalculateRowCount (USHORT nColumnCount) const;
+};
+
+} } } // end of namespace ::sd::toolpanel::controls
+
+#endif
diff --git a/sd/source/ui/toolpanel/controls/RecentMasterPagesSelector.cxx b/sd/source/ui/toolpanel/controls/RecentMasterPagesSelector.cxx
new file mode 100644
index 000000000000..2f2789216b8d
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/RecentMasterPagesSelector.cxx
@@ -0,0 +1,159 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "RecentMasterPagesSelector.hxx"
+#include "PreviewValueSet.hxx"
+
+#include "RecentlyUsedMasterPages.hxx"
+#include "MasterPageContainerProviders.hxx"
+#include "MasterPageObserver.hxx"
+#include "sdpage.hxx"
+#include "drawdoc.hxx"
+#include "app.hrc"
+#include <vcl/bitmap.hxx>
+#include <tools/color.hxx>
+
+namespace sd { namespace toolpanel { namespace controls {
+
+
+RecentMasterPagesSelector::RecentMasterPagesSelector (
+ TreeNode* pParent,
+ SdDrawDocument& rDocument,
+ ViewShellBase& rBase,
+ const ::boost::shared_ptr<MasterPageContainer>& rpContainer)
+ : MasterPagesSelector (pParent, rDocument, rBase, rpContainer)
+{
+ SetName (String(RTL_CONSTASCII_USTRINGPARAM("RecentMasterPagesSelector")));
+}
+
+
+
+
+RecentMasterPagesSelector::~RecentMasterPagesSelector (void)
+{
+ RecentlyUsedMasterPages::Instance().RemoveEventListener (
+ LINK(this,RecentMasterPagesSelector,MasterPageListListener));
+}
+
+
+
+
+void RecentMasterPagesSelector::LateInit (void)
+{
+ MasterPagesSelector::LateInit();
+
+ MasterPagesSelector::Fill();
+ RecentlyUsedMasterPages::Instance().AddEventListener (
+ LINK(this,RecentMasterPagesSelector,MasterPageListListener));
+}
+
+
+
+
+IMPL_LINK(RecentMasterPagesSelector,MasterPageListListener, void*, EMPTYARG)
+{
+ MasterPagesSelector::Fill();
+ return 0;
+}
+
+
+
+
+void RecentMasterPagesSelector::Fill (ItemList& rItemList)
+{
+ // Create a set of names of the master pages used by the document.
+ MasterPageObserver::MasterPageNameSet aCurrentNames;
+ USHORT nMasterPageCount = mrDocument.GetMasterSdPageCount(PK_STANDARD);
+ USHORT nIndex;
+ for (nIndex=0; nIndex<nMasterPageCount; nIndex++)
+ {
+ SdPage* pMasterPage = mrDocument.GetMasterSdPage (nIndex, PK_STANDARD);
+ if (pMasterPage != NULL)
+ aCurrentNames.insert (pMasterPage->GetName());
+ }
+ MasterPageObserver::MasterPageNameSet::iterator aI;
+
+ // Insert the recently used master pages that are currently not used.
+ RecentlyUsedMasterPages& rInstance (RecentlyUsedMasterPages::Instance());
+ int nPageCount = rInstance.GetMasterPageCount();
+ for (nIndex=0; nIndex<nPageCount; nIndex++)
+ {
+ // Add an entry when a) the page is already known to the
+ // MasterPageContainer, b) the style name is empty, i.e. it has not yet
+ // been loaded (and thus can not be in use) or otherwise c) the
+ // style name is not currently in use.
+ MasterPageContainer::Token aToken (rInstance.GetTokenForIndex(nIndex));
+ if (aToken != MasterPageContainer::NIL_TOKEN)
+ {
+ String sStyleName (mpContainer->GetStyleNameForToken(aToken));
+ if (sStyleName.Len()==0
+ || aCurrentNames.find(sStyleName) == aCurrentNames.end())
+ {
+ rItemList.push_back(aToken);
+ }
+ }
+ }
+}
+
+
+
+
+void RecentMasterPagesSelector::AssignMasterPageToPageList (
+ SdPage* pMasterPage,
+ const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList)
+{
+ USHORT nSelectedItemId = mpPageSet->GetSelectItemId();
+
+ MasterPagesSelector::AssignMasterPageToPageList(pMasterPage, rpPageList);
+
+ // Restore the selection.
+ if (mpPageSet->GetItemCount() > 0)
+ {
+ if (mpPageSet->GetItemCount() >= nSelectedItemId)
+ mpPageSet->SelectItem(nSelectedItemId);
+ else
+ mpPageSet->SelectItem(mpPageSet->GetItemCount());
+ }
+}
+
+
+
+
+void RecentMasterPagesSelector::GetState (SfxItemSet& rItemSet)
+{
+ MasterPagesSelector::GetState (rItemSet);
+ if (rItemSet.GetItemState(SID_TP_EDIT_MASTER) == SFX_ITEM_AVAILABLE)
+ rItemSet.DisableItem (SID_TP_EDIT_MASTER);
+}
+
+
+
+
+} } } // end of namespace ::sd::toolpanel::controls
diff --git a/sd/source/ui/toolpanel/controls/RecentMasterPagesSelector.hxx b/sd/source/ui/toolpanel/controls/RecentMasterPagesSelector.hxx
new file mode 100644
index 000000000000..adac66187b71
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/RecentMasterPagesSelector.hxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANEL_CONTROLS_RECENT_MASTER_PAGES_SELECTOR_HXX
+#define SD_TOOLPANEL_CONTROLS_RECENT_MASTER_PAGES_SELECTOR_HXX
+
+#include "MasterPagesSelector.hxx"
+
+namespace sd { namespace toolpanel { namespace controls {
+
+
+/** Show the recently used master pages (that are not currently used).
+*/
+class RecentMasterPagesSelector
+ : public MasterPagesSelector
+{
+public:
+ RecentMasterPagesSelector (
+ TreeNode* pParent,
+ SdDrawDocument& rDocument,
+ ViewShellBase& rBase,
+ const ::boost::shared_ptr<MasterPageContainer>& rpContainer);
+ virtual ~RecentMasterPagesSelector (void);
+
+ virtual void LateInit (void);
+
+ virtual void GetState (SfxItemSet& rItemSet);
+
+protected:
+ DECL_LINK(MasterPageListListener, void*);
+ virtual void Fill (ItemList& rItemList);
+
+ using sd::toolpanel::controls::MasterPagesSelector::Fill;
+
+ /** Forward this call to the base class but save and restore the
+ currently selected item.
+ Assign the given master page to the list of pages.
+ @param pMasterPage
+ This master page will usually be a member of the list of all
+ available master pages as provided by the MasterPageContainer.
+ @param rPageList
+ The pages to which to assign the master page. These pages may
+ be slides or master pages themselves.
+ */
+ virtual void AssignMasterPageToPageList (
+ SdPage* pMasterPage,
+ const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList);
+};
+
+} } } // end of namespace ::sd::toolpanel::controls
+
+#endif
diff --git a/sd/source/ui/toolpanel/controls/RecentlyUsedMasterPages.cxx b/sd/source/ui/toolpanel/controls/RecentlyUsedMasterPages.cxx
new file mode 100644
index 000000000000..63d7f72e2903
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/RecentlyUsedMasterPages.cxx
@@ -0,0 +1,501 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "RecentlyUsedMasterPages.hxx"
+#include "MasterPageObserver.hxx"
+#include "MasterPagesSelector.hxx"
+#include "MasterPageDescriptor.hxx"
+#include "tools/ConfigurationAccess.hxx"
+#include "drawdoc.hxx"
+#include "sdpage.hxx"
+
+#include <algorithm>
+#include <vector>
+
+#include <comphelper/processfactory.hxx>
+#include "unomodel.hxx"
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPages.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <tools/urlobj.hxx>
+#include <unotools/confignode.hxx>
+#include <osl/doublecheckedlocking.h>
+#include <osl/getglobalmutex.hxx>
+
+using namespace ::std;
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+
+namespace {
+
+static const OUString& GetPathToImpressConfigurationRoot (void)
+{
+ static const OUString sPathToImpressConfigurationRoot (
+ RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.Impress/"));
+ return sPathToImpressConfigurationRoot;
+}
+static const OUString& GetPathToSetNode (void)
+{
+ static const OUString sPathToSetNode(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "MultiPaneGUI/ToolPanel/RecentlyUsedMasterPages"));
+ return sPathToSetNode;
+}
+
+
+class Descriptor
+{
+public:
+ ::rtl::OUString msURL;
+ ::rtl::OUString msName;
+ ::sd::toolpanel::controls::MasterPageContainer::Token maToken;
+ Descriptor (const ::rtl::OUString& rsURL, const ::rtl::OUString& rsName)
+ : msURL(rsURL),
+ msName(rsName),
+ maToken(::sd::toolpanel::controls::MasterPageContainer::NIL_TOKEN)
+ {}
+ Descriptor (::sd::toolpanel::controls::MasterPageContainer::Token aToken,
+ const ::rtl::OUString& rsURL, const ::rtl::OUString& rsName)
+ : msURL(rsURL),
+ msName(rsName),
+ maToken(aToken)
+ {}
+ class TokenComparator
+ { public:
+ TokenComparator(::sd::toolpanel::controls::MasterPageContainer::Token aToken)
+ : maToken(aToken) {}
+ bool operator () (const Descriptor& rDescriptor)
+ { return maToken==rDescriptor.maToken; }
+ private: ::sd::toolpanel::controls::MasterPageContainer::Token maToken;
+ };
+};
+
+} // end of anonymous namespace
+
+
+
+
+namespace sd { namespace toolpanel { namespace controls {
+
+class RecentlyUsedMasterPages::MasterPageList : public ::std::vector<Descriptor>
+{
+public:
+ MasterPageList (void) {}
+};
+
+
+RecentlyUsedMasterPages* RecentlyUsedMasterPages::mpInstance = NULL;
+
+
+RecentlyUsedMasterPages& RecentlyUsedMasterPages::Instance (void)
+{
+ if (mpInstance == NULL)
+ {
+ ::osl::GetGlobalMutex aMutexFunctor;
+ ::osl::MutexGuard aGuard (aMutexFunctor());
+ if (mpInstance == NULL)
+ {
+ RecentlyUsedMasterPages* pInstance = new RecentlyUsedMasterPages();
+ pInstance->LateInit();
+ SdGlobalResourceContainer::Instance().AddResource (
+ ::std::auto_ptr<SdGlobalResource>(pInstance));
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ mpInstance = pInstance;
+ }
+ }
+ else {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+
+ return *mpInstance;
+}
+
+
+
+
+RecentlyUsedMasterPages::RecentlyUsedMasterPages (void)
+ : maListeners(),
+ mpMasterPages(new MasterPageList()),
+ mnMaxListSize(8),
+ mpContainer(new MasterPageContainer())
+{
+}
+
+
+
+
+RecentlyUsedMasterPages::~RecentlyUsedMasterPages (void)
+{
+ Link aLink (LINK(this,RecentlyUsedMasterPages,MasterPageContainerChangeListener));
+ mpContainer->RemoveChangeListener(aLink);
+
+ MasterPageObserver::Instance().RemoveEventListener(
+ LINK(this,RecentlyUsedMasterPages,MasterPageChangeListener));
+}
+
+
+
+
+void RecentlyUsedMasterPages::LateInit (void)
+{
+ Link aLink (LINK(this,RecentlyUsedMasterPages,MasterPageContainerChangeListener));
+ mpContainer->AddChangeListener(aLink);
+
+ LoadPersistentValues ();
+ MasterPageObserver::Instance().AddEventListener(
+ LINK(this,RecentlyUsedMasterPages,MasterPageChangeListener));
+}
+
+
+
+
+void RecentlyUsedMasterPages::LoadPersistentValues (void)
+{
+ try
+ {
+ do
+ {
+ tools::ConfigurationAccess aConfiguration (
+ GetPathToImpressConfigurationRoot(),
+ tools::ConfigurationAccess::READ_ONLY);
+ Reference<container::XNameAccess> xSet (
+ aConfiguration.GetConfigurationNode(GetPathToSetNode()),
+ UNO_QUERY);
+ if ( ! xSet.is())
+ break;
+
+ const String sURLMemberName (OUString::createFromAscii("URL"));
+ const String sNameMemberName (OUString::createFromAscii("Name"));
+ OUString sURL;
+ OUString sName;
+
+ // Read the names and URLs of the master pages.
+ Sequence<OUString> aKeys (xSet->getElementNames());
+ mpMasterPages->clear();
+ mpMasterPages->reserve(aKeys.getLength());
+ for (int i=0; i<aKeys.getLength(); i++)
+ {
+ Reference<container::XNameAccess> xSetItem (
+ xSet->getByName(aKeys[i]), UNO_QUERY);
+ if (xSetItem.is())
+ {
+ Any aURL (xSetItem->getByName(sURLMemberName));
+ Any aName (xSetItem->getByName(sNameMemberName));
+ aURL >>= sURL;
+ aName >>= sName;
+ SharedMasterPageDescriptor pDescriptor (new MasterPageDescriptor(
+ MasterPageContainer::TEMPLATE,
+ -1,
+ sURL,
+ String(),
+ sName,
+ false,
+ ::boost::shared_ptr<PageObjectProvider>(
+ new TemplatePageObjectProvider(sURL)),
+ ::boost::shared_ptr<PreviewProvider>(
+ new TemplatePreviewProvider(sURL))));
+ // For user supplied templates we use a different
+ // preview provider: The preview in the document shows
+ // not only shapes on the master page but also shapes on
+ // the foreground. This is misleading and therefore
+ // these previews are discarded and created directly
+ // from the page objects.
+ if (pDescriptor->GetURLClassification() == MasterPageDescriptor::URLCLASS_USER)
+ pDescriptor->mpPreviewProvider = ::boost::shared_ptr<PreviewProvider>(
+ new PagePreviewProvider());
+ MasterPageContainer::Token aToken (mpContainer->PutMasterPage(pDescriptor));
+ mpMasterPages->push_back(Descriptor(aToken,sURL,sName));
+ }
+ }
+
+ ResolveList();
+ }
+ while (false);
+ }
+ catch (Exception&)
+ {
+ // Ignore exception.
+ }
+}
+
+
+
+
+void RecentlyUsedMasterPages::SavePersistentValues (void)
+{
+ try
+ {
+ do
+ {
+ tools::ConfigurationAccess aConfiguration (
+ GetPathToImpressConfigurationRoot(),
+ tools::ConfigurationAccess::READ_WRITE);
+ Reference<container::XNameContainer> xSet (
+ aConfiguration.GetConfigurationNode(GetPathToSetNode()),
+ UNO_QUERY);
+ if ( ! xSet.is())
+ break;
+
+ // Clear the set.
+ Sequence<OUString> aKeys (xSet->getElementNames());
+ sal_Int32 i;
+ for (i=0; i<aKeys.getLength(); i++)
+ xSet->removeByName (aKeys[i]);
+
+ // Fill it with the URLs of this object.
+ const String sURLMemberName (OUString::createFromAscii("URL"));
+ const String sNameMemberName (OUString::createFromAscii("Name"));
+ Any aValue;
+ Reference<lang::XSingleServiceFactory> xChildFactory (
+ xSet, UNO_QUERY);
+ if ( ! xChildFactory.is())
+ break;
+ MasterPageList::const_iterator iDescriptor;
+ sal_Int32 nIndex(0);
+ for (iDescriptor=mpMasterPages->begin();
+ iDescriptor!=mpMasterPages->end();
+ ++iDescriptor,++nIndex)
+ {
+ // Create new child.
+ OUString sKey (OUString::createFromAscii("index_"));
+ sKey += OUString::valueOf(nIndex);
+ Reference<container::XNameReplace> xChild(
+ xChildFactory->createInstance(), UNO_QUERY);
+ if (xChild.is())
+ {
+ xSet->insertByName (sKey, makeAny(xChild));
+
+ aValue <<= OUString(iDescriptor->msURL);
+ xChild->replaceByName (sURLMemberName, aValue);
+
+ aValue <<= OUString(iDescriptor->msName);
+ xChild->replaceByName (sNameMemberName, aValue);
+ }
+ }
+
+ // Write the data back to disk.
+ aConfiguration.CommitChanges();
+ }
+ while (false);
+ }
+ catch (Exception&)
+ {
+ // Ignore exception.
+ }
+}
+
+
+
+
+void RecentlyUsedMasterPages::AddEventListener (const Link& rEventListener)
+{
+ if (::std::find (
+ maListeners.begin(),
+ maListeners.end(),
+ rEventListener) == maListeners.end())
+ {
+ maListeners.push_back (rEventListener);
+ }
+}
+
+
+
+
+void RecentlyUsedMasterPages::RemoveEventListener (const Link& rEventListener)
+{
+ maListeners.erase (
+ ::std::find (
+ maListeners.begin(),
+ maListeners.end(),
+ rEventListener));
+}
+
+
+
+
+int RecentlyUsedMasterPages::GetMasterPageCount (void) const
+{
+ return mpMasterPages->size();
+}
+
+
+
+
+MasterPageContainer::Token RecentlyUsedMasterPages::GetTokenForIndex (sal_uInt32 nIndex) const
+{
+ if(nIndex<mpMasterPages->size())
+ return (*mpMasterPages)[nIndex].maToken;
+ else
+ return MasterPageContainer::NIL_TOKEN;
+}
+
+
+
+
+void RecentlyUsedMasterPages::SendEvent (void)
+{
+ ::std::vector<Link>::iterator aLink (maListeners.begin());
+ ::std::vector<Link>::iterator aEnd (maListeners.end());
+ while (aLink!=aEnd)
+ {
+ aLink->Call (NULL);
+ ++aLink;
+ }
+}
+
+
+
+
+IMPL_LINK(RecentlyUsedMasterPages, MasterPageChangeListener,
+ MasterPageObserverEvent*, pEvent)
+{
+ switch (pEvent->meType)
+ {
+ case MasterPageObserverEvent::ET_MASTER_PAGE_ADDED:
+ case MasterPageObserverEvent::ET_MASTER_PAGE_EXISTS:
+ AddMasterPage(
+ mpContainer->GetTokenForStyleName(pEvent->mrMasterPageName));
+ break;
+
+ case MasterPageObserverEvent::ET_MASTER_PAGE_REMOVED:
+ // Do not change the list of recently master pages (the deleted
+ // page was recently used) but tell the listeners. They may want
+ // to update their lists.
+ SendEvent();
+ break;
+ }
+ return 0;
+}
+
+
+
+
+IMPL_LINK(RecentlyUsedMasterPages, MasterPageContainerChangeListener,
+ MasterPageContainerChangeEvent*, pEvent)
+{
+ if (pEvent != NULL)
+ switch (pEvent->meEventType)
+ {
+ case MasterPageContainerChangeEvent::CHILD_ADDED:
+ case MasterPageContainerChangeEvent::CHILD_REMOVED:
+ case MasterPageContainerChangeEvent::INDEX_CHANGED:
+ case MasterPageContainerChangeEvent::INDEXES_CHANGED:
+ ResolveList();
+ break;
+
+ default:
+ // Ignored.
+ break;
+ }
+ return 0;
+}
+
+
+
+
+void RecentlyUsedMasterPages::AddMasterPage (
+ MasterPageContainer::Token aToken,
+ bool bMakePersistent)
+{
+ // For the page to be inserted the token has to be valid and the page
+ // has to have a valid URL. This excludes master pages that do not come
+ // from template files.
+ if (aToken != MasterPageContainer::NIL_TOKEN
+ && mpContainer->GetURLForToken(aToken).Len()>0)
+ {
+
+ MasterPageList::iterator aIterator (
+ ::std::find_if(mpMasterPages->begin(),mpMasterPages->end(),
+ Descriptor::TokenComparator(aToken)));
+ if (aIterator != mpMasterPages->end())
+ {
+ // When an entry for the given token already exists then remove
+ // it now and insert it later at the head of the list.
+ mpMasterPages->erase (aIterator);
+ }
+
+ mpMasterPages->insert(mpMasterPages->begin(),
+ Descriptor(
+ aToken,
+ mpContainer->GetURLForToken(aToken),
+ mpContainer->GetStyleNameForToken(aToken)));
+
+ // Shorten list to maximal size.
+ while (mpMasterPages->size() > mnMaxListSize)
+ {
+ mpMasterPages->pop_back ();
+ }
+
+ if (bMakePersistent)
+ SavePersistentValues ();
+ SendEvent();
+ }
+}
+
+
+
+
+void RecentlyUsedMasterPages::ResolveList (void)
+{
+ bool bNotify (false);
+
+ MasterPageList::iterator iDescriptor;
+ for (iDescriptor=mpMasterPages->begin(); iDescriptor!=mpMasterPages->end(); ++iDescriptor)
+ {
+ if (iDescriptor->maToken == MasterPageContainer::NIL_TOKEN)
+ {
+ MasterPageContainer::Token aToken (mpContainer->GetTokenForURL(iDescriptor->msURL));
+ iDescriptor->maToken = aToken;
+ if (aToken != MasterPageContainer::NIL_TOKEN)
+ bNotify = true;
+ }
+ else
+ {
+ if ( ! mpContainer->HasToken(iDescriptor->maToken))
+ {
+ iDescriptor->maToken = MasterPageContainer::NIL_TOKEN;
+ bNotify = true;
+ }
+ }
+ }
+
+ if (bNotify)
+ SendEvent();
+}
+
+
+} } } // end of namespace ::sd::toolpanel::controls
diff --git a/sd/source/ui/toolpanel/controls/RecentlyUsedMasterPages.hxx b/sd/source/ui/toolpanel/controls/RecentlyUsedMasterPages.hxx
new file mode 100644
index 000000000000..1f16d31b95d5
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/RecentlyUsedMasterPages.hxx
@@ -0,0 +1,128 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANEL_CONTROLS_RECENTLY_USED_MASTER_PAGES_HXX
+#define SD_TOOLPANEL_CONTROLS_RECENTLY_USED_MASTER_PAGES_HXX
+
+#include "tools/SdGlobalResourceContainer.hxx"
+#include <osl/mutex.hxx>
+#include <tools/link.hxx>
+#include <vcl/image.hxx>
+#include <vector>
+#include <tools/string.hxx>
+
+#include "DrawDocShell.hxx"
+#include "MasterPageContainer.hxx"
+#include <com/sun/star/uno/XInterface.hpp>
+
+class SdPage;
+
+namespace sd {
+class MasterPageObserverEvent;
+}
+
+
+namespace sd { namespace toolpanel { namespace controls {
+
+/** This singleton holds a list of the most recently used master pages.
+*/
+class RecentlyUsedMasterPages
+ : public SdGlobalResource
+{
+public:
+ /** Return the single instance of this class.
+ */
+ static RecentlyUsedMasterPages& Instance (void);
+
+ void AddEventListener (const Link& rEventListener);
+ void RemoveEventListener (const Link& rEventListener);
+
+ int GetMasterPageCount (void) const;
+ MasterPageContainer::Token GetTokenForIndex (sal_uInt32 nIndex) const;
+
+private:
+ /** The single instance of this class. It is created on demand when
+ Instance() is called for the first time.
+ */
+ static RecentlyUsedMasterPages* mpInstance;
+
+ ::std::vector<Link> maListeners;
+
+ class MasterPageList;
+ ::std::auto_ptr<MasterPageList> mpMasterPages;
+ unsigned long int mnMaxListSize;
+ ::boost::shared_ptr<MasterPageContainer> mpContainer;
+
+ RecentlyUsedMasterPages (void);
+ virtual ~RecentlyUsedMasterPages (void);
+
+ /** Call this method after a new object has been created.
+ */
+ void LateInit (void);
+
+ /// The copy constructor is not implemented. Do not use!
+ RecentlyUsedMasterPages (const RecentlyUsedMasterPages&);
+
+ /// The assignment operator is not implemented. Do not use!
+ RecentlyUsedMasterPages& operator= (const RecentlyUsedMasterPages&);
+
+ void SendEvent (void);
+ DECL_LINK(MasterPageChangeListener, MasterPageObserverEvent*);
+ DECL_LINK(MasterPageContainerChangeListener, MasterPageContainerChangeEvent*);
+
+ /** Add a descriptor for the specified master page to the end of the
+ list of most recently used master pages. When the page is already a
+ member of that list the associated descriptor is moved to the end of
+ the list to make it the most recently used entry.
+ @param bMakePersistent
+ When <TRUE/> is given then the new list of recently used master
+ pages is written back into the configuration to make it
+ persistent. Giving <FALSE/> to ommit this is used while loading
+ the persistent list from the configuration.
+ */
+ void AddMasterPage (
+ MasterPageContainer::Token aToken,
+ bool bMakePersistent = true);
+
+ /** Load the list of recently used master pages from the registry where
+ it was saved to make it persistent.
+ */
+ void LoadPersistentValues (void);
+
+ /** Save the list of recently used master pages to the registry to make
+ it presistent.
+ */
+ void SavePersistentValues (void);
+
+ void ResolveList (void);
+};
+
+
+
+} } } // end of namespace ::sd::toolpanel::controls
+
+#endif
diff --git a/sd/source/ui/toolpanel/controls/SlideTransitionPanel.cxx b/sd/source/ui/toolpanel/controls/SlideTransitionPanel.cxx
new file mode 100755
index 000000000000..4ad67b876983
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/SlideTransitionPanel.cxx
@@ -0,0 +1,116 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+#include "SlideTransitionPanel.hxx"
+
+#include "taskpane/TaskPaneControlFactory.hxx"
+#include "taskpane/ToolPanelViewShell.hxx"
+
+#include "strings.hrc"
+#include "sdresid.hxx"
+#include <com/sun/star/frame/XModel.hpp>
+
+namespace sd
+{
+
+ class ViewShellBase;
+ extern ::Window * createSlideTransitionPanel( ::Window* pParent, ViewShellBase& rBase );
+
+namespace toolpanel { namespace controls {
+
+
+
+SlideTransitionPanel::SlideTransitionPanel(Window& i_rParentWindow, ToolPanelViewShell& i_rToolPanelShell)
+ :SubToolPanel( i_rParentWindow )
+ ,maPreferredSize( 100, 200 )
+ ,m_pPanelViewShell( &i_rToolPanelShell )
+{
+ mpWrappedControl = createSlideTransitionPanel( &i_rParentWindow, i_rToolPanelShell.GetViewShellBase() );
+ mpWrappedControl->Show();
+}
+
+SlideTransitionPanel::~SlideTransitionPanel()
+{
+ delete mpWrappedControl;
+}
+
+std::auto_ptr< ControlFactory > SlideTransitionPanel::CreateControlFactory( ToolPanelViewShell& i_rToolPanelShell )
+{
+ return std::auto_ptr< ControlFactory >(
+ new RootControlFactoryWithArg< SlideTransitionPanel, ToolPanelViewShell >( i_rToolPanelShell ) );
+}
+
+TaskPaneShellManager* SlideTransitionPanel::GetShellManager()
+{
+ if ( m_pPanelViewShell )
+ return &m_pPanelViewShell->GetSubShellManager();
+ return SubToolPanel::GetShellManager();
+}
+
+Size SlideTransitionPanel::GetPreferredSize()
+{
+ return maPreferredSize;
+}
+sal_Int32 SlideTransitionPanel::GetPreferredWidth(sal_Int32 )
+{
+ return maPreferredSize.Width();
+}
+sal_Int32 SlideTransitionPanel::GetPreferredHeight(sal_Int32 )
+{
+ return maPreferredSize.Height();
+}
+::Window* SlideTransitionPanel::GetWindow()
+{
+ return mpWrappedControl;
+}
+bool SlideTransitionPanel::IsResizable()
+{
+ return true;
+}
+bool SlideTransitionPanel::IsExpandable() const
+{
+ return true;
+}
+
+
+
+
+::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible> SlideTransitionPanel::CreateAccessibleObject (
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& )
+{
+ if (GetWindow() != NULL)
+ return GetWindow()->GetAccessible();
+ else
+ return NULL;
+}
+
+
+} } } // end of namespace ::sd::toolpanel::controls
diff --git a/sd/source/ui/toolpanel/controls/SlideTransitionPanel.hxx b/sd/source/ui/toolpanel/controls/SlideTransitionPanel.hxx
new file mode 100755
index 000000000000..f62cb918806b
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/SlideTransitionPanel.hxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SD_TOOLPANEL_CONTROLS_SLIDE_TRANSITION_PANEL_HXX
+#define SD_TOOLPANEL_CONTROLS_SLIDE_TRANSITION_PANEL_HXX
+
+#include "taskpane/SubToolPanel.hxx"
+
+namespace sd {
+class ViewShellBase;
+}
+
+namespace sd { namespace toolpanel {
+class ControlFactory;
+class TreeNode;
+class ToolPanelViewShell;
+} }
+
+namespace sd { namespace toolpanel { namespace controls {
+
+class SlideTransitionPanel
+ : public SubToolPanel
+{
+public:
+ SlideTransitionPanel (
+ Window& i_rParentWindow,
+ ToolPanelViewShell& i_rToolPanelShell);
+ virtual ~SlideTransitionPanel (void);
+
+ static std::auto_ptr<ControlFactory> CreateControlFactory (ToolPanelViewShell& i_rToolPanelShell);
+
+ // TreeNode overridables
+ virtual TaskPaneShellManager* GetShellManager();
+
+ // ILayoutableWindow overridables
+ virtual Size GetPreferredSize (void);
+ virtual sal_Int32 GetPreferredWidth (sal_Int32 nHeigh);
+ virtual sal_Int32 GetPreferredHeight (sal_Int32 nWidth);
+ virtual ::Window* GetWindow (void);
+ virtual bool IsResizable (void);
+ virtual bool IsExpandable (void) const;
+
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible > CreateAccessibleObject (
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent);
+
+ using Window::GetWindow;
+
+private:
+ Size maPreferredSize;
+ ::Window* mpWrappedControl;
+ ToolPanelViewShell* m_pPanelViewShell;
+};
+
+} } } // end of namespace ::sd::toolpanel::controls
+
+#endif
diff --git a/sd/source/ui/toolpanel/controls/TableDesignPanel.cxx b/sd/source/ui/toolpanel/controls/TableDesignPanel.cxx
new file mode 100755
index 000000000000..d6507a25c11f
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/TableDesignPanel.cxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sd.hxx"
+
+#include "TableDesignPanel.hxx"
+
+#include "taskpane/TaskPaneControlFactory.hxx"
+#include "taskpane/ToolPanelViewShell.hxx"
+
+#include "strings.hrc"
+#include "sdresid.hxx"
+
+namespace sd
+{
+
+ class ViewShellBase;
+ extern ::Window * createTableDesignPanel( ::Window* pParent, ViewShellBase& rBase );
+
+namespace toolpanel { namespace controls {
+
+
+TableDesignPanel::TableDesignPanel( ::Window& i_rParentWindow, ToolPanelViewShell& i_rPanelViewShell )
+ :SubToolPanel( i_rParentWindow )
+ ,m_pPanelViewShell( &i_rPanelViewShell )
+{
+ mpWrappedControl = createTableDesignPanel( &i_rParentWindow, i_rPanelViewShell.GetViewShellBase() );
+ mpWrappedControl->Show();
+}
+
+TableDesignPanel::~TableDesignPanel()
+{
+ delete mpWrappedControl;
+}
+
+std::auto_ptr< ControlFactory > TableDesignPanel::CreateControlFactory( ToolPanelViewShell& i_rToolPanelShell )
+{
+ return std::auto_ptr< ControlFactory >(
+ new RootControlFactoryWithArg< TableDesignPanel, ToolPanelViewShell >( i_rToolPanelShell ) );
+}
+
+TaskPaneShellManager* TableDesignPanel::GetShellManager()
+{
+ if ( m_pPanelViewShell )
+ return &m_pPanelViewShell->GetSubShellManager();
+ return SubToolPanel::GetShellManager();
+}
+
+Size TableDesignPanel::GetPreferredSize()
+{
+ return maPreferredSize;
+}
+sal_Int32 TableDesignPanel::GetPreferredWidth(sal_Int32 )
+{
+ return maPreferredSize.Width();
+}
+sal_Int32 TableDesignPanel::GetPreferredHeight(sal_Int32 )
+{
+ return maPreferredSize.Height();
+}
+::Window* TableDesignPanel::GetWindow()
+{
+ return mpWrappedControl;
+}
+bool TableDesignPanel::IsResizable()
+{
+ return true;
+}
+bool TableDesignPanel::IsExpandable() const
+{
+ return true;
+}
+
+::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible> TableDesignPanel::CreateAccessibleObject (
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& )
+{
+ if (GetWindow() != NULL)
+ return GetWindow()->GetAccessible();
+ else
+ return NULL;
+}
+
+} } } // end of namespace ::sd::toolpanel::controls
diff --git a/sd/source/ui/toolpanel/controls/TableDesignPanel.hxx b/sd/source/ui/toolpanel/controls/TableDesignPanel.hxx
new file mode 100755
index 000000000000..a3620df2ef68
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/TableDesignPanel.hxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SD_TOOLPANEL_CONTROLS_TABLE_DESIGN_PANEL_HXX
+#define SD_TOOLPANEL_CONTROLS_TABLE_DESIGN_PANEL_HXX
+
+#include "taskpane/SubToolPanel.hxx"
+
+namespace sd {
+class ViewShellBase;
+}
+
+namespace sd { namespace toolpanel {
+class TreeNode;
+class ControlFactory;
+class ToolPanelViewShell;
+} }
+
+namespace sd { namespace toolpanel { namespace controls {
+
+class TableDesignPanel
+ : public SubToolPanel
+{
+public:
+ TableDesignPanel (
+ ::Window& i_rParentWindow,
+ ToolPanelViewShell& i_rPanelViewShell);
+ virtual ~TableDesignPanel (void);
+
+ static std::auto_ptr<ControlFactory> CreateControlFactory (ToolPanelViewShell& i_rToolPanelShell);
+
+ // TreeNode overridables
+ virtual TaskPaneShellManager* GetShellManager();
+
+ // ILayoutableWindow overridables
+ virtual Size GetPreferredSize (void);
+ virtual sal_Int32 GetPreferredWidth (sal_Int32 nHeigh);
+ virtual sal_Int32 GetPreferredHeight (sal_Int32 nWidth);
+ virtual ::Window* GetWindow (void);
+ virtual bool IsResizable (void);
+ virtual bool IsExpandable (void) const;
+
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible > CreateAccessibleObject (
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent);
+
+ using Window::GetWindow;
+private:
+ Size maPreferredSize;
+ ::Window* mpWrappedControl;
+ ToolPanelViewShell* m_pPanelViewShell;
+};
+
+} } } // end of namespace ::sd::toolpanel::controls
+
+#endif
diff --git a/sd/source/ui/toolpanel/controls/makefile.mk b/sd/source/ui/toolpanel/controls/makefile.mk
new file mode 100755
index 000000000000..b2218e55008c
--- /dev/null
+++ b/sd/source/ui/toolpanel/controls/makefile.mk
@@ -0,0 +1,67 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+
+PROJECTPCH=sd
+PROJECTPCHSOURCE=$(PRJ)$/util$/sd
+PRJNAME=sd
+TARGET=tpcontrols
+ENABLE_EXCEPTIONS=TRUE
+AUTOSEG=true
+PRJINC=..$/..$/ ..$/..$/slidesorter
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/AllMasterPagesSelector.obj \
+ $(SLO)$/CurrentMasterPagesSelector.obj \
+ $(SLO)$/DocumentHelper.obj \
+ $(SLO)$/MasterPageObserver.obj \
+ $(SLO)$/MasterPagesPanel.obj \
+ $(SLO)$/MasterPagesSelector.obj \
+ $(SLO)$/MasterPageContainer.obj \
+ $(SLO)$/MasterPageContainerFiller.obj \
+ $(SLO)$/MasterPageContainerProviders.obj\
+ $(SLO)$/MasterPageContainerQueue.obj \
+ $(SLO)$/MasterPageDescriptor.obj \
+ $(SLO)$/PreviewValueSet.obj \
+ $(SLO)$/RecentlyUsedMasterPages.obj \
+ $(SLO)$/RecentMasterPagesSelector.obj \
+ $(SLO)$/CustomAnimationPanel.obj \
+ $(SLO)$/SlideTransitionPanel.obj \
+ $(SLO)$/TableDesignPanel.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sd/source/ui/toolpanel/makefile.mk b/sd/source/ui/toolpanel/makefile.mk
new file mode 100755
index 000000000000..262b32535ef3
--- /dev/null
+++ b/sd/source/ui/toolpanel/makefile.mk
@@ -0,0 +1,70 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PROJECTPCH=sd
+PROJECTPCHSOURCE=$(PRJ)$/util$/sd
+PRJNAME=sd
+TARGET=toolpanel
+ENABLE_EXCEPTIONS=TRUE
+AUTOSEG=true
+PRJINC=..$/slidesorter
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/ControlContainer.obj \
+ $(SLO)$/ScrollPanel.obj \
+ $(SLO)$/SubToolPanel.obj \
+ $(SLO)$/TitleBar.obj \
+ $(SLO)$/TitledControl.obj \
+ $(SLO)$/TaskPaneControlFactory.obj \
+ $(SLO)$/TaskPaneFocusManager.obj \
+ $(SLO)$/TaskPaneShellManager.obj \
+ $(SLO)$/TaskPaneTreeNode.obj \
+ $(SLO)$/ToolPanel.obj \
+ $(SLO)$/ToolPanelViewShell.obj \
+ $(SLO)$/ToolPanelFactory.obj \
+ $(SLO)$/ToolPanelUIElement.obj \
+ \
+ $(SLO)$/LayoutMenu.obj \
+ $(SLO)$/TestMenu.obj \
+ $(SLO)$/TestPanel.obj \
+ $(SLO)$/SlideSorterCacheDisplay.obj
+
+EXCEPTIONSFILES=
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+