vclwidget: improve detection of vcl::Window fields
that need to be wrapped in VclPtr, and convert several sites
Change-Id: I1fb1ed164a99642a0c1ccbf433eb14df688fa476
diff --git a/compilerplugins/clang/vclwidgets.cxx b/compilerplugins/clang/vclwidgets.cxx
index 4189024..c71b75e 100644
--- a/compilerplugins/clang/vclwidgets.cxx
+++ b/compilerplugins/clang/vclwidgets.cxx
@@ -48,17 +48,22 @@ private:
bool isDisposeCallingSuperclassDispose(const CXXMethodDecl* pMethodDecl);
};
static const char sVclPtr[] = "VclPtr";
static bool startsWith(const std::string& s, const char* other)
{
return s.compare(0, strlen(other), other) == 0;
}
bool BaseCheckNotWindowSubclass(const CXXRecordDecl *BaseDefinition, void *) {
if (BaseDefinition->getQualifiedNameAsString().compare("vcl::Window") == 0) {
if (BaseDefinition && BaseDefinition->getQualifiedNameAsString().compare("vcl::Window") == 0) {
return false;
}
return true;
}
bool isDerivedFromWindow(const CXXRecordDecl *decl) {
if (decl->getQualifiedNameAsString().compare("vcl::Window") == 0)
if (!decl)
return false;
if (decl->getQualifiedNameAsString() == "vcl::Window")
return true;
if (!decl->hasDefinition()) {
return false;
@@ -72,26 +77,24 @@ bool isDerivedFromWindow(const CXXRecordDecl *decl) {
return false;
}
bool isPointerToWindowSubclass(const Type* pType0) {
const Type* pType = pType0->getUnqualifiedDesugaredType();
if (!pType->isPointerType()) {
bool containsWindowSubclass(const Type* pType0);
bool containsWindowSubclass(const QualType& qType) {
if (startsWith(qType.getAsString(), "VclPtr"))
return false;
}
QualType pointeeType = pType->getPointeeType();
const RecordType *recordType = pointeeType->getAs<RecordType>();
if (recordType == nullptr) {
if (startsWith(qType.getAsString(), "class VclPtr"))
return false;
}
const CXXRecordDecl *recordDecl = dyn_cast<CXXRecordDecl>(recordType->getDecl());
if (recordDecl == nullptr) {
if (startsWith(qType.getAsString(), "const class VclPtr"))
return false;
}
bool b = isDerivedFromWindow(recordDecl);
return b;
return containsWindowSubclass(qType.getTypePtr());
}
bool containsPointerToWindowSubclass(const Type* pType0) {
bool containsWindowSubclass(const Type* pType0) {
if (!pType0)
return false;
const Type* pType = pType0->getUnqualifiedDesugaredType();
if (!pType)
return false;
const CXXRecordDecl* pRecordDecl = pType->getAsCXXRecordDecl();
if (pRecordDecl) {
const ClassTemplateSpecializationDecl* pTemplate = dyn_cast<ClassTemplateSpecializationDecl>(pRecordDecl);
@@ -99,14 +102,19 @@ bool containsPointerToWindowSubclass(const Type* pType0) {
for(unsigned i=0; i<pTemplate->getTemplateArgs().size(); ++i) {
const TemplateArgument& rArg = pTemplate->getTemplateArgs()[i];
if (rArg.getKind() == TemplateArgument::ArgKind::Type &&
containsPointerToWindowSubclass(rArg.getAsType().getTypePtr()))
containsWindowSubclass(rArg.getAsType()))
{
return true;
}
}
}
}
return isPointerToWindowSubclass(pType);
if (pType->isPointerType()) {
QualType pointeeType = pType->getPointeeType();
return containsWindowSubclass(pointeeType);
} else {
return isDerivedFromWindow(pRecordDecl);
}
}
bool VCLWidgets::VisitCXXDestructorDecl(const CXXDestructorDecl* pCXXDestructorDecl)
@@ -131,7 +139,7 @@ bool VCLWidgets::VisitCXXDestructorDecl(const CXXDestructorDecl* pCXXDestructorD
const RecordType *pFieldRecordType = fieldDecl->getType()->getAs<RecordType>();
if (pFieldRecordType) {
const CXXRecordDecl *pFieldRecordTypeDecl = dyn_cast<CXXRecordDecl>(pFieldRecordType->getDecl());
if (pFieldRecordTypeDecl->getQualifiedNameAsString().compare(0, strlen(sVclPtr), sVclPtr) == 0) {
if (startsWith(pFieldRecordTypeDecl->getQualifiedNameAsString(), "VclPtr")) {
foundVclPtrField = true;
break;
}
@@ -213,15 +221,14 @@ bool VCLWidgets::VisitFieldDecl(const FieldDecl * fieldDecl) {
if (fieldDecl->isBitField()) {
return true;
}
if (containsPointerToWindowSubclass(fieldDecl->getType().getTypePtr())) {
if (containsWindowSubclass(fieldDecl->getType())) {
report(
DiagnosticsEngine::Warning,
"vcl::Window subclass declared as a pointer field, should be wrapped in VclPtr.",
"vcl::Window subclass declared as a pointer field, should be wrapped in VclPtr." + fieldDecl->getType().getAsString(),
fieldDecl->getLocation())
<< fieldDecl->getSourceRange();
return true;
}
const RecordType *recordType = fieldDecl->getType()->getAs<RecordType>();
if (recordType == nullptr) {
return true;
@@ -243,7 +250,7 @@ bool VCLWidgets::VisitFieldDecl(const FieldDecl * fieldDecl) {
// If this field is a VclPtr field, then the class MUST have a dispose method
const CXXRecordDecl *pParentRecordDecl = dyn_cast<CXXRecordDecl>(fieldDecl->getParent());
if (pParentRecordDecl && isDerivedFromWindow(pParentRecordDecl)
&& recordDecl->getQualifiedNameAsString().compare(0, strlen(sVclPtr), sVclPtr) == 0)
&& startsWith(recordDecl->getQualifiedNameAsString(), "VclPtr"))
{
bool foundDispose = false;
for(auto methodDecl : pParentRecordDecl->methods()) {
@@ -287,8 +294,8 @@ bool VCLWidgets::VisitParmVarDecl(ParmVarDecl const * pvDecl)
report(
DiagnosticsEngine::Warning,
"vcl::Window subclass passed as a VclPtr parameter, should be passed as a raw pointer.",
pvDecl->getLocation())
<< pvDecl->getSourceRange();
pvDecl->getCanonicalDecl()->getLocation())
<< pvDecl->getCanonicalDecl()->getSourceRange();
}
return true;
}
@@ -400,7 +407,7 @@ bool VCLWidgets::VisitFunctionDecl( const FunctionDecl* functionDecl )
std::vector<std::string> aVclPtrFields;
for(auto fieldDecl : pMethodDecl->getParent()->fields()) {
if (fieldDecl->getType().getAsString().compare(0, strlen(sVclPtr), sVclPtr) == 0) {
if (startsWith(fieldDecl->getType().getAsString(), "VclPtr")) {
aVclPtrFields.push_back(fieldDecl->getNameAsString());
}
}
diff --git a/include/svtools/toolpanel/drawerlayouter.hxx b/include/svtools/toolpanel/drawerlayouter.hxx
index cba7f02..e35d0dd 100644
--- a/include/svtools/toolpanel/drawerlayouter.hxx
+++ b/include/svtools/toolpanel/drawerlayouter.hxx
@@ -29,12 +29,8 @@
namespace svt
{
class ToolPanelViewShell;
class ToolPanelDrawer;
typedef std::shared_ptr< ToolPanelDrawer > PToolPanelDrawer;
//= ToolPanelDrawer
@@ -79,7 +75,7 @@ namespace svt
private:
vcl::Window& m_rParentWindow;
IToolPanelDeck& m_rPanelDeck;
::std::vector< PToolPanelDrawer > m_aDrawers;
::std::vector< VclPtr<ToolPanelDrawer> > m_aDrawers;
::boost::optional< size_t > m_aLastKnownActivePanel;
};
diff --git a/include/svtools/valueset.hxx b/include/svtools/valueset.hxx
index b9753d2..35f5b4a 100644
--- a/include/svtools/valueset.hxx
+++ b/include/svtools/valueset.hxx
@@ -201,7 +201,7 @@ private:
Timer maTimer;
ValueItemList mItemList;
ValueSetItemPtr mpNoneItem;
std::unique_ptr<ScrollBar> mxScrollBar;
VclPtr<ScrollBar> mxScrollBar;
Rectangle maNoneItemRect;
Rectangle maItemListRect;
long mnItemWidth;
diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx
index b69bda3..80f785f 100644
--- a/include/vcl/opengl/OpenGLContext.hxx
+++ b/include/vcl/opengl/OpenGLContext.hxx
@@ -252,7 +252,6 @@ private:
VclPtr<vcl::Window> m_xWindow;
VclPtr<vcl::Window> mpWindow; //points to m_pWindow or the parent window, don't delete it
VclPtr<SystemChildWindow> m_pChildWindow;
boost::scoped_ptr<SystemChildWindow> m_pChildWindowGC;
bool mbInitialized;
int mnRefCount;
bool mbRequestLegacyContext;
diff --git a/svtools/source/control/valueset.cxx b/svtools/source/control/valueset.cxx
index 67b2464..2d0cb078 100644
--- a/svtools/source/control/valueset.cxx
+++ b/svtools/source/control/valueset.cxx
@@ -135,6 +135,7 @@ void ValueSet::dispose()
xComponent->dispose();
ImplDeleteItems();
mpScrollBar.disposeAndClear();
Control::dispose();
}
@@ -350,18 +351,15 @@ void ValueSet::Format()
long nOff;
long nNoneHeight;
long nNoneSpace;
std::unique_ptr<ScrollBar> xDeletedScrollBar;
VclPtr<ScrollBar> xDeletedScrollBar;
// consider the scrolling
if ( nStyle & WB_VSCROLL )
ImplInitScrollBar();
else
{
if ( mxScrollBar.get() )
{
// delete ScrollBar not until later, to prevent recursive calls
xDeletedScrollBar.swap(mxScrollBar);
}
xDeletedScrollBar = mxScrollBar;
mxScrollBar.clear();
}
// calculate item offset
@@ -674,6 +672,8 @@ void ValueSet::Format()
// waiting for the next since the formatting is finished
mbFormat = false;
xDeletedScrollBar.disposeAndClear();
}
void ValueSet::ImplDrawItemText(const OUString& rText)
diff --git a/svtools/source/table/tablecontrol_impl.hxx b/svtools/source/table/tablecontrol_impl.hxx
index 530823a..4a587c8 100644
--- a/svtools/source/table/tablecontrol_impl.hxx
+++ b/svtools/source/table/tablecontrol_impl.hxx
@@ -122,8 +122,7 @@ namespace svt { namespace table
The window's upper left corner is at position (0,0), relative to the
table control, which is the direct parent of the data window.
*/
::boost::scoped_ptr< TableDataWindow >
m_pDataWindow;
VclPtr<TableDataWindow> m_pDataWindow;
/// the vertical scrollbar, if any
VclPtr<ScrollBar> m_pVScroll;
/// the horizontal scrollbar, if any
diff --git a/svtools/source/toolpanel/drawerlayouter.cxx b/svtools/source/toolpanel/drawerlayouter.cxx
index b2e692c..9d3d5e1 100644
--- a/svtools/source/toolpanel/drawerlayouter.cxx
+++ b/svtools/source/toolpanel/drawerlayouter.cxx
@@ -132,7 +132,7 @@ namespace svt
{
ENSURE_OR_RETURN( i_nChildIndex < m_aDrawers.size(), "illegal index", NULL );
const PToolPanelDrawer pDrawer( m_aDrawers[ i_nChildIndex ] );
ToolPanelDrawer *pDrawer( m_aDrawers[ i_nChildIndex ] );
Reference< XAccessible > xItemAccessible = pDrawer->GetAccessible( false );
if ( !xItemAccessible.is() )
@@ -151,7 +151,7 @@ namespace svt
{
OSL_PRECOND( i_nPosition <= m_aDrawers.size(), "DrawerDeckLayouter::PanelInserted: inconsistency!" );
PToolPanelDrawer pDrawer( new ToolPanelDrawer( m_rParentWindow, i_pPanel->GetDisplayName() ) );
ToolPanelDrawer *pDrawer( new ToolPanelDrawer( m_rParentWindow, i_pPanel->GetDisplayName() ) );
pDrawer->SetHelpId( i_pPanel->GetHelpID() );
// proper Z-Order
if ( i_nPosition == 0 )
@@ -160,8 +160,8 @@ namespace svt
}
else
{
const PToolPanelDrawer pFirstDrawer( m_aDrawers[ i_nPosition - 1 ] );
pDrawer->SetZOrder( pFirstDrawer.get(), WINDOW_ZORDER_BEHIND );
ToolPanelDrawer* pFirstDrawer( m_aDrawers[ i_nPosition - 1 ] );
pDrawer->SetZOrder( pFirstDrawer, WINDOW_ZORDER_BEHIND );
}
pDrawer->Show();
@@ -213,10 +213,7 @@ namespace svt
size_t DrawerDeckLayouter::impl_getPanelPositionFromWindow( const vcl::Window* i_pDrawerWindow ) const
{
for ( ::std::vector< PToolPanelDrawer >::const_iterator drawerPos = m_aDrawers.begin();
drawerPos != m_aDrawers.end();
++drawerPos
)
for ( auto drawerPos = m_aDrawers.begin(); drawerPos != m_aDrawers.end(); ++drawerPos )
{
if ( drawerPos->get() == i_pDrawerWindow )
return drawerPos - m_aDrawers.begin();
@@ -229,7 +226,6 @@ namespace svt
{
OSL_PRECOND( i_nPosition < m_aDrawers.size(), "DrawerDeckLayouter::impl_removeDrawer: invalid panel position!" );
m_aDrawers[ i_nPosition ]->RemoveEventListener( LINK( this, DrawerDeckLayouter, OnWindowEvent ) );
OSL_ENSURE( m_aDrawers[ i_nPosition ].unique(), "DrawerDeckLayouter::impl_removeDrawer: somebody else is still holding a reference!" );
m_aDrawers.erase( m_aDrawers.begin() + i_nPosition );
}
diff --git a/svtools/source/toolpanel/tablayouter.cxx b/svtools/source/toolpanel/tablayouter.cxx
index 39a0874..b2e6f24 100644
--- a/svtools/source/toolpanel/tablayouter.cxx
+++ b/svtools/source/toolpanel/tablayouter.cxx
@@ -41,7 +41,7 @@ namespace svt
{
TabAlignment eAlignment;
IToolPanelDeck& rPanels;
::std::unique_ptr< PanelTabBar > pTabBar;
VclPtr< PanelTabBar > pTabBar;
AccessibleFactoryAccess aAccessibleFactory;
TabDeckLayouter_Data( vcl::Window& i_rParent, IToolPanelDeck& i_rPanels,
diff --git a/vcl/inc/ilstbox.hxx b/vcl/inc/ilstbox.hxx
index 1e81f60f..eaea4a4 100644
--- a/vcl/inc/ilstbox.hxx
+++ b/vcl/inc/ilstbox.hxx
@@ -378,12 +378,10 @@ protected:
virtual void SelectEntry( ::vcl::StringEntryIdentifier _entry ) SAL_OVERRIDE;
};
typedef rtl::Reference<ImplListBoxWindow> ImplListBoxWindowPtr;
class ImplListBox : public Control
{
private:
ImplListBoxWindowPtr maLBWindow;
VclPtr<ImplListBoxWindow> maLBWindow;
VclPtr<ScrollBar> mpHScrollBar;
VclPtr<ScrollBar> mpVScrollBar;
VclPtr<ScrollBarBox> mpScrollBarBox;
@@ -418,7 +416,7 @@ public:
virtual void dispose() SAL_OVERRIDE;
const ImplEntryList* GetEntryList() const { return maLBWindow->GetEntryList(); }
ImplListBoxWindowPtr GetMainWindow() { return maLBWindow; }
ImplListBoxWindow* GetMainWindow() { return maLBWindow.get(); }
virtual void Resize() SAL_OVERRIDE;
virtual const Wallpaper& GetDisplayBackground() const SAL_OVERRIDE;
diff --git a/vcl/source/control/combobox.cxx b/vcl/source/control/combobox.cxx
index c5ef3eb..441b3b5 100644
--- a/vcl/source/control/combobox.cxx
+++ b/vcl/source/control/combobox.cxx
@@ -582,19 +582,19 @@ void ComboBox::FillLayoutData() const
mpControlData->mpLayoutData = new vcl::ControlLayoutData();
AppendLayoutData( *mpSubEdit );
mpSubEdit->SetLayoutDataParent( this );
ImplListBoxWindowPtr rMainWindow = mpImplLB->GetMainWindow();
ImplListBoxWindow* rMainWindow = mpImplLB->GetMainWindow();
if( mpFloatWin )
{
// dropdown mode
if( mpFloatWin->IsReallyVisible() )
{
AppendLayoutData( *(rMainWindow.get()) );
AppendLayoutData( *rMainWindow );
rMainWindow->SetLayoutDataParent( this );
}
}
else
{
AppendLayoutData( *(rMainWindow.get()) );
AppendLayoutData( *rMainWindow );
rMainWindow->SetLayoutDataParent( this );
}
}
@@ -766,7 +766,7 @@ bool ComboBox::Notify( NotifyEvent& rNEvt )
nDone = false; // don't eat this event, let the default handling happen (i.e. scroll the context)
}
}
else if( ( rNEvt.GetType() == MouseNotifyEvent::MOUSEBUTTONDOWN ) && ( rNEvt.GetWindow() == mpImplLB->GetMainWindow().get() ) )
else if( ( rNEvt.GetType() == MouseNotifyEvent::MOUSEBUTTONDOWN ) && ( rNEvt.GetWindow() == mpImplLB->GetMainWindow() ) )
{
mpSubEdit->GrabFocus();
}
@@ -1244,7 +1244,7 @@ void ComboBox::EnableUserDraw( bool bUserDraw )
void ComboBox::DrawEntry( const UserDrawEvent& rEvt, bool bDrawImage, bool bDrawText, bool bDrawTextAtImagePos )
{
DBG_ASSERT( rEvt.GetDevice() == mpImplLB->GetMainWindow().get(), "DrawEntry?!" );
DBG_ASSERT( rEvt.GetDevice() == mpImplLB->GetMainWindow(), "DrawEntry?!" );
mpImplLB->GetMainWindow()->DrawEntry( rEvt.GetItemId(), bDrawImage, bDrawText, bDrawTextAtImagePos );
}
@@ -1383,7 +1383,7 @@ long ComboBox::GetIndexForPoint( const Point& rPoint, sal_Int32& rPos ) const
{
// point must be either in main list window
// or in impl window (dropdown case)
ImplListBoxWindowPtr rMain = mpImplLB->GetMainWindow();
ImplListBoxWindow* rMain = mpImplLB->GetMainWindow();
// convert coordinates to ImplListBoxWindow pixel coordinate space
Point aConvPoint = LogicToPixel( rPoint );
diff --git a/vcl/source/control/ilstbox.cxx b/vcl/source/control/ilstbox.cxx
index d6fde49..e05746e 100644
--- a/vcl/source/control/ilstbox.cxx
+++ b/vcl/source/control/ilstbox.cxx
@@ -2178,6 +2178,7 @@ void ImplListBox::dispose()
mpVScrollBar.clear();
mpScrollBarBox.clear();
maLBWindow.clear();
maLBWindow.disposeAndClear();
Control::dispose();
}
@@ -2984,7 +2985,7 @@ void ImplListBoxFloatingWindow::setPosSizePixel( long nX, long nY, long nWidth,
// this the presence of the vertical Scrollbar has to be known.
mpImplLB->SetSizePixel( GetOutputSizePixel() );
((vcl::Window*)mpImplLB)->Resize();
((vcl::Window*)mpImplLB->GetMainWindow().get())->Resize();
((vcl::Window*)mpImplLB->GetMainWindow())->Resize();
}
}
diff --git a/vcl/source/control/lstbox.cxx b/vcl/source/control/lstbox.cxx
index 00eba39..01ac564 100644
--- a/vcl/source/control/lstbox.cxx
+++ b/vcl/source/control/lstbox.cxx
@@ -693,7 +693,7 @@ void ListBox::Resize()
void ListBox::FillLayoutData() const
{
mpControlData->mpLayoutData = new vcl::ControlLayoutData();
const ImplListBoxWindowPtr rMainWin = mpImplLB->GetMainWindow();
const ImplListBoxWindow* rMainWin = mpImplLB->GetMainWindow();
if( mpFloatWin )
{
// Dropdown mode
@@ -701,13 +701,13 @@ void ListBox::FillLayoutData() const
mpImplWin->SetLayoutDataParent( this );
if( mpFloatWin->IsReallyVisible() )
{
AppendLayoutData( *(rMainWin.get()) );
AppendLayoutData( *rMainWin );
rMainWin->SetLayoutDataParent( this );
}
}
else
{
AppendLayoutData( *(rMainWin.get()) );
AppendLayoutData( *rMainWin );
rMainWin->SetLayoutDataParent( this );
}
}
@@ -723,7 +723,7 @@ long ListBox::GetIndexForPoint( const Point& rPoint, sal_Int32& rPos ) const
{
// Point must be either in main list window
// or in impl window (dropdown case)
ImplListBoxWindowPtr rMain = mpImplLB->GetMainWindow();
ImplListBoxWindow* rMain = mpImplLB->GetMainWindow();
// Convert coordinates to ImplListBoxWindow pixel coordinate space
Point aConvPoint = LogicToPixel( rPoint );
@@ -1373,7 +1373,7 @@ void ListBox::UserDraw( const UserDrawEvent& )
void ListBox::DrawEntry( const UserDrawEvent& rEvt, bool bDrawImage, bool bDrawText, bool bDrawTextAtImagePos )
{
if ( rEvt.GetDevice() == mpImplLB->GetMainWindow().get() )
if ( rEvt.GetDevice() == mpImplLB->GetMainWindow() )
mpImplLB->GetMainWindow()->DrawEntry( rEvt.GetItemId(), bDrawImage, bDrawText, bDrawTextAtImagePos );
else if ( rEvt.GetDevice() == mpImplWin )
mpImplWin->DrawEntry( bDrawImage, bDrawText, bDrawTextAtImagePos );
diff --git a/vcl/source/control/morebtn.cxx b/vcl/source/control/morebtn.cxx
index aa542ca..999c3c3 100644
--- a/vcl/source/control/morebtn.cxx
+++ b/vcl/source/control/morebtn.cxx
@@ -22,7 +22,7 @@
#include <tools/rc.h>
#include <vector>
typedef ::std::vector< vcl::Window* > ImplMoreWindowList;
typedef ::std::vector< VclPtr<vcl::Window> > ImplMoreWindowList;
struct ImplMoreButtonData
{
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index be14c22..9a15a45 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -1142,7 +1142,7 @@ bool OpenGLContext::initWindow()
{
if( !m_pChildWindow )
{
m_pChildWindow = new SystemChildWindow(mpWindow, 0, &winData, false);
m_pChildWindow = VclPtrInstance<SystemChildWindow>(mpWindow, 0, &winData, false);
m_xChildWindowGC.reset(m_pChildWindow);
}
pChildSysData = m_pChildWindow->GetSystemData();
diff --git a/vcl/source/window/openglwin.cxx b/vcl/source/window/openglwin.cxx
index 13cf52e..bb7ef27 100644
--- a/vcl/source/window/openglwin.cxx
+++ b/vcl/source/window/openglwin.cxx
@@ -19,7 +19,7 @@ public:
OpenGLContext& getContext() { return maContext;}
private:
OpenGLContext maContext;
std::unique_ptr<SystemChildWindow> mxChildWindow;
VclPtr<SystemChildWindow> mxChildWindow;
};
OpenGLWindowImpl::OpenGLWindowImpl(vcl::Window* pWindow)
diff --git a/vcl/source/window/toolbox.cxx b/vcl/source/window/toolbox.cxx
index 83d61cb..3c3256a 100644
--- a/vcl/source/window/toolbox.cxx
+++ b/vcl/source/window/toolbox.cxx
@@ -84,7 +84,7 @@
static void ImplDrawButton( ToolBox* pThis, const Rectangle &rRect, sal_uInt16 highlight, bool bChecked, bool bEnabled, bool bIsWindow );
typedef ::std::vector< ToolBox* > ImplTBList;
typedef ::std::vector< VclPtr<ToolBox> > ImplTBList;
class ImplTBDragMgr
{