summaryview_part.cpp
1/*
2 This file is part of KDE Kontact.
3
4 Copyright (C) 2003 Sven Lüppken <sven@kde.org>
5 Copyright (C) 2003 Tobias König <tokoe@kde.org>
6 Copyright (C) 2003 Daniel Molkentin <molkentin@kde.org>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA.
22*/
23
24#include <tqframe.h>
25#include <tqlabel.h>
26#include <tqlayout.h>
27#include <tqtimer.h>
28
29#include <dcopclient.h>
30#include <tdeaction.h>
31#include <tdeapplication.h>
32#include <tdeconfig.h>
33#include <kdcopservicestarter.h>
34#include <kdebug.h>
35#include <kdialog.h>
36#include <tdelocale.h>
37#include <tdemessagebox.h>
38#include <kservice.h>
39#include <ktrader.h>
40#include <tdestandarddirs.h>
41#include <tqscrollview.h>
42#include <tdeglobal.h>
43#include <tdelocale.h>
44#include <kcmultidialog.h>
45
46#include <tdeparts/componentfactory.h>
47#include <tdeparts/event.h>
48
49#include <libkpimidentities/identity.h>
50#include <libkpimidentities/identitymanager.h>
51
52#include <infoextension.h>
53#include <sidebarextension.h>
54
55#include "plugin.h"
56#include "summary.h"
57
58#include "summaryview_part.h"
59
60#include "broadcaststatus.h"
61using KPIM::BroadcastStatus;
62
63namespace Kontact
64{
65 class MainWindow;
66}
67
68SummaryViewPart::SummaryViewPart( Kontact::Core *core, const char*,
69 const TDEAboutData *aboutData,
70 TQObject *parent, const char *name )
71 : KParts::ReadOnlyPart( parent, name ),
72 mCore( core ), mFrame( 0 ), mConfigAction( 0 )
73{
74 setInstance( new TDEInstance( aboutData ) );
75
76 loadLayout();
77
78 initGUI( core );
79
80 connect( tdeApp, TQ_SIGNAL( tdedisplayPaletteChanged() ), TQ_SLOT( slotAdjustPalette() ) );
81 slotAdjustPalette();
82
83 setDate( TQDate::currentDate() );
84 connect( mCore, TQ_SIGNAL( dayChanged( const TQDate& ) ),
85 TQ_SLOT( setDate( const TQDate& ) ) );
86
87 KParts::InfoExtension *info = new KParts::InfoExtension( this, "Summary" );
88 connect( this, TQ_SIGNAL( textChanged( const TQString& ) ),
89 info, TQ_SIGNAL( textChanged( const TQString& ) ) );
90
91 mConfigAction = new TDEAction( i18n( "&Configure Summary View..." ),
92 "configure", 0, this,
93 TQ_SLOT( slotConfigure() ), actionCollection(),
94 "summaryview_configure" );
95
96 setXMLFile( "kontactsummary_part.rc" );
97
98 TQTimer::singleShot( 0, this, TQ_SLOT( slotTextChanged() ) );
99}
100
101SummaryViewPart::~SummaryViewPart()
102{
103 saveLayout();
104}
105
106bool SummaryViewPart::openFile()
107{
108 kdDebug(5006) << "SummaryViewPart:openFile()" << endl;
109 return true;
110}
111
112void SummaryViewPart::partActivateEvent( KParts::PartActivateEvent *event )
113{
114 // inform the plugins that the part has been activated so that they can
115 // update the displayed information
116 if ( event->activated() && ( event->part() == this ) ) {
117 updateSummaries();
118 }
119
120 KParts::ReadOnlyPart::partActivateEvent( event );
121}
122
123void SummaryViewPart::updateSummaries()
124{
125 TQMap<TQString, Kontact::Summary*>::Iterator it;
126 for ( it = mSummaries.begin(); it != mSummaries.end(); ++it )
127 it.data()->updateSummary( false );
128}
129
130void SummaryViewPart::updateWidgets()
131{
132 mMainWidget->setUpdatesEnabled( false );
133
134 delete mFrame;
135
136 KPIM::IdentityManager idm( true, this );
137 const KPIM::Identity &id = idm.defaultIdentity();
138
139 TQString currentUser = i18n( "Summary for %1" ).arg( id.fullName() );
140 mUsernameLabel->setText( TQString::fromLatin1( "<b>%1</b>" ).arg( currentUser ) );
141
142 mSummaries.clear();
143
144 mFrame = new DropWidget( mMainWidget );
145 connect( mFrame, TQ_SIGNAL( summaryWidgetDropped( TQWidget*, TQWidget*, int ) ),
146 this, TQ_SLOT( summaryWidgetMoved( TQWidget*, TQWidget*, int ) ) );
147
148 mMainLayout->insertWidget( 2, mFrame );
149
150 TQStringList activeSummaries;
151
152 TDEConfig config( "kontact_summaryrc" );
153 if ( !config.hasKey( "ActiveSummaries" ) ) {
154 activeSummaries << "kontact_kmailplugin";
155 activeSummaries << "kontact_specialdatesplugin";
156 activeSummaries << "kontact_korganizerplugin";
157 activeSummaries << "kontact_todoplugin";
158 activeSummaries << "kontact_newstickerplugin";
159 } else {
160 activeSummaries = config.readListEntry( "ActiveSummaries" );
161 }
162
163 // Collect all summary widgets with a summaryHeight > 0
164 TQStringList loadedSummaries;
165
166 TQValueList<Kontact::Plugin*> plugins = mCore->pluginList();
167 TQValueList<Kontact::Plugin*>::ConstIterator end = plugins.end();
168 TQValueList<Kontact::Plugin*>::ConstIterator it = plugins.begin();
169 for ( ; it != end; ++it ) {
170 Kontact::Plugin *plugin = *it;
171 if ( activeSummaries.find( plugin->identifier() ) == activeSummaries.end() )
172 continue;
173
174 Kontact::Summary *summary = plugin->createSummaryWidget( mFrame );
175 if ( summary ) {
176 if ( summary->summaryHeight() > 0 ) {
177 mSummaries.insert( plugin->identifier(), summary );
178
179 connect( summary, TQ_SIGNAL( message( const TQString& ) ),
180 BroadcastStatus::instance(), TQ_SLOT( setStatusMsg( const TQString& ) ) );
181 connect( summary, TQ_SIGNAL( summaryWidgetDropped( TQWidget*, TQWidget*, int ) ),
182 this, TQ_SLOT( summaryWidgetMoved( TQWidget*, TQWidget*, int ) ) );
183
184 if ( !mLeftColumnSummaries.contains( plugin->identifier() ) &&
185 !mRightColumnSummaries.contains( plugin->identifier() ) ) {
186 mLeftColumnSummaries.append( plugin->identifier() );
187 }
188
189 loadedSummaries.append( plugin->identifier() );
190 } else {
191 summary->hide();
192 }
193 }
194 }
195
196 // Remove all unavailable summary widgets
197 {
198 TQStringList::Iterator strIt;
199 for ( strIt = mLeftColumnSummaries.begin(); strIt != mLeftColumnSummaries.end(); ++strIt ) {
200 if ( loadedSummaries.find( *strIt ) == loadedSummaries.end() ) {
201 strIt = mLeftColumnSummaries.remove( strIt );
202 --strIt;
203 }
204 }
205 for ( strIt = mRightColumnSummaries.begin(); strIt != mRightColumnSummaries.end(); ++strIt ) {
206 if ( loadedSummaries.find( *strIt ) == loadedSummaries.end() ) {
207 strIt = mRightColumnSummaries.remove( strIt );
208 --strIt;
209 }
210 }
211 }
212
213 // Add vertical line between the two rows of summary widgets.
214 TQFrame *vline = new TQFrame( mFrame );
215 vline->setFrameStyle( TQFrame::VLine | TQFrame::Plain );
216
217 TQHBoxLayout *layout = new TQHBoxLayout( mFrame );
218
219 mLeftColumn = new TQVBoxLayout( layout, KDialog::spacingHint() );
220 layout->addWidget( vline );
221 mRightColumn = new TQVBoxLayout( layout, KDialog::spacingHint() );
222
223
224 TQStringList::Iterator strIt;
225 for ( strIt = mLeftColumnSummaries.begin(); strIt != mLeftColumnSummaries.end(); ++strIt ) {
226 if ( mSummaries.find( *strIt ) != mSummaries.end() )
227 mLeftColumn->addWidget( mSummaries[ *strIt ] );
228 }
229
230 for ( strIt = mRightColumnSummaries.begin(); strIt != mRightColumnSummaries.end(); ++strIt ) {
231 if ( mSummaries.find( *strIt ) != mSummaries.end() )
232 mRightColumn->addWidget( mSummaries[ *strIt ] );
233 }
234
235 mFrame->show();
236
237 mMainWidget->setUpdatesEnabled( true );
238 mMainWidget->update();
239
240 mLeftColumn->addStretch();
241 mRightColumn->addStretch();
242}
243
244void SummaryViewPart::summaryWidgetMoved( TQWidget *target, TQWidget *widget, int alignment )
245{
246 if ( target == widget )
247 return;
248
249 if ( target == mFrame ) {
250 if ( mLeftColumn->findWidget( widget ) == -1 && mRightColumn->findWidget( widget ) == -1 )
251 return;
252 } else {
253 if ( mLeftColumn->findWidget( target ) == -1 && mRightColumn->findWidget( target ) == -1 ||
254 mLeftColumn->findWidget( widget ) == -1 && mRightColumn->findWidget( widget ) == -1 )
255 return;
256 }
257
258 if ( mLeftColumn->findWidget( widget ) != -1 ) {
259 mLeftColumn->remove( widget );
260 mLeftColumnSummaries.remove( widgetName( widget ) );
261 } else if ( mRightColumn->findWidget( widget ) != -1 ) {
262 mRightColumn->remove( widget );
263 mRightColumnSummaries.remove( widgetName( widget ) );
264 }
265
266 if ( target == mFrame ) {
267 int pos = 0;
268
269 if ( alignment & TQt::AlignTop )
270 pos = 0;
271
272 if ( alignment & TQt::AlignLeft ) {
273 if ( alignment & TQt::AlignBottom )
274 pos = mLeftColumnSummaries.count();
275
276 mLeftColumn->insertWidget( pos, widget );
277 mLeftColumnSummaries.insert( mLeftColumnSummaries.at( pos ), widgetName( widget ) );
278 } else {
279 if ( alignment & TQt::AlignBottom )
280 pos = mRightColumnSummaries.count();
281
282 mRightColumn->insertWidget( pos, widget );
283 mRightColumnSummaries.insert( mRightColumnSummaries.at( pos ), widgetName( widget ) );
284 }
285
286 return;
287 }
288
289 int targetPos = mLeftColumn->findWidget( target );
290 if ( targetPos != -1 ) {
291 if ( alignment == TQt::AlignBottom )
292 targetPos++;
293
294 mLeftColumn->insertWidget( targetPos, widget );
295 mLeftColumnSummaries.insert( mLeftColumnSummaries.at( targetPos ), widgetName( widget ) );
296 } else {
297 targetPos = mRightColumn->findWidget( target );
298
299 if ( alignment == TQt::AlignBottom )
300 targetPos++;
301
302 mRightColumn->insertWidget( targetPos, widget );
303 mRightColumnSummaries.insert( mRightColumnSummaries.at( targetPos ), widgetName( widget ) );
304 }
305}
306
307void SummaryViewPart::slotTextChanged()
308{
309 emit textChanged( i18n( "What's next?" ) );
310}
311
312void SummaryViewPart::slotAdjustPalette()
313{
314 mMainWidget->setPaletteBackgroundColor( tdeApp->palette().active().base() );
315}
316
317void SummaryViewPart::setDate( const TQDate& newDate )
318{
319 TQString date( "<b>%1</b>" );
320 date = date.arg( TDEGlobal::locale()->formatDate( newDate ) );
321 mDateLabel->setText( date );
322}
323
324void SummaryViewPart::slotConfigure()
325{
326 KCMultiDialog dlg( mMainWidget, "ConfigDialog", true );
327
328 TQStringList modules = configModules();
329 modules.prepend( "kcmkontactsummary.desktop" );
330 connect( &dlg, TQ_SIGNAL( configCommitted() ),
331 this, TQ_SLOT( updateWidgets() ) );
332
333 TQStringList::ConstIterator strIt;
334 for ( strIt = modules.begin(); strIt != modules.end(); ++strIt )
335 dlg.addModule( *strIt );
336
337 dlg.exec();
338}
339
340TQStringList SummaryViewPart::configModules() const
341{
342 TQStringList modules;
343
344 TQMap<TQString, Kontact::Summary*>::ConstIterator it;
345 for ( it = mSummaries.begin(); it != mSummaries.end(); ++it ) {
346 TQStringList cm = it.data()->configModules();
347 TQStringList::ConstIterator strIt;
348 for ( strIt = cm.begin(); strIt != cm.end(); ++strIt )
349 if ( !(*strIt).isEmpty() && !modules.contains( *strIt ) )
350 modules.append( *strIt );
351 }
352
353 return modules;
354}
355
356void SummaryViewPart::initGUI( Kontact::Core *core )
357{
358 TQScrollView *sv = new TQScrollView( core );
359
360 sv->setResizePolicy( TQScrollView::AutoOneFit );
361 sv->setFrameStyle( TQFrame::NoFrame | TQFrame::Plain );
362 sv->setHScrollBarMode( TQScrollView::AlwaysOff );
363
364 mMainWidget = new TQFrame( sv->viewport() );
365 sv->addChild( mMainWidget );
366 mMainWidget->setFrameStyle( TQFrame::Panel | TQFrame::Sunken );
367 sv->setFocusPolicy( TQWidget::StrongFocus );
368 setWidget( sv );
369
370 mMainLayout = new TQVBoxLayout( mMainWidget,KDialog::marginHint(),
371 KDialog::spacingHint() );
372
373 TQHBoxLayout *hbl = new TQHBoxLayout( mMainLayout );
374 mUsernameLabel = new TQLabel( mMainWidget );
375 hbl->addWidget( mUsernameLabel );
376 mDateLabel = new TQLabel( mMainWidget );
377 mDateLabel->setAlignment( AlignRight );
378 hbl->addWidget( mDateLabel );
379
380 TQFrame *hline = new TQFrame( mMainWidget );
381 hline->setFrameStyle( TQFrame::HLine | TQFrame::Plain );
382 mMainLayout->insertWidget( 1, hline );
383
384 mFrame = new DropWidget( mMainWidget );
385 mMainLayout->insertWidget( 2, mFrame );
386
387 connect( mFrame, TQ_SIGNAL( summaryWidgetDropped( TQWidget*, TQWidget*, int ) ),
388 this, TQ_SLOT( summaryWidgetMoved( TQWidget*, TQWidget*, int ) ) );
389
390 updateWidgets();
391}
392
393void SummaryViewPart::loadLayout()
394{
395 TDEConfig config( "kontact_summaryrc" );
396
397 if ( !config.hasKey( "LeftColumnSummaries" ) ) {
398 mLeftColumnSummaries << "kontact_korganizerplugin";
399 mLeftColumnSummaries << "kontact_todoplugin";
400 mLeftColumnSummaries << "kontact_kaddressbookplugin";
401 mLeftColumnSummaries << "kontact_specialdatesplugin";
402 } else {
403 mLeftColumnSummaries = config.readListEntry( "LeftColumnSummaries" );
404 }
405
406 if ( !config.hasKey( "RightColumnSummaries" ) ) {
407 mRightColumnSummaries << "kontact_newstickerplugin";
408 } else {
409 mRightColumnSummaries = config.readListEntry( "RightColumnSummaries" );
410 }
411}
412
413void SummaryViewPart::saveLayout()
414{
415 TDEConfig config( "kontact_summaryrc" );
416
417 config.writeEntry( "LeftColumnSummaries", mLeftColumnSummaries );
418 config.writeEntry( "RightColumnSummaries", mRightColumnSummaries );
419
420 config.sync();
421}
422
423TQString SummaryViewPart::widgetName( TQWidget *widget ) const
424{
425 TQMap<TQString, Kontact::Summary*>::ConstIterator it;
426 for ( it = mSummaries.begin(); it != mSummaries.end(); ++it ) {
427 if ( it.data() == widget )
428 return it.key();
429 }
430
431 return TQString();
432}
433
434#include "summaryview_part.moc"
This class provides the interface to the Kontact core for the plugins.
Definition: core.h:42
Base class for all Plugins in Kontact.
Definition: plugin.h:59
TQString identifier() const
Returns the identifier.
Definition: plugin.cpp:84
virtual Summary * createSummaryWidget(TQWidget *)
Reimplement this method if you want to add a widget for your application to Kontact's summary page.
Definition: plugin.h:174
Summary widget for display in the Summary View plugin.
Definition: summary.h:37
virtual int summaryHeight() const
Return logical height of summary widget.
Definition: summary.h:51