1 | /* This file is part of the KDE project |
2 | Copyright (C) 2007, 2012 Dag Andersen <danders@get2net> |
3 | |
4 | This library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Library General Public |
6 | License as published by the Free Software Foundation; either |
7 | version 2 of the License, or (at your option) any later version. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Library General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Library General Public License |
15 | along with this library; see the file COPYING.LIB. If not, write to |
16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 | * Boston, MA 02110-1301, USA. |
18 | */ |
19 | |
20 | #include "kptcalendarmodel.h" |
21 | |
22 | #include "kptglobal.h" |
23 | #include "kptcommonstrings.h" |
24 | #include "kptcommand.h" |
25 | #include "kptitemmodelbase.h" |
26 | #include "kptcalendar.h" |
27 | #include "kptduration.h" |
28 | #include "kptnode.h" |
29 | #include "kptproject.h" |
30 | #include "kpttask.h" |
31 | #include "kptdatetime.h" |
32 | #include "kcalendar/kdatetable.h" |
33 | #include "kptdebug.h" |
34 | |
35 | #include <QMimeData> |
36 | #include <QList> |
37 | #include <QObject> |
38 | #include <QPainter> |
39 | |
40 | #include <kglobal.h> |
41 | #include <klocale.h> |
42 | #include <kcalendarsystem.h> |
43 | #include <ksystemtimezone.h> |
44 | #include <ktimezone.h> |
45 | #include <kdeversion.h> |
46 | |
47 | |
48 | namespace KPlato |
49 | { |
50 | |
51 | |
52 | //----------------------------------------- |
53 | CalendarDayItemModelBase::CalendarDayItemModelBase( QObject *parent ) |
54 | : ItemModelBase( parent ), |
55 | m_calendar( 0 ) |
56 | { |
57 | } |
58 | |
59 | CalendarDayItemModelBase::~CalendarDayItemModelBase() |
60 | { |
61 | } |
62 | |
63 | void CalendarDayItemModelBase::slotCalendarToBeRemoved( const Calendar *calendar ) |
64 | { |
65 | if ( calendar && calendar == m_calendar ) { |
66 | setCalendar( 0 ); |
67 | } |
68 | } |
69 | |
70 | |
71 | void CalendarDayItemModelBase::setCalendar( Calendar *calendar ) |
72 | { |
73 | m_calendar = calendar; |
74 | } |
75 | |
76 | void CalendarDayItemModelBase::setProject( Project *project ) |
77 | { |
78 | setCalendar( 0 ); |
79 | if ( m_project ) { |
80 | disconnect( m_project, SIGNAL(calendarToBeRemoved(const Calendar*)), this, SLOT(slotCalendarToBeRemoved(const Calendar*)) ); |
81 | } |
82 | m_project = project; |
83 | if ( project ) { |
84 | connect( m_project, SIGNAL(calendarToBeRemoved(const Calendar*)), this, SLOT(slotCalendarToBeRemoved(const Calendar*)) ); |
85 | } |
86 | reset(); |
87 | } |
88 | |
89 | |
90 | //------------------------------------- |
91 | CalendarItemModel::CalendarItemModel( QObject *parent ) |
92 | : ItemModelBase( parent ), |
93 | m_calendar( 0 ) |
94 | { |
95 | } |
96 | |
97 | CalendarItemModel::~CalendarItemModel() |
98 | { |
99 | } |
100 | |
101 | const QMetaEnum CalendarItemModel::columnMap() const |
102 | { |
103 | return metaObject()->enumerator( metaObject()->indexOfEnumerator("Properties" ) ); |
104 | } |
105 | |
106 | void CalendarItemModel::slotCalendarToBeInserted( const Calendar *parent, int row ) |
107 | { |
108 | //kDebug(planDbg())<<(parent?parent->name():"Top level")<<","<<row; |
109 | Q_ASSERT( m_calendar == 0 ); |
110 | m_calendar = const_cast<Calendar *>(parent); |
111 | beginInsertRows( index( parent ), row, row ); |
112 | } |
113 | |
114 | void CalendarItemModel::slotCalendarInserted( const Calendar *calendar ) |
115 | { |
116 | //kDebug(planDbg())<<calendar->name(); |
117 | Q_ASSERT( calendar->parentCal() == m_calendar ); |
118 | #ifdef NDEBUG |
119 | Q_UNUSED(calendar) |
120 | #endif |
121 | |
122 | endInsertRows(); |
123 | m_calendar = 0; |
124 | } |
125 | |
126 | void CalendarItemModel::slotCalendarToBeRemoved( const Calendar *calendar ) |
127 | { |
128 | //kDebug(planDbg())<<calendar->name(); |
129 | int row = index( calendar ).row(); |
130 | beginRemoveRows( index( calendar->parentCal() ), row, row ); |
131 | } |
132 | |
133 | void CalendarItemModel::slotCalendarRemoved( const Calendar * ) |
134 | { |
135 | //kDebug(planDbg())<<calendar->name(); |
136 | endRemoveRows(); |
137 | } |
138 | |
139 | void CalendarItemModel::setProject( Project *project ) |
140 | { |
141 | if ( m_project ) { |
142 | disconnect( m_project , SIGNAL(calendarChanged(Calendar*)), this, SLOT(slotCalendarChanged(Calendar*)) ); |
143 | |
144 | disconnect( m_project, SIGNAL(calendarAdded(const Calendar*)), this, SLOT(slotCalendarInserted(const Calendar*)) ); |
145 | disconnect( m_project, SIGNAL(calendarToBeAdded(const Calendar*,int)), this, SLOT(slotCalendarToBeInserted(const Calendar*,int)) ); |
146 | |
147 | disconnect( m_project, SIGNAL(calendarRemoved(const Calendar*)), this, SLOT(slotCalendarRemoved(const Calendar*)) ); |
148 | disconnect( m_project, SIGNAL(calendarToBeRemoved(const Calendar*)), this, SLOT(slotCalendarToBeRemoved(const Calendar*)) ); |
149 | } |
150 | m_project = project; |
151 | if ( project ) { |
152 | connect( m_project, SIGNAL(calendarChanged(Calendar*)), this, SLOT(slotCalendarChanged(Calendar*)) ); |
153 | |
154 | connect( m_project, SIGNAL(calendarAdded(const Calendar*)), this, SLOT(slotCalendarInserted(const Calendar*)) ); |
155 | connect( m_project, SIGNAL(calendarToBeAdded(const Calendar*,int)), this, SLOT(slotCalendarToBeInserted(const Calendar*,int)) ); |
156 | |
157 | connect( m_project, SIGNAL(calendarRemoved(const Calendar*)), this, SLOT(slotCalendarRemoved(const Calendar*)) ); |
158 | connect( m_project, SIGNAL(calendarToBeRemoved(const Calendar*)), this, SLOT(slotCalendarToBeRemoved(const Calendar*)) ); |
159 | } |
160 | reset(); |
161 | } |
162 | |
163 | Qt::ItemFlags CalendarItemModel::flags( const QModelIndex &index ) const |
164 | { |
165 | Qt::ItemFlags flags = ItemModelBase::flags( index ); |
166 | if ( !m_readWrite ) { |
167 | return flags &= ~Qt::ItemIsEditable; |
168 | } |
169 | flags |= Qt::ItemIsDropEnabled; |
170 | if ( !index.isValid() ) { |
171 | return flags; |
172 | } |
173 | flags |= Qt::ItemIsDragEnabled; |
174 | if ( calendar ( index ) ) { |
175 | switch ( index.column() ) { |
176 | case Name: |
177 | flags |= ( Qt::ItemIsEditable | Qt::ItemIsUserCheckable ); |
178 | break; |
179 | case TimeZone: |
180 | if ( parent( index ).isValid() ) { |
181 | flags &= ~Qt::ItemIsEditable; |
182 | } else { |
183 | flags |= Qt::ItemIsEditable; |
184 | } |
185 | break; |
186 | default: |
187 | flags |= Qt::ItemIsEditable; |
188 | break; |
189 | } |
190 | } |
191 | return flags; |
192 | } |
193 | |
194 | |
195 | QModelIndex CalendarItemModel::parent( const QModelIndex &index ) const |
196 | { |
197 | if ( !index.isValid() || m_project == 0 ) { |
198 | return QModelIndex(); |
199 | } |
200 | //kDebug(planDbg())<<index.internalPointer()<<":"<<index.row()<<","<<index.column(); |
201 | Calendar *a = calendar( index ); |
202 | if ( a == 0 ) { |
203 | return QModelIndex(); |
204 | } |
205 | Calendar *par = a->parentCal(); |
206 | if ( par ) { |
207 | a = par->parentCal(); |
208 | int row = -1; |
209 | if ( a ) { |
210 | row = a->indexOf( par ); |
211 | } else { |
212 | row = m_project->indexOf( par ); |
213 | } |
214 | //kDebug(planDbg())<<par->name()<<":"<<row; |
215 | return createIndex( row, 0, par ); |
216 | } |
217 | return QModelIndex(); |
218 | } |
219 | |
220 | QModelIndex CalendarItemModel::index( int row, int column, const QModelIndex &parent ) const |
221 | { |
222 | if ( m_project == 0 || column < 0 || column >= columnCount() || row < 0 ) { |
223 | return QModelIndex(); |
224 | } |
225 | Calendar *par = calendar( parent ); |
226 | if ( par == 0 ) { |
227 | if ( row < m_project->calendars().count() ) { |
228 | return createIndex( row, column, m_project->calendars().at( row ) ); |
229 | } |
230 | } else if ( row < par->calendars().count() ) { |
231 | return createIndex( row, column, par->calendars().at( row ) ); |
232 | } |
233 | return QModelIndex(); |
234 | } |
235 | |
236 | QModelIndex CalendarItemModel::index( const Calendar *calendar, int column ) const |
237 | { |
238 | if ( m_project == 0 || calendar == 0 ) { |
239 | return QModelIndex(); |
240 | } |
241 | Calendar *a = const_cast<Calendar*>(calendar); |
242 | int row = -1; |
243 | Calendar *par = a->parentCal(); |
244 | if ( par == 0 ) { |
245 | row = m_project->calendars().indexOf( a ); |
246 | } else { |
247 | row = par->indexOf( a ); |
248 | } |
249 | if ( row == -1 ) { |
250 | return QModelIndex(); |
251 | } |
252 | return createIndex( row, column, a ); |
253 | |
254 | } |
255 | |
256 | int CalendarItemModel::columnCount( const QModelIndex & ) const |
257 | { |
258 | return columnMap().keyCount(); |
259 | } |
260 | |
261 | int CalendarItemModel::rowCount( const QModelIndex &parent ) const |
262 | { |
263 | if ( m_project == 0 ) { |
264 | return 0; |
265 | } |
266 | Calendar *par = calendar( parent ); |
267 | if ( par == 0 ) { |
268 | return m_project->calendars().count(); |
269 | } |
270 | return par->calendars().count(); |
271 | } |
272 | |
273 | QVariant CalendarItemModel::name( const Calendar *a, int role ) const |
274 | { |
275 | //kDebug(planDbg())<<res->name()<<","<<role; |
276 | switch ( role ) { |
277 | case Qt::DisplayRole: |
278 | case Qt::EditRole: |
279 | return a->name(); |
280 | case Qt::ToolTipRole: |
281 | if ( a->isDefault() ) { |
282 | return i18nc( "1=calendar name" , "%1 (Default calendar)" , a->name() ); |
283 | } |
284 | return a->name(); |
285 | case Qt::StatusTipRole: |
286 | case Qt::WhatsThisRole: |
287 | return QVariant(); |
288 | case Qt::CheckStateRole: |
289 | return a->isDefault() ? Qt::Checked : Qt::Unchecked; |
290 | } |
291 | return QVariant(); |
292 | } |
293 | |
294 | bool CalendarItemModel::setName( Calendar *a, const QVariant &value, int role ) |
295 | { |
296 | switch ( role ) { |
297 | case Qt::EditRole: |
298 | if ( value.toString() != a->name() ) { |
299 | emit executeCommand( new CalendarModifyNameCmd( a, value.toString(), kundo2_i18n( "Modify calendar name" ) ) ); |
300 | return true; |
301 | } |
302 | break; |
303 | case Qt::CheckStateRole: { |
304 | switch ( value.toInt() ) { |
305 | case Qt::Unchecked: |
306 | if ( a->isDefault() ) { |
307 | emit executeCommand( new ProjectModifyDefaultCalendarCmd( m_project, 0, kundo2_i18n( "De-select as default calendar" ) ) ); |
308 | return true; |
309 | } |
310 | break; |
311 | case Qt::Checked: |
312 | if ( ! a->isDefault() ) { |
313 | emit executeCommand( new ProjectModifyDefaultCalendarCmd( m_project, a, kundo2_i18n( "Select as default calendar" ) ) ); |
314 | return true; |
315 | } |
316 | break; |
317 | default: break; |
318 | } |
319 | } |
320 | default: break; |
321 | } |
322 | return false; |
323 | } |
324 | |
325 | QVariant CalendarItemModel::timeZone( const Calendar *a, int role ) const |
326 | { |
327 | //kDebug(planDbg())<<res->name()<<","<<role; |
328 | switch ( role ) { |
329 | case Qt::DisplayRole: |
330 | case Qt::EditRole: |
331 | case Qt::ToolTipRole: |
332 | return i18n( a->timeZone().name().toUtf8() ); |
333 | case Role::EnumList: { |
334 | QStringList lst; |
335 | foreach ( const QString &s, KSystemTimeZones::timeZones()->zones().keys() ) { |
336 | lst << i18n( s.toUtf8() ); |
337 | } |
338 | lst.sort(); |
339 | return lst; |
340 | } |
341 | case Role::EnumListValue: { |
342 | QStringList lst = timeZone( a, Role::EnumList ).toStringList(); |
343 | return lst.indexOf( i18n ( a->timeZone().name().toUtf8() ) ); |
344 | } |
345 | case Qt::StatusTipRole: |
346 | case Qt::WhatsThisRole: |
347 | return QVariant(); |
348 | } |
349 | return QVariant(); |
350 | } |
351 | |
352 | bool CalendarItemModel::setTimeZone( Calendar *a, const QVariant &value, int role ) |
353 | { |
354 | switch ( role ) { |
355 | case Qt::EditRole: { |
356 | if ( timeZone( a, Role::EnumListValue ) == value.toInt() ) { |
357 | return false; |
358 | } |
359 | QStringList lst = timeZone( a, Role::EnumList ).toStringList(); |
360 | QString name = lst.value( value.toInt() ); |
361 | KTimeZone tz; |
362 | foreach ( const QString &s, KSystemTimeZones::timeZones()->zones().keys() ) { |
363 | if ( name == i18n( s.toUtf8() ) ) { |
364 | tz = KSystemTimeZones::zone( s ); |
365 | break; |
366 | } |
367 | } |
368 | if ( !tz.isValid() ) { |
369 | return false; |
370 | } |
371 | emit executeCommand( new CalendarModifyTimeZoneCmd( a, tz, kundo2_i18n( "Modify calendar timezone" ) ) ); |
372 | return true; |
373 | } |
374 | } |
375 | return false; |
376 | } |
377 | |
378 | QVariant CalendarItemModel::data( const QModelIndex &index, int role ) const |
379 | { |
380 | QVariant result; |
381 | Calendar *a = calendar( index ); |
382 | if ( a == 0 ) { |
383 | return QVariant(); |
384 | } |
385 | switch ( index.column() ) { |
386 | case Name: result = name( a, role ); break; |
387 | case TimeZone: result = timeZone( a, role ); break; |
388 | default: |
389 | kDebug(planDbg())<<"data: invalid display value column" <<index.column(); |
390 | return QVariant(); |
391 | } |
392 | return result; |
393 | } |
394 | |
395 | bool CalendarItemModel::setData( const QModelIndex &index, const QVariant &value, int role ) |
396 | { |
397 | if ( ! index.isValid() ) { |
398 | return ItemModelBase::setData( index, value, role ); |
399 | } |
400 | if ( ( flags( index ) &( Qt::ItemIsEditable | Qt::CheckStateRole ) ) == 0 ) { |
401 | Q_ASSERT( true ); |
402 | return false; |
403 | } |
404 | Calendar *a = calendar( index ); |
405 | switch (index.column()) { |
406 | case Name: return setName( a, value, role ); |
407 | case TimeZone: return setTimeZone( a, value, role ); |
408 | default: |
409 | kWarning()<<"data: invalid display value column " <<index.column(); |
410 | return false; |
411 | } |
412 | return false; |
413 | } |
414 | |
415 | QVariant CalendarItemModel::( int section, Qt::Orientation orientation, int role ) const |
416 | { |
417 | if ( orientation == Qt::Horizontal ) { |
418 | if ( role == Qt::DisplayRole ) { |
419 | switch ( section ) { |
420 | case Name: return i18nc( "@title:column" , "Name" ); |
421 | case TimeZone: return i18nc( "@title:column" , "Timezone" ); |
422 | default: return QVariant(); |
423 | } |
424 | } else if ( role == Qt::TextAlignmentRole ) { |
425 | switch (section) { |
426 | default: return QVariant(); |
427 | } |
428 | } |
429 | } |
430 | if ( role == Qt::ToolTipRole ) { |
431 | switch ( section ) { |
432 | case Name: return ToolTip::calendarName(); |
433 | case TimeZone: return ToolTip::calendarTimeZone(); |
434 | default: return QVariant(); |
435 | } |
436 | } |
437 | return ItemModelBase::headerData(section, orientation, role); |
438 | } |
439 | |
440 | Calendar *CalendarItemModel::calendar( const QModelIndex &index ) const |
441 | { |
442 | return static_cast<Calendar*>( index.internalPointer() ); |
443 | } |
444 | |
445 | void CalendarItemModel::slotCalendarChanged( Calendar *calendar ) |
446 | { |
447 | Calendar *par = calendar->parentCal(); |
448 | if ( par ) { |
449 | int row = par->indexOf( calendar ); |
450 | emit dataChanged( createIndex( row, 0, calendar ), createIndex( row, columnCount() - 1, calendar ) ); |
451 | } else { |
452 | int row = m_project->indexOf( calendar ); |
453 | emit dataChanged( createIndex( row, 0, calendar ), createIndex( row, columnCount() - 1, calendar ) ); |
454 | } |
455 | } |
456 | |
457 | Qt::DropActions CalendarItemModel::supportedDropActions() const |
458 | { |
459 | return Qt::CopyAction | Qt::MoveAction; |
460 | } |
461 | |
462 | |
463 | QStringList CalendarItemModel::mimeTypes() const |
464 | { |
465 | return QStringList() << "application/x-vnd.kde.plan.calendarid.internal" ; |
466 | } |
467 | |
468 | QMimeData *CalendarItemModel::mimeData( const QModelIndexList & indexes ) const |
469 | { |
470 | QMimeData *m = new QMimeData(); |
471 | QByteArray encodedData; |
472 | QDataStream stream(&encodedData, QIODevice::WriteOnly); |
473 | QList<int> rows; |
474 | foreach (const QModelIndex &index, indexes) { |
475 | if ( index.isValid() && !rows.contains( index.row() ) ) { |
476 | kDebug(planDbg())<<index.row(); |
477 | Calendar *c = calendar( index ); |
478 | if ( c ) { |
479 | stream << c->id(); |
480 | } |
481 | } |
482 | } |
483 | m->setData("application/x-vnd.kde.plan.calendarid.internal" , encodedData); |
484 | return m; |
485 | } |
486 | |
487 | bool CalendarItemModel::dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int /*column*/, const QModelIndex &parent ) |
488 | { |
489 | kDebug(planDbg())<<action<<row; |
490 | if (action == Qt::IgnoreAction) { |
491 | return true; |
492 | } |
493 | if ( !data->hasFormat( "application/x-vnd.kde.plan.calendarid.internal" ) ) { |
494 | return false; |
495 | } |
496 | if ( action == Qt::MoveAction ) { |
497 | kDebug(planDbg())<<"MoveAction" ; |
498 | |
499 | QByteArray encodedData = data->data( "application/x-vnd.kde.plan.calendarid.internal" ); |
500 | QDataStream stream(&encodedData, QIODevice::ReadOnly); |
501 | Calendar *par = 0; |
502 | if ( parent.isValid() ) { |
503 | par = calendar( parent ); |
504 | } |
505 | MacroCommand *cmd = 0; |
506 | QList<Calendar*> lst = calendarList( stream ); |
507 | foreach ( Calendar *c, lst ) { |
508 | if ( c->parentCal() != par ) { |
509 | if ( cmd == 0 ) cmd = new MacroCommand( kundo2_i18n( "Re-parent calendar" ) ); |
510 | cmd->addCommand( new CalendarModifyParentCmd( m_project, c, par ) ); |
511 | } else { |
512 | if ( cmd == 0 ) cmd = new MacroCommand( kundo2_i18n( "Move calendar" ) ); |
513 | cmd->addCommand( new CalendarMoveCmd( m_project, c, row, par ) ); |
514 | } |
515 | } |
516 | if ( cmd ) { |
517 | emit executeCommand( cmd ); |
518 | return true; |
519 | } |
520 | //kDebug(planDbg())<<row<<","<<column<<" parent="<<parent.row()<<","<<parent.column()<<":"<<par->name(); |
521 | } |
522 | return false; |
523 | } |
524 | |
525 | QList<Calendar*> CalendarItemModel::calendarList( QDataStream &stream ) const |
526 | { |
527 | QList<Calendar*> lst; |
528 | while (!stream.atEnd()) { |
529 | QString id; |
530 | stream >> id; |
531 | Calendar *c = m_project->findCalendar( id ); |
532 | if ( c ) { |
533 | lst << c; |
534 | } |
535 | } |
536 | return lst; |
537 | } |
538 | |
539 | bool CalendarItemModel::dropAllowed( Calendar *on, const QMimeData *data ) |
540 | { |
541 | kDebug(planDbg())<<on<<data->hasFormat("application/x-vnd.kde.plan.calendarid.internal" ); |
542 | if ( !data->hasFormat("application/x-vnd.kde.plan.calendarid.internal" ) ) { |
543 | return false; |
544 | } |
545 | if ( on == 0 && ! ( flags( QModelIndex() ) & (int)Qt::ItemIsDropEnabled ) ) { |
546 | return false; |
547 | } |
548 | QByteArray encodedData = data->data( "application/x-vnd.kde.plan.calendarid.internal" ); |
549 | QDataStream stream(&encodedData, QIODevice::ReadOnly); |
550 | QList<Calendar*> lst = calendarList( stream ); |
551 | foreach ( Calendar *c, lst ) { |
552 | if ( (flags( index( c ) ) & (int)Qt::ItemIsDropEnabled) == 0 ) { |
553 | return false; |
554 | } |
555 | if ( on != 0 && on == c->parentCal() ) { |
556 | return false; |
557 | } |
558 | if ( on != 0 && ( on == c || on->isChildOf( c ) ) ) { |
559 | return false; |
560 | } |
561 | } |
562 | return true; |
563 | } |
564 | |
565 | QModelIndex CalendarItemModel::insertCalendar ( Calendar *calendar, int pos, Calendar *parent ) |
566 | { |
567 | //kDebug(planDbg())<<calendar<<pos<<parent; |
568 | emit executeCommand( new CalendarAddCmd( m_project, calendar, pos, parent, kundo2_i18n( "Add calendar" ) ) ); |
569 | int row = -1; |
570 | if ( parent ) { |
571 | row = parent->indexOf( calendar ); |
572 | } else { |
573 | row = m_project->indexOf( calendar ); |
574 | } |
575 | if ( row != -1 ) { |
576 | //kDebug(planDbg())<<"Inserted:"<<calendar->name()<<"row="<<row; |
577 | return createIndex( row, 0, calendar ); |
578 | } |
579 | return QModelIndex(); |
580 | } |
581 | |
582 | void CalendarItemModel::removeCalendar( QList<Calendar *> /*lst*/ ) |
583 | { |
584 | } |
585 | |
586 | void CalendarItemModel::removeCalendar( Calendar *calendar ) |
587 | { |
588 | if ( calendar == 0 ) { |
589 | return; |
590 | } |
591 | emit executeCommand( new CalendarRemoveCmd( m_project, calendar, kundo2_i18n( "Delete calendar" ) ) ); |
592 | } |
593 | |
594 | |
595 | //------------------------------------------ |
596 | CalendarDayItemModel::CalendarDayItemModel( QObject *parent ) |
597 | : CalendarDayItemModelBase( parent ) |
598 | { |
599 | } |
600 | |
601 | CalendarDayItemModel::~CalendarDayItemModel() |
602 | { |
603 | } |
604 | |
605 | void CalendarDayItemModel::slotWorkIntervalAdded( CalendarDay *day, TimeInterval *ti ) |
606 | { |
607 | Q_UNUSED(ti); |
608 | //kDebug(planDbg())<<day<<","<<ti; |
609 | int c = m_calendar->indexOfWeekday( day ); |
610 | if ( c == -1 ) { |
611 | return; |
612 | } |
613 | dataChanged( createIndex( 0, c, day ), createIndex( 0, c, day ) ); |
614 | } |
615 | |
616 | void CalendarDayItemModel::slotWorkIntervalRemoved( CalendarDay *day, TimeInterval *ti ) |
617 | { |
618 | Q_UNUSED(ti); |
619 | int c = m_calendar->indexOfWeekday( day ); |
620 | if ( c == -1 ) { |
621 | return; |
622 | } |
623 | dataChanged( createIndex( 0, c, day ), createIndex( 0, c, day ) ); |
624 | } |
625 | |
626 | void CalendarDayItemModel::slotDayChanged( CalendarDay *day ) |
627 | { |
628 | int c = m_calendar->indexOfWeekday( day ); |
629 | if ( c == -1 ) { |
630 | return; |
631 | } |
632 | kDebug(planDbg())<<day<<", " <<c; |
633 | emit dataChanged( createIndex( 0, c, day ), createIndex( 0, c, day ) ); |
634 | } |
635 | |
636 | void CalendarDayItemModel::slotTimeIntervalChanged( TimeInterval *ti ) |
637 | { |
638 | Q_UNUSED(ti); |
639 | /* CalendarDay *d = parentDay( ti ); |
640 | if ( d == 0 ) { |
641 | return; |
642 | } |
643 | int row = d->indexOf( ti ); |
644 | emit dataChanged( createIndex( row, 0, ti ), createIndex( row, columnCount() - 1, ti ) );*/ |
645 | } |
646 | |
647 | void CalendarDayItemModel::setCalendar( Calendar *calendar ) |
648 | { |
649 | //kDebug(planDbg())<<m_calendar<<" -->"<<calendar; |
650 | if ( m_calendar ) { |
651 | disconnect( m_calendar, SIGNAL(changed(CalendarDay*)), this, SLOT(slotDayChanged(CalendarDay*)) ); |
652 | disconnect( m_calendar, SIGNAL(changed(TimeInterval*)), this, SLOT(slotTimeIntervalChanged(TimeInterval*)) ); |
653 | |
654 | disconnect( m_calendar, SIGNAL(workIntervalAdded(CalendarDay*,TimeInterval*)), this, SLOT(slotWorkIntervalAdded(CalendarDay*,TimeInterval*)) ); |
655 | disconnect( m_calendar, SIGNAL(workIntervalRemoved(CalendarDay*,TimeInterval*)), this, SLOT(slotWorkIntervalRemoved(CalendarDay*,TimeInterval*)) ); |
656 | } |
657 | m_calendar = calendar; |
658 | if ( calendar ) { |
659 | connect( m_calendar, SIGNAL(changed(CalendarDay*)), this, SLOT(slotDayChanged(CalendarDay*)) ); |
660 | connect( m_calendar, SIGNAL(changed(TimeInterval*)), this, SLOT(slotTimeIntervalChanged(TimeInterval*)) ); |
661 | |
662 | connect( m_calendar, SIGNAL(workIntervalAdded(CalendarDay*,TimeInterval*)), this, SLOT(slotWorkIntervalAdded(CalendarDay*,TimeInterval*)) ); |
663 | connect( m_calendar, SIGNAL(workIntervalRemoved(CalendarDay*,TimeInterval*)), this, SLOT(slotWorkIntervalRemoved(CalendarDay*,TimeInterval*)) ); |
664 | } |
665 | reset(); |
666 | } |
667 | |
668 | Qt::ItemFlags CalendarDayItemModel::flags( const QModelIndex &index ) const |
669 | { |
670 | Qt::ItemFlags flags = ItemModelBase::flags( index ); |
671 | if ( !m_readWrite ) { |
672 | return flags &= ~Qt::ItemIsEditable; |
673 | } |
674 | return flags |= Qt::ItemIsEditable; |
675 | } |
676 | |
677 | QModelIndex CalendarDayItemModel::parent( const QModelIndex &index ) const |
678 | { |
679 | Q_UNUSED(index); |
680 | return QModelIndex(); |
681 | } |
682 | |
683 | bool CalendarDayItemModel::hasChildren( const QModelIndex &parent ) const |
684 | { |
685 | //kDebug(planDbg())<<parent.internalPointer()<<":"<<parent.row()<<","<<parent.column(); |
686 | if ( m_project == 0 || m_calendar == 0 ) { |
687 | return false; |
688 | } |
689 | return ! parent.isValid(); |
690 | } |
691 | |
692 | QModelIndex CalendarDayItemModel::index( int row, int column, const QModelIndex &par ) const |
693 | { |
694 | if ( m_project == 0 || m_calendar == 0 ) { |
695 | return QModelIndex(); |
696 | } |
697 | if ( par.isValid() ) { |
698 | return QModelIndex(); |
699 | } |
700 | CalendarDay *d = m_calendar->weekday( column + 1 ); // weekdays are 1..7 |
701 | if ( d == 0 ) { |
702 | return QModelIndex(); |
703 | } |
704 | return createIndex( row, column, d ); |
705 | } |
706 | |
707 | QModelIndex CalendarDayItemModel::index( const CalendarDay *d) const |
708 | { |
709 | if ( m_project == 0 || m_calendar == 0 ) { |
710 | return QModelIndex(); |
711 | } |
712 | int col = m_calendar->indexOfWeekday( d ); |
713 | if ( col == -1 ) { |
714 | return QModelIndex(); |
715 | } |
716 | return createIndex( 0, col, const_cast<CalendarDay*>( d ) ); |
717 | } |
718 | |
719 | int CalendarDayItemModel::columnCount( const QModelIndex &/*parent*/ ) const |
720 | { |
721 | return 7; |
722 | } |
723 | |
724 | int CalendarDayItemModel::rowCount( const QModelIndex &parent ) const |
725 | { |
726 | if ( m_project == 0 || m_calendar == 0 || parent.isValid() ) { |
727 | return 0; |
728 | } |
729 | return 1; |
730 | } |
731 | |
732 | QVariant CalendarDayItemModel::name( int weekday, int role ) const |
733 | { |
734 | //kDebug(planDbg())<<res->name()<<","<<role; |
735 | switch ( role ) { |
736 | case Qt::DisplayRole: |
737 | if ( weekday >= 1 && weekday <= 7 ) { |
738 | return KGlobal::locale()->calendar()->weekDayName( weekday, KCalendarSystem::ShortDayName ); |
739 | } |
740 | break; |
741 | case Qt::ToolTipRole: |
742 | if ( weekday >= 1 && weekday <= 7 ) { |
743 | return KGlobal::locale()->calendar()->weekDayName( weekday ); |
744 | } |
745 | break; |
746 | case Qt::EditRole: |
747 | case Qt::StatusTipRole: |
748 | case Qt::WhatsThisRole: |
749 | return QVariant(); |
750 | } |
751 | return QVariant(); |
752 | } |
753 | |
754 | QVariant CalendarDayItemModel::dayState( const CalendarDay *d, int role ) const |
755 | { |
756 | switch ( role ) { |
757 | case Qt::DisplayRole: |
758 | switch ( d->state() ) { |
759 | case CalendarDay::Undefined: return i18nc( "Undefined" , "U" ); |
760 | case CalendarDay::NonWorking: return i18nc( "NonWorking" , "NW" ); |
761 | case CalendarDay::Working: return i18nc( "Working" , "W" ); |
762 | } |
763 | break; |
764 | case Qt::ToolTipRole: |
765 | return CalendarDay::stateToString( d->state(), true ); |
766 | case Role::EnumList: { |
767 | QStringList lst = CalendarDay::stateList( true ); |
768 | return lst; |
769 | } |
770 | case Qt::EditRole: |
771 | case Role::EnumListValue: { |
772 | return d->state(); |
773 | } |
774 | case Qt::TextAlignmentRole: |
775 | return Qt::AlignCenter; |
776 | case Qt::StatusTipRole: |
777 | case Qt::WhatsThisRole: |
778 | return QVariant(); |
779 | case Role::EditorType: |
780 | return Delegate::EnumEditor; |
781 | } |
782 | return QVariant(); |
783 | } |
784 | bool CalendarDayItemModel::setDayState( CalendarDay *d, const QVariant &value, int role ) |
785 | { |
786 | //kDebug(planDbg()); |
787 | switch ( role ) { |
788 | case Qt::EditRole: |
789 | int v = value.toInt(); |
790 | emit executeCommand( new CalendarModifyStateCmd( m_calendar, d, static_cast<CalendarDay::State>( v ), kundo2_i18n( "Modify calendar state" ) ) ); |
791 | return true; |
792 | } |
793 | return false; |
794 | } |
795 | |
796 | QVariant CalendarDayItemModel::workDuration( const CalendarDay *day, int role ) const |
797 | { |
798 | //kDebug(planDbg())<<day->date()<<","<<role; |
799 | switch ( role ) { |
800 | case Qt::DisplayRole: { |
801 | if ( day->state() == CalendarDay::Working ) { |
802 | return KGlobal::locale()->formatNumber( day->workDuration().toDouble( Duration::Unit_h ), 1 ); |
803 | } |
804 | return QVariant(); |
805 | } |
806 | case Qt::ToolTipRole: { |
807 | if ( day->state() == CalendarDay::Working ) { |
808 | KLocale *l = KGlobal::locale(); |
809 | QStringList tip; |
810 | foreach ( TimeInterval *i, day->timeIntervals() ) { |
811 | tip << i18nc( "1=time 2=The number of hours of work duration (non integer)" , "%1, %2 hours" , l->formatTime( i->startTime() ), l->formatNumber( i->hours() ) ); |
812 | } |
813 | return tip.join( "\n" ); |
814 | } |
815 | return QVariant(); |
816 | } |
817 | case Qt::EditRole: |
818 | break; |
819 | case Qt::StatusTipRole: |
820 | case Qt::WhatsThisRole: |
821 | return QVariant(); |
822 | case Qt::TextAlignmentRole: |
823 | return Qt::AlignCenter; |
824 | } |
825 | return QVariant(); |
826 | } |
827 | |
828 | QVariant CalendarDayItemModel::data( const QModelIndex &index, int role ) const |
829 | { |
830 | QVariant result; |
831 | if ( ! index.isValid() ) { |
832 | return result; |
833 | } |
834 | CalendarDay *d = day( index ); |
835 | if ( d == 0 ) { |
836 | return QVariant(); |
837 | } |
838 | switch ( role ) { |
839 | case Qt::DisplayRole: { |
840 | switch ( d->state() ) { |
841 | case CalendarDay::Working: |
842 | result = workDuration( d, role ); |
843 | break; |
844 | case CalendarDay::NonWorking: |
845 | result = dayState( d, role ); |
846 | break; |
847 | default: { |
848 | // Return parent value (if any) |
849 | for ( Calendar *c = m_calendar->parentCal(); c != 0; c = c->parentCal() ) { |
850 | d = c->weekday( index.column() + 1 ); |
851 | Q_ASSERT( d ); |
852 | if ( d->state() == CalendarDay::Working ) { |
853 | return workDuration( d, role ); |
854 | } |
855 | if ( d->state() == CalendarDay::NonWorking ) { |
856 | return dayState( d, role ); |
857 | } |
858 | } |
859 | break; |
860 | } |
861 | } |
862 | break; |
863 | } |
864 | case Qt::ToolTipRole: { |
865 | if ( d->state() == CalendarDay::Undefined ) { |
866 | return i18nc( "@info:tooltip" , "Undefined" ); |
867 | } |
868 | if ( d->state() == CalendarDay::NonWorking ) { |
869 | return i18nc( "@info:tooltip" , "Non-working" ); |
870 | } |
871 | KLocale *l = KGlobal::locale(); |
872 | QStringList tip; |
873 | foreach ( TimeInterval *i, d->timeIntervals() ) { |
874 | tip << i18nc( "@info:tooltip 1=time 2=The work duration (non integer)" , "%1, %2" , l->formatLocaleTime( i->startTime(), KLocale::TimeWithoutSeconds ), l->formatDuration( i->second ) ); |
875 | } |
876 | return tip.join( "\n" ); |
877 | } |
878 | case Qt::FontRole: { |
879 | if ( d->state() != CalendarDay::Undefined ) { |
880 | return QVariant(); |
881 | } |
882 | // If defined in parent, return italic |
883 | for ( Calendar *c = m_calendar->parentCal(); c != 0; c = c->parentCal() ) { |
884 | d = c->weekday( index.column() + 1 ); |
885 | Q_ASSERT( d ); |
886 | if ( d->state() != CalendarDay::Undefined ) { |
887 | QFont f; |
888 | f.setItalic( true ); |
889 | return f; |
890 | } |
891 | } |
892 | break; |
893 | } |
894 | } |
895 | return result; |
896 | } |
897 | |
898 | bool CalendarDayItemModel::setData( const QModelIndex &index, const QVariant &value, int role ) |
899 | { |
900 | return ItemModelBase::setData( index, value, role ); |
901 | } |
902 | |
903 | QVariant CalendarDayItemModel::( int section, Qt::Orientation orientation, int role ) const |
904 | { |
905 | if ( orientation == Qt::Horizontal ) { |
906 | if ( role == Qt::DisplayRole ) { |
907 | switch ( section ) { |
908 | case 0: |
909 | case 1: |
910 | case 2: |
911 | case 3: |
912 | case 4: |
913 | case 5: |
914 | case 6: |
915 | return name( section + 1, role ); |
916 | default: |
917 | return QVariant(); |
918 | } |
919 | } else if ( role == Qt::TextAlignmentRole ) { |
920 | switch (section) { |
921 | default: return Qt::AlignCenter; |
922 | } |
923 | } |
924 | } |
925 | if ( role == Qt::ToolTipRole ) { |
926 | switch ( section ) { |
927 | /* case 0: return ToolTip::Calendar Name;*/ |
928 | default: return QVariant(); |
929 | } |
930 | } |
931 | return ItemModelBase::headerData(section, orientation, role); |
932 | } |
933 | |
934 | CalendarDay *CalendarDayItemModel::day( const QModelIndex &index ) const |
935 | { |
936 | return static_cast<CalendarDay*>( index.internalPointer() ); |
937 | } |
938 | |
939 | QAbstractItemDelegate *CalendarDayItemModel::createDelegate( int column, QWidget *parent ) const |
940 | { |
941 | Q_UNUSED(parent); |
942 | switch ( column ) { |
943 | default: return 0; |
944 | } |
945 | return 0; |
946 | } |
947 | |
948 | //----------------------- |
949 | DateTableDataModel::DateTableDataModel( QObject *parent ) |
950 | : KDateTableDataModel( parent ), |
951 | m_calendar( 0 ) |
952 | { |
953 | } |
954 | |
955 | void DateTableDataModel::setCalendar( Calendar *calendar ) |
956 | { |
957 | if ( m_calendar ) { |
958 | disconnect( m_calendar, SIGNAL(dayAdded(CalendarDay*)), this, SIGNAL(reset()) ); |
959 | disconnect( m_calendar, SIGNAL(dayRemoved(CalendarDay*)), this, SIGNAL(reset()) ); |
960 | disconnect( m_calendar, SIGNAL(changed(CalendarDay*)), this, SIGNAL(reset()) ); |
961 | } |
962 | m_calendar = calendar; |
963 | if ( m_calendar ) { |
964 | connect( m_calendar, SIGNAL(dayAdded(CalendarDay*)), this, SIGNAL(reset()) ); |
965 | connect( m_calendar, SIGNAL(dayRemoved(CalendarDay*)), this, SIGNAL(reset()) ); |
966 | connect( m_calendar, SIGNAL(changed(CalendarDay*)), this, SIGNAL(reset()) ); |
967 | } |
968 | emit reset(); |
969 | } |
970 | |
971 | QVariant DateTableDataModel::data( const Calendar &cal, const QDate &date, int role ) const |
972 | { |
973 | switch ( role ) { |
974 | case Qt::DisplayRole: { |
975 | CalendarDay *day = cal.findDay( date ); |
976 | if ( day == 0 || day->state() == CalendarDay::Undefined ) { |
977 | if ( cal.parentCal() ) { |
978 | return data( *( cal.parentCal() ), date, role ); |
979 | } |
980 | return "" ; |
981 | } |
982 | if ( day->state() == CalendarDay::NonWorking ) { |
983 | return i18nc( "NonWorking" , "NW" ); |
984 | } |
985 | double v; |
986 | v = day->workDuration().toDouble( Duration::Unit_h ); |
987 | return KGlobal::locale()->formatNumber( v, 1 ); |
988 | } |
989 | case Qt::TextAlignmentRole: |
990 | return (uint)( Qt::AlignHCenter | Qt::AlignBottom ); |
991 | case Qt::FontRole: { |
992 | CalendarDay *day = cal.findDay( date ); |
993 | if ( day && day->state() != CalendarDay::Undefined ) { |
994 | if ( &cal != m_calendar ) { |
995 | QFont f; |
996 | f.setItalic( true ); |
997 | return f; |
998 | } |
999 | return QVariant(); |
1000 | } |
1001 | if ( cal.parentCal() ) { |
1002 | return data( *( cal.parentCal() ), date, role ); |
1003 | } |
1004 | break; |
1005 | } |
1006 | default: |
1007 | break; |
1008 | } |
1009 | return QVariant(); |
1010 | } |
1011 | |
1012 | QVariant DateTableDataModel::data( const QDate &date, int role, int dataType ) const |
1013 | { |
1014 | //kDebug(planDbg())<<date<<role<<dataType; |
1015 | if ( role == Qt::ToolTipRole ) { |
1016 | if ( m_calendar == 0 ) { |
1017 | return QVariant(); |
1018 | } |
1019 | CalendarDay *day = m_calendar->findDay( date ); |
1020 | if ( day == 0 || day->state() == CalendarDay::Undefined ) { |
1021 | return i18nc( "@info:tooltip" , "Undefined" ); |
1022 | } |
1023 | if ( day->state() == CalendarDay::NonWorking ) { |
1024 | return i18nc( "@info:tooltip" , "Non-working" ); |
1025 | } |
1026 | KLocale *l = KGlobal::locale(); |
1027 | QStringList tip; |
1028 | foreach ( TimeInterval *i, day->timeIntervals() ) { |
1029 | tip << i18nc( "@info:tooltip 1=time 2=The work duration (non integer)" , "%1, %2" , l->formatLocaleTime( i->startTime(), KLocale::TimeWithoutSeconds ), l->formatDuration( i->second ) ); |
1030 | } |
1031 | return tip.join( "\n" ); |
1032 | } |
1033 | |
1034 | switch ( dataType ) { |
1035 | case -1: { //default (date) |
1036 | switch ( role ) { |
1037 | case Qt::DisplayRole: { |
1038 | return QVariant(); |
1039 | } |
1040 | case Qt::TextAlignmentRole: |
1041 | return (uint)Qt::AlignLeft | Qt::AlignTop; |
1042 | case Qt::FontRole: |
1043 | break;//return QFont( "Helvetica", 6 ); |
1044 | case Qt::BackgroundRole: |
1045 | break;//return QColor( "red" ); |
1046 | default: |
1047 | break; |
1048 | } |
1049 | break; |
1050 | } |
1051 | case 0: { |
1052 | if ( m_calendar == 0 ) { |
1053 | return "" ; |
1054 | } |
1055 | return data( *m_calendar, date, role ); |
1056 | } |
1057 | default: |
1058 | break; |
1059 | } |
1060 | return QVariant(); |
1061 | } |
1062 | |
1063 | QVariant DateTableDataModel::weekDayData( int day, int role ) const |
1064 | { |
1065 | Q_UNUSED(day); |
1066 | Q_UNUSED(role); |
1067 | return QVariant(); |
1068 | } |
1069 | |
1070 | QVariant DateTableDataModel::weekNumberData( int week, int role ) const |
1071 | { |
1072 | Q_UNUSED(week); |
1073 | Q_UNUSED(role); |
1074 | return QVariant(); |
1075 | } |
1076 | |
1077 | //------------- |
1078 | DateTableDateDelegate::DateTableDateDelegate( QObject *parent ) |
1079 | : KDateTableDateDelegate( parent ) |
1080 | { |
1081 | } |
1082 | |
1083 | QRectF DateTableDateDelegate::paint( QPainter *painter, const StyleOptionViewItem &option, const QDate &date, KDateTableDataModel *model ) |
1084 | { |
1085 | //kDebug(planDbg())<<date; |
1086 | QRectF r; |
1087 | StyleOptionViewItem style = option; |
1088 | style.font.setPointSize( style.font.pointSize() - 2 ); |
1089 | //kDebug(planDbg())<<" fonts: "<<option.font.pointSize()<<style.font.pointSize(); |
1090 | r = KDateTableDateDelegate::paint( painter, style, date, model ); |
1091 | if ( model == 0 ) { |
1092 | return r; |
1093 | } |
1094 | painter->save(); |
1095 | //const KCalendarSystem * calendar = KGlobal::locale()->calendar(); |
1096 | |
1097 | painter->translate( r.width(), 0.0 ); |
1098 | QRectF rect( 1, 1, option.rectF.right() - r.width(), option.rectF.bottom() ); |
1099 | //kDebug(planDbg())<<" rects: "<<r<<rect; |
1100 | |
1101 | QString text = model->data( date, Qt::DisplayRole, 0 ).toString(); |
1102 | int align = model->data( date, Qt::TextAlignmentRole, 0 ).toInt(); |
1103 | QFont f = option.font; |
1104 | QVariant v = model->data( date, Qt::FontRole, 0 ); |
1105 | if ( v.isValid() ) { |
1106 | f = v.value<QFont>(); |
1107 | } |
1108 | painter->setFont( f ); |
1109 | |
1110 | if ( option.state & QStyle::State_Selected ) { |
1111 | painter->setPen( option.palette.highlightedText().color() ); |
1112 | } else { |
1113 | painter->setPen( option.palette.color( QPalette::Text ) ); |
1114 | } |
1115 | painter->drawText(rect, align, text, &r); |
1116 | |
1117 | painter->restore(); |
1118 | return r; |
1119 | } |
1120 | |
1121 | //------------------------------------- |
1122 | CalendarExtendedItemModel::CalendarExtendedItemModel( QObject *parent ) |
1123 | : CalendarItemModel( parent ) |
1124 | { |
1125 | } |
1126 | |
1127 | Qt::ItemFlags CalendarExtendedItemModel::flags( const QModelIndex &index ) const |
1128 | { |
1129 | Qt::ItemFlags flags = CalendarItemModel::flags( index ); |
1130 | if ( ! m_readWrite || ! index.isValid() || calendar( index ) == 0 ) { |
1131 | return flags; |
1132 | } |
1133 | return flags |= Qt::ItemIsEditable; |
1134 | } |
1135 | |
1136 | |
1137 | QModelIndex CalendarExtendedItemModel::index( int row, int column, const QModelIndex &parent ) const |
1138 | { |
1139 | if ( m_project == 0 || column < 0 || column >= columnCount() || row < 0 ) { |
1140 | return QModelIndex(); |
1141 | } |
1142 | Calendar *par = calendar( parent ); |
1143 | if ( par == 0 ) { |
1144 | if ( row < m_project->calendars().count() ) { |
1145 | return createIndex( row, column, m_project->calendars().at( row ) ); |
1146 | } |
1147 | } else if ( row < par->calendars().count() ) { |
1148 | return createIndex( row, column, par->calendars().at( row ) ); |
1149 | } |
1150 | return QModelIndex(); |
1151 | } |
1152 | |
1153 | int CalendarExtendedItemModel::columnCount( const QModelIndex & ) const |
1154 | { |
1155 | return CalendarItemModel::columnCount() + 2; // weekdays + date |
1156 | } |
1157 | |
1158 | QVariant CalendarExtendedItemModel::data( const QModelIndex &index, int role ) const |
1159 | { |
1160 | QVariant result; |
1161 | Calendar *a = calendar( index ); |
1162 | if ( a == 0 ) { |
1163 | return QVariant(); |
1164 | } |
1165 | int col = index.column() - CalendarItemModel::columnCount( index ); |
1166 | if ( col < 0 ) { |
1167 | return CalendarItemModel::data( index, role ); |
1168 | } |
1169 | switch ( col ) { |
1170 | default: |
1171 | kDebug(planDbg())<<"Fetching data from weekdays and date is not supported" ; |
1172 | break; |
1173 | } |
1174 | return result; |
1175 | } |
1176 | |
1177 | bool CalendarExtendedItemModel::setData( const QModelIndex &index, const QVariant &value, int role ) |
1178 | { |
1179 | int col = index.column() - CalendarItemModel::columnCount( index ); |
1180 | if ( col < 0 ) { |
1181 | return CalendarItemModel::setData( index, value, role ); |
1182 | } |
1183 | if ( ( flags( index ) &( Qt::ItemIsEditable ) ) == 0 ) { |
1184 | return false; |
1185 | } |
1186 | Calendar *cal = calendar( index ); |
1187 | if ( cal == 0 || col > 2 ) { |
1188 | return false; |
1189 | } |
1190 | switch ( col ) { |
1191 | case 0: { // weekday |
1192 | if ( value.type() != QVariant::List ) { |
1193 | return false; |
1194 | } |
1195 | QVariantList lst = value.toList(); |
1196 | if ( lst.count() < 2 ) { |
1197 | return false; |
1198 | } |
1199 | int wd = CalendarWeekdays::dayOfWeek( lst.at( 0 ).toString() ); |
1200 | if ( wd < 1 || wd > 7 ) { |
1201 | return false; |
1202 | } |
1203 | CalendarDay *day = new CalendarDay(); |
1204 | if ( lst.count() == 2 ) { |
1205 | QString state = lst.at( 1 ).toString(); |
1206 | if ( state == "NonWorking" ) { |
1207 | day->setState( CalendarDay::NonWorking ); |
1208 | } else if ( state == "Undefined" ) { |
1209 | day->setState( CalendarDay::Undefined ); |
1210 | } else { |
1211 | delete day; |
1212 | return false; |
1213 | } |
1214 | CalendarModifyWeekdayCmd *cmd = new CalendarModifyWeekdayCmd( cal, wd, day, kundo2_i18n( "Modify calendar weekday" ) ); |
1215 | emit executeCommand( cmd ); |
1216 | return true; |
1217 | } |
1218 | if ( lst.count() % 2 == 0 ) { |
1219 | delete day; |
1220 | return false; |
1221 | } |
1222 | day->setState( CalendarDay::Working ); |
1223 | for ( int i = 1; i < lst.count(); i = i + 2 ) { |
1224 | QTime t1 = lst.at( i ).toTime(); |
1225 | QTime t2 = lst.at( i + 1 ).toTime(); |
1226 | int length = t1.msecsTo( t2 ); |
1227 | if ( t1 == QTime( 0, 0, 0 ) && t2 == t1 ) { |
1228 | length = 24 * 60 * 60 *1000; |
1229 | } else if ( length < 0 && t2 == QTime( 0, 0, 0 ) ) { |
1230 | length += 24 * 60 * 60 *1000; |
1231 | } else if ( length == 0 || ( length < 0 && t2 != QTime( 0, 0, 0 ) ) ) { |
1232 | delete day; |
1233 | return false; |
1234 | } |
1235 | length = qAbs( length ); |
1236 | day->addInterval( t1, length ); |
1237 | } |
1238 | CalendarModifyWeekdayCmd *cmd = new CalendarModifyWeekdayCmd( cal, wd, day, kundo2_i18n( "Modify calendar weekday" ) ); |
1239 | emit executeCommand( cmd ); |
1240 | return true; |
1241 | } |
1242 | case 1: { // day |
1243 | if ( value.type() != QVariant::List ) { |
1244 | return false; |
1245 | } |
1246 | CalendarDay *day = new CalendarDay(); |
1247 | QVariantList lst = value.toList(); |
1248 | if ( lst.count() < 2 ) { |
1249 | return false; |
1250 | } |
1251 | day->setDate( lst.at( 0 ).toDate() ); |
1252 | if ( ! day->date().isValid() ) { |
1253 | delete day; |
1254 | return false; |
1255 | } |
1256 | if ( lst.count() == 2 ) { |
1257 | QString state = lst.at( 1 ).toString(); |
1258 | if ( state == "NonWorking" ) { |
1259 | day->setState( CalendarDay::NonWorking ); |
1260 | } else if ( state == "Undefined" ) { |
1261 | day->setState( CalendarDay::Undefined ); |
1262 | } else { |
1263 | delete day; |
1264 | return false; |
1265 | } |
1266 | CalendarModifyDayCmd *cmd = new CalendarModifyDayCmd( cal, day, kundo2_i18n( "Modify calendar date" ) ); |
1267 | emit executeCommand( cmd ); |
1268 | return true; |
1269 | } |
1270 | if ( lst.count() % 2 == 0 ) { |
1271 | delete day; |
1272 | return false; |
1273 | } |
1274 | day->setState( CalendarDay::Working ); |
1275 | for ( int i = 1; i < lst.count(); i = i + 2 ) { |
1276 | QTime t1 = lst.at( i ).toTime(); |
1277 | QTime t2 = lst.at( i + 1 ).toTime(); |
1278 | int length = t1.msecsTo( t2 ); |
1279 | if ( t1 == QTime( 0, 0, 0 ) && t2 == t1 ) { |
1280 | length = 24 * 60 * 60 *1000; |
1281 | } else if ( length < 0 && t2 == QTime( 0, 0, 0 ) ) { |
1282 | length += 24 * 60 * 60 *1000; |
1283 | } else if ( length == 0 || ( length < 0 && t2 != QTime( 0, 0, 0 ) ) ) { |
1284 | delete day; |
1285 | return false; |
1286 | } |
1287 | length = qAbs( length ); |
1288 | day->addInterval( t1, length ); |
1289 | } |
1290 | CalendarModifyDayCmd *cmd = new CalendarModifyDayCmd( cal, day, kundo2_i18n( "Modify calendar date" ) ); |
1291 | emit executeCommand( cmd ); |
1292 | return true; |
1293 | } |
1294 | } |
1295 | return false; |
1296 | } |
1297 | |
1298 | QVariant CalendarExtendedItemModel::( int section, Qt::Orientation orientation, int role ) const |
1299 | { |
1300 | int col = section - CalendarItemModel::columnCount(); |
1301 | if ( col < 0 ) { |
1302 | return CalendarItemModel::headerData( section, orientation, role ); |
1303 | } |
1304 | if ( orientation == Qt::Horizontal ) { |
1305 | if ( role == Qt::DisplayRole ) { |
1306 | switch ( col ) { |
1307 | case 0: return i18nc( "@title:column" , "Weekday" ); |
1308 | case 1: return i18nc( "@title:column" , "Date" ); |
1309 | default: return QVariant(); |
1310 | } |
1311 | } else if ( role == Qt::TextAlignmentRole ) { |
1312 | switch ( col ) { |
1313 | default: return QVariant(); |
1314 | } |
1315 | } |
1316 | } |
1317 | if ( role == Qt::ToolTipRole ) { |
1318 | switch ( section ) { |
1319 | default: return QVariant(); |
1320 | } |
1321 | } |
1322 | return QVariant(); |
1323 | } |
1324 | |
1325 | int CalendarExtendedItemModel::columnNumber(const QString& name) const |
1326 | { |
1327 | QStringList lst; |
1328 | lst << "Weekday" |
1329 | << "Date" ; |
1330 | if ( lst.contains( name ) ) { |
1331 | return lst.indexOf( name ) + CalendarItemModel::columnCount(); |
1332 | } |
1333 | return CalendarItemModel::columnMap().keyToValue( name.toUtf8() ); |
1334 | } |
1335 | |
1336 | } // namespace KPlato |
1337 | |
1338 | #include "kptcalendarmodel.moc" |
1339 | |