1 | /* |
2 | This file is part of KHelpcenter. |
3 | |
4 | Copyright (C) 2002 Cornelius Schumacher <schumacher@kde.org> |
5 | |
6 | This program is free software; you can redistribute it and/or |
7 | modify it under the terms of the GNU General Public |
8 | License as published by the Free Software Foundation; either |
9 | version 2 of the License, or (at your option) any later version. |
10 | |
11 | This program is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU General Public License |
17 | along with this program; see the file COPYING. If not, write to |
18 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 | Boston, MA 02110-1301, USA. |
20 | */ |
21 | |
22 | #include "kcmhelpcenter.h" |
23 | |
24 | #include "htmlsearchconfig.h" |
25 | #include "docmetainfo.h" |
26 | #include "prefs.h" |
27 | #include "searchhandler.h" |
28 | #include "searchengine.h" |
29 | |
30 | #include "kcmhelpcenteradaptor.h" |
31 | |
32 | #include <KConfig> |
33 | #include <KDebug> |
34 | #include <KLocale> |
35 | #include <KGlobal> |
36 | #include <KAboutData> |
37 | #include <KDialog> |
38 | #include <KStandardDirs> |
39 | #include <KProcess> |
40 | #include <KApplication> |
41 | #include <KTemporaryFile> |
42 | #include <KUrlRequester> |
43 | #include <KMessageBox> |
44 | #include <KLineEdit> |
45 | |
46 | #include <QTreeWidget> |
47 | #include <QtDBus/QtDBus> |
48 | #include <QLabel> |
49 | #include <QLayout> |
50 | #include <QHeaderView> |
51 | #include <QProgressBar> |
52 | #include <QTextEdit> |
53 | |
54 | #include <unistd.h> |
55 | #include <sys/types.h> |
56 | |
57 | using namespace KHC; |
58 | |
59 | IndexDirDialog::IndexDirDialog( QWidget *parent ) |
60 | : KDialog( parent ) |
61 | { |
62 | setModal( true ); |
63 | setCaption( i18n("Change Index Folder" ) ); |
64 | setButtons( Ok | Cancel ); |
65 | |
66 | QFrame *topFrame = new QFrame( this ); |
67 | setMainWidget( topFrame ); |
68 | |
69 | QBoxLayout *urlLayout = new QHBoxLayout( topFrame ); |
70 | |
71 | QLabel *label = new QLabel( i18n("Index folder:" ), topFrame ); |
72 | urlLayout->addWidget( label ); |
73 | |
74 | mIndexUrlRequester = new KUrlRequester( topFrame ); |
75 | mIndexUrlRequester->setMode( KFile::Directory | KFile::ExistingOnly | |
76 | KFile::LocalOnly ); |
77 | urlLayout->addWidget( mIndexUrlRequester ); |
78 | |
79 | mIndexUrlRequester->setUrl( Prefs::indexDirectory() ); |
80 | connect(mIndexUrlRequester->lineEdit(),SIGNAL(textChanged ( const QString & )), this, SLOT(slotUrlChanged( const QString &))); |
81 | slotUrlChanged( mIndexUrlRequester->lineEdit()->text() ); |
82 | |
83 | connect( this, SIGNAL( okClicked() ), SLOT( slotOk() ) ); |
84 | } |
85 | |
86 | void IndexDirDialog::slotUrlChanged( const QString &_url ) |
87 | { |
88 | enableButtonOk( !_url.isEmpty() ); |
89 | } |
90 | |
91 | |
92 | void IndexDirDialog::slotOk() |
93 | { |
94 | Prefs::setIndexDirectory( mIndexUrlRequester->url().url() ); |
95 | accept(); |
96 | } |
97 | |
98 | |
99 | IndexProgressDialog::IndexProgressDialog( QWidget *parent ) |
100 | : KDialog( parent ), |
101 | mFinished( true ) |
102 | { |
103 | setCaption( i18n("Build Search Indices" ) ); |
104 | |
105 | QVBoxLayout *topLayout = new QVBoxLayout( mainWidget() ); |
106 | topLayout->setMargin( marginHint() ); |
107 | topLayout->setSpacing( spacingHint() ); |
108 | |
109 | mLabel = new QLabel( mainWidget() ); |
110 | mLabel->setAlignment( Qt::AlignHCenter ); |
111 | topLayout->addWidget( mLabel ); |
112 | |
113 | mProgressBar = new QProgressBar( mainWidget() ); |
114 | topLayout->addWidget( mProgressBar ); |
115 | |
116 | mLogLabel = new QLabel( i18n("Index creation log:" ), mainWidget() ); |
117 | topLayout->addWidget( mLogLabel ); |
118 | |
119 | mLogView = new QTextEdit( mainWidget() ); |
120 | mLogView->setReadOnly( true ); |
121 | mLogView->setWordWrapMode( QTextOption::NoWrap ); |
122 | mLogView->setMinimumHeight( 200 ); |
123 | topLayout->addWidget( mLogView ); |
124 | |
125 | setButtons( User1 | Close ); |
126 | connect( this, SIGNAL( closeClicked() ), SLOT( slotEnd() ) ); |
127 | connect( this, SIGNAL( user1Clicked() ), SLOT( toggleDetails() ) ); |
128 | |
129 | hideDetails(); |
130 | |
131 | setFinished( false ); |
132 | } |
133 | |
134 | IndexProgressDialog::~IndexProgressDialog() |
135 | { |
136 | if ( !mLogView->isHidden() ) { |
137 | KConfigGroup cfg(KGlobal::config(), "indexprogressdialog" ); |
138 | cfg.writeEntry( "size" , size() ); |
139 | } |
140 | } |
141 | |
142 | void IndexProgressDialog::setTotalSteps( int steps ) |
143 | { |
144 | mProgressBar->setRange( 0, steps ); |
145 | mProgressBar->setValue( 0 ); |
146 | setFinished( false ); |
147 | mLogView->clear(); |
148 | } |
149 | |
150 | void IndexProgressDialog::advanceProgress() |
151 | { |
152 | mProgressBar->setValue( mProgressBar->value() + 1 ); |
153 | } |
154 | |
155 | void IndexProgressDialog::setLabelText( const QString &text ) |
156 | { |
157 | mLabel->setText( text ); |
158 | } |
159 | |
160 | void IndexProgressDialog::setMinimumLabelWidth( int width ) |
161 | { |
162 | mLabel->setMinimumWidth( width ); |
163 | } |
164 | |
165 | void IndexProgressDialog::setFinished( bool finished ) |
166 | { |
167 | if ( finished == mFinished ) return; |
168 | |
169 | mFinished = finished; |
170 | |
171 | if ( mFinished ) { |
172 | setButtonText( Close, i18nc("Label for button to close search index progress dialog after successful completion" , "Close" ) ); |
173 | mLabel->setText( i18n("Index creation finished." ) ); |
174 | mProgressBar->setValue( mProgressBar->maximum() ); |
175 | } else { |
176 | setButtonText( Close, i18nc("Label for stopping search index generation before completion" , "Stop" ) ); |
177 | } |
178 | } |
179 | |
180 | void IndexProgressDialog::appendLog( const QString &text ) |
181 | { |
182 | mLogView->append( text ); |
183 | } |
184 | |
185 | void IndexProgressDialog::slotEnd() |
186 | { |
187 | if ( mFinished ) { |
188 | emit closed(); |
189 | accept(); |
190 | } else { |
191 | emit cancelled(); |
192 | reject(); |
193 | } |
194 | } |
195 | |
196 | void IndexProgressDialog::toggleDetails() |
197 | { |
198 | KConfigGroup cfg(KGlobal::config(), "indexprogressdialog" ); |
199 | if ( mLogView->isHidden() ) { |
200 | mLogLabel->show(); |
201 | mLogView->show(); |
202 | setButtonText( User1, i18n("Details <<" ) ); |
203 | QSize size = cfg.readEntry( "size" , QSize() ); |
204 | if ( !size.isEmpty() ) resize( size ); |
205 | } else { |
206 | cfg.writeEntry( "size" , size() ); |
207 | hideDetails(); |
208 | } |
209 | } |
210 | |
211 | void IndexProgressDialog::hideDetails() |
212 | { |
213 | mLogLabel->hide(); |
214 | mLogView->hide(); |
215 | setButtonText( User1, i18n("Details >>" ) ); |
216 | |
217 | // causes bug 166343 |
218 | //layout()->activate(); |
219 | adjustSize(); |
220 | } |
221 | |
222 | |
223 | KCMHelpCenter::KCMHelpCenter( KHC::SearchEngine *engine, QWidget *parent, |
224 | const char *name) |
225 | : KDialog( parent ), |
226 | mEngine( engine ), mProgressDialog( 0 ), mCmdFile( 0 ), |
227 | mProcess( 0 ), mIsClosing( false ), mRunAsRoot( false ) |
228 | { |
229 | new KcmhelpcenterAdaptor(this); |
230 | QDBusConnection::sessionBus().registerObject(QLatin1String("/kcmhelpcenter" ), this); |
231 | setObjectName( name ); |
232 | setCaption( i18n("Build Search Index" ) ); |
233 | setButtons( Ok | Cancel ); |
234 | |
235 | QWidget *widget = new QWidget( this ); |
236 | setMainWidget( widget ); |
237 | |
238 | setupMainWidget( widget ); |
239 | |
240 | setButtonGuiItem( KDialog::Ok, KGuiItem(i18n("Build Index" )) ); |
241 | |
242 | mConfig = KGlobal::config(); |
243 | |
244 | DocMetaInfo::self()->scanMetaInfo(); |
245 | |
246 | load(); |
247 | const QString dbusInterface = "org.kde.khelpcenter.kcmhelpcenter" ; |
248 | QDBusConnection dbus = QDBusConnection::sessionBus(); |
249 | bool success = dbus.connect(QString(), "/kcmhelpcenter" , dbusInterface, "buildIndexProgress" , this, SLOT(slotIndexProgress())); |
250 | if ( !success ) |
251 | kError() << "connect D-Bus signal failed" << endl; |
252 | success = dbus.connect(QString(), "/kcmhelpcenter" , dbusInterface, "buildIndexError" , this, SLOT(slotIndexError(const QString&))); |
253 | if ( !success ) |
254 | kError() << "connect D-Bus signal failed" << endl; |
255 | KConfigGroup id( mConfig, "IndexDialog" ); |
256 | restoreDialogSize( id ); |
257 | } |
258 | |
259 | KCMHelpCenter::~KCMHelpCenter() |
260 | { |
261 | KConfigGroup cg( KGlobal::config(), "IndexDialog" ); |
262 | KDialog::saveDialogSize( cg ); |
263 | } |
264 | |
265 | void KCMHelpCenter::setupMainWidget( QWidget *parent ) |
266 | { |
267 | QVBoxLayout *topLayout = new QVBoxLayout( parent ); |
268 | topLayout->setSpacing( KDialog::spacingHint() ); |
269 | |
270 | QString helpText = |
271 | i18n("To be able to search a document, a search\n" |
272 | "index needs to exist. The status column of the list below shows whether an index\n" |
273 | "for a document exists.\n" ) + |
274 | i18n("To create an index, check the box in the list and press the\n" |
275 | "\"Build Index\" button.\n" ); |
276 | |
277 | QLabel *label = new QLabel( helpText, parent ); |
278 | topLayout->addWidget( label ); |
279 | |
280 | mListView = new QTreeWidget( parent ); |
281 | //mListView->setFullWidth( true ); |
282 | mListView->setColumnCount(2); |
283 | mListView->setHeaderLabels( QStringList() << i18n("Search Scope" ) << i18n("Status" ) ); |
284 | topLayout->addWidget( mListView ); |
285 | // not just itemClicked, so that Key_Space also triggers it (#123954) |
286 | connect( mListView, SIGNAL(itemChanged(QTreeWidgetItem*,int)), |
287 | SLOT(checkSelection()) ); |
288 | |
289 | QBoxLayout *urlLayout = new QHBoxLayout(); |
290 | topLayout->addLayout( urlLayout ); |
291 | |
292 | QLabel *urlLabel = new QLabel( i18n("Index folder:" ), parent ); |
293 | urlLayout->addWidget( urlLabel ); |
294 | |
295 | mIndexDirLabel = new QLabel( parent ); |
296 | urlLayout->addWidget( mIndexDirLabel, 1 ); |
297 | |
298 | QPushButton *button = new QPushButton( i18n("Change..." ), parent ); |
299 | connect( button, SIGNAL( clicked() ), SLOT( showIndexDirDialog() ) ); |
300 | urlLayout->addWidget( button ); |
301 | |
302 | QBoxLayout *buttonLayout = new QHBoxLayout(); |
303 | topLayout->addLayout( buttonLayout ); |
304 | |
305 | buttonLayout->addStretch( 1 ); |
306 | |
307 | connect( this, SIGNAL( okClicked() ), SLOT( slotOk() ) ); |
308 | } |
309 | |
310 | void KCMHelpCenter::defaults() |
311 | { |
312 | } |
313 | |
314 | bool KCMHelpCenter::save() |
315 | { |
316 | kDebug(1401) << "KCMHelpCenter::save()" ; |
317 | |
318 | if ( !QFile::exists( Prefs::indexDirectory() ) ) { |
319 | KMessageBox::sorry( this, |
320 | i18n("<qt>The folder <b>%1</b> does not exist; unable to create index.</qt>" , |
321 | Prefs::indexDirectory() ) ); |
322 | return false; |
323 | } else { |
324 | return buildIndex(); |
325 | } |
326 | |
327 | return true; |
328 | } |
329 | |
330 | void KCMHelpCenter::load() |
331 | { |
332 | mIndexDirLabel->setText( Prefs::indexDirectory() ); |
333 | |
334 | mListView->clear(); |
335 | |
336 | const DocEntry::List &entries = DocMetaInfo::self()->docEntries(); |
337 | DocEntry::List::ConstIterator it; |
338 | for( it = entries.begin(); it != entries.end(); ++it ) { |
339 | // kDebug(1401) << "Entry: " << (*it)->name() << " Indexer: '" |
340 | // << (*it)->indexer() << "'" << endl; |
341 | if ( mEngine->needsIndex( *it ) ) { |
342 | ScopeItem *item = new ScopeItem( mListView, *it ); |
343 | item->setOn( (*it)->searchEnabled() ); |
344 | } |
345 | } |
346 | |
347 | mListView->header()->setResizeMode( QHeaderView::ResizeToContents ); |
348 | |
349 | updateStatus(); |
350 | } |
351 | |
352 | void KCMHelpCenter::updateStatus() |
353 | { |
354 | QTreeWidgetItemIterator it( mListView ); |
355 | while ( (*it) != 0 ) { |
356 | ScopeItem *item = static_cast<ScopeItem *>( (*it) ); |
357 | QString status; |
358 | if ( item->entry()->indexExists( Prefs::indexDirectory() ) ) { |
359 | status = i18nc("Describes the status of a documentation index that is present" , "OK" ); |
360 | item->setOn( false ); |
361 | } else { |
362 | status = i18nc("Describes the status of a documentation index that is missing" , "Missing" ); |
363 | } |
364 | item->setText( 1, status ); |
365 | |
366 | ++it; |
367 | } |
368 | |
369 | checkSelection(); |
370 | } |
371 | |
372 | bool KCMHelpCenter::buildIndex() |
373 | { |
374 | kDebug(1401) << "Build Index" ; |
375 | |
376 | kDebug() << "IndexPath: '" << Prefs::indexDirectory() << "'" ; |
377 | |
378 | if ( mProcess ) { |
379 | kError() << "Error: Index Process still running." << endl; |
380 | return false; |
381 | } |
382 | |
383 | mIndexQueue.clear(); |
384 | |
385 | QFontMetrics fm( font() ); |
386 | int maxWidth = 0; |
387 | |
388 | mCmdFile = new KTemporaryFile; |
389 | if ( !mCmdFile->open() ) { |
390 | kError() << "Error opening command file." << endl; |
391 | deleteCmdFile(); |
392 | return false; |
393 | } |
394 | |
395 | QTextStream ts ( mCmdFile ); |
396 | kDebug() << "Writing to file '" << mCmdFile->fileName() << "'" ; |
397 | |
398 | bool hasError = false; |
399 | |
400 | QTreeWidgetItemIterator it( mListView ); |
401 | while ( (*it) != 0 ) { |
402 | ScopeItem *item = static_cast<ScopeItem *>( (*it) ); |
403 | if ( item->isOn() ) { |
404 | DocEntry *entry = item->entry(); |
405 | |
406 | QString docText = i18nc(" Generic prefix label for error messages when creating documentation index, first arg is the document's identifier, second is the document's name" , "Document '%1' (%2):\n" , |
407 | entry->identifier() , |
408 | entry->name() ); |
409 | if ( entry->documentType().isEmpty() ) { |
410 | KMessageBox::sorry( this, docText + |
411 | i18n("No document type." ) ); |
412 | hasError = true; |
413 | } else { |
414 | QString error; |
415 | SearchHandler *handler = mEngine->handler( entry->documentType() ); |
416 | if ( !handler ) { |
417 | KMessageBox::sorry( this, docText + |
418 | i18n("No search handler available for document type '%1'." , |
419 | entry->documentType() ) ); |
420 | hasError = true; |
421 | } else if ( !handler->checkPaths( &error ) ) { |
422 | KMessageBox::sorry( this, docText + error ); |
423 | hasError = true; |
424 | } else { |
425 | QString indexer = handler->indexCommand( entry->identifier() ); |
426 | if ( indexer.isEmpty() ) { |
427 | KMessageBox::sorry( this, docText + |
428 | i18n("No indexing command specified for document type '%1'." , |
429 | entry->documentType() ) ); |
430 | hasError = true; |
431 | } else { |
432 | indexer.replace( QLatin1String("%i" ), entry->identifier() ); |
433 | indexer.replace( QLatin1String( "%d" ), Prefs::indexDirectory() ); |
434 | indexer.replace( QLatin1String( "%p" ), entry->url() ); |
435 | kDebug() << "INDEXER: " << indexer; |
436 | ts << indexer << endl; |
437 | |
438 | int width = fm.width( entry->name() ); |
439 | if ( width > maxWidth ) maxWidth = width; |
440 | |
441 | mIndexQueue.append( entry ); |
442 | } |
443 | } |
444 | } |
445 | } |
446 | ++it; |
447 | } |
448 | |
449 | ts.flush(); |
450 | |
451 | if ( mIndexQueue.isEmpty() ) { |
452 | deleteCmdFile(); |
453 | return !hasError; |
454 | } |
455 | |
456 | mCurrentEntry = mIndexQueue.constBegin(); |
457 | QString name = (*mCurrentEntry)->name(); |
458 | |
459 | if ( !mProgressDialog ) { |
460 | mProgressDialog = new IndexProgressDialog( parentWidget() ); |
461 | connect( mProgressDialog, SIGNAL( cancelled() ), |
462 | SLOT( cancelBuildIndex() ) ); |
463 | connect( mProgressDialog, SIGNAL( closed() ), |
464 | SLOT( slotProgressClosed() ) ); |
465 | } |
466 | mProgressDialog->setLabelText( name ); |
467 | mProgressDialog->setTotalSteps( mIndexQueue.count() ); |
468 | mProgressDialog->setMinimumLabelWidth( maxWidth ); |
469 | mProgressDialog->show(); |
470 | |
471 | startIndexProcess(); |
472 | |
473 | return true; |
474 | } |
475 | |
476 | void KCMHelpCenter::startIndexProcess() |
477 | { |
478 | kDebug() << "KCMHelpCenter::startIndexProcess()" ; |
479 | |
480 | mProcess = new KProcess; |
481 | #ifndef Q_WS_WIN |
482 | if ( mRunAsRoot ) { |
483 | QString kdesu = KStandardDirs::findExe("kdesu" ); |
484 | if(kdesu.isEmpty()) { |
485 | kError() << "Failed to run index process as root - could not find kdesu" ; |
486 | } else { |
487 | *mProcess << kdesu; |
488 | if(parentWidget()) { |
489 | *mProcess << "--attach" << QString::number(parentWidget()->window()->winId()); |
490 | kDebug() << "Run as root, attaching kdesu to winid " << QString::number(parentWidget()->window()->winId()); |
491 | } |
492 | *mProcess << "--" ; |
493 | } |
494 | } |
495 | #endif |
496 | |
497 | *mProcess << KStandardDirs::findExe("khc_indexbuilder" ); |
498 | *mProcess << mCmdFile->fileName(); |
499 | *mProcess << Prefs::indexDirectory(); |
500 | |
501 | mProcess->setOutputChannelMode(KProcess::SeparateChannels); |
502 | connect( mProcess, SIGNAL( readyReadStandardError() ), |
503 | SLOT( slotReceivedStderr() ) ); |
504 | connect( mProcess, SIGNAL( readyReadStandardOutput() ), |
505 | SLOT( slotReceivedStdout() ) ); |
506 | connect( mProcess, SIGNAL( finished(int, QProcess::ExitStatus) ), |
507 | SLOT( slotIndexFinished(int, QProcess::ExitStatus) ) ); |
508 | |
509 | mProcess->start(); |
510 | if (!mProcess->waitForStarted()) { |
511 | kError() << "KCMHelpcenter::startIndexProcess(): Failed to start process." ; |
512 | deleteProcess(); |
513 | deleteCmdFile(); |
514 | } |
515 | } |
516 | |
517 | void KCMHelpCenter::cancelBuildIndex() |
518 | { |
519 | kDebug() << "cancelBuildIndex()" ; |
520 | |
521 | deleteProcess(); |
522 | deleteCmdFile(); |
523 | mIndexQueue.clear(); |
524 | |
525 | if ( mIsClosing ) { |
526 | mIsClosing = false; |
527 | } |
528 | } |
529 | |
530 | void KCMHelpCenter::slotIndexFinished(int exitCode, QProcess::ExitStatus exitStatus) |
531 | { |
532 | kDebug() << "KCMHelpCenter::slotIndexFinished()" ; |
533 | |
534 | if ( exitStatus == QProcess::NormalExit && exitCode == 2 ) { |
535 | if ( mRunAsRoot ) { |
536 | kError() << "Insufficient permissions." << endl; |
537 | } else { |
538 | kDebug() << "Insufficient permissions. Trying again as root." ; |
539 | mRunAsRoot = true; |
540 | deleteProcess(); |
541 | startIndexProcess(); |
542 | return; |
543 | } |
544 | } else if ( exitStatus != QProcess::NormalExit || exitCode != 0 ) { |
545 | kDebug() << "KProcess reported an error." ; |
546 | KMessageBox::error( this, i18n("Failed to build index." ) ); |
547 | } else { |
548 | mConfig->group( "Search" ).writeEntry( "IndexExists" , true ); |
549 | emit searchIndexUpdated(); |
550 | } |
551 | |
552 | deleteProcess(); |
553 | deleteCmdFile(); |
554 | |
555 | if ( mProgressDialog ) { |
556 | mProgressDialog->setFinished( true ); |
557 | } |
558 | |
559 | mStdOut.clear(); |
560 | mStdErr.clear(); |
561 | |
562 | if ( mIsClosing ) { |
563 | if ( !mProgressDialog || !mProgressDialog->isVisible() ) { |
564 | mIsClosing = false; |
565 | accept(); |
566 | } |
567 | } |
568 | } |
569 | |
570 | void KCMHelpCenter::deleteProcess() |
571 | { |
572 | delete mProcess; |
573 | mProcess = 0; |
574 | } |
575 | |
576 | void KCMHelpCenter::deleteCmdFile() |
577 | { |
578 | delete mCmdFile; |
579 | mCmdFile = 0; |
580 | } |
581 | |
582 | void KCMHelpCenter::slotIndexProgress() |
583 | { |
584 | if( !mProcess ) |
585 | return; |
586 | |
587 | kDebug() << "KCMHelpCenter::slotIndexProgress()" ; |
588 | |
589 | updateStatus(); |
590 | |
591 | advanceProgress(); |
592 | } |
593 | |
594 | void KCMHelpCenter::slotIndexError( const QString &str ) |
595 | { |
596 | if( !mProcess ) |
597 | return; |
598 | |
599 | kDebug() << "KCMHelpCenter::slotIndexError()" ; |
600 | |
601 | KMessageBox::sorry( this, i18n("Error executing indexing build command:\n%1" , |
602 | str ) ); |
603 | |
604 | if ( mProgressDialog ) { |
605 | mProgressDialog->appendLog( "<i>" + str + "</i>" ); |
606 | } |
607 | |
608 | advanceProgress(); |
609 | } |
610 | |
611 | void KCMHelpCenter::advanceProgress() |
612 | { |
613 | if ( mProgressDialog && mProgressDialog->isVisible() ) { |
614 | mProgressDialog->advanceProgress(); |
615 | mCurrentEntry++; |
616 | if ( mCurrentEntry != mIndexQueue.constEnd() ) { |
617 | QString name = (*mCurrentEntry)->name(); |
618 | mProgressDialog->setLabelText( name ); |
619 | } |
620 | } |
621 | } |
622 | |
623 | void KCMHelpCenter::slotReceivedStdout() |
624 | { |
625 | QByteArray text= mProcess->readAllStandardOutput(); |
626 | int pos = text.lastIndexOf( '\n' ); |
627 | if ( pos < 0 ) { |
628 | mStdOut.append( text ); |
629 | } else { |
630 | if ( mProgressDialog ) { |
631 | mProgressDialog->appendLog( mStdOut + text.left( pos ) ); |
632 | mStdOut = text.mid( pos + 1 ); |
633 | } |
634 | } |
635 | } |
636 | |
637 | void KCMHelpCenter::slotReceivedStderr( ) |
638 | { |
639 | QByteArray text = mProcess->readAllStandardError(); |
640 | int pos = text.lastIndexOf( '\n' ); |
641 | if ( pos < 0 ) { |
642 | mStdErr.append( text ); |
643 | } else { |
644 | if ( mProgressDialog ) { |
645 | mProgressDialog->appendLog( QLatin1String("<i>" ) + mStdErr + text.left( pos ) + |
646 | QLatin1String("</i>" )); |
647 | mStdErr = text.mid( pos + 1 ); |
648 | } |
649 | } |
650 | } |
651 | |
652 | void KCMHelpCenter::slotOk() |
653 | { |
654 | if ( buildIndex() ) { |
655 | if ( !mProcess ) accept(); |
656 | else mIsClosing = true; |
657 | } |
658 | } |
659 | |
660 | void KCMHelpCenter::slotProgressClosed() |
661 | { |
662 | kDebug() << "KCMHelpCenter::slotProgressClosed()" ; |
663 | |
664 | if ( mIsClosing ) accept(); |
665 | } |
666 | |
667 | void KCMHelpCenter::showIndexDirDialog() |
668 | { |
669 | IndexDirDialog dlg( this ); |
670 | if ( dlg.exec() == QDialog::Accepted ) { |
671 | load(); |
672 | } |
673 | } |
674 | |
675 | void KCMHelpCenter::checkSelection() |
676 | { |
677 | int count = 0; |
678 | |
679 | QTreeWidgetItemIterator it( mListView ); |
680 | while ( (*it) != 0 ) { |
681 | ScopeItem *item = static_cast<ScopeItem *>( (*it) ); |
682 | if ( item->isOn() ) { |
683 | ++count; |
684 | } |
685 | ++it; |
686 | } |
687 | |
688 | enableButtonOk( count != 0 ); |
689 | } |
690 | |
691 | #include "kcmhelpcenter.moc" |
692 | |
693 | // vim:ts=2:sw=2:et |
694 | |