Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
core
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
LibreOffice
core
Commits
d45ba6bb
Kaydet (Commit)
d45ba6bb
authored
Eyl 20, 2013
tarafından
Caolán McNamara
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
missing file
Change-Id: Ia1e179ab423b847a6303d63cc663cf31db3283e8
üst
3f0e95cd
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
414 additions
and
0 deletions
+414
-0
MasterPageObserver.cxx
sd/source/ui/sidebar/MasterPageObserver.cxx
+414
-0
No files found.
sd/source/ui/sidebar/MasterPageObserver.cxx
0 → 100644
Dosyayı görüntüle @
d45ba6bb
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include "MasterPageObserver.hxx"
#include <algorithm>
#include "drawdoc.hxx"
#include "sdpage.hxx"
#include <boost/unordered_map.hpp>
#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
::
boost
::
unordered_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
::
mapped_type
aMasterPageSet
;
sal_uInt16
nMasterPageCount
=
rDocument
.
GetMasterSdPageCount
(
PK_STANDARD
);
for
(
sal_uInt16
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.
sal_uInt16
nMasterPageCount
=
rDocument
.
GetMasterSdPageCount
(
PK_STANDARD
);
::
std
::
set
<
String
>
aCurrentMasterPages
;
for
(
sal_uInt16
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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment