1 /*
2  * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB.  All rights reserved.
3  *
4  * This file is part of the KGantt library.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18  */
19 /** \file kganttglobal.h
20 \brief Contains KGantt macros.
21 
22 Contains KGantt macros.  */
23 
24 #ifndef KGANTTGLOBAL_H
25 #define KGANTTGLOBAL_H
26 
27 #include <Qt>
28 #include <QDateTime>
29 #include <QDebug>
30 #include <QMetaType>
31 
32 #include "kgantt_export.h"
33 
34 #if (defined(__MINGW32__) || defined(__MINGW64__)) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 4) && (__GNUC_PATCHLEVEL__ == 0)
35 // workaround a mingw bug, http://sourceforge.net/tracker/index.php?func=detail&aid=2373234&group_id=2435&atid=102435
36 int swprintf (wchar_t *, size_t, const wchar_t *, ...);
37 int vswprintf(wchar_t *, const wchar_t *, va_list);
38 #endif
39 
40 #ifndef KDAB_SET_OBJECT_NAME
41 template <typename T>
__kdab__dereference_for_methodcall(T & o)42 inline T & __kdab__dereference_for_methodcall( T & o ) {
43     return o;
44 }
45 
46 template <typename T>
__kdab__dereference_for_methodcall(T * o)47 inline T & __kdab__dereference_for_methodcall( T * o ) {
48     return *o;
49 }
50 
51 #define KDAB_SET_OBJECT_NAME( x ) __kdab__dereference_for_methodcall( x ).setObjectName( QLatin1String( #x ) )
52 #endif
53 
54 #if defined(_MSC_VER) && _MSC_VER <= 1300
55 #define KGANTT_DECLARE_PRIVATE_DERIVED( X )      \
56 public:                                           \
57     class Private;                                \
58 	friend class Private;                     \
59 protected:                                        \
60     inline Private * d_func();                    \
61     inline const Private * d_func() const;        \
62     explicit inline X( Private * );               \
63 private:                                          \
64     void init();
65 #else
66 #define KGANTT_DECLARE_PRIVATE_DERIVED( X )      \
67 protected:                                        \
68     class Private;                                \
69 	friend class Private;                     \
70     inline Private * d_func();                    \
71     inline const Private * d_func() const;        \
72     explicit inline X( Private * );               \
73 private:                                          \
74     void init();
75 #endif
76 
77 #if defined(_MSC_VER) && _MSC_VER <= 1300
78 #define KGANTT_DECLARE_PRIVATE_DERIVED_PARENT( X, ParentType )      \
79 public:                                           \
80     class Private;                                \
81 	friend class Private;                     \
82 protected:                                        \
83     inline Private * d_func();                    \
84     inline const Private * d_func() const;        \
85     explicit inline X( Private *, ParentType );   \
86 private:                                          \
87     void init();
88 #else
89 #define KGANTT_DECLARE_PRIVATE_DERIVED_PARENT( X, ParentType )      \
90 protected:                                        \
91     class Private;                                \
92 	friend class Private;                     \
93     inline Private * d_func();                    \
94     inline const Private * d_func() const;        \
95     explicit inline X( Private *, ParentType );   \
96 private:                                          \
97     void init();
98 #endif
99 
100 #define KGANTT_DECLARE_PRIVATE_DERIVED_QWIDGET( X )         \
101     KGANTT_DECLARE_PRIVATE_DERIVED_PARENT( X, QWidget* )
102 
103 #define KGANTT_DECLARE_PRIVATE_BASE_VALUE( X )              \
104 public:                                                      \
105     inline void swap( X & other ) { qSwap( _d, other._d ); } \
106 protected:                                                   \
107     class Private;                                           \
108 	friend class Private;                                \
109     Private * d_func() { return _d; }                        \
110     const Private * d_func() const { return _d; }            \
111 private:                                                     \
112     void init();                                             \
113     Private * _d;
114 
115 #if defined(_MSC_VER) && _MSC_VER <= 1300
116 #define KGANTT_DECLARE_PRIVATE_BASE_POLYMORPHIC( X ) \
117 public:                                               \
118     class Private;                                    \
119 	friend class Private;                         \
120 protected:                                            \
121     Private * d_func() { return _d; }                 \
122     const Private * d_func() const { return _d; }     \
123     explicit inline X( Private * );                   \
124 private:                                              \
125     void init();                                      \
126     Private * _d;
127 #else
128 #define KGANTT_DECLARE_PRIVATE_BASE_POLYMORPHIC( X ) \
129 protected:                                            \
130     class Private;                                    \
131 	friend class Private;                         \
132     Private * d_func() { return _d; }                 \
133     const Private * d_func() const { return _d; }     \
134     explicit inline X( Private * );                   \
135 private:                                              \
136     void init();                                      \
137     Private * _d;
138 #endif
139 
140 #if defined(_MSC_VER) && _MSC_VER <= 1300
141 #define KGANTT_DECLARE_PRIVATE_BASE_POLYMORPHIC_QWIDGET( X ) \
142 public:                                               \
143     class Private;                                    \
144 	friend class Private;                         \
145 protected:                                            \
146     Private * d_func() { return _d; }                 \
147     const Private * d_func() const { return _d; }     \
148     explicit inline X( Private *, QWidget* );         \
149 private:                                              \
150     void init();                                      \
151     Private * _d;
152 #else
153 #define KGANTT_DECLARE_PRIVATE_BASE_POLYMORPHIC_QWIDGET( X ) \
154 protected:                                            \
155     class Private;                                    \
156 	friend class Private;                         \
157     Private * d_func() { return _d; }                 \
158     const Private * d_func() const { return _d; }     \
159     explicit inline X( Private *, QWidget* );         \
160 private:                                              \
161     void init();                                      \
162     Private * _d;
163 #endif
164 
165 
166 
167 // enable this for testing if KD Gantt works without STL support in Qt:
168 //
169 // #define QT_NO_STL
170 
171 
172 #include <QtAlgorithms> // qSwap
173 #ifndef QT_NO_STL
174 #include <algorithm>
175 #define KGANTT_DECLARE_SWAP_SPECIALISATION( X )            \
176 QT_BEGIN_NAMESPACE                                          \
177     template <> inline void qSwap<X>( X & lhs, X & rhs )    \
178     { lhs.swap( rhs ); }                                    \
179 QT_END_NAMESPACE                                            \
180     namespace std {                                         \
181         template <> inline void swap<X>( X & lhs, X & rhs ) \
182         { lhs.swap( rhs ); }                                \
183     }
184 #else
185 #define KGANTT_DECLARE_SWAP_SPECIALISATION( X )            \
186 QT_BEGIN_NAMESPACE                                          \
187     template <> inline void qSwap<X>( X & lhs, X & rhs )    \
188     { lhs.swap( rhs ); }                                    \
189 QT_END_NAMESPACE
190 #endif
191 
192 #define KGANTT_DECLARE_SWAP_SPECIALISATION_DERIVED( X )    \
193     KGANTT_DECLARE_SWAP_SPECIALISATION( X )
194 
195 #define KGANTT_DECLARE_SWAP_BASE( X ) \
196 protected: \
197     void doSwap( X& other ) \
198     { qSwap( _d, other._d); }
199 
200 #define KGANTT_DECLARE_SWAP_DERIVED( X ) \
201     void swap( X& other ) { doSwap( other ); }
202 
203 #if defined(Q_OS_WIN) && defined(QT_DLL)
204 #if defined(_MSC_VER) && _MSC_VER >= 1300
205 // workaround http://support.microsoft.com/default.aspx?scid=kb;en-us;309801
206 #include <QPointF>
207 #include <QVector>
208 template class Q_DECL_IMPORT QVector<QPointF>;
209 #endif
210 #endif
211 
212 /*!\namespace KGantt
213  *\ingroup KGantt
214  *\brief Global namespace
215  */
216 namespace KGantt {
217 
218     /*!\enum KGantt::ItemDataRole
219      *\ingroup KGantt
220      * The values of this enum are used for the special data roles
221      * for gantt items
222      */
223     enum ItemDataRole {
224         KGanttRoleBase     = Qt::UserRole + 1174, ///< The base value used for the KGantt role enum values. The actual roles have values base+1, base+2, ...
225         StartTimeRole       = KGanttRoleBase + 1, ///< Start time (or other start value) for a gantt item.
226         EndTimeRole         = KGanttRoleBase + 2, ///< End time (or other end value) for a gantt item.
227         TaskCompletionRole  = KGanttRoleBase + 3, ///< Task completetion percentage used by Task items. Should be an integer og a qreal between 0 and 100.
228         ItemTypeRole        = KGanttRoleBase + 4, ///< The item type. \see KGantt::ItemType.
229         LegendRole          = KGanttRoleBase + 5, ///< The Legend text
230         TextPositionRole    = KGanttRoleBase + 6 ///< The position of the text label on the item. The type of this value is KGantt::StyleOptionGanttItem::Position and the default values is Right.
231     };
232 
233     /*!\enum KGantt::ItemType
234      *\ingroup KGantt
235      * The values of this enum are used to represent the different
236      * types of gantt items that KGantt understands. The itemtype
237      * is served through the KGantt::ItemTypeRole role
238      */
239     enum ItemType {
240         TypeNone    = 0,
241         TypeEvent   = 1,
242         TypeTask    = 2,
243         TypeSummary = 3,
244         TypeMulti   = 4,
245         TypeUser    = 1000
246     };
247 
248     /*!\class KGantt::Span kganttglobal.h KGanttGlobal
249      *\ingroup KGantt
250      * \brief A class representing a start point and a length */
251     class Span {
252         qreal m_start;
253         qreal m_length;
254     public:
Span()255         inline Span() : m_start( -1 ), m_length( 0 ) {}
Span(qreal start,qreal length)256         inline Span( qreal start, qreal length ) : m_start( start ), m_length( length ) {}
Span(const Span & other)257         inline Span( const Span& other ) : m_start(other.m_start), m_length(other.m_length) {}
258 
259         inline Span& operator=( const Span& other ) { m_start=other.m_start; m_length=other.m_length; return *this; }
260 
setStart(qreal start)261         inline void setStart( qreal start ) { m_start=start; }
start()262         inline qreal start() const { return m_start; }
setEnd(qreal end)263         inline void setEnd( qreal end ) { m_length = m_start-end; }
end()264         inline qreal end() const { return m_start+m_length; }
265 
setLength(qreal length)266         inline void setLength( qreal length ) { m_length=length; }
length()267         inline qreal length() const { return m_length; }
268 
isValid()269         inline bool isValid() const { return m_start >= 0.;}
270 
equals(const Span & other)271         inline bool equals( const Span& other ) const {
272             return m_start == other.m_start && m_length == other.m_length;
273         }
expandedTo(const Span & other)274         inline Span expandedTo( const Span& other) const {
275             const qreal new_start = qMin(start(),other.start());
276             return Span( new_start, (end()<other.end())?other.end()-new_start:end()-new_start);
277         }
278     };
279 
280     inline bool operator==( const Span& s1, const Span& s2) { return s1.equals( s2 ); }
281     inline bool operator!=( const Span& s1, const Span& s2) { return !s1.equals( s2 ); }
282 
283 
284     class DateTimeSpan {
285         QDateTime m_start;
286         QDateTime m_end;
287     public:
288         DateTimeSpan();
289         DateTimeSpan( const QDateTime& start, const QDateTime& end );
290         DateTimeSpan( const DateTimeSpan& other );
291         ~DateTimeSpan();
292 
293         DateTimeSpan& operator=( const DateTimeSpan& other );
294 
setStart(const QDateTime & start)295         inline void setStart( const QDateTime& start ) { m_start=start; }
start()296         inline QDateTime start() const { return m_start; }
297 
setEnd(const QDateTime & end)298         inline void setEnd( const QDateTime& end ) { m_end=end; }
end()299         inline QDateTime end() const { return m_end; }
300 
301         bool isValid() const;
302 
303         bool equals( const DateTimeSpan& other ) const;
304     };
305 
306     inline bool operator==( const DateTimeSpan& s1, const DateTimeSpan& s2) { return s1.equals( s2 ); }
307     inline bool operator!=( const DateTimeSpan& s1, const DateTimeSpan& s2) { return !s1.equals( s2 ); }
308 }
309 
310 Q_DECLARE_METATYPE(KGantt::ItemType)
311 
312 #ifndef QT_NO_DEBUG_STREAM
313 QDebug KGANTT_EXPORT operator<<( QDebug dbg, KGantt::ItemDataRole r);
314 QDebug KGANTT_EXPORT operator<<( QDebug dbg, KGantt::ItemType t);
315 QDebug KGANTT_EXPORT operator<<( QDebug dbg, const KGantt::Span& s );
316 QDebug KGANTT_EXPORT operator<<( QDebug dbg, const KGantt::DateTimeSpan& s );
317 #endif /* QT_NO_DEBUG_STREAM */
318 
319 QT_BEGIN_NAMESPACE
320 Q_DECLARE_TYPEINFO(KGantt::Span, Q_MOVABLE_TYPE);
321 Q_DECLARE_TYPEINFO(KGantt::DateTimeSpan, Q_MOVABLE_TYPE);
322 QT_END_NAMESPACE
323 
324 #endif /* KGANTTGLOBAL_H */
325