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 <qpopupmenu.h>
00023 #include <qstringlist.h>
00024 #include <qvaluestack.h>
00025 
00026 #include <kactionclasses.h>
00027 #include <kcombobox.h>
00028 #include <kconfig.h>
00029 #include <kfiledialog.h>
00030 #include <kfilespeedbar.h>
00031 #include <kglobalsettings.h>
00032 #include <kiconloader.h>
00033 #include <klocale.h>
00034 #include <kprotocolinfo.h>
00035 #include <krecentdirs.h>
00036 #include <kurl.h>
00037 #include <kurlcompletion.h>
00038 #include <kurlpixmapprovider.h>
00039 
00040 #include "kfiletreeview.h"
00041 #include "kdirselectdialog.h"
00042 
00043 // ### add mutator for treeview!
00044 
00045 class KDirSelectDialog::KDirSelectDialogPrivate
00046 {
00047 public:
00048     KDirSelectDialogPrivate()
00049     {
00050         urlCombo = 0L;
00051         branch = 0L;
00052         comboLocked = false;
00053     }
00054 
00055     KFileSpeedBar *speedBar;
00056     KHistoryCombo *urlCombo;
00057     KFileTreeBranch *branch;
00058     QString recentDirClass;
00059     KURL startURL;
00060     QValueStack<KURL> dirsToList;
00061 
00062     bool comboLocked : 1;
00063 };
00064 
00065 KDirSelectDialog::KDirSelectDialog(const QString &startDir, bool localOnly,
00066                                    QWidget *parent, const char *name,
00067                                    bool modal)
00068     : KDialogBase( parent, name, modal, i18n("Select Folder"), Ok|Cancel),
00069       m_localOnly( localOnly )
00070 {
00071     d = new KDirSelectDialogPrivate;
00072     d->branch = 0L;
00073 
00074     QFrame *page = makeMainWidget();
00075     QHBoxLayout *hlay = new QHBoxLayout( page, 0, spacingHint() );
00076     m_mainLayout = new QVBoxLayout();
00077     d->speedBar = new KFileSpeedBar( page, "speedbar" );
00078     connect( d->speedBar, SIGNAL( activated( const KURL& )),
00079              SLOT( setCurrentURL( const KURL& )) );
00080     hlay->addWidget( d->speedBar, 0 );
00081     hlay->addLayout( m_mainLayout, 1 );
00082 
00083     // Create dir list
00084     m_treeView = new KFileTreeView( page );
00085     m_treeView->addColumn( i18n("Folder") );
00086     m_treeView->setColumnWidthMode( 0, QListView::Maximum );
00087     m_treeView->setResizeMode( QListView::AllColumns );
00088 
00089     d->urlCombo = new KHistoryCombo( page, "url combo" );
00090     d->urlCombo->setTrapReturnKey( true );
00091     d->urlCombo->setPixmapProvider( new KURLPixmapProvider() );
00092     KURLCompletion *comp = new KURLCompletion();
00093     comp->setMode( KURLCompletion::DirCompletion );
00094     d->urlCombo->setCompletionObject( comp, true );
00095     d->urlCombo->setAutoDeleteCompletionObject( true );
00096     d->urlCombo->setDuplicatesEnabled( false );
00097     connect( d->urlCombo, SIGNAL( textChanged( const QString& ) ),
00098              SLOT( slotComboTextChanged( const QString& ) ));
00099 
00100     m_contextMenu = new QPopupMenu( this );
00101     m_showHiddenFiles = new KToggleAction ( i18n( "Show Hidden Files" ), 0, this,
00102                                         SLOT( slotShowHiddenFilesToggled() ), this);
00103     m_showHiddenFiles->plug(m_contextMenu);
00104 
00105     d->startURL = KFileDialog::getStartURL( startDir, d->recentDirClass );
00106     if ( localOnly && !d->startURL.isLocalFile() )
00107         d->startURL = KURL::fromPathOrURL( KGlobalSettings::documentPath() );
00108 
00109     KURL root = d->startURL;
00110     root.setPath( "/" );
00111 
00112     m_startDir = d->startURL.url();
00113 
00114     d->branch = createBranch( root );
00115 
00116     readConfig( KGlobal::config(), "DirSelect Dialog" );
00117 
00118     m_mainLayout->addWidget( m_treeView, 1 );
00119     m_mainLayout->addWidget( d->urlCombo, 0 );
00120 
00121     connect( m_treeView, SIGNAL( currentChanged( QListViewItem * )),
00122              SLOT( slotCurrentChanged() ));
00123     connect( m_treeView, SIGNAL( contextMenu( KListView *, QListViewItem *, const QPoint & )),
00124              SLOT( slotContextMenu( KListView *, QListViewItem *, const QPoint & )));
00125 
00126     connect( d->urlCombo, SIGNAL( activated( const QString& )),
00127              SLOT( slotURLActivated( const QString& )));
00128     connect( d->urlCombo, SIGNAL( returnPressed( const QString& )),
00129              SLOT( slotURLActivated( const QString& )));
00130 
00131     setCurrentURL( d->startURL );
00132 }
00133 
00134 
00135 KDirSelectDialog::~KDirSelectDialog()
00136 {
00137     delete d;
00138 }
00139 
00140 void KDirSelectDialog::setCurrentURL( const KURL& url )
00141 {
00142     if ( !url.isValid() )
00143         return;
00144 
00145     KURL root = url;
00146     root.setPath( "/" );
00147 
00148     d->startURL = url;
00149     if ( !d->branch ||
00150          url.protocol() != d->branch->url().protocol() ||
00151          url.host() != d->branch->url().host() )
00152     {
00153         if ( d->branch )
00154         {
00155             // removing the root-item causes the currentChanged() signal to be
00156             // emitted, but we don't want to update the location-combo yet.
00157             d->comboLocked = true;
00158             view()->removeBranch( d->branch );
00159             d->comboLocked = false;
00160         }
00161 
00162         d->branch = createBranch( root );
00163     }
00164 
00165     d->branch->disconnect( SIGNAL( populateFinished( KFileTreeViewItem * )),
00166                            this, SLOT( slotNextDirToList( KFileTreeViewItem *)));
00167     connect( d->branch, SIGNAL( populateFinished( KFileTreeViewItem * )),
00168              SLOT( slotNextDirToList( KFileTreeViewItem * ) ));
00169 
00170     KURL dirToList = root;
00171     d->dirsToList.clear();
00172     QString path = url.path(+1);
00173     int pos = path.length();
00174 
00175     if ( path.isEmpty() ) // e.g. ftp://host.com/ -> just list the root dir
00176         d->dirsToList.push( root );
00177 
00178     else
00179     {
00180         while ( pos > 0 )
00181         {
00182             pos = path.findRev( '/', pos -1 );
00183             if ( pos >= 0 )
00184             {
00185                 dirToList.setPath( path.left( pos +1 ) );
00186                 d->dirsToList.push( dirToList );
00187 //                 qDebug( "List: %s", dirToList.url().latin1());
00188             }
00189         }
00190     }
00191 
00192     if ( !d->dirsToList.isEmpty() )
00193         openNextDir( d->branch->root() );
00194 }
00195 
00196 void KDirSelectDialog::openNextDir( KFileTreeViewItem * /*parent*/ )
00197 {
00198     if ( !d->branch )
00199         return;
00200 
00201     KURL url = d->dirsToList.pop();
00202 
00203     KFileTreeViewItem *item = view()->findItem( d->branch, url.path().mid(1));
00204     if ( item )
00205     {
00206         if ( !item->isOpen() )
00207             item->setOpen( true );
00208         else // already open -> go to next one
00209             slotNextDirToList( item );
00210     }
00211 //     else
00212 //         qDebug("###### openNextDir: item not found!");
00213 }
00214 
00215 void KDirSelectDialog::slotNextDirToList( KFileTreeViewItem *item )
00216 {
00217     // scroll to make item the topmost item
00218     view()->ensureItemVisible( item );
00219     QRect r = view()->itemRect( item );
00220     if ( r.isValid() )
00221     {
00222         int x, y;
00223         view()->viewportToContents( view()->contentsX(), r.y(), x, y );
00224         view()->setContentsPos( x, y );
00225     }
00226 
00227     if ( !d->dirsToList.isEmpty() )
00228         openNextDir( item );
00229     else
00230     {
00231         d->branch->disconnect( SIGNAL( populateFinished( KFileTreeViewItem * )),
00232                                this, SLOT( slotNextDirToList( KFileTreeViewItem *)));
00233         view()->setCurrentItem( item );
00234         item->setSelected( true );
00235     }
00236 }
00237 
00238 void KDirSelectDialog::readConfig( KConfig *config, const QString& group )
00239 {
00240     d->urlCombo->clear();
00241 
00242     KConfigGroup conf( config, group );
00243     d->urlCombo->setHistoryItems( conf.readPathListEntry( "History Items" ));
00244 
00245     QSize defaultSize( 400, 450 );
00246     resize( conf.readSizeEntry( "DirSelectDialog Size", &defaultSize ));
00247 }
00248 
00249 void KDirSelectDialog::saveConfig( KConfig *config, const QString& group )
00250 {
00251     KConfigGroup conf( config, group );
00252     conf.writePathEntry( "History Items", d->urlCombo->historyItems(), ',',
00253                      true, true);
00254     conf.writeEntry( "DirSelectDialog Size", size(), true, true );
00255 
00256     d->speedBar->save( config );
00257 
00258     config->sync();
00259 }
00260 
00261 void KDirSelectDialog::accept()
00262 {
00263     KFileTreeViewItem *item = m_treeView->currentKFileTreeViewItem();
00264     if ( !item )
00265         return;
00266 
00267     if ( !d->recentDirClass.isEmpty() )
00268     {
00269         KURL dir = item->url();
00270         if ( !item->isDir() )
00271             dir = dir.upURL();
00272 
00273         KRecentDirs::add(d->recentDirClass, dir.url());
00274     }
00275 
00276     d->urlCombo->addToHistory( item->url().prettyURL() );
00277     KFileDialog::setStartDir( url() );
00278 
00279     KDialogBase::accept();
00280     saveConfig( KGlobal::config(), "DirSelect Dialog" );
00281 }
00282 
00283 
00284 KURL KDirSelectDialog::url() const
00285 {
00286     return m_treeView->currentURL();
00287 }
00288 
00289 void KDirSelectDialog::slotCurrentChanged()
00290 {
00291     if ( d->comboLocked )
00292         return;
00293 
00294     KFileTreeViewItem *current = view()->currentKFileTreeViewItem();
00295     KURL u = current ? current->url() : (d->branch ? d->branch->rootUrl() : KURL());
00296 
00297     if ( u.isValid() )
00298     {
00299         if ( u.isLocalFile() )
00300             d->urlCombo->setEditText( u.path() );
00301 
00302         else // remote url
00303             d->urlCombo->setEditText( u.prettyURL() );
00304     }
00305     else
00306         d->urlCombo->setEditText( QString::null );
00307 }
00308 
00309 void KDirSelectDialog::slotURLActivated( const QString& text )
00310 {
00311     if ( text.isEmpty() )
00312         return;
00313 
00314     KURL url = KURL::fromPathOrURL( text );
00315     d->urlCombo->addToHistory( url.prettyURL() );
00316 
00317     if ( localOnly() && !url.isLocalFile() )
00318         return; // ### messagebox
00319 
00320     KURL oldURL = m_treeView->currentURL();
00321     if ( oldURL.isEmpty() )
00322         oldURL = KURL::fromPathOrURL( m_startDir );
00323 
00324     setCurrentURL( url );
00325 }
00326 
00327 KFileTreeBranch * KDirSelectDialog::createBranch( const KURL& url )
00328 {
00329     QString title = url.isLocalFile() ? url.path() : url.prettyURL();
00330     KFileTreeBranch *branch = view()->addBranch( url, title, m_showHiddenFiles->isChecked() );
00331     branch->setChildRecurse( false );
00332     view()->setDirOnlyMode( branch, true );
00333 
00334     return branch;
00335 }
00336 
00337 void KDirSelectDialog::slotComboTextChanged( const QString& text )
00338 {
00339     if ( d->branch )
00340     {
00341         KURL url = KURL::fromPathOrURL( text );
00342         KFileTreeViewItem *item = d->branch->findTVIByURL( url );
00343         if ( item )
00344         {
00345             view()->setCurrentItem( item );
00346             view()->setSelected( item, true );
00347             view()->ensureItemVisible( item );
00348             return;
00349         }
00350     }
00351 
00352     QListViewItem *item = view()->currentItem();
00353     if ( item )
00354     {
00355         item->setSelected( false );
00356         // 2002/12/27, deselected item is not repainted, so force it
00357         item->repaint();
00358     }
00359 }
00360 
00361 void KDirSelectDialog::slotContextMenu( KListView *, QListViewItem *, const QPoint& pos )
00362 {
00363     m_contextMenu->popup( pos );
00364 }
00365 
00366 void KDirSelectDialog::slotShowHiddenFilesToggled()
00367 {
00368     KURL currentURL = url();
00369 
00370     d->comboLocked = true;
00371     view()->removeBranch( d->branch );
00372     d->comboLocked = false;
00373 
00374     KURL root = d->startURL;
00375     root.setPath( "/" );
00376     d->branch = createBranch( root );
00377 
00378     setCurrentURL( currentURL );
00379 }
00380 
00381 // static
00382 KURL KDirSelectDialog::selectDirectory( const QString& startDir,
00383                                         bool localOnly,
00384                                         QWidget *parent,
00385                                         const QString& caption)
00386 {
00387     KDirSelectDialog myDialog( startDir, localOnly, parent,
00388                                "kdirselect dialog", true );
00389 
00390     if ( !caption.isNull() )
00391         myDialog.setCaption( caption );
00392 
00393     if ( myDialog.exec() == QDialog::Accepted )
00394         return myDialog.url();
00395     else
00396         return KURL();
00397 }
00398 
00399 void KDirSelectDialog::virtual_hook( int id, void* data )
00400 { KDialogBase::virtual_hook( id, data ); }
00401 
00402 #include "kdirselectdialog.moc"
KDE Logo
This file is part of the documentation for kio Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Sep 30 05:18:23 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2003