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

searchwidget.cpp

/***************************************************************************
*   Copyright (C) 2005 by Adam Treat                                      *
*   treat@kde.org                                                         *
*                                                                         *
*   Copyright (C) 2004 by Scott Wheeler                                   *
*   wheeler@kde.org                                                       *
*                                                                         *
*   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.                                   *
*                                                                         *
***************************************************************************/

#include <klocale.h>
#include <klineedit.h>
#include <kiconloader.h>
#include <ktextedit.h>
#include <kcombobox.h>
#include <kdebug.h>
#include <kaction.h>
#include <kdialog.h>

#include <qlayout.h>
#include <qlabel.h>
#include <qtimer.h>
#include <qcheckbox.h>
#include <qpushbutton.h>
#include <qtoolbutton.h>
#include <qpopupmenu.h>

#include "searchwidget.h"
#include "datatable.h"
#include "actioncollection.h"

using namespace ActionCollection;

SearchLine::SearchLine( QWidget *parent, DataTableList dataTables,
                        bool simple, const char *name ) :
        QHBox( parent, name ),
        m_dataTables( dataTables ),
        m_simple( simple ),
        m_calendarMode( false ),
        m_searchFieldsBox( 0L ),
        m_operator( 0L ),
        m_prompt( 0L )
{
    setSpacing( 5 );

    if ( !m_simple )
    {
        m_searchFieldsBox = new KComboBox( this, "searchFields" );
        connect( m_searchFieldsBox, SIGNAL( activated( int ) ),
                 this, SLOT( searchFieldChanged() ) );

        m_operator = new KComboBox( this, "operator" );
        m_prompt = new QCheckBox( this, "prompt" );
        m_prompt->setChecked( true );
    }

    m_lineEdit = new KLineEdit( this, "searchLineEdit" );
    connect( m_lineEdit, SIGNAL( returnPressed() ),
             this, SIGNAL( signalQueryChanged() ) );

    if ( !m_simple )
        connect( m_prompt, SIGNAL( toggled( bool ) ),
                 m_lineEdit, SLOT( setEnabled( bool ) ) );

    updateColumns();
}

DataTableSearch::Component SearchLine::searchComponent() const
{
    QString query = m_lineEdit->text();

    DataField *field = 0;
    DataTable *table = 0;
    if ( m_searchFieldsBox )
    {
        for ( DataTableList::ConstIterator t = m_dataTables.begin(); t != m_dataTables.end(); ++t )
        {
            DataFieldList fields = ( *t ) ->fieldList();
            for ( DataFieldList::Iterator it = fields.begin(); it != fields.end(); ++it )
            {
                //Can you say UuuugGGLYY?  I thought you could...
                int i = m_searchFieldsBox->currentItem();
                QString text = m_searchFieldsBox->currentText();
                if ( ( *it ) ->label() == m_searchFieldsBox->currentText() &&
                     m_searchFieldsBox ->pixmap( i ) ->convertToImage() ==
                     SmallIcon( ( *t ) ->iconName(), 12 ).convertToImage()
                   )
                {
                    table = ( *t );
                    field = ( *it );
                }
            }
        }
    }

    if ( !m_simple )
    {
        QString op = m_operator->currentText();
        DataTableSearch::MatchMode mode;
        if ( op == i18n("Contains") )
            mode = DataTableSearch::Contains;
        else if ( op == i18n("Does Not Contain") )
            mode = DataTableSearch::DoesNotContain;
        else if ( op == i18n("Equals") )
            mode = DataTableSearch::Equals;
        else if ( op == i18n("Does Not Equal") )
            mode = DataTableSearch::DoesNotEqual;
        else if ( op == i18n("Is Null") )
            mode = DataTableSearch::IsNull;
        else if ( op == i18n("Is Not Null") )
            mode = DataTableSearch::IsNotNull;
        else if ( op == i18n("Before") )
            mode = DataTableSearch::Before;
        else if ( op == i18n("After") )
            mode = DataTableSearch::After;
        else if ( op == i18n("On or Before") )
            mode = DataTableSearch::OnOrBefore;
        else if ( op == i18n("On or After") )
            mode = DataTableSearch::OnOrAfter;
        else if ( op == i18n("Less Than") )
            mode = DataTableSearch::LessThan;
        else if ( op == i18n("Greater Than") )
            mode = DataTableSearch::GreaterThan;
        else if ( op == i18n("Less or Equals") )
            mode = DataTableSearch::LessOrEquals;
        else if ( op == i18n("Greater or Equals") )
            mode = DataTableSearch::GreaterOrEquals;
        else
            mode = DataTableSearch::Contains;

        return DataTableSearch::Component( query, table, field, !m_prompt->isChecked(), mode );
    }
    else
        return DataTableSearch::Component( query, table, field, false, DataTableSearch::Contains );
}

void SearchLine::setSearchComponent( const DataTableSearch::Component &component )
{
    /*    kdDebug() << "Here: SearchLine::setSearchComponent" << endl;*/
    if ( component == searchComponent() )
        return ;

    if ( m_simple )
    {
        m_lineEdit->setText( component.query() );
        if ( m_operator )
            m_operator->setCurrentItem( DataTableSearch::Contains );
    }
    else
    {
        if ( !component.dataField() )
        {
            m_searchFieldsBox->setCurrentItem( 0 );
        }
        else
        {
            //Can you say UuuugGGLYY?  I thought you could...
            QPixmap pixmap;
            DataTableList::ConstIterator table = m_dataTables.begin();
            for ( ; table != m_dataTables.end(); ++table )
            {
                DataFieldList fields = ( *table ) ->fieldList();
                for ( DataFieldList::Iterator it = fields.begin(); it != fields.end(); ++it )
                {
                    if ( ( *it ) ->table() == component.dataField() ->table() )
                    {
                        pixmap = SmallIcon( ( *table ) ->iconName(), 12 );
                        break;
                    }
                }
            }

            const int itemCount = m_searchFieldsBox->count();
            for ( int i = 0; i < itemCount; ++i )
            {
                if ( m_searchFieldsBox ->text( i ) == component.dataField() ->label() &&
                     m_searchFieldsBox ->pixmap( i ) ->convertToImage() == pixmap.convertToImage() )
                    m_searchFieldsBox->setCurrentItem( i );
            }
        }

        if ( m_operator )
        {
            QString op;
            switch ( component.matchMode() )
            {
            case DataTableSearch::Contains:
                op = i18n("Contains");
                break;
            case DataTableSearch::DoesNotContain:
                op = i18n("Does Not Contain");
                break;
            case DataTableSearch::Equals:
                op = i18n("Equals");
                break;
            case DataTableSearch::DoesNotEqual:
                op = i18n("Does Not Equal");
                break;
            case DataTableSearch::IsNull:
                op = i18n("Is Null");
                break;
            case DataTableSearch::IsNotNull:
                op = i18n("Is Not Null");
                break;
            case DataTableSearch::Before:
                op = i18n("Before");
                break;
            case DataTableSearch::After:
                op = i18n("After");
                break;
            case DataTableSearch::OnOrBefore:
                op = i18n("On or Before");
                break;
            case DataTableSearch::OnOrAfter:
                op = i18n("On or After");
                break;
            case DataTableSearch::LessThan:
                op = i18n("Less Than");
                break;
            case DataTableSearch::GreaterThan:
                op = i18n("Greater Than");
                break;
            case DataTableSearch::LessOrEquals:
                op = i18n("Less or Equals");
                break;
            case DataTableSearch::GreaterOrEquals:
                op = i18n("Greater or Equals");
                break;
            }
            m_operator->setCurrentText( op );
        }

        m_lineEdit->setText( component.query() );
    }
}

bool SearchLine::isPrompt() const
{
    return !m_prompt->isChecked();
}

void SearchLine::setPrompt( bool prompt )
{
    m_prompt->setChecked( !prompt );
}

void SearchLine::clear()
{
    // We don't want to emit the signal if it's already empty.
    if ( !m_lineEdit->text().isEmpty() )
    {
        m_lineEdit->clear();
    }

    if ( !isEnabled() )
    {
        setEnabled( true );
        emit signalClearAdvancedQuery();
    }
    else
        emit signalQueryChanged();
}

void SearchLine::searchFieldChanged()
{
    m_calendarMode = false;
    DataField *field = 0;
    if ( m_searchFieldsBox )
    {
        for ( DataTableList::ConstIterator table = m_dataTables.begin(); table != m_dataTables.end(); ++table )
        {
            DataFieldList fields = ( *table ) ->fieldList();
            for ( DataFieldList::Iterator it = fields.begin(); it != fields.end(); ++it )
            {
                if ( ( *it ) ->label() == m_searchFieldsBox->currentText() )
                {
                    QVariant::Type type;

                    if ( ( *it ) ->relation() )
                        type = ( *it ) ->relation() ->type();
                    else
                        type = ( *it ) ->type();

//                     kdDebug() << ( *it ) ->label() << " is a " << QVariant::typeToName( type ) << endl;

                    m_operator->clear();
//                     m_operator->insertItem( i18n( "Contains" ) );
//                     m_operator->insertItem( i18n( "Does Not Contain" ) );
//                     m_operator->insertItem( i18n( "Equals" ) );
//                     m_operator->insertItem( i18n( "Does Not Equal" ) );
//                     m_operator->insertItem( i18n( "Is Null" ) );
//                     m_operator->insertItem( i18n( "Is Not Null" ) );
                    switch ( type )
                    {
                    case QVariant::Invalid:
                    case QVariant::Map:
                    case QVariant::List:
                    case QVariant::StringList:
                    case QVariant::Font:
                    case QVariant::Pixmap:
                    case QVariant::Brush:
                    case QVariant::Rect:
                    case QVariant::Size:
                    case QVariant::Color:
                    case QVariant::Palette:
                    case QVariant::ColorGroup:
                    case QVariant::IconSet:
                    case QVariant::Point:
                    case QVariant::Image:
                    case QVariant::UInt:
                    case QVariant::Bool:
                    case QVariant::CString:
                    case QVariant::PointArray:
                    case QVariant::Region:
                    case QVariant::Bitmap:
                    case QVariant::Cursor:
                    case QVariant::SizePolicy:
                    case QVariant::Date:
                    case QVariant::Time:
                    case QVariant::ByteArray:
                    case QVariant::BitArray:
                    case QVariant::KeySequence:
                    case QVariant::Pen:
                    case QVariant::LongLong:
                    case QVariant::ULongLong:
                    case QVariant::DateTime:
//                         kdDebug() << ( *it ) ->label() << " is a QDateTime" << endl;
                        m_operator->insertItem( i18n( "Before" ) );
                        m_operator->insertItem( i18n( "After" ) );
                        m_operator->insertItem( i18n( "On or Before" ) );
                        m_operator->insertItem( i18n( "On or After" ) );
                        m_operator->insertItem( i18n( "Equals" ) );
                        m_operator->insertItem( i18n( "Does Not Equal" ) );
                        m_operator->insertItem( i18n( "Is Null" ) );
                        m_operator->insertItem( i18n( "Is Not Null" ) );
                        break;
                    case QVariant::Double:
//                         kdDebug() << ( *it ) ->label() << " is a double" << endl;
                        m_operator->insertItem( i18n( "Less Than" ) );
                        m_operator->insertItem( i18n( "Greater Than" ) );
                        m_operator->insertItem( i18n( "Less or Equals" ) );
                        m_operator->insertItem( i18n( "Greater or Equals" ) );
                        m_operator->insertItem( i18n( "Equals" ) );
                        m_operator->insertItem( i18n( "Does Not Equal" ) );
                        m_operator->insertItem( i18n( "Is Null" ) );
                        m_operator->insertItem( i18n( "Is Not Null" ) );
                        break;
                    case QVariant::Int:
//                         kdDebug() << ( *it ) ->label() << " is an int" << endl;
                        m_operator->insertItem( i18n( "Less Than" ) );
                        m_operator->insertItem( i18n( "Greater Than" ) );
                        m_operator->insertItem( i18n( "Less or Equals" ) );
                        m_operator->insertItem( i18n( "Greater or Equals" ) );
                        m_operator->insertItem( i18n( "Equals" ) );
                        m_operator->insertItem( i18n( "Does Not Equal" ) );
                        m_operator->insertItem( i18n( "Is Null" ) );
                        m_operator->insertItem( i18n( "Is Not Null" ) );
                        break;
                    case QVariant::String:
//                         kdDebug() << ( *it ) ->label() << " is a QString" << endl;
                        m_operator->insertItem( i18n( "Contains" ) );
                        m_operator->insertItem( i18n( "Does Not Contain" ) );
                        m_operator->insertItem( i18n( "Equals" ) );
                        m_operator->insertItem( i18n( "Does Not Equal" ) );
                        m_operator->insertItem( i18n( "Is Null" ) );
                        m_operator->insertItem( i18n( "Is Not Null" ) );
                        break;
                    }

                    field = ( *it );
                }
            }
        }
    }
}

void SearchLine::setText( const QString &txt )
{
    m_lineEdit->setText( txt );
}

void SearchLine::updateColumns()
{
    QString currentText;

    if ( m_searchFieldsBox )
    {
        currentText = m_searchFieldsBox->currentText();
        m_searchFieldsBox->clear();
    }

    if ( m_searchFieldsBox )
    {
        for ( DataTableList::ConstIterator table = m_dataTables.begin(); table != m_dataTables.end(); ++table )
        {
            DataFieldList fields = ( *table ) ->fieldList();
            for ( DataFieldList::Iterator it = fields.begin(); it != fields.end(); ++it )
            {
                if ( !( *it ) ->hidden() && !( *it ) ->isVirtual() )
                {
                    m_searchFieldsBox->insertItem(
                        SmallIcon( ( *table ) ->iconName(), 12 ), ( *it ) ->label() );
                }
            }
        }
        searchFieldChanged();
    }
}

AdvancedLine::AdvancedLine( QWidget *parent, DataTableList dataTables,
                        const char *name ) :
        QHBox( parent, name ),
        m_dataTables( dataTables ),
        m_searchTablesBox( 0 )
{
    setSpacing( 5 );

    new QLabel( i18n("Search:"), this );
    m_searchTablesBox = new KComboBox( this, "searchTables" );
    connect( m_searchTablesBox, SIGNAL( activated( int ) ),
                this, SLOT( searchTableChanged() ) );

    new QLabel( i18n("Where:"), this );
    m_customSqlQuery = new KTextEdit( this, "searchTextEdit" );

    updateTables();
}

DataTableSearch::Component AdvancedLine::searchComponent() const
{
    QString query = m_customSqlQuery->text();

    DataTable *table = 0;
    for ( DataTableList::ConstIterator t = m_dataTables.begin(); t != m_dataTables.end(); ++t )
    {
        if ( ( *t ) ->name() == m_searchTablesBox->currentText() )
        {
            table = ( *t );
        }
    }

    return DataTableSearch::Component( query, table );
}

void AdvancedLine::setSearchComponent( const DataTableSearch::Component &component )
{
    /*    kdDebug() << "Here: SearchLine::setSearchComponent" << endl;*/
    if ( component == searchComponent() )
        return ;

    m_searchTablesBox->setCurrentText( component.dataTable()->name() );
    m_customSqlQuery->setText( component.query() );
}

void AdvancedLine::clear()
{
    m_customSqlQuery->clear();
}

void AdvancedLine::searchTableChanged()
{
}

void AdvancedLine::updateTables()
{
    QString currentText;

    if ( m_searchTablesBox )
    {
        currentText = m_searchTablesBox->currentText();
        m_searchTablesBox->clear();
    }

    if ( m_searchTablesBox )
    {
        for ( DataTableList::ConstIterator table = m_dataTables.begin(); table != m_dataTables.end(); ++table )
        {
            m_searchTablesBox->insertItem(
                SmallIcon( ( *table ) ->iconName(), 12 ), ( *table ) ->name() );
        }
        searchTableChanged();
    }
}

SearchWidget::SearchWidget( QWidget *parent, const char *name ) : KToolBar( parent, name )
{
    setupLayout();
}

SearchWidget::~SearchWidget()
{}

DataTableSearch SearchWidget::createSearch( const DataTableList &dataTables ) const
{
    DataTableSearch::ComponentList components;
    components.append( m_searchLine->searchComponent() );
    return DataTableSearch( dataTables, components );
}

DataTableSearch SearchWidget::search() const
{
    return m_search;
}

void SearchWidget::setSearch( const DataTableSearch &search )
{
    DataTableSearch::ComponentList components = search.components();
    m_searchLine->setSearchComponent( *components.begin() );
    if ( !search.name().isEmpty() )
    {
        m_searchCombo->setCurrentText( search.name() );
        m_searchLine->setText( search.name() );
    }
    m_search = search;
}

DataSearchList SearchWidget::searchList( const DataTableList & ) const
{
    return m_searchList;
}

void SearchWidget::setSearchList( const DataSearchList &searchList )
{
    m_searchList = searchList;
    m_searchCombo->clear();
    m_searchCombo->insertItem( i18n("Saved Searches") );
    DataSearchList::ConstIterator it = searchList.begin();
    for ( ; it != searchList.end(); ++it )
    {
        m_searchCombo->insertItem( ( *it ).name() );
    }
}

void SearchWidget::clear()
{
    m_searchLine->clear();
    setSearchList( m_searchList );
}

void SearchWidget::setLineEnabled( bool enable )
{
    m_searchLine->setEnabled( enable );
}

void SearchWidget::setEnabled( bool enable )
{
    emit signalShown( enable );
    setShown( enable );
}

void SearchWidget::searchListChanged()
{
    if ( m_searchCombo->currentText() == i18n("Saved Searches") )
        return ;

    DataSearchList::Iterator it = m_searchList.begin();
    for ( ; it != m_searchList.end(); ++it )
    {
        if ( ( *it ).name() == m_searchCombo->currentText() )
        {
            ( *it ).search();
            m_searchLine->setEnabled( false );
            emit signalSearchListChanged( ( *it ) );
            return;
        }
    }
}

void SearchWidget::invokeSearch( const QString &dataSearch )
{
    if ( m_searchCombo->currentText() == dataSearch )
        return;

    m_searchCombo->setCurrentText( dataSearch );
    searchListChanged();
}

void SearchWidget::searchRemoved()
{
    m_searchCombo->removeItem( m_searchCombo->currentItem() );
    clear();
}

void SearchWidget::setupLayout()
{
    setEnabled( false );

    boxLayout() ->setSpacing( 5 );

    QToolButton *clearSearchButton = new QToolButton( this );
    clearSearchButton->setTextLabel( i18n( "Clear Search" ), true );
    clearSearchButton->setIconSet( SmallIconSet( QApplication::reverseLayout() ? "clear_left" : "locationbar_erase" ) );

    new QLabel( i18n( "Search:" ), this, "kde toolbar widget" );

    m_searchLine = new SearchLine( this, DataTableList(), true, "kde toolbar widget" );
    connect( m_searchLine, SIGNAL( signalQueryChanged() ), this, SIGNAL( signalQueryChanged() ) );
    connect( m_searchLine, SIGNAL( signalClearAdvancedQuery() ), this, SIGNAL( signalClearAdvancedQuery() ) );
    connect( clearSearchButton, SIGNAL( pressed() ), this, SLOT( clear() ) );
    setStretchableWidget( m_searchLine );

    m_searchCombo = new KComboBox( this );
    m_searchCombo->setFocusPolicy( QWidget::ClickFocus );
    m_searchCombo->insertItem( i18n("Saved Searches") );
    connect( m_searchCombo, SIGNAL( activated( int ) ), this, SLOT( searchListChanged() ) );
}

#include "searchwidget.moc"

Generated by  Doxygen 1.6.0   Back to index