/*
 * ktagcombobox.cpp - A combobox with support for submenues, icons and tags
 *
 * Copyright (c) 1999-2000 Hans Petter Bieker <bieker@kde.org>
 *
 * Requires the TQt widget libraries, available at no cost at
 * http://www.troll.no/
 *
 *  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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#define INCLUDE_MENUITEM_DEF 1
#include <tqpainter.h>
#include <tqpopupmenu.h>
#include <kdebug.h>


#include "ktagcombobox.h"
#include "ktagcombobox.moc"

KTagComboBox::~KTagComboBox ()
{
    delete _popup;
    delete _tags;
}

KTagComboBox::KTagComboBox (TQWidget * parent, const char *name)
    : TQComboBox(parent, name)
{
    _popup = new TQPopupMenu(this);
    _tags = new TQStringList;
    connect( _popup, TQ_SIGNAL(activated(int)),
             TQ_SLOT(internalActivate(int)) );
    connect( _popup, TQ_SIGNAL(highlighted(int)),
             TQ_SLOT(internalHighlight(int)) );
}

void KTagComboBox::popupMenu()
{
    _popup->popup( mapToGlobal( TQPoint(0,0) ), _current );
}

void KTagComboBox::keyPressEvent( TQKeyEvent *e )
{
    int c;

    if ( ( e->key() == Key_F4 && e->state() == 0 ) ||
         ( e->key() == Key_Down && (e->state() & AltButton) ) ||
         ( e->key() == Key_Space ) ) {
        if ( count() ) {
            _popup->setActiveItem( _current );
            popupMenu();
        }
        return;
    } else {
        e->ignore();
        return;
    }

    c = currentItem();
    emit highlighted( c );
    emit activated( c );
}

void KTagComboBox::mousePressEvent( TQMouseEvent * )
{
    popupMenu();
}

void KTagComboBox::internalActivate( int index )
{
    if (_current == index) return;
    _current = index;
    emit activated( index );
    repaint();
}

void KTagComboBox::internalHighlight( int index )
{
    emit highlighted( index );
}

void KTagComboBox::clear()
{
    _popup->clear();
    _tags->clear();
}

int KTagComboBox::count() const
{
    return _tags->count();
}

static inline TQPopupMenu *checkInsertIndex(TQPopupMenu *popup, const TQStringList *tags, const TQString &submenu, int *index)
{
    int pos = tags->findIndex(submenu);

    TQPopupMenu *pi = 0;
    if (pos != -1)
    {
        TQMenuItem *p = popup->findItem(popup->idAt(pos));
        pi = p?p->popup():0;
    }
    if (!pi) pi = popup;

    if (*index > (int)pi->count())
        *index = -1;

    return pi;
}

void KTagComboBox::insertItem(const TQIconSet& icon, const TQString &text, const TQString &tag, const TQString &submenu, int index )
{
    TQPopupMenu *pi = checkInsertIndex(_popup, _tags, submenu, &index);
    pi->insertItem(icon, text, count(), index);
    _tags->append(tag);
}

void KTagComboBox::insertItem(const TQString &text, const TQString &tag, const TQString &submenu, int index )
{
    TQPopupMenu *pi = checkInsertIndex(_popup, _tags, submenu, &index);
    pi->insertItem(text, count(), index);
    _tags->append(tag);
}

void KTagComboBox::insertSeparator(const TQString &submenu, int index)
{
    TQPopupMenu *pi = checkInsertIndex(_popup, _tags, submenu, &index);
    pi->insertSeparator(index);
    _tags->append(TQString());
}

void KTagComboBox::insertSubmenu(const TQString &text, const TQString &tag, const TQString &submenu, int index)
{
    TQPopupMenu *pi = checkInsertIndex(_popup, _tags, submenu, &index);
    TQPopupMenu *p = new TQPopupMenu(pi);
    pi->insertItem(text, p, count(), index);
    _tags->append(tag);
    connect( p, TQ_SIGNAL(activated(int)),
             TQ_SLOT(internalActivate(int)) );
    connect( p, TQ_SIGNAL(highlighted(int)),
             TQ_SLOT(internalHighlight(int)) );
}

void KTagComboBox::changeItem( const TQString &text, int index )
{
    _popup->changeItem( text, index);
    if (index == _current)
        repaint();
}

void KTagComboBox::paintEvent( TQPaintEvent * ev)
{
    TQComboBox::paintEvent(ev);

    TQPainter p (this);

    // Text
    TQRect clip(2, 2, width() - 4, height() - 4);
    if ( hasFocus())
        p.setPen( colorGroup().highlightedText() );
    p.drawText(clip, AlignCenter | SingleLine, _popup->text( _current ));

    // Icon
    TQIconSet *icon = _popup->iconSet( _current );
    if (icon) {
        TQPixmap pm = icon->pixmap();
        p.drawPixmap( 4, (height()-pm.height())/2, pm );
    }
}

bool KTagComboBox::containsTag( const TQString &str ) const
{
    return _tags->contains(str) > 0;
}

TQString KTagComboBox::currentTag() const
{
    return *_tags->at(currentItem());
}

TQString KTagComboBox::tag(int i) const
{
    if (i < 0 || i >= count())
    {
        kdDebug() << "KTagComboBox::tag(), unknown tag " << i << endl;
        return TQString();
    }
    return *_tags->at(i);
}

int KTagComboBox::currentItem() const
{
    return _current;
}

void KTagComboBox::setCurrentItem(int i)
{
    if (i < 0 || i >= count()) return;
    _current = i;
    repaint();
}

void KTagComboBox::setCurrentItem(const TQString &code)
{
    int i = _tags->findIndex(code);
    if (code.isNull())
        i = 0;
    if (i != -1)
        setCurrentItem(i);
}

void KTagComboBox::setFont( const TQFont &font )
{
    TQComboBox::setFont( font );
    _popup->setFont( font );
}
