kio Library API Documentation

kdirselectdialog.cpp

00001 /*
00002     Copyright (C) 2001,2002 Carsten Pfeiffer <pfeiffer@kde.org>
00003     Copyright (C) 2001 Michael Jarrett <michaelj@corel.com>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License version 2 as published by the Free Software Foundation.
00008 
00009     This library is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012     Library General Public License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to
00016     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017     Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #include <qdir.h>
00021 #include <qlayout.h>
00022 #include <qstringlist.h>
00023 #include <qvaluestack.h>
00024 
00025 #include <kcombobox.h>
00026 #include <kconfig.h>
00027 #include <kfiledialog.h>
00028 #include <kfilespeedbar.h>
00029 #include <kglobalsettings.h>
00030 #include <kiconloader.h>
00031 #include <klocale.h>
00032 #include <kprotocolinfo.h>
00033 #include <krecentdirs.h>
00034 #include <kurl.h>
00035 #include <kurlcompletion.h>
00036 #include <kurlpixmapprovider.h>
00037 
00038 #include "kfiletreeview.h"
00039 #include "kdirselectdialog.h"
00040 
00041 // ### add mutator for treeview!
00042 
00043 class KDirSelectDialog::KDirSelectDialogPrivate
00044 {
00045 public:
00046     KDirSelectDialogPrivate()
00047     {
00048         urlCombo = 0L;
00049         branch = 0L;
00050         comboLocked = false;
00051     }
00052     
00053     KFileSpeedBar *speedBar;
00054     KHistoryCombo *urlCombo;
00055     KFileTreeBranch *branch;
00056     QString recentDirClass;
00057     KURL startURL;
00058     QValueStack<KURL> dirsToList;
00059 
00060     bool comboLocked : 1;
00061 };
00062 
00063 KDirSelectDialog::KDirSelectDialog(const QString &startDir, bool localOnly,
00064                                    QWidget *parent, const char *name,
00065                                    bool modal)
00066     : KDialogBase( parent, name, modal, i18n("Select a Directory"), Ok|Cancel),
00067       m_localOnly( localOnly )
00068 {
00069     d = new KDirSelectDialogPrivate;
00070     d->branch = 0L;
00071 
00072     QFrame *page = makeMainWidget();
00073     QHBoxLayout *hlay = new QHBoxLayout( page, 0, spacingHint() );
00074     m_mainLayout = new QVBoxLayout();
00075     d->speedBar = new KFileSpeedBar( page, "speedbar" );
00076     connect( d->speedBar, SIGNAL( activated( const KURL& )),
00077              SLOT( setCurrentURL( const KURL& )) );
00078     hlay->addWidget( d->speedBar, 0 );
00079     hlay->addLayout( m_mainLayout, 1 );
00080 
00081     // Create dir list
00082     m_treeView = new KFileTreeView( page );
00083     m_treeView->addColumn( i18n("Directory") );
00084     m_treeView->setColumnWidthMode( 0, QListView::Maximum );
00085     m_treeView->setResizeMode( QListView::AllColumns );
00086 
00087     d->urlCombo = new KHistoryCombo( page, "url combo" );
00088     d->urlCombo->setTrapReturnKey( true );
00089     d->urlCombo->setPixmapProvider( new KURLPixmapProvider() );
00090     KURLCompletion *comp = new KURLCompletion();
00091     comp->setMode( KURLCompletion::DirCompletion );
00092     d->urlCombo->setCompletionObject( comp, true );
00093     d->urlCombo->setAutoDeleteCompletionObject( true );
00094     d->urlCombo->setDuplicatesEnabled( false );
00095     connect( d->urlCombo, SIGNAL( textChanged( const QString& ) ),
00096              SLOT( slotComboTextChanged( const QString& ) ));
00097 
00098 
00099     d->startURL = KFileDialog::getStartURL( startDir, d->recentDirClass );
00100     if ( localOnly && !d->startURL.isLocalFile() )
00101         d->startURL = KURL::fromPathOrURL( KGlobalSettings::documentPath() );
00102 
00103     KURL root = d->startURL;
00104     root.setPath( "/" );
00105 
00106     m_startDir = d->startURL.url();
00107 
00108     d->branch = createBranch( root );
00109 
00110     readConfig( KGlobal::config(), "DirSelect Dialog" );
00111 
00112     m_mainLayout->addWidget(m_treeView, 1);
00113     m_mainLayout->addWidget(d->urlCombo, 0);
00114 
00115     connect( m_treeView, SIGNAL( currentChanged( QListViewItem * )),
00116              SLOT( slotCurrentChanged() ));
00117 
00118     connect( d->urlCombo, SIGNAL( activated( const QString& )),
00119              SLOT( slotURLActivated( const QString& )));
00120     connect( d->urlCombo, SIGNAL( returnPressed( const QString& )),
00121              SLOT( slotURLActivated( const QString& )));
00122 
00123     setCurrentURL( d->startURL );
00124 }
00125 
00126 
00127 KDirSelectDialog::~KDirSelectDialog()
00128 {
00129     delete d;
00130 }
00131 
00132 void KDirSelectDialog::setCurrentURL( const KURL& url )
00133 {
00134     if ( !url.isValid() )
00135         return;
00136     
00137     KURL root = url;
00138     root.setPath( "/" );
00139 
00140     d->startURL = url;
00141     if ( !d->branch || 
00142          url.protocol() != d->branch->url().protocol() ||
00143          url.host() != d->branch->url().host() )
00144     {
00145         if ( d->branch )
00146         {
00147             // removing the root-item causes the currentChanged() signal to be
00148             // emitted, but we don't want to update the location-combo yet.
00149             d->comboLocked = true;
00150             view()->removeBranch( d->branch );
00151             d->comboLocked = false;
00152         }
00153 
00154         d->branch = createBranch( root );
00155     }
00156     
00157     d->branch->disconnect( SIGNAL( populateFinished( KFileTreeViewItem * )),
00158                            this, SLOT( slotNextDirToList( KFileTreeViewItem *)));
00159     connect( d->branch, SIGNAL( populateFinished( KFileTreeViewItem * )),
00160              SLOT( slotNextDirToList( KFileTreeViewItem * ) ));
00161 
00162     KURL dirToList = root;
00163     d->dirsToList.clear();
00164     QString path = url.path(+1);
00165     int pos = path.length();
00166     
00167     if ( path.isEmpty() ) // e.g. ftp://host.com/ -> just list the root dir
00168         d->dirsToList.push( root );
00169 
00170     else
00171     {
00172     while ( pos > 0 )
00173     {
00174         pos = path.findRev( '/', pos -1 );
00175         if ( pos >= 0 )
00176         {
00177             dirToList.setPath( path.left( pos +1 ) );
00178             d->dirsToList.push( dirToList );
00179 //             qDebug( "List: %s", dirToList.url().latin1());
00180         }
00181     }
00182     }
00183 
00184     if ( !d->dirsToList.isEmpty() )
00185         openNextDir( d->branch->root() );
00186 }
00187 
00188 void KDirSelectDialog::openNextDir( KFileTreeViewItem * /*parent*/ )
00189 {
00190     if ( !d->branch )
00191         return;
00192 
00193     KURL url = d->dirsToList.pop();
00194 
00195     KFileTreeViewItem *item = view()->findItem( d->branch, url.path().mid(1));
00196     if ( item )
00197     {
00198         if ( !item->isOpen() )
00199             item->setOpen( true );
00200         else // already open -> go to next one
00201             slotNextDirToList( item );
00202     }
00203 //     else
00204 //         qDebug("###### openNextDir: item not found!");
00205 }
00206 
00207 void KDirSelectDialog::slotNextDirToList( KFileTreeViewItem *item )
00208 {
00209     // scroll to make item the topmost item
00210     view()->ensureItemVisible( item );
00211     QRect r = view()->itemRect( item );
00212     if ( r.isValid() )
00213     {
00214         int x, y;
00215         view()->viewportToContents( view()->contentsX(), r.y(), x, y );
00216         view()->setContentsPos( x, y );
00217     }
00218 
00219     if ( !d->dirsToList.isEmpty() )
00220         openNextDir( item );
00221     else
00222     {
00223         d->branch->disconnect( SIGNAL( populateFinished( KFileTreeViewItem * )),
00224                                this, SLOT( slotNextDirToList( KFileTreeViewItem *)));
00225         view()->setCurrentItem( item );
00226         item->setSelected( true );
00227     }
00228 }
00229 
00230 void KDirSelectDialog::readConfig( KConfig *config, const QString& group )
00231 {
00232     d->urlCombo->clear();
00233 
00234     KConfigGroup conf( config, group );
00235     d->urlCombo->setHistoryItems( conf.readListEntry( "History Items" ));
00236     
00237     QSize defaultSize( 400, 450 );
00238     resize( conf.readSizeEntry( "DirSelectDialog Size", &defaultSize ));
00239 }
00240 
00241 void KDirSelectDialog::saveConfig( KConfig *config, const QString& group )
00242 {
00243     KConfigGroup conf( config, group );
00244     conf.writeEntry( "History Items", d->urlCombo->historyItems(), ',',
00245                      true, true);
00246     conf.writeEntry( "DirSelectDialog Size", size(), true, true );
00247 
00248     d->speedBar->save( config );
00249     
00250     config->sync();
00251 }
00252 
00253 void KDirSelectDialog::accept()
00254 {
00255     KFileTreeViewItem *item = m_treeView->currentKFileTreeViewItem();
00256     if ( !item )
00257         return;
00258 
00259     if ( !d->recentDirClass.isEmpty() )
00260     {
00261         KURL dir = item->url();
00262         if ( !item->isDir() )
00263             dir = dir.upURL();
00264 
00265         KRecentDirs::add(d->recentDirClass, dir.url());
00266     }
00267 
00268     d->urlCombo->addToHistory( item->url().prettyURL() );
00269 
00270     KDialogBase::accept();
00271     saveConfig( KGlobal::config(), "DirSelect Dialog" );
00272 }
00273 
00274 
00275 KURL KDirSelectDialog::url() const
00276 {
00277     return m_treeView->currentURL();
00278 }
00279 
00280 void KDirSelectDialog::slotCurrentChanged()
00281 {
00282     if ( d->comboLocked )
00283         return;
00284     
00285     KFileTreeViewItem *current = view()->currentKFileTreeViewItem();
00286     KURL u = current ? current->url() : (d->branch ? d->branch->rootUrl() : KURL());
00287     
00288     if ( u.isValid() )
00289     {
00290         if ( u.isLocalFile() )
00291             d->urlCombo->setEditText( u.path() );
00292 
00293         else // remote url
00294             d->urlCombo->setEditText( u.prettyURL() );
00295     }
00296     else
00297         d->urlCombo->setEditText( QString::null );
00298 }
00299 
00300 void KDirSelectDialog::slotURLActivated( const QString& text )
00301 {
00302     if ( text.isEmpty() )
00303         return;
00304 
00305     KURL url = KURL::fromPathOrURL( text );
00306     d->urlCombo->addToHistory( url.prettyURL() );
00307     
00308     if ( localOnly() && !url.isLocalFile() )
00309         return; // ### messagebox
00310 
00311     KURL oldURL = m_treeView->currentURL();
00312     if ( oldURL.isEmpty() )
00313         oldURL = KURL::fromPathOrURL( m_startDir );
00314 
00315     setCurrentURL( url );
00316 }
00317 
00318 KFileTreeBranch * KDirSelectDialog::createBranch( const KURL& url )
00319 {
00320     QString title = url.isLocalFile() ? url.path() : url.prettyURL();
00321     KFileTreeBranch *branch = view()->addBranch( url, title );
00322     branch->setChildRecurse( false );
00323     view()->setDirOnlyMode( branch, true );
00324     
00325     return branch;
00326 }
00327 
00328 void KDirSelectDialog::slotComboTextChanged( const QString& text )
00329 {
00330     if ( d->branch )
00331     {
00332         KURL url = KURL::fromPathOrURL( text );
00333         KFileTreeViewItem *item = d->branch->findTVIByURL( url );
00334         if ( item )
00335         {
00336             view()->setCurrentItem( item );
00337             view()->setSelected( item, true );
00338             view()->ensureItemVisible( item );
00339             return;
00340         }
00341     }
00342     
00343     QListViewItem *item = view()->currentItem();
00344     if ( item )
00345     {
00346         item->setSelected( false );
00347         // 2002/12/27, deselected item is not repainted, so force it
00348         item->repaint(); 
00349     }
00350 }
00351 
00352 
00353 // static
00354 KURL KDirSelectDialog::selectDirectory( const QString& startDir,
00355                                         bool localOnly,
00356                                         QWidget *parent,
00357                                         const QString& caption)
00358 {
00359     KDirSelectDialog myDialog( startDir, localOnly, parent,
00360                                "kdirselect dialog", true );
00361     
00362     if ( !caption.isNull() )
00363         myDialog.setCaption( caption );
00364 
00365     if ( myDialog.exec() == QDialog::Accepted )
00366         return myDialog.url();
00367     else
00368         return KURL();
00369 }
00370 
00371 void KDirSelectDialog::virtual_hook( int id, void* data )
00372 { KDialogBase::virtual_hook( id, data ); }
00373 
00374 #include "kdirselectdialog.moc"
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.0.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Oct 8 12:21:28 2003 by doxygen 1.2.18 written by Dimitri van Heesch, © 1997-2001