/*  This file is part of the KDE libraries
    Nicked from KDElibs since KDevApplicationTree is not a public class..

    Copyright (C) 1997 Torben Weis <weis@stud.uni-frankfurt.de>
    Copyright (C) 1999 Dirk A. Mueller <dmuell@gmx.net>
    Portions copyright (C) 1999 Preston Brown <pbrown@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include <tqfile.h>
#include <tqdir.h>
#include <tqdialog.h>
#include <tqpixmap.h>
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqpushbutton.h>
#include <tqtoolbutton.h>
#include <tqcheckbox.h>
#include <tqtooltip.h>
#include <tqstyle.h>

#include <tdeapplication.h>
#include <kbuttonbox.h>
#include <kcombobox.h>
#include <kdesktopfile.h>
#include <kdialog.h>
#include <tdeglobal.h>
#include <klineedit.h>
#include <tdelocale.h>
#include <kiconloader.h>
#include <kmimemagic.h>
#include <krun.h>
#include <kstandarddirs.h>
#include <kstringhandler.h>
#include <kuserprofile.h>
#include <kurlcompletion.h>
#include <kurlrequester.h>
#include <dcopclient.h>
#include <kmimetype.h>
#include <kservicegroup.h>
#include <tdelistview.h>
#include <tdesycoca.h>
#include <kdebug.h>

#include "kapplicationtree.h"

template class TQPtrList<TQString>;

#define SORT_SPEC (TQDir::DirsFirst | TQDir::Name | TQDir::IgnoreCase)


// ----------------------------------------------------------------------

KDevAppTreeListItem::KDevAppTreeListItem( TDEListView* parent, const TQString & name,
                                    const TQPixmap& pixmap, bool parse, bool dir, const TQString& p, const TQString& c, const TQString& dE )
    : TQListViewItem( parent, name )
{
    init(pixmap, parse, dir, p, c, dE);
}


// ----------------------------------------------------------------------

KDevAppTreeListItem::KDevAppTreeListItem( TQListViewItem* parent, const TQString & name,
                                    const TQPixmap& pixmap, bool parse, bool dir, const TQString& p, const TQString& c, const TQString& dE )
    : TQListViewItem( parent, name )
{
    init(pixmap, parse, dir, p, c, dE);
}


// ----------------------------------------------------------------------

void KDevAppTreeListItem::init(const TQPixmap& pixmap, bool parse, bool dir, const TQString& _path, const TQString& _exec, const TQString& _dEntry)
{
    setPixmap(0, pixmap);
    parsed = parse;
    directory = dir;
    path = _path; // relative path
    exec = _exec;
    dEntry = _dEntry;
    exec.simplifyWhiteSpace();
    exec.truncate(exec.find(' '));
}


// ----------------------------------------------------------------------
// Ensure that dirs are sorted in front of files and case is ignored

TQString KDevAppTreeListItem::key(int column, bool /*ascending*/) const
{
    if (directory)
        return TQString::fromLatin1(" ") + text(column).upper();
    else
        return text(column).upper();
}

void KDevAppTreeListItem::activate()
{
    if ( directory )
        setOpen(!isOpen());
}

void KDevAppTreeListItem::setOpen( bool o )
{
    if( o && !parsed ) { // fill the children before opening
        ((KDevApplicationTree *) parent())->addDesktopGroup( path, this );
        parsed = true;
    }
    TQListViewItem::setOpen( o );
}

bool KDevAppTreeListItem::isDirectory()
{
    return directory;
}

// ----------------------------------------------------------------------

KDevApplicationTree::KDevApplicationTree( TQWidget *parent, const char* name )
    : TDEListView( parent, name ), currentitem(0)
{
    addColumn( i18n("Known Applications") );
    setRootIsDecorated( true );

    addDesktopGroup( TQString() );

    connect( this, TQT_SIGNAL( currentChanged(TQListViewItem*) ), TQT_SLOT( slotItemHighlighted(TQListViewItem*) ) );
    connect( this, TQT_SIGNAL( selectionChanged(TQListViewItem*) ), TQT_SLOT( slotSelectionChanged(TQListViewItem*) ) );
}

// ----------------------------------------------------------------------

bool KDevApplicationTree::isDirSel()
{
    if (!currentitem) return false; // if currentitem isn't set
    return currentitem->isDirectory();
}

// ----------------------------------------------------------------------

void KDevApplicationTree::addDesktopGroup( TQString relPath, KDevAppTreeListItem *item)
{
   KServiceGroup::Ptr root = KServiceGroup::group(relPath);
   KServiceGroup::List list = root->entries();

   KDevAppTreeListItem * newItem;
   for( KServiceGroup::List::ConstIterator it = list.begin();
       it != list.end(); it++)
   {
      TQString icon;
      TQString text;
      TQString relPath;
      TQString exec;
      TQString dEntry;
      bool isDir = false;
      KSycocaEntry *p = (*it);
      if (p->isType(KST_KService))
      {
         KService *service = static_cast<KService *>(p);
         icon = service->icon();
         text = service->name();
         exec = service->exec();
         dEntry = service->desktopEntryPath();
      }
      else if (p->isType(KST_KServiceGroup))
      {
         KServiceGroup *serviceGroup = static_cast<KServiceGroup *>(p);
         icon = serviceGroup->icon();
         text = serviceGroup->caption();
         relPath = serviceGroup->relPath();
         isDir = true;
         if ( text[0] == '.' ) // skip ".hidden" like kicker does
           continue;
         // avoid adding empty groups
         KServiceGroup::Ptr subMenuRoot = KServiceGroup::group(relPath);
         if (subMenuRoot->childCount() == 0)
           continue;
      }
      else
      {
         kdWarning(250) << "KServiceGroup: Unexpected object in list!" << endl;
         continue;
      }

      TQPixmap pixmap = SmallIcon( icon );

      if (item)
         newItem = new KDevAppTreeListItem( item, text, pixmap, false, isDir,
                                         relPath, exec, dEntry );
      else
         newItem = new KDevAppTreeListItem( this, text, pixmap, false, isDir,
                                         relPath, exec, dEntry );
      if (isDir)
         newItem->setExpandable( true );
   }
}


// ----------------------------------------------------------------------

void KDevApplicationTree::slotItemHighlighted(TQListViewItem* i)
{
    // i may be 0 (see documentation)
    if(!i)
        return;

    KDevAppTreeListItem *item = (KDevAppTreeListItem *) i;

    currentitem = item;

    if( (!item->directory ) && (!item->exec.isEmpty()) )
        emit highlighted( item->text(0), item->exec );
}


// ----------------------------------------------------------------------

void KDevApplicationTree::slotSelectionChanged(TQListViewItem* i)
{
    // i may be 0 (see documentation)
    if(!i)
        return;

    KDevAppTreeListItem *item = (KDevAppTreeListItem *) i;

    currentitem = item;

    if( ( !item->directory ) && (!item->exec.isEmpty() ) )
        emit selected( item->text(0), item->exec );
}

// ----------------------------------------------------------------------

void KDevApplicationTree::resizeEvent( TQResizeEvent * e)
{
    setColumnWidth(0, width()-TQApplication::style().pixelMetric(TQStyle::PM_ScrollBarExtent));
    TDEListView::resizeEvent(e);
}



#include "kapplicationtree.moc"

