xref: /aoo42x/main/canvas/inc/canvas/vclwrapper.hxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef INCLUDED_CANVAS_VCLWRAPPER_HXX
29 #define INCLUDED_CANVAS_VCLWRAPPER_HXX
30 
31 #include <osl/mutex.hxx>
32 #include <vos/mutex.hxx>
33 #include <vcl/svapp.hxx>
34 
35 
36 namespace canvas
37 {
38     namespace vcltools
39     {
40         /** This helper template wraps VCL objects, and protects
41             object deletion with the Solar mutex. All other operations
42             are unprotected, this must be handled by client code.
43 
44 			The reason for this template is the fact that VCL objects
45 			hold by value in uno::Reference-handled classes are
46 			deleted without having the chance to get inbetween and
47 			lock the solar mutex.
48 
49             This template handles that problem transparently, the only
50             inconvenience is the fact that object member access now
51             has to be performed via operator->, since . is not
52             overloadable.
53 
54             Otherwise, the template preserves the value semantics of
55             the wrapped object, that is, copy operations are performed
56             not by copying pointers, but by copying the underlying
57             object. This includes constness, i.e. on a const
58             VCLObject, only const methods of the wrapped object can be
59             called. Simply imagine this to be a value object of type
60             "template argument", with the only peculiarity that
61             member/method access is performed by operator-> instead of
62             the non-existing "operator.".
63          */
64         template< class _Wrappee > class VCLObject
65         {
66         public:
67             typedef _Wrappee Wrappee;
68 
69             VCLObject() :
70                 mpWrappee( new Wrappee() )
71             {
72 	        }
73 
74             // no explicit here. VCLObjects should be freely
75             // constructible with Wrappees, and AFAIK there is no other
76             // implicit conversion path that could cause harm here
77             VCLObject( Wrappee* pWrappee ) :
78                 mpWrappee( pWrappee )
79             {
80 	        }
81 
82             // This object has value semantics, thus, forward copy
83             // to wrappee
84             VCLObject( const VCLObject& rOrig )
85             {
86                 if( rOrig.mpWrappee )
87                     mpWrappee = new Wrappee( *rOrig.mpWrappee );
88                 else
89                     mpWrappee = NULL;
90             }
91 
92             // This object has value semantics, thus, forward copy
93             // to wrappee
94             VCLObject( const Wrappee& rOrig ) :
95                 mpWrappee( new Wrappee( rOrig ) )
96             {
97             }
98 
99             // This object has value semantics, thus, forward
100             // assignment to wrappee
101             VCLObject& operator=( const VCLObject& rhs )
102             {
103                 if( mpWrappee )
104                 {
105                     if( rhs.mpWrappee )
106                         *mpWrappee = *rhs.mpWrappee;
107                 }
108                 else
109                 {
110                     if( rhs.mpWrappee )
111                         mpWrappee = new Wrappee( *rhs.mpWrappee );
112                 }
113 
114                 return *this;
115             }
116 
117             ~VCLObject()
118             {
119                 // This here is the whole purpose of the template:
120                 // protecting object deletion with the solar mutex
121                 ::vos::OGuard aGuard( Application::GetSolarMutex() );
122 
123                 if( mpWrappee )
124                     delete mpWrappee;
125             }
126 
127             Wrappee* 		operator->() { return mpWrappee; }
128             const Wrappee* 	operator->() const { return mpWrappee; }
129 
130             Wrappee& 		operator*() { return *mpWrappee; }
131             const Wrappee& 	operator*() const { return *mpWrappee; }
132 
133             Wrappee& 		get() { return *mpWrappee; }
134             const Wrappee& 	get() const { return *mpWrappee; }
135 
136             void swap( VCLObject& rOther )
137             {
138                 ::std::swap( mpWrappee, rOther.mpWrappee );
139             }
140 
141         private:
142 
143             Wrappee* mpWrappee;
144         };
145 
146     }
147 }
148 
149 #endif /* INCLUDED_CANVAS_VCLWRAPPER_HXX */
150