Logo Search packages:      
Sourcecode: kat version File versions  Download package

dlgstartupwizard.cpp

/***************************************************************************
 *   Copyright (C) 2005 by Roberto Cappuccio and the Kat team              *
 *   Roberto Cappuccio : roberto.cappuccio@gmail.com                       *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA.           *
 ***************************************************************************/

#include <kdialog.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <kdebug.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <qvariant.h>
#include <qwidget.h>
#include <qlabel.h>
#include <qheader.h>
#include <qlistview.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qwhatsthis.h>
#include <qimage.h>
#include <qpixmap.h>
#include <kstandarddirs.h>
#include <kapplication.h>
#include <qvaluevector.h>
#include <qpainter.h>
#include <dcopclient.h>

#include "dlgstartupwizard.h"
#include <linux/types.h>
#include "../katdaemon/inotify-syscalls.h"

QColor FancyListViewItem::foreground( uint column ) const
{
    if ( column < foregrounds.size() )
        return foregrounds[ column ];
    return listView()->colorGroup().text();
}

void FancyListViewItem::setForeground( uint column, const QColor& color )
{
    if ( column >= foregrounds.size() )
        foregrounds.resize( column + 1, listView()->colorGroup().text() );
    foregrounds[ column ] = color;
}

bool FancyListViewItem::bold( uint column ) const
{
    if ( column < bolds.size() )
        return bolds[ column ];
    return listView()->font().bold();
}

void FancyListViewItem::setBold( uint column, bool bold )
{
    if ( column >= bolds.size() )
        bolds.resize( column + 1, listView()->font().bold() );
    bolds[ column ] = bold;
}

void FancyListViewItem::paintCell( QPainter* painter,
                                   const QColorGroup& cg,
                                   int column,
                                   int width,
                                   int align )
{
    painter->save();

    QFont font = painter->font();
    if ( column >= 0 && column < (int)bolds.size() )
    {
        font.setBold( bolds[ column ] );
        painter->setFont( font );
    }
    QColorGroup grp( cg );
    if ( column >= 0 && column < (int)foregrounds.size() )
        grp.setColor( QColorGroup::Text, foregrounds[ column ] );
    QListViewItem::paintCell( painter, grp, column, width, align );
    painter->restore();
}

DlgStartupWizard::DlgStartupWizard( QWidget* parent, const char* name, bool modal, WFlags fl )
    : KWizard( parent, name, modal, fl )
{
    setCaption( i18n( "Welcome to Kat" ) );

    Welcome = new QWidget( this, "Welcome" );

    QHBoxLayout* hlayout = new QHBoxLayout( Welcome, 0, 2 );
    QString appDataPath = locate( "data", "kat/kat_startup_0.png" );
    QPixmap pixmap( appDataPath );

    QLabel* picture = new QLabel( Welcome );
    picture->setPixmap( QPixmap( appDataPath ) );
    picture->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1,
                                         (QSizePolicy::SizeType)1,
                                         0,
                                         0,
                                         picture->sizePolicy().hasHeightForWidth() ) );
    picture->setMaximumSize( QSize( 80, 32767 ) );
    picture->setPaletteBackgroundColor( QColor( 163, 184, 245 ) );
    picture->setScaledContents( false );
    hlayout->addWidget( picture );

    QVBoxLayout* layout = new QVBoxLayout;
    hlayout->addLayout( layout );

    tlWelcome = new QLabel( Welcome, "tlWelcome" );
    tlWelcome->setTextFormat( QLabel::RichText );
    tlWelcome->setAlignment( int( QLabel::WordBreak | QLabel::AlignTop ) );
    tlWelcome->setText(
        i18n( "This is the first time you run Kat, so let's check if "
        "everything is working fine and create the main catalog for Kat.<br><br>"
        "<b>1. Check for Inotify</b><br>"
        "If you want your catalog to be updated automatically whenever a file is "
        "modified, your kernel needs to contain a particular module called Inotify.<br>"
        "This module watches the file system and notifies Kat about files being created, "
        "deleted or modified.<br><br>"
        "<b>2. Check for Kat Daemon Running</b><br>"
        "In order to receive the notifications coming from Inotify whenever a file is "
        "modified, a particular process must be running in background.<br>"
        "This process is called Kat daemon and in this step we will check if it is "
        "running. If it is not running, we will start it.<br><br>"
        "<b>3. Check for Helper Programs</b><br>"
        "In order to extract the text from different MIME types, Kat's fulltext "
        "plugins need a series of helper programs, applications not produced by the "
        "Kat team and not distributed with Kat, which are able to perform the extraction "
        "of text from different types of documents.<br><br>"
        "<b>4. Create Main Catalog</b><br>"
        "Before you can start searching for files on your computer, you have to instruct "
        "the desktop search environment about the locations you want to index and the way the "
        "indexing procedure has to be performed.<br>"
        "In other words, you have to create at least one catalog. In this step you will "
        "be guided through the steps needed to create the main catalog of Kat." ) );
    layout->addWidget( tlWelcome );

    addPage( Welcome, i18n( "Welcome" ) );

    //page1
    Page1 = new QWidget( this, "Page1" );
    hlayout = new QHBoxLayout( Page1, 0, 2 );

    appDataPath = locate( "data", "kat/kat_startup_1.png" );

    picture = new QLabel( Page1 );
    picture->setPixmap( QPixmap( appDataPath ) );
    picture->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1,
                                         (QSizePolicy::SizeType)1,
                                         0,
                                         0,
                                         picture->sizePolicy().hasHeightForWidth() ) );
    picture->setMaximumSize( QSize( 80, 32767 ) );
    picture->setPaletteBackgroundColor( QColor( 163, 184, 245 ) );
    picture->setScaledContents( false );
    hlayout->addWidget( picture );

    layout = new QVBoxLayout;
    hlayout->addLayout( layout );

    tlInotify = new QLabel( Page1, "tlInotify" );
    tlInotify->setTextFormat( QLabel::RichText );
    tlInotify->setAlignment( int( QLabel::WordBreak | QLabel::AlignTop ) );
    tlInotify->setText(
        i18n( "If you want your catalog to be updated automatically whenever a file is "
        "modified, your kernel needs to contain a particular module called Inotify.<br>"
        "This module watches the file system and notifies Kat about files being created, "
        "deleted or modified." ) );
    layout->addWidget( tlInotify );

    tlInotifyResults = new QLabel( Page1, "tlInotifyResults" );
    tlInotifyResults->setTextFormat( QLabel::RichText );
    tlInotifyResults->setAlignment( int( QLabel::WordBreak | QLabel::AlignTop ) );
    layout->addWidget( tlInotifyResults );

    addPage( Page1, i18n( "1. Check for Inotify" ) );

    //page2
    Page2 = new QWidget( this, "Page2" );
    hlayout = new QHBoxLayout( Page2, 0, 2 );

    appDataPath = locate( "data", "kat/kat_startup_2.png" );

    picture = new QLabel( Page2 );
    picture->setPixmap( QPixmap( appDataPath ) );
    picture->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1,
                                         (QSizePolicy::SizeType)1,
                                         0,
                                         0,
                                         picture->sizePolicy().hasHeightForWidth() ) );
    picture->setMaximumSize( QSize( 80, 32767 ) );
    picture->setPaletteBackgroundColor( QColor( 163, 184, 245 ) );
    picture->setScaledContents( false );
    hlayout->addWidget( picture );

    layout = new QVBoxLayout;
    hlayout->addLayout( layout );

    tlDaemon = new QLabel( Page2, "tlDaemon" );
    tlDaemon->setTextFormat( QLabel::RichText );
    tlDaemon->setAlignment( int( QLabel::WordBreak | QLabel::AlignTop ) );
    tlDaemon->setText(
        i18n( "In order to receive the notifications coming from Inotify whenever a file is "
        "modified, a particular process must be running in background.<br>"
        "This process is called Kat daemon and in this step we will check if it is "
        "running. If it is not running, we will start it.<br><br>" ) );
    layout->addWidget( tlDaemon );

    tlDaemonResults = new QLabel( Page2, "tlDaemonResults" );
    tlDaemonResults->setTextFormat( QLabel::RichText );
    tlDaemonResults->setAlignment( int( QLabel::WordBreak | QLabel::AlignTop ) );
    layout->addWidget( tlDaemonResults );

    pbStart = new QPushButton( Page2, "pbStart" );
    pbStart->setText( "x" );
    layout->addWidget( pbStart );

    addPage( Page2, i18n( "2. Check for Kat Daemon Running" ) );

    //page3
    Page3 = new QWidget( this, "Page3" );
    hlayout = new QHBoxLayout( Page3, 0, 2 );

    appDataPath = locate( "data", "kat/kat_startup_3.png" );

    picture = new QLabel( Page3 );
    picture->setPixmap( QPixmap( appDataPath ) );
    picture->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1,
                                         (QSizePolicy::SizeType)1,
                                         0,
                                         0,
                                         picture->sizePolicy().hasHeightForWidth() ) );
    picture->setMaximumSize( QSize( 80, 32767 ) );
    picture->setPaletteBackgroundColor( QColor( 163, 184, 245 ) );
    picture->setScaledContents( false );
    hlayout->addWidget( picture );

    layout = new QVBoxLayout;
    hlayout->addLayout( layout );

    tlHelpers = new QLabel( Page3, "tlHelpers" );
    layout->addWidget( tlHelpers );
    tlHelpers->setTextFormat( QLabel::RichText );
    tlHelpers->setAlignment( int( QLabel::WordBreak | QLabel::AlignTop ) );
    tlHelpers->setText(
        i18n( "In order to extract the text from different MIME types, Kat's fulltext "
        "plugins need a series of helper programs, applications not produced by the "
        "Kat team and not distributed with Kat, which are able to perform the extraction "
        "of text from different types of documents.<br><br>"
        "You can install the missing programs without closing this window and re-check "
        "the status of the helpers by pressing the <b>Re-check</b> button.<br>" ) );

    listView1 = new QListView( Page3, "listView1" );
    listView1->addColumn( i18n( "Program" ) );
    listView1->addColumn( i18n( "Mime Type" ) );
    listView1->addColumn( i18n( "Package" ) );
    listView1->addColumn( i18n( "Status" ) );
    listView1->setResizeMode( QListView::LastColumn );

    layout->addWidget( listView1 );

    pbRecheck = new QPushButton( Page3, "pbRecheck" );
    layout->addWidget( pbRecheck );
    pbRecheck->setText( i18n( "&Recheck" ) );
    connect( pbRecheck, SIGNAL( clicked() ),
             this, SLOT( slotRecheckHelpers() ) );

    addPage( Page3, i18n( "3. Check for Helper Programs" ) );

    //page4
    Page4 = new QWidget( this, "Page4" );

    hlayout = new QHBoxLayout( Page4, 0, 2 );

    appDataPath = locate( "data", "kat/kat_startup_4.png" );

    picture = new QLabel( Page4 );
    picture->setPixmap( QPixmap( appDataPath ) );
    picture->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1,
                                         (QSizePolicy::SizeType)1,
                                         0,
                                         0,
                                         picture->sizePolicy().hasHeightForWidth() ) );
    picture->setMaximumSize( QSize( 80, 32767 ) );
    picture->setPaletteBackgroundColor( QColor( 163, 184, 245 ) );
    picture->setScaledContents( false );
    hlayout->addWidget( picture );

    layout = new QVBoxLayout;
    hlayout->addLayout( layout );

    tlCatalog = new QLabel( Page4, "tlCatalog" );
    layout->addWidget( tlCatalog );
    tlCatalog->setTextFormat( QLabel::RichText );
    tlCatalog->setAlignment( int( QLabel::WordBreak | QLabel::AlignTop ) );
    tlCatalog->setText(
        i18n( "Before you can start searching for files on your computer, "
        "you have to instruct the desktop search environment about the locations you want to "
        "index and the way the indexing procedure has to be performed.<br>"
        "In other words, you have to create at least one catalog. In this step you will "
        "be guided through the steps needed to create the main catalog of Kat.<br><br>" ) );

    addPage( Page4, i18n( "4. Create Main Catalog" ) );

    setFinishEnabled( Page4, true );
    initWizard();

    // check for Kat daemon
    // this code has not to be moved in initWizard because it is tested only at the beginning
    if ( testKatdRunning() )
    {
        kdDebug() << "The Kat daemon is running" << endl;
        tlDaemonResults->setText(
            i18n( "<font color=\"#00aa00\"><b>The Kat daemon is running</b></font>"
            "<br><br>Our test reveals that the Kat daemon is running. "
            "Being this the first time you run this version of Kat, we can be reasonably "
            "sure that the running daemon comes from a previuos installation of Kat.<br>"
            "For this reason, pressing the <b>Re-start daemon</b> button, the old daemon "
            "will be terminated and the new one will be started.<br>" ) );

        pbStart->setText( i18n( "Restart &Daemon" ) );
        connect( pbStart, SIGNAL( clicked() ),
                this, SLOT( slotRestartDaemon() ) );
    }
    else
    {
        kdDebug() << "The Kat daemon is NOT running" << endl;
        tlDaemonResults->setText(
            i18n( "<font color=\"#aa0000\"><b>The Kat daemon is not running</b></font>"
            "<br><br>Our test reveals that the Kat daemon is not running. "
            "Being this the first time you install Kat on your machine, this can be "
            "considered pretty normal.<br><br>"
            "<b>Action to be performed to fix this problem:</b> Start the Kat daemon<br><br>"
            "Pressing the <b>Start daemon</b> button, the daemon will be started.<br>" ) );

        pbStart->setText( i18n( "Start &Daemon" ) );
        connect( pbStart, SIGNAL( clicked() ),
                this, SLOT( slotStartDaemon() ) );
   }

    resize( QSize( 598, 429 ).expandedTo( minimumSizeHint() ) );
    clearWState( WState_Polished );
}

DlgStartupWizard::~DlgStartupWizard()
{
}

void DlgStartupWizard::initWizard()
{
      // check for inotify
    int inotify_fd = -1;
    inotify_fd = inotify_init ();
    if ( inotify_fd == -1 )
    {
        kdDebug() << "Could not open inotify syscall" << endl;
        tlInotifyResults->setText(
            i18n( "<font color=\"#aa0000\"><b>Your kernel is not inotify-enabled</b></font>"
            "<br><br>Our test reveals that your kernel does not contain the Inotify module. "
            "This means that Kat will not be able to update your catalogs automatically "
            "every time a file or folder is created, renamed, moved or deleted.<br><br>"
            "<b>Action to be performed to fix this problem:</b> Install an inotify-enabled "
            "kernel<br>" ) );
    }
    else
    {
        kdDebug() << "Correctly opened inotify syscall" << endl;
        tlInotifyResults->setText(
            i18n( "<font color=\"#00aa00\"><b>Your kernel is notify-enabled</b></font>"
            "<br><br>Our test reveals that your kernel contains the Inotify module. "
            "This means that Kat will be able to update your catalogs automatically "
            "every time a file or folder is created, renamed, moved or deleted." ) );
        ::close( inotify_fd );
    }
    listView1->clear();

    // antiword
    addItem( "antiword", "application/msword", "antiword");

    // pdftotext
    addItem( "pdftotext", "application/pdf", "xpdf-utils" );

    // unrtf
    addItem( "unrtf", "text/rtf", "unrtf" );

    // html
    addItem( "html2text", "text/html", "html2text" );

    // ps
    addItem( "pstotext", "application/postscript", "pstotext" );

    // tex
    addItem( "untex", "text/x-tex", "untex" );

    // eml
    addItem( "mhonarc", "message/rfc822", "mhonarc" );

    // xls
    addItem( "xlhtml", "application/msexcel", "xlhtml" );

    // ppt
    addItem( "ppthtml", "application/mspowerpoint", "ppthtml" );

    //lyx
    addItem( "lyx2html", "application/x-lyx", "lyx2html" );

    //man
    addItem( "man2html", "application/x-troff-man", "man" );
    
    // dvi
    addItem( "dvi2tty", "application/x-dvi", "dvi2tty" );

    // chemistry files
    addItem( "cat", "chemical/x-pdb", "cat" );
}

void DlgStartupWizard::addItem( const QString& programname,
                                const QString& mimetype,
                                const QString& name )
{
    FancyListViewItem* item = new FancyListViewItem( listView1 );
    item->setText( 0, programname );
    item->setText( 1, mimetype );
    item->setText( 2, name );
    item->setBold( 3, true );
    searchProgram( programname, item );
}

void DlgStartupWizard::searchProgram( const QString& prog, FancyListViewItem* item )
{
    QString tmpProgPath = KStandardDirs::findExe( prog );
    if ( tmpProgPath.isEmpty() )
    {
        kdDebug() << "Unable to find " << prog << " program" << endl;
        item->setText( 3, i18n( "MISSING" ) );
        item->setForeground( 3, QColor::QColor( 170, 0 , 0 ) );
    }
    else
    {
        kdDebug() << "Helper program " << prog << " is available" << endl;
        item->setText( 3, i18n( "PRESENT" ) );
        item->setForeground( 3, QColor::QColor( 0, 170 , 0 ) );
    }
}

bool DlgStartupWizard::testKatdRunning()
{
    QCStringList modules;
    QCString replyType;
    QByteArray replyData;

    if ( !kapp->dcopClient()->call( "kded", "kded", "loadedModules()", QByteArray(),
            replyType, replyData ) )
        return false;
    else
    {
        if ( replyType == "QCStringList" ) {
            QDataStream reply( replyData, IO_ReadOnly );
            reply >> modules;
        }
    }
    QCStringList::ConstIterator end( modules.end() );
    for ( QCStringList::ConstIterator it = modules.begin(); it != end; ++it )
    {
        if ( *it == "katd" )
            return true;
    }

    return false;
}

void DlgStartupWizard::slotRecheckHelpers()
{
    initWizard();
}

bool DlgStartupWizard::slotStartDaemon()
{
    QCString service = "katd";
    kdDebug() << "Starting: " << service << endl;

    pbStart->setEnabled( false );

    QByteArray data, replyData;
    QCString replyType;
    QDataStream arg( data, IO_WriteOnly );
    arg << service;
    if ( kapp->dcopClient()->call( "kded", "kded", "loadModule(QCString)", data, replyType, replyData ) )
    {
        QDataStream reply( replyData, IO_ReadOnly );
        if ( replyType == "bool" )
        {
            bool result;
            reply >> result;
            if ( !result )
            {
                KMessageBox::error( this, i18n( "Unable to start service." ) );
                return false;
            }
        }
        else
        {
            kdDebug() << "loadModule() on kded returned an unexpected type of reply: " << replyType << endl;
            return false;
        }
    }
    else
    {
        KMessageBox::error( this, i18n( "Unable to contact KDED." ) );
        return false;
    }

    tlDaemonResults->setText( i18n( "<font color=\"#00aa00\"><b>The Kat daemon is now running</b></font>" ) );

    kdDebug() << "Started: " << service << endl;
    return true;
}

bool DlgStartupWizard::slotRestartDaemon()
{
    // stop the old KDED
    QCString service = "katd";
    kdDebug() << "Stopping: " << service << endl;

    pbStart->setEnabled( false );

    QByteArray data;
    QDataStream arg( data, IO_WriteOnly );

    arg << service;
    if ( !kapp->dcopClient()->send( "kded", "kded", "unloadModule(QCString)", data ) )
    {
        KMessageBox::error( this, i18n( "Unable to stop service." ) );
        return false;
    }
    kdDebug() << "Stopped: " << service << endl;

    // start the new KDED
    return slotStartDaemon();
}

#include "dlgstartupwizard.moc"

Generated by  Doxygen 1.6.0   Back to index