summaryrefslogtreecommitdiffstats
path: root/korganizer/kodaymatrix.h
blob: 79231b4676df26aaf784a1d8da78e908ef8e838a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
/*
    This file is part of KOrganizer.

    Copyright (c) 2001 Eitzenberger Thomas <thomas.eitzenberger@siemens.at>
    Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
    Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of TQt, and distribute the resulting executable,
    without including the source code for TQt in the source distribution.
*/
#ifndef KODAYMATRIX_H
#define KODAYMATRIX_H

#include <libkcal/incidencebase.h>
#include <libkcal/calendar.h>

#include <tqframe.h>
#include <tqcolor.h>
#include <tqtooltip.h>
#include <tqmap.h>

class TQDragEnterEvent;
class TQDragMoveEvent;
class TQDragLeaveEvent;
class TQDropEvent;

class KODayMatrix;

namespace KCal {
class Incidence;
class Calendar;
}
using namespace KCal;


/**
 *  small helper class to dynamically show tooltips inside the day matrix.
 *  This class asks the day matrix object for a appropriate label which
 *  is in our special case the name of the holiday or null if this day is no holiday.
 */
class DynamicTip : public TQToolTip
{
  public:
    /**
     * Constructor that expects a KODayMatrix object as parent.
     *
     * @param parent the parent KODayMatrix control.
     */
    DynamicTip( TQWidget *parent );

  protected:
    /**
     * TQt's callback to ask the object to provide an approrpiate text for the
     * tooltip to be shown.
     *
     * @param pos coordinates of the mouse.
     */
    void maybeTip( const TQPoint &pos );

  private:
    /** the parent control this tooltip is designed for. */
    KODayMatrix *mMatrix;
};

/**
 *  Replacement for kdpdatebuton.cpp that used 42 widgets for the day matrix to be displayed.
 *  Cornelius thought this was a waste of memory and a lot of overhead.
 *  In addition the selection was not very intuitive so I decided to rewrite it using a TQFrame
 *  that draws the labels and allows for dragging selection while maintaining nearly full
 *  compatibility in behavior with its predecessor.
 *
 *  The following functionality has been changed:
 *
 *  o when shifting events in the agenda view from one day to another the day matrix is updated now
 *  o dragging an event to the matrix will MOVE not COPY the event to the new date.
 *  o no support for Ctrl+click to create groups of dates
 *    (This has not really been supported in the predecessor. It was not very intuitive nor was it
 *     user friendly.)
 *    This feature has been replaced with dragging a selection on the matrix. The matrix will
 *    automatically choose the appropriate selection (e.g. you are not any longer able to select
 *    two distinct groups of date selections as in the old class)
 *  o now that you can select more then a week it can happen that not all selected days are
 *    displayed in the matrix. However this is preferred to the alternative which would mean to
 *    adjust the selection and leave some days undisplayed while scrolling through the months
 *
 *  @short day matrix widget of the KDateNavigator
 *
 *  @author Eitzenberger Thomas
 */
class KODayMatrix: public TQFrame, public KCal::Calendar::Observer
{
    Q_OBJECT
  
  public:
    /** constructor to create a day matrix widget.
     *
     *  @param parent widget that is the parent of the day matrix.
     *  Normally this should be a KDateNavigator
     *  @param name name of the widget
     */
    KODayMatrix( TQWidget *parent, const char *name );

    /** destructor that deallocates all dynamically allocated private members.
     */
    ~KODayMatrix();

    /** returns the first and last date of the 6*7 matrix that displays @p month
     * @param month The month we want to get matrix boundaries
     */
    static TQPair<TQDate,TQDate> matrixLimits( const TQDate &month );

    /**
      Associate a calendar with this day matrix. If there is a calendar, the day
      matrix will accept drops and days with events will be highlighted.
    */
    void setCalendar( Calendar * );

    /** updates the day matrix to start with the given date. Does all the necessary
     *  checks for holidays or events on a day and stores them for display later on.
     *  Does NOT update the view visually. Call repaint() for this.
     *
     *  @param actdate recalculates the day matrix to show NUMDAYS starting from this
     *                 date.
     */
    void updateView( const TQDate &actdate );

    /**
      Update event states of dates. Depending of the preferences days with
      events are highlighted in some way.
    */
    void updateEvents();

    /** returns the TQDate object associated with day indexed by the
     *  supplied offset.
     */
    const TQDate& getDate( int offset );

    /** returns the official name of this holy day or 0 if there is no label
     *  for this day.
     */
    TQString getHolidayLabel( int offset );

    /** adds all actual selected days from mSelStart to mSelEnd to the supplied
     *  DateList.
     */
    void addSelectedDaysTo( DateList & );

    /** sets the actual to be displayed selection in the day matrix starting from
     *  start and ending with end. Theview must be manually updated by calling
     *  repaint. (?)
     */
    void setSelectedDaysFrom( const TQDate &start, const TQDate &end );

    /**
      Clear all selections.
    */
    void clearSelection();

    /** Is today visible in the view? Keep this in sync with
    * the values today (below) can take.
    */
    bool isTodayVisible() const { return mToday >= 0; }

    /** If today is visible, then we can find out if today is
    * near the beginning or the end of the month.
    * This is dependent on today remaining the index
    * in the array of visible dates and going from
    * top left (0) to bottom right (41).
    */
    bool isBeginningOfMonth() const { return mToday <= 8; }
    bool isEndOfMonth() const { return mToday >= 27; }

    /* reimplmented from KCal::Calendar::Observer */
    void calendarIncidenceAdded( Incidence *incidence );
    void calendarIncidenceChanged( Incidence *incidence );
    void calendarIncidenceDeleted( Incidence *incidence );

    void setUpdateNeeded();

  public slots:
    /** Recalculates all the flags of the days in the matrix like holidays or events
     *  on a day (Actually calls above method with the actual startdate).
     */
    void updateView();

    /**
    * Calculate which square in the matrix should be
    * hilighted to indicate it's today.
    */
    void recalculateToday();

    /**
     * Handle resource changes.
     */
    void resourcesChanged();

  signals:
    /** emitted if the user selects a block of days with the mouse by dragging a rectangle
     *  inside the matrix
     *
     *  @param daylist list of days that have been selected by the user
     */
    void selected( const KCal::DateList &daylist );

    /** emitted if the user has dropped an incidence (event or todo) inside the matrix
     *
     *  @param incidence the dropped calendar incidence
     *  @param dt TQDate that has been selected
     */
    void incidenceDropped( Incidence *incidence, const TQDate &dt );
    /** emitted if the user has dropped an event inside the matrix and chose to move it instead of copy
     *
     *  @param oldincidence the new calendar incidence
     *  @param dt TQDate that has been selected
     */
    void incidenceDroppedMove( Incidence *oldincidence, const TQDate &dt );

  protected:
    void paintEvent( TQPaintEvent *ev );

    void mousePressEvent( TQMouseEvent *e );

    void mouseReleaseEvent( TQMouseEvent *e );

    void mouseMoveEvent( TQMouseEvent *e );

    void dragEnterEvent( TQDragEnterEvent * );

    void dragMoveEvent( TQDragMoveEvent * );

    void dragLeaveEvent( TQDragLeaveEvent * );

    void dropEvent( TQDropEvent * );

    void resizeEvent( TQResizeEvent * );

  private:
    /** returns the index of the day located at the matrix's widget (x,y) position.
     *
     *  @param x horizontal coordinate
     *  @param y vertical coordinate
     */
    int getDayIndexFrom( int x, int y );

    /** calculates a "shaded" color from the supplied color object.
     *  (Copied from Cornelius's kdpdatebutton.cpp)
     *
     *  @param color source based on which a shaded color should be calculated.
     */
    TQColor getShadedColor( const TQColor &color );

    /** number of days to be displayed. For now there is no support for any other number then 42.
        so change it at your own risk :o) */
    static const int NUMDAYS;

    /** calendar instance to be queried for holidays, events, ... */
    Calendar  *mCalendar;

    /** starting date of the matrix */
    TQDate     mStartDate;

    /** array of day labels to optimeize drawing performance. */
    TQString   *mDayLabels;

    /** array of days displayed to reduce memory consumption by
        subsequently calling TQDate::addDays(). */
    TQDate     *mDays;

    /** array of storing the number of events on a given day.
      *  used for drawing a bold font if there is at least one event on that day.
      */
    int      *mEvents;

    /** stores holiday names of the days shown in the matrix. */
    TQMap<int,TQString>  mHolidays;

    /** index of today or -1 if today is not visible in the matrix. */
    int       mToday;

    /** index of day where dragged selection was initiated.
        used to detect "negative" timely selections */
    int       mSelInit;

    /** if mSelStart has this value it indicates that there is no
        actual selection in the matrix. */
    static const int NOSELECTION;

    /** index of first selected day. */
    int       mSelStart;

    /** index of last selected day. */
    int       mSelEnd;

    /** dynamic tooltip to handle mouse dependent tips for each day in the matrix. */
    DynamicTip* mToolTip;

    /** default width of the frame drawn around today if it is visible in the matrix. */
    int       mTodayMarginWidth;

    /** stores actual size of each day in the widget so that I don't need to ask this data
     *  on every repaint.
     */
    TQRect     mDaySize;

    /**
     * Indicate pending calendar changes.
     */
    bool mPendingChanges;
};

#endif