1 /*
2     This file is part of the KDE libraries
3     SPDX-FileCopyrightText: 2000 Carsten Pfeiffer <pfeiffer@kde.org>
4     SPDX-FileCopyrightText: 2012 Kevin Ottens <ervin+bluesystems@kde.org>
5 
6     SPDX-License-Identifier: LGPL-2.0-or-later
7 */
8 
9 #ifndef KDRAGWIDGETDECORATOR_H
10 #define KDRAGWIDGETDECORATOR_H
11 
12 #include <QObject>
13 
14 #include <kwidgetsaddons_export.h>
15 
16 #include <memory>
17 
18 class QDrag;
19 
20 /**
21  * @brief A decorator which adds drag-support to widgets
22  *
23  * This is a decorator using an event filter to implement drag-support
24  * in widgets.
25  * You must override the virtual method dragObject() to specify the
26  * QDrag to be used.
27  *
28  * @author Carsten Pfeiffer <pfeiffer@kde.org>
29  */
30 class KWIDGETSADDONS_EXPORT KDragWidgetDecoratorBase : public QObject
31 {
32     Q_OBJECT
33     Q_PROPERTY(bool isDragEnabled READ isDragEnabled WRITE setDragEnabled)
34 
35 public:
36     /**
37      * Default constructor.
38      */
39     explicit KDragWidgetDecoratorBase(QWidget *parent = nullptr);
40 
41     /**
42      * Destructs the decorator.
43      */
44     ~KDragWidgetDecoratorBase() override;
45 
46     /**
47      * Enables/disables drag-support. Default is enabled.
48      */
49     void setDragEnabled(bool enable);
50 
51     /**
52      * @returns if drag support is enabled or not.
53      */
54     bool isDragEnabled() const;
55 
56 protected:
57     /**
58      * @return the widget this decorator is attached to
59      */
60     QWidget *decoratedWidget() const;
61 
62     /**
63      * Reimplement this and return the QDrag object that should be used
64      * for the drag. Remember to give it "decoratedWidget()" as parent.
65      *
66      * Default implementation returns a null pointer, so that no drag is initiated.
67      */
68     virtual QDrag *dragObject();
69 
70     /**
71      * Reimplemented to add drag-support
72      */
73     bool eventFilter(QObject *watched, QEvent *event) override;
74 
75     /**
76      * Starts a drag (Copy by default) using dragObject()
77      */
78     virtual void startDrag();
79 
80 private:
81     std::unique_ptr<class KDragWidgetDecoratorBasePrivate> const d;
82 };
83 
84 /**
85  * @class KDragWidgetDecorator kdragwidgetdecorator.h KDragWidgetDecorator
86  *
87  * @brief A decorator which adds drag-support to widgets
88  *
89  * This is a decorator using an event filter to implement drag-support
90  * in widgets.
91  * You must set the dragObjectFactory to specify the QDrag to be used.
92  *
93  * @author Kevin Ottens <ervin@kde.org>
94  */
95 template<class Widget>
96 class KDragWidgetDecorator : public KDragWidgetDecoratorBase
97 {
98 public:
99     typedef QDrag *(*DragObjectFactory)(Widget *);
100 
101     KDragWidgetDecorator(Widget *parent = nullptr)
KDragWidgetDecoratorBase(parent)102         : KDragWidgetDecoratorBase(parent)
103         , m_factory(nullptr)
104     {
105     }
106 
107     /**
108      * @return the QDrag factory used by this decorator
109      */
dragObjectFactory()110     DragObjectFactory dragObjectFactory() const
111     {
112         return m_factory;
113     }
114 
115     /**
116      * Set a factory to be used by this decorator
117      *
118      * @param factory the new QDrag factory to use
119      */
setDragObjectFactory(DragObjectFactory factory)120     void setDragObjectFactory(DragObjectFactory factory)
121     {
122         m_factory = factory;
123     }
124 
125 private:
126     /**
127      * Reimplemented to use the QDrag factory
128      */
dragObject()129     QDrag *dragObject() override
130     {
131         if (m_factory) {
132             Widget *w = static_cast<Widget *>(decoratedWidget());
133             return m_factory(w);
134         } else {
135             return KDragWidgetDecoratorBase::dragObject();
136         }
137     }
138 
139     DragObjectFactory m_factory;
140 };
141 
142 #endif // KDRAGWIDGETDECORATOR_H
143