summaryrefslogtreecommitdiffstats
path: root/korganizer/printing/calprintpluginbase.h
blob: 9312d0042c6cf73de42328fa32f221caa7125895 (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
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
/*
    This file is part of KOrganizer.

    Copyright (c) 1998 Preston Brown <pbrown@kde.org>
    Copyright (c) 2003 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 Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/
#ifndef CALPRINTPLUGINBASE_H
#define CALPRINTPLUGINBASE_H
// #define KORG_NOPRINTER

#ifndef KORG_NOPRINTER

#include <qdatetime.h>
#include <kprinter.h>
#include <kdepimmacros.h>
#include <libkcal/calendar.h>
#include <libkcal/event.h>
#include <libkcal/todo.h>
#include "korganizer/printplugin.h"
#include "korganizer/corehelper.h"


class PrintCellItem;

class QWidget;

using namespace KCal;


#define PORTRAIT_HEADER_HEIGHT 72   // header height, for portrait orientation
#define LANDSCAPE_HEADER_HEIGHT 54  // header height, for landscape orientation
#define SUBHEADER_HEIGHT 20         // subheader height, for all orientations
#define MARGIN_SIZE 36              // margins, for all orientations
#define PADDING_SIZE 7              // padding between the various top-level boxes
#define BOX_BORDER_WIDTH 2          // width of the border of all top-level boxes
#define EVENT_BORDER_WIDTH 0        // with of the border of all incidence boxes

#define TIMELINE_WIDTH 50           // width of timeline (day and timetable)

/**
  Base class for KOrganizer printing classes. Each sub class represents one
  calendar print format.
*/
class KDE_EXPORT CalPrintPluginBase : public KOrg::PrintPlugin
{
  public:
    enum DisplayFlags {
      Text=0x0001,
      TimeBoxes=0x0002
    };

  public:
    /**
      Constructor
    */
    CalPrintPluginBase();
    virtual ~CalPrintPluginBase();

    /**
      Returns widget for configuring the print format.
    */
    virtual QWidget *createConfigWidget( QWidget * );

    /**
      Actually do the printing.

      \param p QPainter the print result is painted to
      \param width Width of printable area
      \param height Height of printable area
    */
    virtual void print( QPainter &p, int width, int height ) = 0;
    /**
      Start printing.
    */
    virtual void doPrint( KPrinter *printer );

    /**
      Load print format configuration from config file.
    */
    virtual void loadConfig() = 0;
    /**
      Write print format configuration to config file.
    */
    virtual void saveConfig() = 0;

    /**
      Load complete config. This also calls loadConfig() of the derived class.
    */
    void doLoadConfig();
    /**
      Save complete config. This also calls saveConfig() of the derived class.
    */
    void doSaveConfig();

  /** HELPER FUNCTIONS */
  public:
    void setKOrgCoreHelper( KOrg::CoreHelper*helper );
    bool useColors() const;
    void setUseColors( bool useColors );
    
    /** Helper functions to hide the KOrg::CoreHelper */
    QColor categoryBgColor( Incidence *incidence );
    QColor textColor( const QColor &color );
    QTime dayStart();
    bool isWorkingDay( const QDate &dt );
    QString holidayString( const QDate &dt );
    Event *holiday( const QDate &dt );
    
    /**
      Determines the column of the given weekday ( 1=Monday, 7=Sunday ), taking the
      start of the week setting into account as given in kcontrol.
      \param weekday Index of the weekday
    */
    static int weekdayColumn( int weekday );
    void setCategoryColors( QPainter &p, Incidence *incidence );

    KPrinter::Orientation orientation() const;

    /** Returns the height of the page header. If the height was explicitly
        set using setHeaderHeight, that value is returned, otherwise a 
        default value based on the printer orientation.
        \return height of the page header of the printout
    */
    int headerHeight() const;
    void setHeaderHeight( const int height );

    int subHeaderHeight() const;
    void setSubHeaderHeight( const int height );

    int margin() const;
    void setMargin( const int margin );
    
    int padding() const;
    void setPadding( const int margin );
    
    int borderWidth() const;
    void setBorderWidth( const int border );

    const KCalendarSystem *calendarSystem() const;
    void setCalendarSystem( const KCalendarSystem *calsys );


  /*****************************************************************
   **               PRINTING HELPER FUNCTIONS                     **
   *****************************************************************/
  public: 
    /**
      Draw a box with given width at the given coordinates.
      \param p The printer to be used
      \param linewidth The border width of the box
      \param rect The rectangle of the box
    */
    static void drawBox( QPainter &p, int linewidth, const QRect &rect );
    /**
      Draw a shaded box with given width at the given coordinates.
      \param p The printer to be used
      \param linewidth The border width of the box
      \param brush The brush to fill the box
      \param rect The rectangle of the box
    */
    static void drawShadedBox( QPainter &p, int linewidth, const QBrush &brush, const QRect &rect );
  
    /**
      Print the given string (event summary) in the given rectangle. Margins
      and justification (centered or not) are automatically adjusted.
      \param p QPainter of the printout
      \param box Coordinates of the surrounding event box
      \param str The text to be printed in the box
    */
    void printEventString( QPainter &p, const QRect &box, const QString &str, int flags = -1 );

    /**
      Print the box for the given event with the given string.
      \param p QPainer of the printout
      \param box Coordinates of the event's box
      \param incidence The incidence (if available), from which the category
                       color will be deduced, if applicable.
      \param str The string to print inside the box
    */
    void showEventBox( QPainter &p, const QRect &box, Incidence *incidence, const QString &str, int flags = -1 );
    
    /** 
      Draw a subheader box with a shaded background and the given string
      \param p QPainter of the printout
      \param str Text to be printed inside the box
      \param box Coordinates of the box
    */
    void drawSubHeaderBox(QPainter &p, const QString &str, const QRect &box );
    
    /**
      Draw an event box with vertical text.
      \param p QPainter of the printout
      \param box Coordinates of the box
      \param str ext to be printed inside the box
    */
    void drawVerticalBox( QPainter &p, const QRect &box, const QString &str );
    
    /**
      Draw a component box with a heading (printed in bold). 
      \param p QPainter of the printout
      \param box Coordinates of the box
      \param caption Caption string to be printed inside the box
      \param contents Normal text contents of the box. If contents.isNull(),
                      then no text will be printed, only the caption.
      \param sameLine Whether the contents should start on the same line as
                      the caption (the space below the caption text will be
                      used as indentation in the subsequent lines) or on the 
                      next line (no indentation of the contents)
      \param expand Whether to expand the box vertically to fit the
                    whole text in it.
      \return The bottom of the printed box. If expand==true, the bottom of
              the drawn box is returned, if expand==false, the vertical
              end of the printed contents inside the box is returned.
              If you want to print some custom graphics or text below
              the contents, use the return value as the top-value of your
              custom contents in that case.
    */
    int drawBoxWithCaption( QPainter &p, const QRect &box, const QString &caption,
                            const QString &contents, 
                            bool sameLine, bool expand, const QFont &captionFont, const QFont &textFont );

    /**
      Draw the gray header bar of the printout to the QPainter.
      It prints the given text and optionally one or two small
      month views, as specified by the two QDate. The printed
      text can also contain a line feed.
      If month2 is invalid, only the month that contains month1
      is printed.
      E.g. the filofax week view draws just the current month,
      while the month view draws the previous and the next month.
      \param p QPainter of the printout
      \param title The string printed as the title of the page
                   (e.g. the date, date range or todo list title)
      \param month1 Date specifying the month for the left one of
                    the small month views in the title bar. If left
                    empty, only month2 will be printed (or none,
                    it that is invalid as well).
      \param month2 Date specifying the month for the right one of
                    the small month views in the title bar. If left
                    empty, only month1 will be printed (or none,
                    it that is invalid as well).
      \param box coordinates of the title bar
      \param expand Whether to expand the box vertically to fit the
                    whole title in it.
      \return The bottom of the printed box. If expand==false, this 
              is box.bottom, otherwise it is larger than box.bottom
              and matches the y-coordinate of the surrounding rectangle.
    */
    int drawHeader( QPainter &p, QString title,
                     const QDate &month1, const QDate &month2,
                     const QRect &box, bool expand = false );
    /**
      Draw a small calendar with the days of a month into the given area.
      Used for example in the title bar of the sheet.
      \param p QPainter of the printout
      \param qd Arbitrary Date within the month to be printed.
      \param box coordinates of the small calendar
    */
    void drawSmallMonth( QPainter &p, const QDate &qd, const QRect &box );

    /**
      Draw a horizontal bar with the weekday names of the given date range
      in the given area of the painter.
      This is used for the weekday-bar on top of the timetable view and the month view.
      \param p QPainter of the printout
      \param fromDate First date of the printed dates
      \param toDate Last date of the printed dates
      \param box coordinates of the box for the days of the week
    */
    void drawDaysOfWeek( QPainter &p,
                         const QDate &fromDate, const QDate &toDate,
                         const QRect &box );
    /**
      Draw a single weekday name in a box inside the given area of the painter.
      This is called in a loop by drawDaysOfWeek.
      \param p QPainter of the printout
      \param qd Date of the printed day
      \param box coordinates of the weekbox
    */
    void drawDaysOfWeekBox( QPainter &p, const QDate &qd, const QRect &box );
    /**
      Draw a (vertical) time scale from time fromTime to toTime inside the given area of the painter.
      Every hour will have a one-pixel line over the whole width, every
      half-hour the line will only span the left half of the width.
      This is used in the day and timetable print styles
      \param p QPainter of the printout
      \param fromTime Start time of the time range to display
      \param toTime End time of the time range to display
      \param box coordinates of the timeline
    */
    void drawTimeLine( QPainter &p,
                       const QTime &fromTime, const QTime &toTime,
                       const QRect &box );
  
    /**
      Draw the all-day box for the agenda print view (the box on top which
      doesn't have a time on the time scale associated). If expandable is set,
      height is the cell height of a single cell, and the returned height will
      be the total height used for the all-day events. If !expandable, only one
      cell will be used, and multiple events are concatenated using ", ".
      \param p QPainter of the printout
      \param eventList The list of all-day events that are supposed to be printed
             inside this box
      \param qd The date of the currently printed day
      \param expandable If true, height is the height of one single cell, the printout
             will use as many cells as events in the list and return the total height
             needed for all of them. If false, height specifies the total height
             allowed for all events, and the events are displayed in one cell,
             with their summaries concatenated by ", ".
      \param box coordinates of the all day box.
      \return The height used for the all-day box.
    */
    int drawAllDayBox( QPainter &p, Event::List &eventList,
                        const QDate &qd, bool expandable,
                        const QRect &box );
    /**
      Draw the agenda box for the day print style (the box showing all events of that day).
      Also draws a grid with half-hour spacing of the grid lines.
      \param p QPainter of the printout
      \param eventList The list of the events that are supposed to be printed
             inside this box
      \param qd The date of the currently printed day
      \param expandable If true, the start and end times are adjusted to include
             the whole range of all events of that day, not just of the given time range.
             The height of the box will not be affected by this (but the height
             of one hour will be scaled down so that the whole range fits into
             the box. fromTime and toTime receive the actual time range printed
             by this function).
      \param fromTime Start of the time range to be printed. Might be adjusted
                      to include all events if expandable==true
      \param toTime End of the time range to be printed. Might be adjusted
                   to include all events if expandable==true
      \param box coordinates of the agenda day box.
    */
    void drawAgendaDayBox( QPainter &p, Event::List &eventList,
                           const QDate &qd, bool expandable,
                           QTime &fromTime, QTime &toTime,
                           const QRect &box );

    void drawAgendaItem( PrintCellItem *item, QPainter &p,
                         const QDateTime &startPrintDate,
                         const QDateTime &endPrintDate,
                         float minlen, const QRect &box );
  
    /**
      Draw the box containing a list of all events of the given day (with their times,
      of course). Used in the Filofax and the month print style.
      \param p QPainter of the printout
      \param qd The date of the currently printed day. All events of the calendar
                that appear on that day will be printed.
      \param box coordinates of the day box.
      \param fullDate Whether the title bar of the box should contain the full
                      date string or just a short.
      \param printRecurDaily Whether daily recurring incidences should be printed.
      \param printRecurWeekly Whether weekly recurring incidences should be printed.
    */
    void drawDayBox( QPainter &p, const QDate &qd,
                     const QRect &box,
                     bool fullDate = false, bool printRecurDaily = true,
                     bool printRecurWeekly = true );
    /**
      Draw the week (filofax) table of the week containing the date qd. The first
      three days of the week will be shown in the first column (using drawDayBox),
      the remaining four in the second column, where the last two days of the week
      (typically Saturday and Sunday) only get half the height of the other day boxes.
      \param p QPainter of the printout
      \param qd Arbitrary date within the week to be printed.
      \param box coordinates of the week box.
    */
    void drawWeek( QPainter &p, const QDate &qd,
                   const QRect &box );
    /**
      Draw the timetable view of the given time range from fromDate to toDate.
      On the left side the time scale is printed (using drawTimeLine), then each
      day gets one column (printed using drawAgendaDayBox),
      and the events are displayed as boxes (like in korganizer's day/week view).
      The first cell of each column contains the all-day events (using
      drawAllDayBox with expandable=false).
      The given time range cannot be expanded to include all events.
      \param p QPainter of the printout
      \param fromDate First day to be included in the page
      \param toDate Last day to be included in the page
      \param fromTime Start time of the displayed time range
      \param toTime End time of the displayed time range
      \param box coordinates of the time table.
    */
    void drawTimeTable( QPainter &p, const QDate &fromDate, const QDate &toDate,
                        QTime &fromTime, QTime &toTime,
                        const QRect &box );

    /**
      Draw the month table of the month containing the date qd. Each day gets one
      box (using drawDayBox) that contains a list of all events on that day. They are arranged
      in a matrix, with the first column being the first day of the
      week (so it might display some days of the previous and the next month).
      Above the matrix there is a bar showing the weekdays (drawn using drawDaysOfWeek).
      \param p QPainter of the printout
      \param qd Arbitrary date within the month to be printed.
      \param recurDaily Whether daily recurring incidences should be printed.
      \param recurWeekly Whether weekly recurring incidences should be printed.
      \param weeknumbers Whether the week numbers are printed left of each row of the matrix
      \param box coordinates of the month.
    */
    void drawMonthTable( QPainter &p, const QDate &qd, bool weeknumbers,
                    bool recurDaily, bool recurWeekly,
                    const QRect &box );
    /**
      Draw a vertical representation of the month containing the date dt. Each
      day gets one line.
      \param p QPainter of the printout
      \param dt Arbitrary date within the month to be printed
      \param box coordinates of the box reserved for the month
      \param maxdays Days to print. If a value of -1 is given, the number of days
                     is deduced from the month. If maxdays is larger than the 
                     number of days in the month, the remaining boxes are 
                     shaded to indicate they are not days of the month.
      \param subDailyFlags Bitfield consisting of DisplayFlags flags to determine
                           how events that do not cross midnight should be printed.
      \param holidaysFlags Bitfield consisting of DisplayFlags flags to determine
                           how holidays should be printed.
    */
    void drawMonth( QPainter &p, const QDate &dt, const QRect &box, int maxdays = -1, int subDailyFlags = TimeBoxes, int holidaysFlags = Text );

    /**
      Internal class representing the start of a todo.
    */
    class TodoParentStart;

    /**
      Draws single to-do and its (intented) sub-to-dos, optionally connects them by a tree-like line, and optionally shows due date, summary, description and priority.
      \param count The number of the currently printed to-do (count will be incremented for each to-do drawn)
      \param todo The to-do to be printed. It's sub-to-dos are recursively drawn, so drawTodo should only be called on the to-dos of the highest level.
      \param p QPainter of the printout
      \param sortField Specifies on which attribute of the todo you want to sort.
      \param sortDir Specifies if you want to sort ascending or descending.
      \param connectSubTodos Whether sub-to-dos shall be connected with their parent by a line (tree-like).
      \param strikeoutCompleted Whether completed to-dos should be printed with strike-out summaries.
      \param desc Whether to print the whole description of the to-do (the summary is always printed).
      \param posPriority x-coordinate where the priority is supposed to be printed. If <0, no priority will be printed.
      \param posSummary x-coordinate where the summary of the to-do is supposed to be printed.
      \param posDueDt x-coordinate where the due date is supposed to the be printed. If <0, no due date will be printed.
      \param posPercentComplete x-coordinate where the percentage complete is supposed to be printed. If <0, percentage complete will not be printed.
      \param level Level of the current to-do in the to-do hierarchy (0 means highest level of printed to-dos, 1 are their sub-to-dos, etc.)
      \param x x-coordinate of the upper left coordinate of the first to-do.
      \param y y-coordinate of the upper left coordinate of the first to-do.
      \param width width of the whole to-do list.
      \param pageHeight Total height allowed for the to-do list on a page. If an to-do would be below that line, a new page is started.
      \param todoList Contains a list of sub-todos for the specified @p todo .
      \param r Internal (used when printing sub-to-dos to give information about its parent)
    */
    void drawTodo( int &count, Todo *todo, QPainter &p,
                   TodoSortField sortField, SortDirection sortDir,
                   bool connectSubTodos, bool strikeoutCompleted, bool desc,
                   int posPriority, int posSummary, int posDueDt,
                   int posPercentComplete, int level, int x, int &y,
                   int width, int pageHeight,
                   const Todo::List &todoList, TodoParentStart *r = 0 );

    /**
      Draws single journal item.
      \param journal The item to be printed.
      \param p QPainter of the printout
      \param x x-coordinate of the upper left coordinate of the first item
      \param y y-coordinate of the upper left coordinate of the first item
      \param width width of the whole list
      \param pageHeight Total height allowed for the list on a page. If an item
                   would be below that line, a new page is started.
    */
    void drawJournal( Journal * journal, QPainter &p, int x, int &y,
                      int width, int pageHeight );
    void drawJournalField( QPainter &p, QString field, QString text,
                           int x, int &y, int width, int pageHeight );

    void drawSplitHeaderRight( QPainter &p, const QDate &fd, const QDate &td,
                               const QDate &cd, int width, int height );


  protected:
    void drawIncidence( QPainter &p, const QRect &dayBox, const QString &time,
                        const QString &summary, int &textY );

  protected:
    bool mUseColors;
    int mHeaderHeight;
    int mSubHeaderHeight;
    int mMargin;
    int mPadding;
    int mBorder;
    const KCalendarSystem *mCalSys;

  public:
};

#endif

#endif