1/* This file is part of the KDE project
2 Copyright (C) 2007 -2010 Dag Andersen <danders@get2net.dk>
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 "kptviewlist.h"
21
22#include <QString>
23#include <QStringList>
24#include <QTreeWidget>
25#include <QTreeWidgetItem>
26#include <QItemDelegate>
27#include <QStyle>
28#include <QHeaderView>
29#include <QBrush>
30#include <QContextMenuEvent>
31#include <QTimer>
32
33#include <kmenu.h>
34#include <kmessagebox.h>
35#include <kcombobox.h>
36
37#include <KoIcon.h>
38#include "KoDocument.h"
39
40#include "kptviewbase.h"
41#include "kptmaindocument.h"
42#include "kptviewlistdialog.h"
43#include "kptviewlistdocker.h"
44#include "kptschedulemodel.h"
45#include <kptdebug.h>
46
47#include <assert.h>
48
49
50namespace KPlato
51{
52
53// <Code mostly nicked from qt designer ;)>
54class ViewCategoryDelegate : public QItemDelegate
55{
56 public:
57 ViewCategoryDelegate( QObject *parent, QTreeView *view )
58 : QItemDelegate( parent ),
59 m_view( view )
60 {}
61
62 QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const;
63 virtual void paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
64
65 private:
66 QTreeView *m_view;
67};
68
69QSize ViewCategoryDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const
70{
71 const QAbstractItemModel * model = index.model();
72 Q_ASSERT( model );
73 if ( model->parent( index ).isValid() ) {
74 return QItemDelegate::sizeHint( option, index );
75 }
76 return QItemDelegate::sizeHint( option, index ).expandedTo( QSize( 0, 16 ) );
77}
78
79void ViewCategoryDelegate::paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
80{
81 const QAbstractItemModel * model = index.model();
82 Q_ASSERT( model );
83
84 if ( !model->parent( index ).isValid() ) {
85 // this is a top-level item.
86 QStyleOptionButton buttonOption;
87 buttonOption.state = option.state;
88
89 buttonOption.rect = option.rect;
90 buttonOption.palette = option.palette;
91 buttonOption.features = QStyleOptionButton::None;
92 m_view->style() ->drawControl( QStyle::CE_PushButton, &buttonOption, painter, m_view );
93
94 QStyleOption branchOption;
95 static const int i = 9; // ### hardcoded in qcommonstyle.cpp
96 QRect r = option.rect;
97 branchOption.rect = QRect( r.left() + i / 2, r.top() + ( r.height() - i ) / 2, i, i );
98 branchOption.palette = option.palette;
99 branchOption.state = QStyle::State_Children;
100
101 if ( m_view->isExpanded( index ) )
102 branchOption.state |= QStyle::State_Open;
103
104 m_view->style() ->drawPrimitive( QStyle::PE_IndicatorBranch, &branchOption, painter, m_view );
105
106 // draw text
107 QRect textrect = QRect( r.left() + i * 2, r.top(), r.width() - ( ( 5 * i ) / 2 ), r.height() );
108 QString text = elidedText( option.fontMetrics, textrect.width(), Qt::ElideMiddle,
109 model->data( index, Qt::DisplayRole ).toString() );
110 m_view->style() ->drawItemText( painter, textrect, Qt::AlignLeft|Qt::AlignVCenter,
111 option.palette, m_view->isEnabled(), text );
112
113 } else {
114 QItemDelegate::paint( painter, option, index );
115 }
116
117}
118
119ViewListItem::ViewListItem( const QString &tag, const QStringList &strings, int type )
120 : QTreeWidgetItem( strings, type ),
121 m_tag( tag )
122{
123}
124
125ViewListItem::ViewListItem( QTreeWidget *parent, const QString &tag, const QStringList &strings, int type )
126 : QTreeWidgetItem( parent, strings, type ),
127 m_tag( tag )
128{
129}
130
131ViewListItem::ViewListItem( QTreeWidgetItem *parent, const QString &tag, const QStringList &strings, int type )
132 : QTreeWidgetItem( parent, strings, type ),
133 m_tag( tag )
134{
135}
136
137void ViewListItem::setReadWrite( bool rw )
138{
139 if ( type() == ItemType_SubView ) {
140 static_cast<ViewBase*>( view() )->updateReadWrite( rw );
141 }
142}
143
144void ViewListItem::setView( ViewBase *view )
145{
146 setData( 0, ViewListItem::DataRole_View, qVariantFromValue(static_cast<QObject*>( view ) ) );
147}
148
149ViewBase *ViewListItem::view() const
150{
151 if ( data(0, ViewListItem::DataRole_View ).isValid() ) {
152 return static_cast<ViewBase*>( data(0, ViewListItem::DataRole_View ).value<QObject*>() );
153 }
154 return 0;
155}
156
157void ViewListItem::setDocument( KoDocument *doc )
158{
159 setData( 0, ViewListItem::DataRole_Document, qVariantFromValue(static_cast<QObject*>( doc ) ) );
160}
161
162KoDocument *ViewListItem::document() const
163{
164 if ( data(0, ViewListItem::DataRole_Document ).isValid() ) {
165 return static_cast<KoDocument*>( data(0, ViewListItem::DataRole_Document ).value<QObject*>() );
166 }
167 return 0;
168}
169
170QString ViewListItem::viewType() const
171{
172 if ( type() != ItemType_SubView ) {
173 return QString();
174 }
175 QString name = view()->metaObject()->className();
176 if ( name.contains( ':' ) ) {
177 name = name.remove( 0, name.lastIndexOf( ':' ) + 1 );
178 }
179 return name;
180}
181
182void ViewListItem::save( QDomElement &element ) const
183{
184 element.setAttribute( "itemtype", type() );
185 element.setAttribute( "tag", tag() );
186
187 if ( type() == ItemType_SubView ) {
188 element.setAttribute( "viewtype", viewType() );
189 element.setAttribute( "name", m_viewinfo.name == text( 0 ) ? "" : text( 0 ) );
190 element.setAttribute( "tooltip", m_viewinfo.tip == toolTip( 0 ) ? TIP_USE_DEFAULT_TEXT : toolTip( 0 ) );
191 } else if ( type() == ItemType_Category ) {
192 kDebug(planDbg())<<text(0)<<m_viewinfo.name;
193 element.setAttribute( "name", text( 0 ) == m_viewinfo.name ? "" : text( 0 ) );
194 element.setAttribute( "tooltip", toolTip( 0 ).isEmpty() ? TIP_USE_DEFAULT_TEXT : toolTip( 0 ) );
195 }
196}
197
198ViewListTreeWidget::ViewListTreeWidget( QWidget *parent )
199 : QTreeWidget( parent )
200{
201 setWhatsThis( i18nc( "@info:whatsthis",
202 "<para>This is the list of available views and editors.</para>"
203 "<para>You can configure the list by using the context menu:"
204 "<list>"
205 "<item>Rename categories or views</item>"
206 "<item>Configure. Move, remove, rename or edit tool tip for categories or views</item>"
207 "<item>Insert categories and views</item>"
208 "</list></para>"
209 ) );
210
211 header() ->hide();
212 setRootIsDecorated( false );
213 setItemDelegate( new ViewCategoryDelegate( this, this ) );
214 setItemsExpandable( true );
215 setSelectionMode( QAbstractItemView::SingleSelection );
216
217 setDragDropMode( QAbstractItemView::InternalMove );
218
219 //setContextMenuPolicy( Qt::ActionsContextMenu );
220
221 connect( this, SIGNAL(itemPressed(QTreeWidgetItem*,int)), SLOT(handleMousePress(QTreeWidgetItem*)) );
222}
223
224void ViewListTreeWidget::drawRow( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
225{
226 QTreeWidget::drawRow( painter, option, index );
227}
228
229void ViewListTreeWidget::handleMousePress( QTreeWidgetItem *item )
230{
231 //kDebug(planDbg());
232 if ( item == 0 )
233 return ;
234
235 if ( item->parent() == 0 ) {
236 setItemExpanded( item, !isItemExpanded( item ) );
237 return ;
238 }
239}
240void ViewListTreeWidget::mousePressEvent ( QMouseEvent *event )
241{
242 if ( event->button() == Qt::RightButton ) {
243 QTreeWidgetItem *item = itemAt( event->pos() );
244 if ( item && item->type() == ViewListItem::ItemType_Category ) {
245 setCurrentItem( item );
246 emit customContextMenuRequested( event->pos() );
247 event->accept();
248 return;
249 }
250 }
251 QTreeWidget::mousePressEvent( event );
252}
253
254void ViewListTreeWidget::save( QDomElement &element ) const
255{
256 int cnt = topLevelItemCount();
257 if ( cnt == 0 ) {
258 return;
259 }
260 QDomElement cs = element.ownerDocument().createElement( "categories" );
261 element.appendChild( cs );
262 for ( int i = 0; i < cnt; ++i ) {
263 ViewListItem *itm = static_cast<ViewListItem*>( topLevelItem( i ) );
264 if ( itm->type() != ViewListItem::ItemType_Category ) {
265 continue;
266 }
267 QDomElement c = cs.ownerDocument().createElement( "category" );
268 cs.appendChild( c );
269 emit const_cast<ViewListTreeWidget*>( this )->updateViewInfo( itm );
270 itm->save( c );
271 for ( int j = 0; j < itm->childCount(); ++j ) {
272 ViewListItem *vi = static_cast<ViewListItem*>( itm->child( j ) );
273 if ( vi->type() != ViewListItem::ItemType_SubView ) {
274 continue;
275 }
276 QDomElement el = c.ownerDocument().createElement( "view" );
277 c.appendChild( el );
278 emit const_cast<ViewListTreeWidget*>( this )->updateViewInfo( vi );
279 vi->save( el );
280 QDomElement elm = el.ownerDocument().createElement( "settings" );
281 el.appendChild( elm );
282 static_cast<ViewBase*>( vi->view() )->saveContext( elm );
283 }
284 }
285}
286
287
288// </Code mostly nicked from qt designer ;)>
289
290void ViewListTreeWidget::startDrag( Qt::DropActions supportedActions )
291{
292 QModelIndexList indexes = selectedIndexes();
293 if ( indexes.count() == 1 ) {
294 ViewListItem *item = static_cast<ViewListItem*>( itemFromIndex( indexes.at( 0 ) ) );
295 Q_ASSERT( item );
296 QTreeWidgetItem *root = invisibleRootItem();
297 int count = root->childCount();
298 if ( item && item->type() == ViewListItem::ItemType_Category ) {
299 root->setFlags( root->flags() | Qt::ItemIsDropEnabled );
300 for ( int i = 0; i < count; ++i ) {
301 QTreeWidgetItem * ch = root->child( i );
302 ch->setFlags( ch->flags() & ~Qt::ItemIsDropEnabled );
303 }
304 } else if ( item ) {
305 root->setFlags( root->flags() & ~Qt::ItemIsDropEnabled );
306 for ( int i = 0; i < count; ++i ) {
307 QTreeWidgetItem * ch = root->child( i );
308 ch->setFlags( ch->flags() | Qt::ItemIsDropEnabled );
309 }
310 }
311 }
312 QTreeWidget::startDrag( supportedActions );
313}
314
315void ViewListTreeWidget::dropEvent( QDropEvent *event )
316{
317 QTreeWidget::dropEvent( event );
318 if ( event->isAccepted() ) {
319 emit modified();
320 }
321}
322
323ViewListItem *ViewListTreeWidget::findCategory( const QString &cat )
324{
325 QTreeWidgetItem * item;
326 int cnt = topLevelItemCount();
327 for ( int i = 0; i < cnt; ++i ) {
328 item = topLevelItem( i );
329 if ( static_cast<ViewListItem*>(item)->tag() == cat )
330 return static_cast<ViewListItem*>(item);
331 }
332 return 0;
333}
334
335ViewListItem *ViewListTreeWidget::category( const KoView *view ) const
336{
337 QTreeWidgetItem * item;
338 int cnt = topLevelItemCount();
339 for ( int i = 0; i < cnt; ++i ) {
340 item = topLevelItem( i );
341 for ( int c = 0; c < item->childCount(); ++c ) {
342 if ( view == static_cast<ViewListItem*>( item->child( c ) )->view() ) {
343 return static_cast<ViewListItem*>( item );
344 }
345 }
346 }
347 return 0;
348}
349
350//-----------------------
351ViewListWidget::ViewListWidget( MainDocument *part, QWidget *parent )//QString name, KXmlGuiWindow *parent )
352 : QWidget( parent ),
353 m_part( part ),
354 m_prev( 0 ),
355 m_temp( 0 )
356{
357 setObjectName("ViewListWidget");
358 m_viewlist = new ViewListTreeWidget( this );
359 m_viewlist->setEditTriggers( QAbstractItemView::NoEditTriggers );
360 connect(m_viewlist, SIGNAL(modified()), this, SIGNAL(modified()));
361
362 m_currentSchedule = new KComboBox( this );
363 m_model.setFlat( true );
364
365 m_sfModel.setFilterKeyColumn ( ScheduleModel::ScheduleScheduled );
366 m_sfModel.setFilterRole( Qt::EditRole );
367 m_sfModel.setFilterFixedString( "true" );
368 m_sfModel.setDynamicSortFilter ( true );
369 m_sfModel.setSourceModel( &m_model );
370 m_currentSchedule->setModel( &m_sfModel );
371
372 QVBoxLayout *l = new QVBoxLayout( this );
373 l->setMargin( 0 );
374 l->addWidget( m_viewlist );
375 l->addWidget( m_currentSchedule );
376
377 connect( m_viewlist, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), SLOT(slotActivated(QTreeWidgetItem*,QTreeWidgetItem*)) );
378
379 connect( m_viewlist, SIGNAL(itemChanged(QTreeWidgetItem*,int)), SLOT(slotItemChanged(QTreeWidgetItem*,int)) );
380
381 setupContextMenus();
382
383 connect( m_currentSchedule, SIGNAL(activated(int)), SLOT(slotCurrentScheduleChanged(int)) );
384
385 connect( &m_model, SIGNAL(scheduleManagerAdded(ScheduleManager*)), SLOT(slotScheduleManagerAdded(ScheduleManager*)) );
386
387 connect( m_viewlist, SIGNAL(updateViewInfo(ViewListItem*)), SIGNAL(updateViewInfo(ViewListItem*)) );
388}
389
390ViewListWidget::~ViewListWidget()
391{
392}
393
394void ViewListWidget::setReadWrite( bool rw )
395{
396 foreach ( ViewListItem *c, categories() ) {
397 for ( int i = 0; i < c->childCount(); ++i ) {
398 static_cast<ViewListItem*>( c->child( i ) )->setReadWrite( rw );
399 }
400 }
401}
402
403void ViewListWidget::slotItemChanged( QTreeWidgetItem */*item*/, int /*col */)
404{
405 //kDebug(planDbg());
406}
407
408void ViewListWidget::slotActivated( QTreeWidgetItem *item, QTreeWidgetItem *prev )
409{
410 if ( m_prev ) {
411 m_prev->setData( 0, Qt::BackgroundRole, QVariant() );
412 }
413 if ( item && item->type() == ViewListItem::ItemType_Category ) {
414 return ;
415 }
416 emit activated( static_cast<ViewListItem*>( item ), static_cast<ViewListItem*>( prev ) );
417 if ( item ) {
418 QVariant v = QBrush( QColor( Qt::yellow ) );
419 item->setData( 0, Qt::BackgroundRole, v );
420 m_prev = static_cast<ViewListItem*>( item );
421 }
422}
423
424ViewListItem *ViewListWidget::addCategory( const QString &tag, const QString& name )
425{
426 //kDebug(planDbg()) ;
427 ViewListItem *item = m_viewlist->findCategory( tag );
428 if ( item == 0 ) {
429 item = new ViewListItem( m_viewlist, tag, QStringList( name ), ViewListItem::ItemType_Category );
430 item->setExpanded( true );
431 item->setFlags( item->flags() | Qt::ItemIsEditable );
432 }
433 return item;
434}
435
436QList<ViewListItem*> ViewListWidget::categories() const
437{
438 QList<ViewListItem*> lst;
439 QTreeWidgetItem *item;
440 int cnt = m_viewlist->topLevelItemCount();
441 for ( int i = 0; i < cnt; ++i ) {
442 item = m_viewlist->topLevelItem( i );
443 if ( item->type() == ViewListItem::ItemType_Category )
444 lst << static_cast<ViewListItem*>( item );
445 }
446 return lst;
447}
448
449ViewListItem *ViewListWidget::findCategory( const QString &tag ) const
450{
451 return m_viewlist->findCategory( tag );
452}
453
454ViewListItem *ViewListWidget::category( const KoView *view ) const
455{
456 return m_viewlist->category( view );
457}
458
459QString ViewListWidget::uniqueTag( const QString &seed ) const
460{
461 QString tag = seed;
462 for ( int i = 1; findItem( tag ); ++i ) {
463 tag = QString("%1-%2").arg( seed ).arg( i );
464 }
465 return tag;
466}
467
468ViewListItem *ViewListWidget::addView(QTreeWidgetItem *category, const QString &tag, const QString &name, ViewBase *view, KoDocument *doc, const QString &iconName, int index)
469{
470 ViewListItem * item = new ViewListItem( uniqueTag( tag ), QStringList( name ), ViewListItem::ItemType_SubView );
471 item->setView( view );
472 item->setDocument( doc );
473 if (! iconName.isEmpty()) {
474 item->setData(0, Qt::DecorationRole, KIcon(iconName));
475 }
476 item->setFlags( ( item->flags() | Qt::ItemIsEditable ) & ~Qt::ItemIsDropEnabled );
477 insertViewListItem( item, category, index );
478
479 connect(view, SIGNAL(optionsModified()), SLOT(setModified()));
480
481 return item;
482}
483
484void ViewListWidget::setSelected( QTreeWidgetItem *item )
485{
486 //kDebug(planDbg())<<item<<","<<m_viewlist->currentItem();
487 if ( item == 0 && m_viewlist->currentItem() ) {
488 m_viewlist->currentItem()->setSelected( false );
489 if ( m_prev ) {
490 m_prev->setData( 0, Qt::BackgroundRole, QVariant() );
491 }
492 }
493 m_viewlist->setCurrentItem( item );
494 //kDebug(planDbg())<<item<<","<<m_viewlist->currentItem();
495}
496
497void ViewListWidget::setCurrentItem( QTreeWidgetItem *item )
498{
499 m_viewlist->setCurrentItem( item );
500 //kDebug(planDbg())<<item<<","<<m_viewlist->currentItem();
501}
502
503ViewListItem *ViewListWidget::currentItem() const
504{
505 return static_cast<ViewListItem*>( m_viewlist->currentItem() );
506}
507
508ViewListItem *ViewListWidget::currentCategory() const
509{
510 ViewListItem *item = static_cast<ViewListItem*>( m_viewlist->currentItem() );
511 if ( item == 0 ) {
512 return 0;
513 }
514 if ( item->type() == ViewListItem::ItemType_Category ) {
515 return item;
516 }
517 return static_cast<ViewListItem*>( item->parent() );
518}
519
520KoView *ViewListWidget::findView( const QString &tag ) const
521{
522 ViewListItem *i = findItem( tag );
523 if ( i == 0 ) {
524 return 0;
525 }
526 return i->view();
527}
528
529ViewListItem *ViewListWidget::findItem( const QString &tag ) const
530{
531 ViewListItem *item = findItem( tag, m_viewlist->invisibleRootItem() );
532 if ( item == 0 ) {
533 QTreeWidgetItem *parent = m_viewlist->invisibleRootItem();
534 for (int i = 0; i < parent->childCount(); ++i ) {
535 item = findItem( tag, parent->child( i ) );
536 if ( item != 0 ) {
537 break;
538 }
539 }
540 }
541 return item;
542}
543
544ViewListItem *ViewListWidget::findItem( const QString &tag, QTreeWidgetItem *parent ) const
545{
546 if ( parent == 0 ) {
547 return findItem( tag, m_viewlist->invisibleRootItem() );
548 }
549 for (int i = 0; i < parent->childCount(); ++i ) {
550 ViewListItem * ch = static_cast<ViewListItem*>( parent->child( i ) );
551 if ( ch->tag() == tag ) {
552 //kDebug(planDbg())<<ch<<","<<view;
553 return ch;
554 }
555 ch = findItem( tag, ch );
556 if ( ch ) {
557 return ch;
558 }
559 }
560 return 0;
561}
562
563ViewListItem *ViewListWidget::findItem( const ViewBase *view, QTreeWidgetItem *parent ) const
564{
565 if ( parent == 0 ) {
566 return findItem( view, m_viewlist->invisibleRootItem() );
567 }
568 for (int i = 0; i < parent->childCount(); ++i ) {
569 ViewListItem * ch = static_cast<ViewListItem*>( parent->child( i ) );
570 if ( ch->view() == view ) {
571 //kDebug(planDbg())<<ch<<","<<view;
572 return ch;
573 }
574 ch = findItem( view, ch );
575 if ( ch ) {
576 return ch;
577 }
578 }
579 return 0;
580}
581
582void ViewListWidget::slotAddView()
583{
584 emit createView();
585}
586
587void ViewListWidget::slotRemoveCategory()
588{
589 if ( m_contextitem == 0 ) {
590 return;
591 }
592 if ( m_contextitem->type() != ViewListItem::ItemType_Category ) {
593 return;
594 }
595 kDebug(planDbg())<<m_contextitem<<":"<<m_contextitem->type();
596 if ( m_contextitem->childCount() > 0 ) {
597 if ( KMessageBox::warningContinueCancel( this, i18n( "Removing this category will also remove all its views." ) ) == KMessageBox::Cancel ) {
598 return;
599 }
600 }
601 // first remove all views in this category
602 while ( m_contextitem->childCount() > 0 ) {
603 ViewListItem *itm = static_cast<ViewListItem*>( m_contextitem->child( 0 ) );
604 takeViewListItem( itm );
605 delete itm->view();
606 delete itm;
607 }
608 takeViewListItem( m_contextitem );
609 delete m_contextitem;
610 m_contextitem = 0;
611 emit modified();
612}
613
614void ViewListWidget::slotRemoveView()
615{
616 if ( m_contextitem ) {
617 takeViewListItem( m_contextitem );
618 delete m_contextitem->view();
619 delete m_contextitem;
620 emit modified();
621 }
622}
623
624void ViewListWidget::slotEditViewTitle()
625{
626 //QTreeWidgetItem *item = m_viewlist->currentItem();
627 if ( m_contextitem ) {
628 kDebug(planDbg())<<m_contextitem<<":"<<m_contextitem->type();
629 QString title = m_contextitem->text( 0 );
630 m_viewlist->editItem( m_contextitem );
631 if ( title != m_contextitem->text( 0 ) ) {
632 emit modified();
633 }
634 }
635}
636
637void ViewListWidget::slotConfigureItem()
638{
639 if ( m_contextitem == 0 ) {
640 return;
641 }
642 KDialog *dlg = 0;
643 if ( m_contextitem->type() == ViewListItem::ItemType_Category ) {
644 kDebug(planDbg())<<m_contextitem<<":"<<m_contextitem->type();
645 dlg = new ViewListEditCategoryDialog( *this, m_contextitem, this );
646 } else if ( m_contextitem->type() == ViewListItem::ItemType_SubView ) {
647 dlg = new ViewListEditViewDialog( *this, m_contextitem, this );
648 }
649 if ( dlg ) {
650 connect(dlg, SIGNAL(finished(int)), SLOT(slotDialogFinished(int)));
651 dlg->show();
652 dlg->raise();
653 dlg->activateWindow();
654 }
655}
656
657void ViewListWidget::slotDialogFinished( int result )
658{
659 if ( result == QDialog::Accepted ) {
660 emit modified();
661 }
662 if ( sender() ) {
663 sender()->deleteLater();
664 }
665}
666
667void ViewListWidget::slotEditDocumentTitle()
668{
669 //QTreeWidgetItem *item = m_viewlist->currentItem();
670 if ( m_contextitem ) {
671 kDebug(planDbg())<<m_contextitem<<":"<<m_contextitem->type();
672 QString title = m_contextitem->text( 0 );
673 m_viewlist->editItem( m_contextitem );
674 }
675}
676
677int ViewListWidget::removeViewListItem( ViewListItem *item )
678{
679 QTreeWidgetItem *p = item->parent();
680 if ( p == 0 ) {
681 p = m_viewlist->invisibleRootItem();
682 }
683 int i = p->indexOfChild( item );
684 if ( i != -1 ) {
685 p->takeChild( i );
686 emit modified();
687 }
688 return i;
689}
690
691void ViewListWidget::addViewListItem( ViewListItem *item, QTreeWidgetItem *parent, int index )
692{
693 QTreeWidgetItem *p = parent;
694 if ( p == 0 ) {
695 p = m_viewlist->invisibleRootItem();
696 }
697 if ( index == -1 ) {
698 index = p->childCount();
699 }
700 p->insertChild( index, item );
701 emit modified();
702}
703
704int ViewListWidget::takeViewListItem( ViewListItem *item )
705{
706 while ( item->childCount() > 0 ) {
707 takeViewListItem( static_cast<ViewListItem*>( item->child( 0 ) ) );
708 }
709 int pos = removeViewListItem( item );
710 if ( pos != -1 ) {
711 emit viewListItemRemoved( item );
712 if ( item == m_prev ) {
713 m_prev = 0;
714 }
715 if ( m_prev ) {
716 setCurrentItem( m_prev );
717 }
718 }
719 return pos;
720}
721
722void ViewListWidget::insertViewListItem( ViewListItem *item, QTreeWidgetItem *parent, int index )
723{
724 addViewListItem( item, parent, index );
725 emit viewListItemInserted( item, static_cast<ViewListItem*>( parent ), index );
726}
727
728void ViewListWidget::setupContextMenus()
729{
730 // NOTE: can't use xml file as there may not be a factory()
731 QAction *action;
732 // view actions
733 action = new QAction(koIcon("edit-rename"), i18nc("@action:inmenu rename view", "Rename"), this);
734 connect( action, SIGNAL(triggered(bool)), this, SLOT(slotEditViewTitle()) );
735 m_viewactions.append( action );
736
737 action = new QAction(koIcon("configure"), i18nc("@action:inmenu configure view", "Configure..."), this );
738 connect( action, SIGNAL(triggered(bool)), this, SLOT(slotConfigureItem()) );
739 m_viewactions.append( action );
740
741 action = new QAction(koIcon("list-remove"), i18nc("@action:inmenu remove view", "Remove"), this);
742 connect( action, SIGNAL(triggered(bool)), this, SLOT(slotRemoveView()) );
743 m_viewactions.append( action );
744
745 action = new QAction( this );
746 action->setSeparator( true );
747 m_viewactions.append( action );
748
749 // Category actions
750 action = new QAction(koIcon("edit-rename"), i18nc("@action:inmenu rename view category", "Rename"), this);
751 connect( action, SIGNAL(triggered(bool)), SLOT(renameCategory()) );
752 m_categoryactions.append( action );
753
754 action = new QAction(koIcon("configure"), i18nc("@action:inmenu configure view category", "Configure..."), this);
755 connect( action, SIGNAL(triggered(bool)), this, SLOT(slotConfigureItem()) );
756 m_categoryactions.append( action );
757
758 action = new QAction(koIcon("list-remove"), i18nc("@action:inmenu Remove view category", "Remove"),this);
759 connect( action, SIGNAL(triggered(bool)), this, SLOT(slotRemoveCategory()) );
760 m_categoryactions.append( action );
761
762 action = new QAction( this );
763 action->setSeparator( true );
764 m_categoryactions.append( action );
765
766 // list actions
767 action = new QAction(koIcon("list-add"), i18nc("@action:inmenu Insert View", "Insert..."), this);
768 connect( action, SIGNAL(triggered(bool)), this, SLOT(slotAddView()) );
769 m_listactions.append( action );
770}
771
772void ViewListWidget::renameCategory()
773{
774 if ( m_contextitem ) {
775 QString title = m_contextitem->text( 0 );
776 m_viewlist->editItem( m_contextitem, 0 );
777 }
778}
779
780void ViewListWidget::contextMenuEvent ( QContextMenuEvent *event )
781{
782 KMenu menu;
783 QList<QAction*> lst;
784 m_contextitem = static_cast<ViewListItem*>(m_viewlist->itemAt( event->pos() ) );
785 if ( m_contextitem == 0 ) {
786 lst += m_listactions;
787 } else {
788 if ( m_contextitem->type() == ViewListItem::ItemType_Category ) {
789 lst += m_categoryactions;
790 } else if ( m_contextitem->type() == ViewListItem::ItemType_SubView ) {
791 lst += m_viewactions;
792 ViewBase *v = dynamic_cast<ViewBase*>( m_contextitem->view() );
793 if ( v ) {
794 lst += v->viewlistActionList();
795 }
796 }
797 lst += m_listactions;
798 }
799 if ( ! lst.isEmpty() ) {
800 //menu.addTitle( i18n( "Edit" ) );
801 foreach ( QAction *a, lst ) {
802 menu.addAction( a );
803 }
804 }
805 if ( ! menu.actions().isEmpty() ) {
806 menu.exec( event->globalPos() );
807 }
808}
809
810void ViewListWidget::save( QDomElement &element ) const
811{
812 m_viewlist->save( element );
813}
814
815void ViewListWidget::setProject( Project *project )
816{
817 kDebug(planDbg())<<project;
818 m_model.setProject( project );
819}
820
821void ViewListWidget::slotCurrentScheduleChanged( int idx )
822{
823 kDebug(planDbg())<<idx<<selectedSchedule();
824 emit selectionChanged( selectedSchedule() );
825}
826
827ScheduleManager *ViewListWidget::selectedSchedule() const
828{
829 QModelIndex idx = m_sfModel.index( m_currentSchedule->currentIndex(), m_currentSchedule->modelColumn() );
830 kDebug(planDbg())<<idx;
831 return m_sfModel.manager( idx );
832}
833
834void ViewListWidget::setSelectedSchedule( ScheduleManager *sm )
835{
836 kDebug(planDbg())<<sm<<m_model.index( sm );
837 QModelIndex idx = m_sfModel.mapFromSource( m_model.index( sm ) );
838 if ( sm && ! idx.isValid()) {
839 m_temp = sm;
840 return;
841 }
842 m_currentSchedule->setCurrentIndex( idx.row() );
843 kDebug(planDbg())<<sm<<idx;
844 m_temp = 0;
845}
846
847void ViewListWidget::slotScheduleManagerAdded( ScheduleManager *sm )
848{
849 if ( m_temp && m_temp == sm ) {
850 setSelectedSchedule( sm );
851 m_temp = 0;
852 }
853}
854
855void ViewListWidget::setModified()
856{
857 emit modified();
858}
859
860} //KPlato namespace
861
862#include "kptviewlist.moc"
863