korganizer

datenavigatorcontainer.cpp
1/*
2 This file is part of KOrganizer.
3
4 Copyright (c) 2001,2002,2003 Cornelius Schumacher <schumacher@kde.org>
5 Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
21 As a special exception, permission is given to link this program
22 with any edition of TQt, and distribute the resulting executable,
23 without including the source code for TQt in the source distribution.
24*/
25
26#include <kdebug.h>
27#include <tdelocale.h>
28
29#include "koglobals.h"
30#include "navigatorbar.h"
31#include "kdatenavigator.h"
32#include "kodaymatrix.h"
33
34#include <kcalendarsystem.h>
35#include <kdialog.h>
36
37#include "datenavigatorcontainer.h"
38
39#include <tqwhatsthis.h>
40#include <tqtimer.h>
41
42DateNavigatorContainer::DateNavigatorContainer( TQWidget *parent,
43 const char *name )
44 : TQFrame( parent, name ), mCalendar( 0 ),
45 mHorizontalCount( 1 ), mVerticalCount( 1 )
46{
47 mExtraViews.setAutoDelete( true );
48 setFrameStyle( TQFrame::Sunken | TQFrame::StyledPanel );
49
50 mNavigatorView = new KDateNavigator( this, name );
51 TQWhatsThis::add( mNavigatorView,
52 i18n( "<qt><p>Select the dates you want to "
53 "display in KOrganizer's main view here. Hold down the "
54 "mouse button to select more than one day.</p>"
55 "<p>Press the top buttons to browse to the next "
56 "/ previous months or years.</p>"
57 "<p>Each line shows a week. The number in the left "
58 "column is the number of the week in the year. "
59 "Press it to select the whole week.</p>"
60 "</qt>" ) );
61
62 connectNavigatorView( mNavigatorView );
63}
64
65DateNavigatorContainer::~DateNavigatorContainer()
66{
67}
68
69void DateNavigatorContainer::connectNavigatorView( KDateNavigator *v )
70{
71 connect( v, TQ_SIGNAL( datesSelected( const KCal::DateList & ) ),
72 TQ_SIGNAL( datesSelected( const KCal::DateList & ) ) );
73 connect( v, TQ_SIGNAL( incidenceDropped( Incidence *, const TQDate & ) ),
74 TQ_SIGNAL( incidenceDropped( Incidence *, const TQDate & ) ) );
75 connect( v, TQ_SIGNAL( incidenceDroppedMove( Incidence *, const TQDate & ) ),
76 TQ_SIGNAL( incidenceDroppedMove( Incidence *, const TQDate & ) ) );
77 connect( v, TQ_SIGNAL( weekClicked( const TQDate & ) ),
78 TQ_SIGNAL( weekClicked( const TQDate & ) ) );
79
80 connect( v, TQ_SIGNAL( goPrevious() ), TQ_SIGNAL( goPrevious() ) );
81 connect( v, TQ_SIGNAL( goNext() ), TQ_SIGNAL( goNext() ) );
82
83 connect( v, TQ_SIGNAL( nextYearClicked() ), TQ_SIGNAL( nextYearClicked() ) );
84 connect( v, TQ_SIGNAL( prevYearClicked() ), TQ_SIGNAL( prevYearClicked() ) );
85
86 connect( v, TQ_SIGNAL( prevMonthClicked() ), this, TQ_SLOT( goPrevMonth() ) );
87 connect( v, TQ_SIGNAL( nextMonthClicked() ), this, TQ_SLOT( goNextMonth() ) );
88
89 connect( v, TQ_SIGNAL( monthSelected( int ) ), TQ_SIGNAL( monthSelected( int ) ) );
90 connect( v, TQ_SIGNAL( yearSelected( int ) ), TQ_SIGNAL( yearSelected( int ) ) );
91}
92
93void DateNavigatorContainer::setCalendar( Calendar *cal )
94{
95 mCalendar = cal;
96 mNavigatorView->setCalendar( cal );
97 KDateNavigator *n;
98 for( n = mExtraViews.first(); n; n = mExtraViews.next() ) {
99 n->setCalendar( cal );
100 }
101}
102
103// TODO_Recurrence: let the navigators update just once, and tell them that
104// if data has changed or just the selection (because then the list of dayss
105// with events doesn't have to be updated if the month stayed the same
106void DateNavigatorContainer::updateDayMatrix()
107{
108 mNavigatorView->updateDayMatrix();
109 KDateNavigator *n;
110 for( n = mExtraViews.first(); n; n = mExtraViews.next() ) {
111 n->updateDayMatrix();
112 }
113}
114
115void DateNavigatorContainer::updateToday()
116{
117 mNavigatorView->updateToday();
118 KDateNavigator *n;
119 for( n = mExtraViews.first(); n; n = mExtraViews.next() ) {
120 n->updateToday();
121 }
122}
123
124void DateNavigatorContainer::setUpdateNeeded()
125{
126 mNavigatorView->setUpdateNeeded();
127 KDateNavigator *n;
128 for ( n = mExtraViews.first(); n; n = mExtraViews.next() ) {
129 n->setUpdateNeeded();
130 }
131}
132
133void DateNavigatorContainer::updateView()
134{
135 mNavigatorView->updateView();
136 KDateNavigator *n;
137 for ( n = mExtraViews.first(); n; n = mExtraViews.next() ) {
138 n->setUpdateNeeded();
139 }
140}
141
142void DateNavigatorContainer::updateConfig()
143{
144 mNavigatorView->updateConfig();
145 KDateNavigator *n;
146 for( n = mExtraViews.first(); n; n = mExtraViews.next() ) {
147 n->updateConfig();
148 }
149}
150
151void DateNavigatorContainer::selectDates( const DateList &dateList, const TQDate &preferredMonth )
152{
153 if ( !dateList.isEmpty() ) {
154 TQDate start( dateList.first() );
155 TQDate end( dateList.last() );
156 TQDate navfirst( mNavigatorView->startDate() );
157 TQDate navsecond; // start of the second shown month if existant
158 TQDate navlast;
159 if ( !mExtraViews.isEmpty() ) {
160 navlast = mExtraViews.last()->endDate();
161 navsecond = mExtraViews.first()->startDate();
162 } else {
163 navlast = mNavigatorView->endDate();
164 navsecond = navfirst;
165 }
166
167 const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
168
169 // If the datelist crosses months we won't know which month to show
170 // so we read what's in preferredMonth
171 const bool changingMonth = ( preferredMonth.isValid() &&
172 calSys->month( mNavigatorView->month() ) != calSys->month( preferredMonth ) );
173
174 if ( start < navfirst // <- start should always be visible
175 // end is not visible and we have a spare month at the beginning:
176 || ( end > navlast && start >= navsecond )
177 || changingMonth ) {
178
179 if ( preferredMonth.isValid() ) {
180 setBaseDates( preferredMonth );
181 } else {
182 setBaseDates( start );
183 }
184 }
185
186 mNavigatorView->selectDates( dateList );
187 KDateNavigator *n = mExtraViews.first();
188 while ( n ) {
189 n->selectDates( dateList );
190 n = mExtraViews.next();
191 }
192 }
193}
194
195void DateNavigatorContainer::setBaseDates( const TQDate &start )
196{
197 TQDate baseDate = start;
198 mNavigatorView->setBaseDate( baseDate );
199 for( KDateNavigator *n = mExtraViews.first(); n; n = mExtraViews.next() ) {
200 baseDate = KOGlobals::self()->calendarSystem()->addMonths( baseDate, 1 );
201 n->setBaseDate( baseDate );
202 }
203}
204
205void DateNavigatorContainer::resizeEvent( TQResizeEvent * )
206{
207#if 0
208 kdDebug(5850) << "DateNavigatorContainer::resizeEvent()" << endl;
209 kdDebug(5850) << " CURRENT SIZE: " << size() << endl;
210 kdDebug(5850) << " MINIMUM SIZEHINT: " << minimumSizeHint() << endl;
211 kdDebug(5850) << " SIZEHINT: " << sizeHint() << endl;
212 kdDebug(5850) << " MINIMUM SIZE: " << minimumSize() << endl;
213#endif
214 TQTimer::singleShot( 0, this, TQ_SLOT( resizeAllContents() ) );
215}
216
217void DateNavigatorContainer::resizeAllContents()
218{
219 TQSize minSize = mNavigatorView->minimumSizeHint();
220
221// kdDebug(5850) << " NAVIGATORVIEW minimumSizeHint: " << minSize << endl;
222
223 int margin = KDialog::spacingHint();
224 int verticalCount = ( size().height() - margin*2 ) / minSize.height();
225 int horizontalCount = ( size().width() - margin*2 ) / minSize.width();
226
227 if ( horizontalCount != mHorizontalCount ||
228 verticalCount != mVerticalCount ) {
229 uint count = horizontalCount * verticalCount;
230 if ( count == 0 ) {
231 return;
232 }
233
234 while ( count > ( mExtraViews.count() + 1 ) ) {
235 KDateNavigator *n = new KDateNavigator( this );
236 mExtraViews.append( n );
237 n->setCalendar( mCalendar );
238 connectNavigatorView( n );
239 }
240
241 while ( count < ( mExtraViews.count() + 1 ) ) {
242 mExtraViews.removeLast();
243 }
244
245 mHorizontalCount = horizontalCount;
246 mVerticalCount = verticalCount;
247 setBaseDates( mNavigatorView->selectedDates().first() );
248 selectDates( mNavigatorView->selectedDates() );
249 for( KDateNavigator *n = mExtraViews.first(); n; n = mExtraViews.next() ) {
250 n->show();
251 }
252 }
253
254 int height = (size().height() - margin*2) / verticalCount;
255 int width = (size().width() - margin*2) / horizontalCount;
256
257 NavigatorBar *bar = mNavigatorView->navigatorBar();
258 if ( horizontalCount > 1 ) {
259 bar->showButtons( true, false );
260 } else {
261 bar->showButtons( true, true );
262 }
263
264 mNavigatorView->setGeometry(
265 ( ( (KOGlobals::self()->reverseLayout())?(horizontalCount-1):0) * width ) + margin,
266 margin, width, height );
267
268 for( uint i = 0; i < mExtraViews.count(); ++i ) {
269 int x = ( i + 1 ) % horizontalCount;
270 int y = ( i + 1 ) / horizontalCount;
271
272 KDateNavigator *view = mExtraViews.at( i );
273 bar = view->navigatorBar();
274 if ( y > 0 ) {
275 bar->showButtons( false, false );
276 } else {
277 if ( x + 1 == horizontalCount ) {
278 bar->showButtons( false, true );
279 } else {
280 bar->showButtons( false, false );
281 }
282 }
283 view->setGeometry(
284 ( ( (KOGlobals::self()->reverseLayout())?(horizontalCount-1-x):x) * width ) + margin,
285 ( y * height ) + margin, width, height );
286 }
287}
288
289TQSize DateNavigatorContainer::minimumSizeHint() const
290{
291 int margin = KDialog::spacingHint() * 2;
292 return mNavigatorView->minimumSizeHint() + TQSize( margin, margin );
293}
294
295TQSize DateNavigatorContainer::sizeHint() const
296{
297 int margin = KDialog::spacingHint() * 2;
298 return mNavigatorView->sizeHint() + TQSize( margin, margin );
299}
300
301void DateNavigatorContainer::goNextMonth()
302{
303 const TQPair<TQDate,TQDate> p = dateLimits( 1 );
304
305 emit nextMonthClicked( mNavigatorView->month(),
306 p.first,
307 p.second);
308}
309
310void DateNavigatorContainer::goPrevMonth()
311{
312 const TQPair<TQDate,TQDate> p = dateLimits( -1 );
313
314 emit prevMonthClicked( mNavigatorView->month(),
315 p.first,
316 p.second );
317}
318
319TQPair<TQDate,TQDate> DateNavigatorContainer::dateLimits( int offset )
320{
321 const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
322 TQDate firstMonth, lastMonth;
323 if ( mExtraViews.isEmpty() ) {
324 lastMonth = mNavigatorView->month();
325 } else {
326 lastMonth = mExtraViews.last()->month();
327 }
328
329 firstMonth = calSys->addMonths( mNavigatorView->month(), offset );
330 lastMonth = calSys->addMonths( lastMonth, offset );
331
332 TQPair<TQDate,TQDate> firstMonthBoundary = KODayMatrix::matrixLimits( firstMonth );
333 TQPair<TQDate,TQDate> lastMonthBoundary = KODayMatrix::matrixLimits( lastMonth );
334
335 return qMakePair( firstMonthBoundary.first, lastMonthBoundary.second );
336}
337
338#include "datenavigatorcontainer.moc"
static TQPair< TQDate, TQDate > matrixLimits(const TQDate &month)
returns the first and last date of the 6*7 matrix that displays month
bool view(TQWidget *parent, Attachment *attachment)