30 #include "korganizer/korganizerinterface.h"
32 #include <Akonadi/Contact/ContactSearchJob>
34 #include <KCal/Calendar>
35 #include <KCal/CalHelper>
36 #include <KCal/IncidenceFormatter>
38 #include <KHolidays/Holidays>
40 #include <KontactInterface/Core>
43 #include <KConfigGroup>
44 #include <KIconLoader>
45 #include <KLocalizedString>
47 #include <KSystemTimeZones>
52 #include <QVBoxLayout>
79 bool operator<(
const SDEntry &entry )
const
81 return daysTo < entry.daysTo;
86 : KontactInterface::Summary( parent ), mPlugin( plugin ), mCalendar( 0 )
92 QWidget *header = createHeader(
this,
"view-pim-summary", i18n(
"Planner" ) );
100 connect( mCalendar, SIGNAL(calendarChanged()), SLOT(updateView()) );
101 connect( mPlugin->core(), SIGNAL(dayChanged(
QDate)), SLOT(updateView()) );
109 KConfig config(
"plannerrc" );
112 KConfigGroup group = config.group(
"General" );
113 mShowRecurrence = group.readEntry(
"ShowRecurrence",
true );
114 mShowReminder = group.readEntry(
"ShowReminder",
true );
115 mUnderline = group.readEntry(
"underlineLink",
true );
116 mTodo = group.readEntry(
"ShowTodo",
true );
117 mSd = group.readEntry(
"ShowSd",
true );
120 group = config.group(
"Calendar" );
121 mCustomDays = group.readEntry(
"DaysToShow", 1 );
124 group = config.group(
"Hide" );
125 mHideCompleted = group.readEntry(
"Completed",
true );
126 mHideOpenEnded = group.readEntry(
"OpenEnded",
false );
127 mHideInProgress = group.readEntry(
"InProgress",
false );
128 mHideOverdue = group.readEntry(
"Overdue",
false );
129 mHideNotStarted = group.readEntry(
"NotStarted",
false );
132 group = config.group(
"SpecialDates" );
134 mBirthdayConList = group.readEntry(
"BirthdayConList",
true );
136 mAnniversariesConList = group.readEntry(
"AnniversariesConList",
true );
137 mHolidaysCal = group.readEntry(
"HolidaysCal",
true );
138 mSpecialOccasionsCal = group.readEntry(
"SpecialOccasionsCal",
true );
141 group = config.group(
"Groupware" );
142 mShowMyEventsOnly = group.readEntry(
"ShowMyEventsOnly",
false );
143 mShowMyTodosOnly = group.readEntry(
"ShowMyTodosOnly",
false );
148 void Planner::updateView()
154 KIconLoader loader(
"kdepim" );
162 for ( dt = currentDate;
163 dt <= currentDate.
addDays( mCustomDays - 1 );
174 if ( !mEvents.empty() || ( !mTodos.empty() && mTodo ) || ( !mDates.
empty() && mSd ) ) {
177 bool makeBold =
false;
182 if ( ( sD.
month() == currentDate.
month() ) && ( sD.
day() == currentDate.
day() ) ) {
183 datestr = i18nc(
"today",
"Today" );
187 datestr = i18nc(
"tomorrow",
"Tomorrow" );
189 datestr = KGlobal::locale()->formatDate( sD );
192 label =
new QLabel( datestr,
this );
211 gridLayout->
addItem( mPlannerGrid );
215 if ( !mDates.
empty() && mSd ) {
216 counter = showSd( counter, dt );
218 if ( !mTodos.empty() && mTodo ) {
219 counter = showTodos( counter, dt );
221 if ( !mEvents.empty() ) {
222 counter = showEvents( counter, dt );
229 i18np(
"No appointments pending within the next day",
230 "No appointments pending within the next %1 days", mCustomDays ),
this );
231 noEvents->
setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
233 mLabels.
append( noEvents );
236 Q_FOREACH ( label, mLabels ) {
241 void Planner::initTodoList(
const QDate &
date )
243 mTodos.setAutoDelete(
true );
245 mTodos.setAutoDelete(
false );
248 Q_FOREACH ( Todo *todo, mCalendar->todos() ) {
250 if ( mShowMyTodosOnly && !CalHelper::isMyCalendarIncidence( mCalendar, todo ) ) {
255 if ( !mHideOverdue && overdue( todo ) && date != currentDate ) {
258 if ( mHideOverdue && overdue( todo ) ) {
262 if ( !mHideInProgress && inProgress( todo ) && date != currentDate ) {
265 if ( mHideInProgress && inProgress( todo ) ) {
269 if ( !mHideCompleted && completed( todo ) && date != currentDate ) {
272 if ( mHideCompleted && completed( todo ) ) {
276 if ( !mHideOpenEnded && openEnded( todo ) && date != currentDate ) {
279 if ( mHideOpenEnded && openEnded( todo ) ) {
283 if ( !mHideNotStarted && notStarted( todo ) && date != currentDate ) {
286 if ( mHideNotStarted && notStarted( todo ) ) {
289 if ( !overdue( todo ) && !inProgress( todo ) && !completed( todo ) && !openEnded( todo ) &&
290 !notStarted( todo ) && todo->hasDueDate() && todo->dtDue().date() !=
date ) {
293 mTodos.append( todo );
296 if ( !mTodos.isEmpty() ) {
297 mTodos = Calendar::sortTodos( &mTodos,
299 SortDirectionAscending );
300 mTodos = Calendar::sortTodos( &mTodos,
302 SortDirectionAscending );
303 mTodos = Calendar::sortTodos( &mTodos,
305 SortDirectionAscending );
309 int Planner::showTodos(
int counter,
const QDate &date )
311 KIconLoader loader(
"kdepim" );
313 if ( !mTodos.empty() ) {
317 Q_FOREACH ( Todo *todo, mTodos ) {
318 QString stateText = initStateText ( todo, date );
322 QPixmap todoPm = loader.loadIcon(
"view-pim-tasks", KIconLoader::Small );
326 mPlannerGrid->
addWidget( label, counter, 1 );
332 KUrlLabel *urlLabel =
new KUrlLabel(
this );
333 urlLabel->setText( percent );
334 urlLabel->setUrl( todo->uid() );
335 if ( stateText == i18nc(
"to-do is overdue",
"overdue" ) ) {
336 urlLabel->setText(
"<font color = red >" + percent +
"</font>" );
338 urlLabel->setAlignment( Qt::AlignHCenter | Qt::AlignTop );
340 urlLabel->setUnderline(
false );
342 urlLabel->setWordWrap(
true );
343 urlLabel->setMaximumWidth( urlLabel->minimumSizeHint().width() );
344 mPlannerGrid->
addWidget( urlLabel, counter, 3 );
345 mLabels.
append( urlLabel );
347 connect( urlLabel, SIGNAL(rightClickedUrl(
QString)),
348 this, SLOT(changePercentage(
QString)) );
350 QString string = todo->summary();
351 if ( todo->relatedTo() ) {
352 string = todo->relatedTo()->summary() +
':' + todo->summary();
357 KUrlLabel *urlLabel2 =
new KUrlLabel(
this );
358 urlLabel2->setText(
string );
359 urlLabel2->setUrl( todo->uid() );
360 urlLabel2->installEventFilter(
this );
361 urlLabel2->setAlignment( Qt::AlignLeft | Qt::AlignTop );
362 urlLabel2->setWordWrap(
true );
363 if ( stateText == i18nc(
"to-do is overdue",
"overdue" ) ) {
364 urlLabel2->setText(
"<font color = red >" +
string +
"</font>" );
367 urlLabel2->setUnderline(
false );
369 mPlannerGrid->
addWidget( urlLabel2, counter, 5 );
370 mLabels.
append( urlLabel2 );
372 connect( urlLabel2, SIGNAL(leftClickedUrl(
QString)),
373 this, SLOT(viewTodo(
QString)) );
374 connect( urlLabel2, SIGNAL(rightClickedUrl(
QString)),
375 this, SLOT(todoPopupMenu(
QString)) );
377 QString tipText( IncidenceFormatter::toolTipStr(
378 mCalendar, todo, date,
true, KSystemTimeZones::local() ) );
379 if ( !tipText.isEmpty() ) {
380 urlLabel2->setToolTip( tipText );
385 label =
new QLabel( stateText,
this );
386 if ( stateText == i18nc(
"to-do is overdue",
"overdue" ) ) {
387 label->
setText(
"<font color = red >" + stateText +
" </font>" );
391 mPlannerGrid->
addWidget( label, counter, 7 );
396 if ( mShowReminder ) {
398 if ( todo->hasEnabledAlarms() ) {
399 alarm = loader.loadIcon(
"task-reminder", KIconLoader::Small );
401 label =
new QLabel(
this );
404 mPlannerGrid->
addWidget( label, counter, 9 );
410 if ( mShowRecurrence ) {
412 if ( todo->hasEnabledAlarms() ) {
413 recur = loader.loadIcon(
"task-recurring", KIconLoader::Small );
415 label =
new QLabel(
this );
418 mPlannerGrid->
addWidget( label, counter, 11 );
427 void Planner::initEventList(
const QDate &date )
429 mEvents.setAutoDelete(
true );
431 mEvents.setAutoDelete(
false );
433 Q_FOREACH ( Event *ev, mCalendar->events( date, mCalendar->timeSpec() ) ) {
435 if ( mShowMyEventsOnly && !CalHelper::isMyCalendarIncidence( mCalendar, ev ) ) {
438 mEvents.append( ev );
442 mEvents = Calendar::sortEvents( &mEvents,
444 SortDirectionAscending );
446 mEvents = Calendar::sortEvents( &mEvents,
448 SortDirectionAscending );
451 int Planner::showEvents(
int counter,
const QDate &date )
453 KIconLoader loader(
"kdepim" );
455 if ( !mEvents.empty() ) {
464 Q_FOREACH ( Event *ev, mEvents ) {
468 if ( ev->isMultiDay() ) {
469 QDate d = ev->dtStart().date();
470 if ( d < currentDate ) {
473 while ( d < ev->dtEnd().
date() ) {
484 if ( ev->isMultiDay() && ev->allDay() && dayof != 1 ) {
491 QPixmap re = loader.loadIcon(
"view-calendar-day", KIconLoader::Small );
492 label =
new QLabel(
this );
496 mPlannerGrid->
addWidget( label, counter, 1 );
503 KDateTime::Spec spec = KSystemTimeZones::local();
504 if ( ev->isMultiDay() && ev->allDay() && dayof == 1 && span > 1 ) {
505 KDateTime ksD( sD.
addDays( span - 1 ), spec );
506 datestr = IncidenceFormatter::dateToString( ev->dtStart(),
false, spec ) +
508 IncidenceFormatter::dateToString( ksD,
false, spec );
509 label =
new QLabel( datestr,
this );
511 mPlannerGrid->
addWidget( label, counter, 3 );
516 if ( !ev->allDay() ) {
517 QTime sST = ev->dtStart().toTimeSpec( spec ).time();
518 QTime sET = ev->dtEnd().toTimeSpec( spec ).time();
519 if ( ev->isMultiDay() ) {
520 if ( ev->dtStart().date() <
date ) {
523 if ( ev->dtEnd().date() >
date ) {
524 sET =
QTime( 23, 59 );
528 datestr = i18nc(
"Time from - to",
"%1 - %2",
529 KGlobal::locale()->formatTime( sST ),
530 KGlobal::locale()->formatTime( sET ) );
531 label =
new QLabel( datestr,
this );
534 mPlannerGrid->
addWidget( label, counter, 3 );
541 QString newtext = ev->summary();
542 if ( ev->isMultiDay() && !ev->allDay() ) {
543 newtext.
append(
QString(
" (%1/%2)" ).arg( dayof ).arg( span ) );
545 KUrlLabel *urlLabel =
new KUrlLabel(
this );
546 urlLabel->setText( newtext );
547 urlLabel->setUrl( ev->uid() );
548 urlLabel->installEventFilter(
this );
549 urlLabel->setAlignment( Qt::AlignLeft | Qt::AlignTop );
550 urlLabel->setWordWrap(
true );
552 urlLabel->setUnderline(
false );
554 mPlannerGrid->
addWidget( urlLabel, counter, 5 );
555 mLabels.
append( urlLabel );
562 if ( mShowReminder ) {
564 if ( ev->hasEnabledAlarms () ) {
565 alarm = loader.loadIcon(
"task-reminder", KIconLoader::Small );
567 label =
new QLabel(
this );
571 mPlannerGrid->
addWidget( label, counter, 9 );
580 if ( mShowRecurrence ) {
582 if ( ev->recurs() ) {
583 recur = loader.loadIcon(
"appointment-recurring", KIconLoader::Small );
585 label =
new QLabel(
this );
589 mPlannerGrid->
addWidget( label, counter, 11 );
593 connect( urlLabel, SIGNAL(leftClickedUrl(
QString)),
594 this, SLOT(viewEvent(
QString)) );
595 connect( urlLabel, SIGNAL(rightClickedUrl(
QString)),
596 this, SLOT(eventPopupMenu(
QString)) );
598 QString tipText( IncidenceFormatter::toolTipStr(
599 mCalendar, ev, date,
true, KSystemTimeZones::local() ) );
600 if ( !tipText.isEmpty() ) {
601 urlLabel->setToolTip( tipText );
610 bool Planner::initHolidays()
612 KConfig _hconfig(
"korganizerrc" );
613 KConfigGroup hconfig( &_hconfig,
"Time & Date" );
614 QString location = hconfig.readEntry(
"Holidays" );
616 mHolidays =
new KHolidays::HolidayRegion( location );
622 void Planner::initSdList(
const QDate &date )
626 Akonadi::ContactSearchJob *job =
new Akonadi::ContactSearchJob(
this );
629 Q_FOREACH (
const Addressee &addressee, job->contacts() ) {
630 const QDate birthday = addressee.birthday().date();
631 if ( birthday.
isValid() && mBirthdayConList &&
636 entry.date = birthday;
637 entry.addressee = addressee;
642 QString anniversaryAsString = addressee.custom(
"KADDRESSBOOK",
"X-Anniversary" );
643 if ( !anniversaryAsString.
isEmpty() ) {
645 if ( anniversary.
isValid() && mAnniversariesConList &&
650 entry.date = anniversary;
651 entry.addressee = addressee;
658 if ( mHolidaysCal ) {
659 if ( initHolidays() ) {
660 Q_FOREACH (
const KHolidays::Holiday &holiday, mHolidays->holidays( date ) ) {
661 if ( !mSpecialOccasionsCal && holiday.dayType() != KHolidays::Holiday::NonWorkday ) {
666 entry.category = ( holiday.dayType() == KHolidays::Holiday::NonWorkday )?
669 entry.summary = holiday.text();
676 int Planner::showSd(
int counter,
const QDate &date )
678 KIconLoader loader(
"kdepim" );
683 loader.loadIcon(
"view-calendar-birthday", KIconLoader::Small );
685 loader.loadIcon(
"view-calendar-wedding-anniversary", KIconLoader::Small );
687 loader.loadIcon(
"view-calendar-holiday", KIconLoader::Small );
689 loader.loadIcon(
"favorites", KIconLoader::Small );
692 Q_FOREACH (
const SDEntry &entry, mDates ) {
697 switch ( entry.category ) {
708 label->
setPixmap( specialOccasionsIcon );
713 mPlannerGrid->
addWidget( label, counter, 1 );
719 switch ( entry.category ) {
721 catName = i18n(
"Birthday" );
724 catName = i18n(
"Anniversary" );
727 catName = i18n(
"Holiday" );
730 catName = i18n(
"Special Occasion" );
733 label =
new QLabel(
this );
735 label->
setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
736 mPlannerGrid->
addWidget( label, counter, 3 );
742 KUrlLabel *urlLabel =
new KUrlLabel(
this );
743 urlLabel->installEventFilter(
this );
744 urlLabel->setUrl( entry.addressee.uid() );
745 urlLabel->setText( entry.addressee.realName() );
746 urlLabel->setTextFormat( Qt::RichText );
747 urlLabel->setWordWrap(
true );
749 urlLabel->setUnderline(
false );
751 mPlannerGrid->
addWidget( urlLabel, counter, 5 );
752 mLabels.
append( urlLabel );
754 label =
new QLabel(
this );
755 label->
setText( entry.summary );
757 mPlannerGrid->
addWidget( label, counter, 5 );
759 if ( !entry.desc.isEmpty() ) {
767 label =
new QLabel(
this );
768 if ( entry.yearsOld <= 0 ) {
771 label->
setText( i18np(
"one year",
"%1 years", entry.yearsOld ) );
773 label->
setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
774 mPlannerGrid->
addWidget( label, counter, 7 );
783 void Planner::viewEvent(
const QString &uid )
785 mPlugin->core()->selectPlugin(
"kontact_korganizerplugin" );
786 OrgKdeKorganizerKorganizerInterface korganizer(
788 korganizer.editIncidence( uid );
791 void Planner::removeEvent(
const QString &uid )
793 mPlugin->core()->selectPlugin(
"kontact_korganizerplugin" );
794 OrgKdeKorganizerKorganizerInterface korganizer(
796 korganizer.deleteIncidence( uid,
false );
799 void Planner::eventPopupMenu(
const QString &uid )
802 QAction *editIt = popup.addAction( i18n(
"&Edit Appointment..." ) );
803 QAction *delIt = popup.addAction( i18n(
"&Delete Appointment" ) );
804 delIt->
setIcon( KIconLoader::global()->loadIcon(
"edit-delete", KIconLoader::Small ) );
807 if ( selectedAction == editIt ) {
809 }
else if ( selectedAction == delIt ) {
816 if ( obj->
inherits(
"KUrlLabel" ) ) {
817 KUrlLabel *label =
static_cast<KUrlLabel*
>( obj );
818 if ( e->
type() == QEvent::Enter ) {
819 emit message( i18n(
"Edit Appointment: \"%1\"", label->text() ) );
821 if ( e->
type() == QEvent::Leave ) {
822 emit message( QString::null );
826 return KontactInterface::Summary::eventFilter( obj, e );
829 QString Planner::initStateText(
const Todo *todo,
const QDate &date )
834 if ( todo->hasDueDate() && !todo->isCompleted() &&
835 todo->dtDue().date() < currentDate ) {
836 stateText = i18nc(
"to-do is overdue",
"overdue" );
840 if ( todo->hasStartDate() && todo->hasDueDate() &&
841 todo->dtStart().date() < date &&
842 date < todo->dtDue().date() ) {
843 stateText = i18nc(
"work on to-do is in progress",
"in progress" );
847 if ( todo->hasStartDate() && todo->dtStart().date() ==
date ) {
848 stateText = i18nc(
"to-do starts today",
"starts today" );
852 if ( todo->hasDueDate() && todo->dtDue().date() == date && todo->dtDue().date() == currentDate ) {
853 stateText = i18nc(
"to-do due today",
"due today" );
855 if ( todo->isCompleted() ) {
856 stateText = i18nc(
"to-do is completed",
"completed" );
861 void Planner::todoPopupMenu(
const QString &uid )
864 QAction *editIt = popup.addAction( i18n(
"&Edit To-do..." ) );
865 QAction *delIt = popup.addAction( i18n(
"&Delete To-do" ) );
866 delIt->
setIcon( KIconLoader::global()->loadIcon(
"edit-delete", KIconLoader::Small ) );
868 Todo *todo = mCalendar->todo( uid );
869 if ( !todo->isCompleted() ) {
870 doneIt = popup.addAction( i18n(
"&Mark To-do Completed" ) );
871 doneIt->
setIcon( KIconLoader::global()->loadIcon(
"task-complete", KIconLoader::Small ) );
876 if ( selectedAction == editIt ) {
878 }
else if ( selectedAction == delIt ) {
880 }
else if ( doneIt && selectedAction == doneIt ) {
885 void Planner::viewTodo(
const QString &uid )
887 mPlugin->core()->selectPlugin(
"kontact_todoplugin" );
888 OrgKdeKorganizerKorganizerInterface korganizer(
890 korganizer.editIncidence( uid );
893 void Planner::removeTodo(
const QString &uid )
895 mPlugin->core()->selectPlugin(
"kontact_todoplugin" );
896 OrgKdeKorganizerKorganizerInterface korganizer(
898 korganizer.deleteIncidence( uid,
false );
901 void Planner::completeTodo(
const QString &uid )
903 Todo *todo = mCalendar->todo( uid );
904 if ( !todo->isReadOnly() ) {
905 todo->setCompleted( KDateTime::currentLocalDateTime() );
911 void Planner::changePercentage(
const QString &uid )
914 QAction *per00 = popup.addAction( i18n(
"%1%", 0 ) );
915 QAction *per10 = popup.addAction( i18n(
"%1%", 10 ) );
916 QAction *per20 = popup.addAction( i18n(
"%1%", 20 ) );
917 QAction *per30 = popup.addAction( i18n(
"%1%", 30 ) );
918 QAction *per40 = popup.addAction( i18n(
"%1%", 40 ) );
919 QAction *per50 = popup.addAction( i18n(
"%1%", 50 ) );
920 QAction *per60 = popup.addAction( i18n(
"%1%", 60 ) );
921 QAction *per70 = popup.addAction( i18n(
"%1%", 70 ) );
922 QAction *per80 = popup.addAction( i18n(
"%1%", 80 ) );
923 QAction *per90 = popup.addAction( i18n(
"%1%", 90 ) );
924 QAction *per100= popup.addAction( i18n(
"%1%", 100 ) );
926 Todo *todo = mCalendar->todo( uid );
927 if ( !todo->isReadOnly() && mCalendar->beginChange( todo ) ) {
929 if ( selectedAction == per00 ) {
930 todo->setPercentComplete( 0 );
931 }
else if ( selectedAction == per10 ) {
932 todo->setPercentComplete( 10 );
933 }
else if ( selectedAction == per20 ) {
934 todo->setPercentComplete( 20 );
935 }
else if ( selectedAction == per30 ) {
936 todo->setPercentComplete( 30 );
937 }
else if ( selectedAction == per40 ) {
938 todo->setPercentComplete( 40 );
939 }
else if ( selectedAction == per50 ) {
940 todo->setPercentComplete( 50 );
941 }
else if ( selectedAction == per60 ) {
942 todo->setPercentComplete( 60 );
943 }
else if ( selectedAction == per70 ) {
944 todo->setPercentComplete( 70 );
945 }
else if ( selectedAction == per80 ) {
946 todo->setPercentComplete( 80 );
947 }
else if ( selectedAction == per90 ) {
948 todo->setPercentComplete( 90 );
949 }
else if ( selectedAction == per100 ) {
950 todo->setCompleted(
true );
952 mCalendar->endChange( todo );
959 if ( obj->
inherits(
"KUrlLabel" ) ) {
960 KUrlLabel *label =
static_cast<KUrlLabel*
>( obj );
961 if ( e->
type() == QEvent::Enter ) {
962 emit message( i18n(
"Edit To-do: \"%1\"", label->text() ) );
964 if ( e->
type() == QEvent::Leave ) {
969 return KontactInterface::Summary::eventFilter( obj, e );
977 bool Planner::overdue( Todo *todo )
979 if ( todo->hasDueDate() && !todo->isCompleted() &&
986 bool Planner::completed( Todo *todo )
988 return todo->isCompleted();
991 bool Planner::openEnded( Todo *todo )
993 if ( !todo->hasDueDate() && !todo->isCompleted() ) {
999 bool Planner::inProgress( Todo *todo )
1001 if ( overdue( todo ) ) {
1005 if ( todo->percentComplete() > 0 ) {
1010 if ( todo->hasStartDate() && todo->hasDueDate() &&
1011 todo->dtStart().date() < currDate &&
1012 currDate < todo->dtDue().date() ) {
1019 bool Planner::notStarted( Todo *todo )
1021 if ( todo->percentComplete() > 0 ) {
1025 if ( !todo->hasStartDate() ) {
QString & append(QChar ch)
QStringList configModules() const
void setPixmap(const QPixmap &)
void setIcon(const QIcon &icon)
void setAlignment(QFlags< Qt::AlignmentFlag >)
QDBusConnection sessionBus()
void setBold(bool enable)
QDate fromString(const QString &string, Qt::DateFormat format)
QString number(int n, int base)
void append(const T &value)
Planner(KontactInterface::Plugin *plugin, QWidget *parent)
bool inherits(const char *className) const
virtual void addItem(QLayoutItem *item)
virtual bool todoEventFilter(QObject *obj, QEvent *e)
void setTextFormat(Qt::TextFormat)
void setText(const QString &)
void setMargin(int margin)
static StdCalendar * self()
void setItalic(bool enable)
void setColumnMinimumWidth(int column, int minSize)
virtual QSize minimumSizeHint() const
QDate addDays(int ndays) const
virtual bool eventFilter(QObject *obj, QEvent *e)
void setSpacing(int spacing)
void addLayout(QLayout *layout, int stretch)