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

filebrowser.cpp

/* This file is part of the KDE project
   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 "filebrowser.h"
#include "filebrowser.moc"

#include <qlayout.h>
#include <qtoolbutton.h>
#include <qhbox.h>
#include <qvbox.h>
#include <qlabel.h>
#include <qstrlist.h>
#include <qtooltip.h>
#include <qwhatsthis.h>
#include <qapplication.h>
#include <qlistbox.h>
#include <qscrollbar.h>
#include <qspinbox.h>
#include <qgroupbox.h>
#include <qcheckbox.h>
#include <qregexp.h>
#include <qdockarea.h>
#include <qtimer.h>
#include <qdir.h>

#include <kactionselector.h>
#include <kapplication.h>
#include <kiconloader.h>
#include <kurlcombobox.h>
#include <kurlcompletion.h>
#include <kprotocolinfo.h>
#include <kdiroperator.h>
#include <kconfig.h>
#include <klocale.h>
#include <kcombobox.h>
#include <kaction.h>
#include <kmessagebox.h>
#include <kstandarddirs.h>
#include <ktoolbarbutton.h>
#include <qtoolbar.h>
#include <kpopupmenu.h>
#include <kdialog.h>
#include <kdebug.h>
//END Includes

//BEGIN Toolbar

namespace FileBrowserNS {

 // from kfiledialog.cpp - avoid qt warning in STDERR (~/.xsessionerrors)
static void silenceQToolBar(QtMsgType, const char *){}

// helper classes to be able to have a toolbar without move handle
FileBrowserToolBar::FileBrowserToolBar(QWidget *parent)
  : KToolBar( parent, "Kate FileSelector Toolbar", true )
{
      setMinimumWidth(10);
}

FileBrowserToolBar::~FileBrowserToolBar(){}

void FileBrowserToolBar::setMovingEnabled( bool)
{
      KToolBar::setMovingEnabled(false);
}


FileBrowserToolBarParent::FileBrowserToolBarParent(QWidget *parent)
      :QFrame(parent),m_tb(0){}
FileBrowserToolBarParent::~FileBrowserToolBarParent(){}
void FileBrowserToolBarParent::setToolBar(FileBrowserToolBar *tb)
{
      m_tb=tb;
}

void FileBrowserToolBarParent::resizeEvent ( QResizeEvent * )
{
      if (m_tb)
      {
            setMinimumHeight(m_tb->sizeHint().height());
            m_tb->resize(width(),height());
      }
}
//END

//BEGIN Constructor/destructor

FileBrowser::FileBrowser(QWidget * parent, const char * name )
    : QVBox (parent, name)
{
  mActionCollection = new KActionCollection( this );

  QtMsgHandler oldHandler = qInstallMsgHandler( silenceQToolBar );

  FileBrowserToolBarParent *tbp=new FileBrowserToolBarParent(this);
  toolbar = new FileBrowserToolBar(tbp);
  tbp->setToolBar(toolbar);
  toolbar->setMovingEnabled(false);
  toolbar->setFlat(true);
  qInstallMsgHandler( oldHandler );

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

  dir = new KDirOperator(KURL(), this, "operator");
  dir->setView(KFile::/* Simple */Detail);
  dir->view()->setSelectionMode(KFile::Single);
  setStretchFactor(dir, 2);

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

  // bookmarks action!
  KActionMenu *acmBookmarks = new KActionMenu( i18n("Bookmarks"), "bookmark",
        mActionCollection, "bookmarks" );
  acmBookmarks->setDelayed( false );
  bookmarkHandler = new KBookmarkHandler( this, acmBookmarks->popupMenu() );

  toolbar->setIconText( KToolBar::IconOnly );
  toolbar->setIconSize( 16 );
  toolbar->setEnableContextMenu( false );

  connect( cmbPath, SIGNAL( urlActivated( const KURL&  )),
             this,  SLOT( cmbPathActivated( const KURL& ) ));
  connect( cmbPath, SIGNAL( returnPressed( const QString&  )),
             this,  SLOT( cmbPathReturnPressed( const QString& ) ));
  connect(dir, SIGNAL(urlEntered(const KURL&)),
             this, SLOT(dirUrlEntered(const KURL&)) );

  connect(dir, SIGNAL(finishedLoading()),
             this, SLOT(dirFinishedLoading()) );

  // Connect the bookmark handler
  connect( bookmarkHandler, SIGNAL( openURL( const QString& )),
           this, SLOT( setDir( const QString& ) ) );


  waitingUrl = QString::null;

  // whatsthis help
  QWhatsThis::add( cmbPath,
       i18n("<p>Here you can enter a path for a folder to display."
            "<p>To go to a folder previously entered, press the arrow on "
            "the right and choose one. <p>The entry has folder "
            "completion. Right-click to choose how completion should behave.") );
}

FileBrowser::~FileBrowser()
{
}
//END Constroctor/Destrctor

//BEGIN Public Methods

void FileBrowser::readConfig(KConfig *config, const QString & name)
{
  dir->setViewConfig( config, name + ":view" );
  dir->readConfig(config, name + ":dir");
  dir->setView( KFile::Default );
  dir->view()->setSelectionMode(KFile::Single);
  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 ) || kapp->isRestored() ) {
    QString loc( config->readPathEntry( "location" ) );
    if ( ! loc.isEmpty() ) {
//       waitingDir = loc;
//       QTimer::singleShot(0, this, SLOT(initialDirChangeHack()));
      setDir( loc );
    }
  }
}

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

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

void FileBrowser::writeConfig(KConfig *config, const QString & name)
{
  dir->writeConfig(config,name + ":dir");

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

void FileBrowser::setView(KFile::FileView view)
{
  dir->setView(view);
  dir->view()->setSelectionMode(KFile::Single);
}

//END Public Methods

//BEGIN Public Slots


bool FileBrowserIsReadable ( const KURL& url )
{
  if ( !url.isLocalFile() )
    return true; // what else can we say?

  QDir dir (url.path());
  return dir.exists ();
}

void FileBrowser::setDir( KURL u )
{
  KURL newurl;

  if ( !u.isValid() )
    newurl.setPath( QDir::homeDirPath() );
  else
    newurl = u;

  QString pathstr = newurl.path(+1);
  newurl.setPath(pathstr);

  if ( !FileBrowserIsReadable ( newurl ) )
    newurl.cd(QString::fromLatin1(".."));

  if ( !FileBrowserIsReadable (newurl) )
     newurl.setPath( QDir::homeDirPath() );

  dir->setURL(newurl, true);
}

//END Public Slots

//BEGIN Private Slots

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

void FileBrowser::cmbPathReturnPressed( const QString& u )
{
  KURL typedURL( u );
  if ( typedURL.hasPass() )
    typedURL.setPass( QString::null );

  QStringList urls = cmbPath->urls();
  urls.remove( typedURL.url() );
  urls.prepend( typedURL.url() );
  cmbPath->setURLs( urls, KURLComboBox::RemoveBottom );
  dir->setFocus();
  dir->setURL( KURL(u), true );
}

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


void FileBrowser::dirFinishedLoading()
{
}

//END Private Slots

//BEGIN Protected

void FileBrowser::focusInEvent( QFocusEvent * )
{
   dir->setFocus();
}

bool FileBrowser::eventFilter( QObject* o, QEvent *e )
{
  /*
      This is rather unfortunate, but:
      QComboBox does not support setting the size of the listbox to something
      reasonable. Even using listbox->setVariableWidth() does not yield 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.
  */
  QListBox *lb = cmbPath->listBox();
  if ( o == lb && e->type() == QEvent::Show ) {
/*    int add = lb->height() < lb->contentsHeight() ? lb->verticalScrollBar()->width() : 0;*/
  //  int w = QMIN( mainwin->width(), lb->contentsWidth() + add );
    //lb->resize( w, lb->height() );
    // TODO - move the listbox to a suitable place if necessary
    // TODO - decide if it is worth caching the size while untill the contents
    //        are changed.
  }
  // TODO - same thing for the completion popup?
  return QWidget::eventFilter( o, e );
}

//END Protected

// ----------------------------------------------------- KBookmarkHandler

KBookmarkHandler::KBookmarkHandler( FileBrowser *parent, KPopupMenu* kpopupmenu )
    : QObject( parent, "KBookmarkHandler" ),
      KBookmarkOwner(),
      mParent( parent ),
      m_menu( kpopupmenu ),
      m_importStream( 0L )
{
    if (!m_menu)
      m_menu = new KPopupMenu( parent, "bookmark menu" );

    QString file = locate( "data", "mailody/fsbookmarks.xml" );
    if ( file.isEmpty() )
        file = locateLocal( "data", "mailody/fsbookmarks.xml" );

    KBookmarkManager *manager = KBookmarkManager::managerForFile( file, false);
    manager->setUpdate( true );
    manager->setShowNSBookmarks( false );

    m_bookmarkMenu = new KBookmarkMenu( manager, this, m_menu, 0, true );
}

KBookmarkHandler::~KBookmarkHandler()
{
    //     delete m_bookmarkMenu; ###
}

QString KBookmarkHandler::currentURL() const
{
    return mParent->dirOperator()->url().url();
}


void KBookmarkHandler::slotNewBookmark( const QString& /*text*/,
                                            const QCString& url,
                                            const QString& additionalInfo )
{
    *m_importStream << "<bookmark icon=\"" << KMimeType::iconForURL( KURL( url ) );
    *m_importStream << "\" href=\"" << QString::fromUtf8(url) << "\">\n";
    *m_importStream << "<title>" << (additionalInfo.isEmpty() ? QString::fromUtf8(url) : additionalInfo) << "</title>\n</bookmark>\n";
}

void KBookmarkHandler::slotNewFolder( const QString& text, bool /*open*/,
                                          const QString& /*additionalInfo*/ )
{
    *m_importStream << "<folder icon=\"bookmark_folder\">\n<title=\"";
    *m_importStream << text << "\">\n";
}

void KBookmarkHandler::newSeparator()
{
    *m_importStream << "<separator/>\n";
}

void KBookmarkHandler::endFolder()
{
    *m_importStream << "</folder>\n";
}

void KBookmarkHandler::virtual_hook( int id, void* data )
{ KBookmarkOwner::virtual_hook( id, data ); }


}



Generated by  Doxygen 1.6.0   Back to index