/* This file is part of the KDE project
   Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net>
   Copyright (C) 2003 Roberto Raggi <roberto@kdevelop.org>
   Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
   Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
   Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

   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.
*/

//BEGIN Includes
#include "fileselector_part.h"
#include "fileselector_widget.h"
#include "tdeactionselector.h"
#include "kbookmarkhandler.h"

#include <kdevcore.h>
#include <kdevmainwindow.h>
#include <kdevpartcontroller.h>

#include <tqlayout.h>
#include <tqtoolbutton.h>
#include <tqhbox.h>
#include <tqvbox.h>
#include <tqlabel.h>
#include <tqstrlist.h>
#include <tqtooltip.h>
#include <tqwhatsthis.h>
#include <tqapplication.h>
#include <tqlistbox.h>
#include <tqscrollbar.h>
#include <tqspinbox.h>
#include <tqgroupbox.h>
#include <tqcheckbox.h>
#include <tqregexp.h>
#include <tqdockarea.h>
#include <tqtimer.h>

#include <tdetexteditor/document.h>

#include <tdemainwindow.h>
#include <tdeapplication.h>
#include <kiconloader.h>
#include <kurlcombobox.h>
#include <kurlcompletion.h>
#include <kprotocolinfo.h>
#include <tdeconfig.h>
#include <tdelocale.h>
#include <kcombobox.h>
#include <tdeaction.h>
#include <tdemessagebox.h>
#include <tdetoolbarbutton.h>
#include <tqtoolbar.h>
#include <tdepopupmenu.h>
#include <kdialog.h>
#include <tdeio/netaccess.h>

#include <kdebug.h>
//END Includes


// from tdefiledialog.cpp - avoid qt warning in STDERR (~/.xsessionerrors)
static void silenceTQToolBar(TQtMsgType, const char *)
{}


KDevFileSelectorToolBar::KDevFileSelectorToolBar(TQWidget *parent)
        : TDEToolBar( parent, "KDev FileSelector Toolbar", true )
{
    setMinimumWidth(10);
}

KDevFileSelectorToolBar::~KDevFileSelectorToolBar()
{}

void KDevFileSelectorToolBar::setMovingEnabled( bool)
{
    TDEToolBar::setMovingEnabled(false);
}


KDevFileSelectorToolBarParent::KDevFileSelectorToolBarParent(TQWidget *parent)
        :TQFrame(parent),m_tb(0)
{}
KDevFileSelectorToolBarParent::~KDevFileSelectorToolBarParent()
{}
void KDevFileSelectorToolBarParent::setToolBar(KDevFileSelectorToolBar *tb)
{
    m_tb=tb;
}

void KDevFileSelectorToolBarParent::resizeEvent ( TQResizeEvent * )
{
    if (m_tb)
    {
        setMinimumHeight(m_tb->sizeHint().height());
        m_tb->resize(width(),height());
    }
}


//BEGIN Constructor/destructor

KDevFileSelector::KDevFileSelector( FileSelectorPart *part, KDevMainWindow *mainWindow,
                                    KDevPartController *partController,
                                    TQWidget * parent, const char * name )
        : TQWidget(parent, name),
        m_part(part),
        mainwin(mainWindow),
        partController(partController)
{
    mActionCollection = new TDEActionCollection( this );

    TQVBoxLayout* lo = new TQVBoxLayout(this);

    TQtMsgHandler oldHandler = qInstallMsgHandler( silenceTQToolBar );

    KDevFileSelectorToolBarParent *tbp=new KDevFileSelectorToolBarParent(this);
    toolbar = new KDevFileSelectorToolBar(tbp);
    tbp->setToolBar(toolbar);
    lo->addWidget(tbp);
    toolbar->setMovingEnabled(false);
    toolbar->setFlat(true);
    qInstallMsgHandler( oldHandler );

    cmbPath = new KURLComboBox( KURLComboBox::Directories, true, this, "path combo" );
    cmbPath->setSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed ));
    KURLCompletion* cmpl = new KURLCompletion(KURLCompletion::DirCompletion);
    cmbPath->setCompletionObject( cmpl );
    lo->addWidget(cmbPath);
    cmbPath->listBox()->installEventFilter( this );

    dir = new KDevDirOperator(m_part, KURL(), this, "operator");
    dir->setView(KFile::/*Simple*/Detail);

    TDEActionCollection *coll = dir->actionCollection();
    // some shortcuts of diroperator that clashes with KDev
    coll->action( "delete" )->setShortcut( TDEShortcut( ALT + Key_Delete ) );
    coll->action( "reload" )->setShortcut( TDEShortcut( ALT + Key_F5 ) );
    coll->action( "back" )->setShortcut( TDEShortcut( ALT + SHIFT + Key_Left ) );
    coll->action( "forward" )->setShortcut( TDEShortcut( ALT + SHIFT + Key_Right ) );
    // some consistency - reset up for dir too
    coll->action( "up" )->setShortcut( TDEShortcut( ALT + SHIFT + Key_Up ) );
    coll->action( "home" )->setShortcut( TDEShortcut( CTRL + ALT + Key_Home ) );

    lo->addWidget(dir);
    lo->setStretchFactor(dir, 2);

    // bookmarks action!
    TDEActionMenu *acmBookmarks = new TDEActionMenu( i18n("Bookmarks"), "bookmark",
                                mActionCollection, "bookmarks" );
    acmBookmarks->setDelayed( false );

    bookmarkHandler = new KBookmarkHandler( this, acmBookmarks->popupMenu() );

    TQHBox* filterBox = new TQHBox(this);

    btnFilter = new TQToolButton( filterBox );
    btnFilter->setIconSet( SmallIconSet("filter" ) );
    btnFilter->setToggleButton( true );
    filter = new KHistoryCombo( true, filterBox, "filter");
    filter->setSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed ));
    filterBox->setStretchFactor(filter, 2);
    connect( btnFilter, TQ_SIGNAL( clicked() ), this, TQ_SLOT( btnFilterClick() ) );
    lo->addWidget(filterBox);

    connect( filter, TQ_SIGNAL( activated(const TQString&) ),
             TQ_SLOT( slotFilterChange(const TQString&) ) );

    connect( filter, TQ_SIGNAL( textChanged(const TQString&) ),
             TQ_SLOT( slotFilterChange(const TQString&) ) );
    connect( filter, TQ_SIGNAL( returnPressed(const TQString&) ),
             filter, TQ_SLOT( addToHistory(const TQString&) ) );

    // tdeaction for the dir sync method
    acSyncDir = new TDEAction( i18n("Current Document Directory"), "dirsynch", 0,
                             this, TQ_SLOT( setActiveDocumentDir() ), mActionCollection, "sync_dir" );
    toolbar->setIconText( TDEToolBar::IconOnly );
    toolbar->setIconSize( 16 );
    toolbar->setEnableContextMenu( false );

    connect( cmbPath, TQ_SIGNAL( urlActivated( const KURL&  )),
             this,  TQ_SLOT( cmbPathActivated( const KURL& ) ));
    connect( cmbPath, TQ_SIGNAL( returnPressed( const TQString&  )),
             this,  TQ_SLOT( cmbPathReturnPressed( const TQString& ) ));
    connect(dir, TQ_SIGNAL(urlEntered(const KURL&)),
            this, TQ_SLOT(dirUrlEntered(const KURL&)) );

    connect(dir, TQ_SIGNAL(finishedLoading()),
            this, TQ_SLOT(dirFinishedLoading()) );

    // enable dir sync button if current doc has a valid URL
    connect ( partController, TQ_SIGNAL(activePartChanged(KParts::Part*) ),
              this, TQ_SLOT(viewChanged() ) );

    // Connect the bookmark handler
    connect( bookmarkHandler, TQ_SIGNAL( openURL( const TQString& )),
             this, TQ_SLOT( setDir( const TQString& ) ) );

    waitingUrl = TQString();

    // whatsthis help
    TQWhatsThis::add
        ( cmbPath,
                i18n("<p>Here you can enter a path for a directory to display."
                     "<p>To go to a directory previously entered, press the arrow on "
                     "the right and choose one. <p>The entry has directory "
                     "completion. Right-click to choose how completion should behave.") );
    TQWhatsThis::add
        ( filter,
                i18n("<p>Here you can enter a name filter to limit which files are displayed."
                     "<p>To clear the filter, toggle off the filter button to the left."
                     "<p>To reapply the last filter used, toggle on the filter button." ) );
    TQWhatsThis::add
        ( btnFilter,
                i18n("<p>This button clears the name filter when toggled off, or "
                     "reapplies the last filter used when toggled on.") );
}

KDevFileSelector::~KDevFileSelector()
{
	writeConfig( m_part->instance()->config(), "fileselector" );
}
//END Constroctor/Destrctor

//BEGIN Public Methods

void KDevFileSelector::readConfig(TDEConfig *config, const TQString & name)
{
    dir->readConfig(config, name + ":dir");
    dir->setView( KFile::Default );

    config->setGroup( name );

    // set up the toolbar
    setupToolbar( config );

    cmbPath->setMaxItems( config->readNumEntry( "pathcombo history len", 9 ) );
    cmbPath->setURLs( config->readPathListEntry("dir history") );
    // if we restore history
    if ( config->readBoolEntry( "restore location", true ) || tdeApp->isRestored() )
    {
        TQString loc( config->readPathEntry( "location" ) );
        if ( ! loc.isEmpty() )
        {
            waitingDir = loc;
            TQTimer::singleShot(0, this, TQ_SLOT(initialDirChangeHack()));
        }
    }

    // else is automatic, as cmpPath->setURL is called when a location is entered.

    filter->setMaxCount( config->readNumEntry( "filter history len", 9 ) );
    filter->setHistoryItems( config->readListEntry("filter history"), true );
    lastFilter = config->readEntry( "last filter" );
    TQString flt("");
    if ( config->readBoolEntry( "restore last filter", true ) || tdeApp->isRestored() )
        flt = config->readEntry("current filter");
    filter->lineEdit()->setText( flt );
    slotFilterChange( flt );

    autoSyncEvents = config->readNumEntry( "AutoSyncEvents", 0 );
    // connect events as needed
    /// @todo - solve startup problem: no need to set location for each doc opened!
    if ( autoSyncEvents & DocumentChanged )
        connect( partController, TQ_SIGNAL( viewChanged() ), this, TQ_SLOT( autoSync() ) );

    if ( autoSyncEvents & DocumentOpened )
        connect( partController, TQ_SIGNAL( partAdded(KParts::Part*) ),
                 this, TQ_SLOT( autoSync(KParts::Part*) ) );

}

void KDevFileSelector::initialDirChangeHack()
{
    setDir( waitingDir );
}

void KDevFileSelector::setupToolbar( TDEConfig *config )
{
    toolbar->clear();
    TQStringList tbactions = config->readListEntry( "toolbar actions", ',' );
    if ( tbactions.isEmpty() )
    {
        // resonable collection for default toolbar
        tbactions << "up" << "back" << "forward" << "home" <<
        "short view" << "detailed view" <<
        "bookmarks" << "sync_dir";
    }
    TDEAction *ac;
    for ( TQStringList::Iterator it=tbactions.begin(); it != tbactions.end(); ++it )
    {
        if ( *it == "bookmarks" || *it == "sync_dir" )
            ac = mActionCollection->action( (*it).latin1() );
        else
            ac = dir->actionCollection()->action( (*it).latin1() );
        if ( ac )
            ac->plug( toolbar );
    }
}

void KDevFileSelector::writeConfig(TDEConfig *config, const TQString & name)
{
    dir->writeConfig(config,name + ":dir");

    config->setGroup( name );
    config->writeEntry( "pathcombo history len", cmbPath->maxItems() );
    TQStringList l;
    for (int i = 0; i < cmbPath->count(); i++)
    {
        l.append( cmbPath->text( i ) );
    }
    config->writePathEntry( "dir history", l );
    config->writePathEntry( "location", cmbPath->currentText() );

    config->writeEntry( "filter history len", filter->maxCount() );
    config->writeEntry( "filter history", filter->historyItems() );
    config->writeEntry( "current filter", filter->currentText() );
    config->writeEntry( "last filter", lastFilter );
    config->writeEntry( "AutoSyncEvents", autoSyncEvents );
}

void KDevFileSelector::setView(KFile::FileView view)
{
    dir->setView(view);
}

//END Public Methods

//BEGIN Public Slots

void KDevFileSelector::slotFilterChange( const TQString & nf )
{
    TQToolTip::remove( btnFilter );
    TQString f = nf.stripWhiteSpace();
    bool empty = f.isEmpty() || f == "*";
    if ( empty )
    {
        dir->clearFilter();
        filter->lineEdit()->setText( TQString() );
        TQToolTip::add
            ( btnFilter,
                    TQString( i18n("Apply last filter (\"%1\")") ).arg( lastFilter ) );
    }
    else
    {
        if ( !f.startsWith( "*" ) )
            f.prepend( '*' );
        if ( !f.endsWith( "*" ) )
            f.append( '*' );
        dir->setNameFilter( f );
        lastFilter = f;
        TQToolTip::add
            ( btnFilter, i18n("Clear filter") );
    }
    btnFilter->setOn( !empty );
    dir->updateDir();
    // this will be never true after the filter has been used;)
    btnFilter->setEnabled( !( empty && lastFilter.isEmpty() ) );

}
void KDevFileSelector::setDir( KURL u )
{
    dir->setURL(u, true);
}

//END Public Slots

//BEGIN Private Slots

void KDevFileSelector::cmbPathActivated( const KURL& u )
{
    cmbPathReturnPressed( u.url() );
}

void KDevFileSelector::cmbPathReturnPressed( const TQString& u )
{
    TQStringList urls = cmbPath->urls();
    urls.remove( u );
    urls.prepend( u );
    cmbPath->setURLs( urls, KURLComboBox::RemoveBottom );
    dir->setFocus();
    dir->setURL( KURL(u), true );
}

void KDevFileSelector::dirUrlEntered( const KURL& u )
{
    cmbPath->setURL( u );
}

void KDevFileSelector::dirFinishedLoading()
{}


/*
   When the button in the filter box toggles:
   If off:
   If the name filer is anything but "" or "*", reset it.
   If on:
   Set last filter.
*/
void KDevFileSelector::btnFilterClick()
{
    if ( !btnFilter->isOn() )
    {
        slotFilterChange( TQString() );
    }
    else
    {
        filter->lineEdit()->setText( lastFilter );
        slotFilterChange( lastFilter );
    }
}


void KDevFileSelector::autoSync()
{
    kdDebug()<<"KDevFileSelector::autoSync()"<<endl;
    // if visible, sync
    if ( isVisible() )
    {
        setActiveDocumentDir();
        waitingUrl = TQString();
    }
    // else set waiting url
    else
    {
        KURL u = activeDocumentUrl();
        if (!u.isEmpty())
            waitingUrl = u.directory();
    }
}

void KDevFileSelector::autoSync( KParts::Part *part )
{
    KTextEditor::Document* doc = dynamic_cast<KTextEditor::Document*>( part );
    if( !doc )
	return;

    // as above, but using document url.
    kdDebug()<<"KDevFileSelector::autoSync( KTextEditor::Document )"<<endl;
    KURL u ( doc->url() );
    if ( u.isEmpty() )
    {
        waitingUrl = TQString();
        return;
    }
    if ( isVisible() )
    {
        setDir( u.directory() );
        waitingUrl = TQString();
    }
    else
    {
        waitingUrl = u.directory();
    }
}
/// \FIXME crash on shutdown
void KDevFileSelector::setActiveDocumentDir()
{
    //kdDebug()<<"KDevFileSelector::setActiveDocumentDir()"<<endl;
    KURL u = activeDocumentUrl();
    if (!u.isEmpty())
        setDir( u.upURL() );
}

void KDevFileSelector::viewChanged()
{
    /// @todo make sure the button is disabled if the directory is unreadable, eg
    ///       the document URL has protocol http
    acSyncDir->setEnabled( ! activeDocumentUrl().directory().isEmpty() );
}

//END Private Slots

//BEGIN Protected

void KDevFileSelector::focusInEvent( TQFocusEvent * )
{
    dir->setFocus();
}

void KDevFileSelector::showEvent( TQShowEvent * )
{
    // sync if we should
    if ( autoSyncEvents & GotVisible )
    {
        kdDebug()<<"syncing fs on show"<<endl;
        setActiveDocumentDir();
        waitingUrl = TQString();
    }
    // else, if we have a waiting URL set it
    else if ( ! waitingUrl.isEmpty() )
    {
        setDir( waitingUrl );
        waitingUrl = TQString();
    }
}

bool KDevFileSelector::eventFilter( TQObject* o, TQEvent *e )
{
    /*
        This is rather unfortunate, but:
        TQComboBox does not support setting the size of the listbox to something
        resonable. Even using listbox->setVariableWidth() does not yeld a
        satisfying result, something is wrong with the handling of the sizehint.
        And the popup is rather useless, if the paths are only partly visible.
    */
    TQListBox *lb = cmbPath->listBox();
    if ( o == lb && e->type() == TQEvent::Show )
    {
        int add
            = lb->height() < lb->contentsHeight() ? lb->verticalScrollBar()->width() : 0;
        int w = TQMIN( mainwin->main()->width(), lb->contentsWidth() + add );
        lb->resize( w, lb->height() );
        /// @todo - move the listbox to a suitable place if nessecary
        /// @todo - decide if it is worth caching the size while untill the contents
        ///        are changed.
    }
    /// @todo - same thing for the completion popup?
    return TQWidget::eventFilter( o, e );
}

//END Protected

//BEGIN ACtionLBItem
/*
   TQListboxItem that can store and return a string,
   used for the toolbar action selector.
*/
class ActionLBItem : public TQListBoxPixmap
{
public:
    ActionLBItem( TQListBox *lb=0,
                  const TQPixmap &pm = TQPixmap(),
                  const TQString &text=TQString(),
                  const TQString &str=TQString() ) :
            TQListBoxPixmap( lb, pm, text ),
            _str(str)
    {}
    ;
    TQString idstring()
    {
        return _str;
    };
private:
    TQString _str;
};

KURL KDevFileSelector::activeDocumentUrl( )
{
	KParts::ReadOnlyPart * part = dynamic_cast<KParts::ReadOnlyPart*>( partController->activePart() );
	if ( part )
	{
		return part->url();
	}

    return KURL();
}
//END ActionLBItem

//BEGIN KFSConfigPage
////////////////////////////////////////////////////////////////////////////////
// KFSConfigPage implementation
////////////////////////////////////////////////////////////////////////////////
KFSConfigPage::KFSConfigPage( TQWidget *parent, const char *name, KDevFileSelector *kfs )
        : TQWidget( parent, name ),
        fileSelector( kfs ),
        bDirty( false )
{
    TQVBoxLayout *lo = new TQVBoxLayout( this );
    int spacing = KDialog::spacingHint();
    lo->setSpacing( spacing );

    // Toolbar - a lot for a little...
    TQGroupBox *gbToolbar = new TQGroupBox( 1, TQt::Vertical, i18n("Toolbar"), this );
    acSel = new TDEActionSelector( gbToolbar );
    acSel->setAvailableLabel( i18n("A&vailable actions:") );
    acSel->setSelectedLabel( i18n("S&elected actions:") );
    lo->addWidget( gbToolbar );
    connect( acSel, TQ_SIGNAL( added( TQListBoxItem * ) ), this, TQ_SLOT( slotChanged() ) );
    connect( acSel, TQ_SIGNAL( removed( TQListBoxItem * ) ), this, TQ_SLOT( slotChanged() ) );
    connect( acSel, TQ_SIGNAL( movedUp( TQListBoxItem * ) ), this, TQ_SLOT( slotChanged() ) );
    connect( acSel, TQ_SIGNAL( movedDown( TQListBoxItem * ) ), this, TQ_SLOT( slotChanged() ) );

    // Sync
    TQGroupBox *gbSync = new TQGroupBox( 1, TQt::Horizontal, i18n("Auto Synchronization"), this );
    cbSyncActive = new TQCheckBox( i18n("When a docu&ment becomes active"), gbSync );
    cbSyncOpen = new TQCheckBox( i18n("When a document is o&pened"), gbSync );
    cbSyncShow = new TQCheckBox( i18n("When the file selector becomes visible"), gbSync );
    lo->addWidget( gbSync );
    connect( cbSyncActive, TQ_SIGNAL( toggled( bool ) ), this, TQ_SLOT( slotChanged() ) );
    connect( cbSyncOpen, TQ_SIGNAL( toggled( bool ) ), this, TQ_SLOT( slotChanged() ) );
    connect( cbSyncShow, TQ_SIGNAL( toggled( bool ) ), this, TQ_SLOT( slotChanged() ) );

    // Histories
    TQHBox *hbPathHist = new TQHBox ( this );
    TQLabel *lbPathHist = new TQLabel( i18n("Remember &locations:"), hbPathHist );
    sbPathHistLength = new TQSpinBox( hbPathHist );
    lbPathHist->setBuddy( sbPathHistLength );
    lo->addWidget( hbPathHist );
    connect( sbPathHistLength, TQ_SIGNAL( valueChanged ( int ) ), this, TQ_SLOT( slotChanged() ) );

    TQHBox *hbFilterHist = new TQHBox ( this );
    TQLabel *lbFilterHist = new TQLabel( i18n("Remember &filters:"), hbFilterHist );
    sbFilterHistLength = new TQSpinBox( hbFilterHist );
    lbFilterHist->setBuddy( sbFilterHistLength );
    lo->addWidget( hbFilterHist );
    connect( sbFilterHistLength, TQ_SIGNAL( valueChanged ( int ) ), this, TQ_SLOT( slotChanged() ) );

    // Session
    TQGroupBox *gbSession = new TQGroupBox( 1, TQt::Horizontal, i18n("Session"), this );
    cbSesLocation = new TQCheckBox( i18n("Restore loca&tion"), gbSession );
    cbSesFilter = new TQCheckBox( i18n("Restore last f&ilter"), gbSession );
    lo->addWidget( gbSession );
    connect( cbSesLocation, TQ_SIGNAL( toggled( bool ) ), this, TQ_SLOT( slotChanged() ) );
    connect( cbSesFilter, TQ_SIGNAL( toggled( bool ) ), this, TQ_SLOT( slotChanged() ) );

    // make it look nice
    lo->addStretch( 1 );

    // be helpfull
    /*
    TQWhatsThis::add( lbAvailableActions, i18n(
          "<p>Available actions for the toolbar. To add an action, select it here "
          "and press the add (<strong>-&gt;</strong>) button" ) );
    TQWhatsThis::add( lbUsedActions, i18n(
          "<p>Actions used in the toolbar. To remove an action, select it and "
          "press the remove (<strong>&lt;-</strong>) button."
          "<p>To change the order of the actions, use the Up and Down buttons to "
          "move the selected action.") );
    */
    TQString lhwt( i18n(
                      "<p>Decides how many locations to keep in the history of the location "
                      "combo box") );
    TQWhatsThis::add
        ( lbPathHist, lhwt );
    TQWhatsThis::add
        ( sbPathHistLength, lhwt );
    TQString fhwt( i18n(
                      "<p>Decides how many filters to keep in the history of the filter "
                      "combo box") );
    TQWhatsThis::add
        ( lbFilterHist, fhwt );
    TQWhatsThis::add
        ( sbFilterHistLength, fhwt );
    TQString synwt( i18n(
                       "<p>These options allow you to have the File Selector automatically "
                       "change location to the directory of the active document on certain "
                       "events."
                       "<p>Auto synchronization is <em>lazy</em>, meaning it will not take "
                       "effect until the file selector is visible."
                       "<p>None of these are enabled by default, but you can always sync the "
                       "location by pressing the sync button in the toolbar.") );
    TQWhatsThis::add
        ( gbSync, synwt );
    TQWhatsThis::add
        ( cbSesLocation, i18n(
                    "<p>If this option is enabled (default), the location will be restored "
                    "when you start KDev.<p><strong>Note</strong> that if the session is "
                    "handled by the TDE session manager, the location is always restored.") );
    TQWhatsThis::add
        ( cbSesFilter, i18n(
                    "<p>If this option is enabled (default), the current filter will be "
                    "restored when you start KDev.<p><strong>Note</strong> that if the "
                    "session is handled by the TDE session manager, the filter is always "
                    "restored."
                    "<p><strong>Note</strong> that some of the autosync settings may "
                    "override the restored location if on.") );

    init();

}

void KFSConfigPage::apply()
{
    TDEConfig *config = fileSelector->m_part->instance()->config();
    config->setGroup( "fileselector" );
    // toolbar
    TQStringList l;
    TQListBoxItem *item = acSel->selectedListBox()->firstItem();
    ActionLBItem *aItem;
    while ( item )
    {
        aItem = (ActionLBItem*)item;
        if ( aItem )
        {
            l << aItem->idstring();
        }
        item = item->next();
    }
    config->writeEntry( "toolbar actions", l );
    fileSelector->setupToolbar( config );
    // sync
    int s = 0;
    if ( cbSyncActive->isChecked() )
        s |= KDevFileSelector::DocumentChanged;
    if ( cbSyncOpen->isChecked() )
        s |= KDevFileSelector::DocumentOpened;
    if ( cbSyncShow->isChecked() )
        s |= KDevFileSelector::GotVisible;
    fileSelector->autoSyncEvents = s;
    // reset connections
    disconnect( fileSelector->partController, 0, fileSelector, TQ_SLOT( autoSync() ) );
    disconnect( fileSelector->partController, 0,
                fileSelector, TQ_SLOT( autoSync( KParts::Part *) ) );
    if ( s & KDevFileSelector::DocumentChanged )
        connect( fileSelector->partController, TQ_SIGNAL( viewChanged() ),
                 fileSelector, TQ_SLOT( autoSync() ) );
    if ( s & KDevFileSelector::DocumentOpened )
        connect( fileSelector->partController,
                 TQ_SIGNAL( partAdded(KParts::Part *) ),
                 fileSelector, TQ_SLOT( autoSync(KParts::Part *) ) );

    // histories
    fileSelector->cmbPath->setMaxItems( sbPathHistLength->value() );
    fileSelector->filter->setMaxCount( sbFilterHistLength->value() );
    // session - theese are read/written directly to the app config,
    //           as they are not needed during operation.
    config->writeEntry( "restore location", cbSesLocation->isChecked() );
    config->writeEntry( "restore last filter", cbSesFilter->isChecked() );
}

void KFSConfigPage::reload()
{
    // hmm, what is this supposed to do, actually??
    init();
}

void KFSConfigPage::init()
{
    TDEConfig *config = fileSelector->m_part->instance()->config();
    config->setGroup( "fileselector" );
    // toolbar
    TQStringList l = config->readListEntry( "toolbar actions", ',' );
    if ( l.isEmpty() ) // default toolbar
        l << "up" << "back" << "forward" << "home" <<
        "short view" << "detailed view" <<
        "bookmarks" << "sync_dir";

    // actions from diroperator + two of our own
    TQStringList allActions;
    allActions << "up" << "back" << "forward" << "home" <<
    "reload" << "mkdir" << "delete" <<
    "short view" << "detailed view" /*<< "view menu" <<
                      "show hidden" << "properties"*/ <<
    "bookmarks" << "sync_dir";
    TQRegExp re("&(?=[^&])");
    TDEAction *ac;
    TQListBox *lb;
    for ( TQStringList::Iterator it=allActions.begin(); it != allActions.end(); ++it )
    {
        lb = l.contains( *it ) ? acSel->selectedListBox() : acSel->availableListBox();
        if ( *it == "bookmarks" || *it == "sync_dir" )
            ac = fileSelector->actionCollection()->action( (*it).latin1() );
        else
            ac = fileSelector->dirOperator()->actionCollection()->action( (*it).latin1() );
        if ( ac )
            new ActionLBItem( lb, SmallIcon( ac->icon() ), ac->text().replace( re, "" ), *it );
    }

    // sync
    int s = fileSelector->autoSyncEvents;
    cbSyncActive->setChecked( s & KDevFileSelector::DocumentChanged );
    cbSyncOpen->setChecked( s & KDevFileSelector::DocumentOpened );
    cbSyncShow->setChecked( s & KDevFileSelector::GotVisible );
    // histories
    sbPathHistLength->setValue( fileSelector->cmbPath->maxItems() );
    sbFilterHistLength->setValue( fileSelector->filter->maxCount() );
    // session
    cbSesLocation->setChecked( config->readBoolEntry( "restore location", true ) );
    cbSesFilter->setChecked( config->readBoolEntry( "restore last filter", true ) );
}

void KFSConfigPage::slotChanged()
{
}

//END KFSConfigPage


//BEGIN KDevDirOperator

void KDevDirOperator::activatedMenu( const KFileItem *fi, const TQPoint & pos )
{
    setupMenu();
    updateSelectionDependentActions();

    TDEActionMenu * am = dynamic_cast<TDEActionMenu*>(actionCollection()->action("popupMenu"));
    if (!am)
        return;
    TDEPopupMenu *popup = am->popupMenu();

    popup->insertSeparator();
    m_part->newFileAction()->plug(popup);

    if (fi)
    {
        FileContext context( KURL::List(fi->url()));
        if ( (m_part) && (m_part->core()))
            m_part->core()->fillContextMenu(popup, &context);
    }

    popup->popup(pos);
}

//END KDevDirOperator

#include "fileselector_widget.moc"
