kio Library: kdirselectdialog.cpp Source File (kio Library)

| # kio Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# 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 <kapplication.h>
    00028 #include <kcombobox.h>
    00029 #include <kconfig.h>
    00030 #include <kfiledialog.h>
    00031 #include <kfilespeedbar.h>
    00032 #include <kglobalsettings.h>
    00033 #include <kiconloader.h>
    00034 #include <klocale.h>
    00035 #include <kprotocolinfo.h>
    00036 #include <krecentdirs.h>
    00037 #include <kurl.h>
    00038 #include <kurlcompletion.h>
    00039 #include <kurlpixmapprovider.h>
    00040 #include <kinputdialog.h>
    00041 #include <kio/netaccess.h>
    00042 #include <kio/renamedlg.h>
    00043 #include <kmessagebox.h>
    00044
    00045 #include "kfiletreeview.h"
    00046 #include "kdirselectdialog.h"
    00047
    00048 // ### add mutator for treeview!
    00049
    00050 class KDirSelectDialog::KDirSelectDialogPrivate
    00051 {
    00052 public:
    00053     KDirSelectDialogPrivate()
    00054     {
    00055         urlCombo = 0L;
    00056         branch = 0L;
    00057         comboLocked = false;
    00058     }
    00059
    00060     KFileSpeedBar *speedBar;
    00061     KHistoryCombo *urlCombo;
    00062     KFileTreeBranch *branch;
    00063     QString recentDirClass;
    00064     KURL startURL;
    00065     QValueStack<KURL> dirsToList;
    00066
    00067     bool comboLocked : 1;
    00068 };
    00069
    00070 static KURL rootUrl(const KURL &url)
    00071 {
    00072     KURL root = url;
    00073     root.setPath( "/" );
    00074
    00075     if (!kapp->authorizeURLAction("list", KURL(), root))
    00076     {
    00077         root = KURL::fromPathOrURL( QDir::homeDirPath() );
    00078         if (!kapp->authorizeURLAction("list", KURL(), root))
    00079         {
    00080             root = url;
    00081         }
    00082     }
    00083     return root;
    00084 }
    00085
    00086 KDirSelectDialog::KDirSelectDialog(const QString &startDir, bool localOnly,
    00087                                    QWidget *parent, const char *name,
    00088                                    bool modal)
    00089     : KDialogBase( parent, name, modal, i18n("Select Folder"), Ok|Cancel),
    00090       m_localOnly( localOnly )
    00091 {
    00092     d = new KDirSelectDialogPrivate;
    00093     d->branch = 0L;
    00094
    00095     QFrame *page = makeMainWidget();
    00096     QHBoxLayout *hlay = new QHBoxLayout( page, 0, spacingHint() );
    00097     m_mainLayout = new QVBoxLayout();
    00098     d->speedBar = new KFileSpeedBar( page, "speedbar" );
    00099     connect( d->speedBar, SIGNAL( activated( const KURL& )),
    00100              SLOT( setCurrentURL( const KURL& )) );
    00101     hlay->addWidget( d->speedBar, 0 );
    00102     hlay->addLayout( m_mainLayout, 1 );
    00103
    00104     // Create dir list
    00105     m_treeView = new KFileTreeView( page );
    00106     m_treeView->addColumn( i18n("Folder") );
    00107     m_treeView->setColumnWidthMode( 0, QListView::Maximum );
    00108     m_treeView->setResizeMode( QListView::AllColumns );
    00109
    00110     d->urlCombo = new KHistoryCombo( page, "url combo" );
    00111     d->urlCombo->setTrapReturnKey( true );
    00112     d->urlCombo->setPixmapProvider( new KURLPixmapProvider() );
    00113     KURLCompletion *comp = new KURLCompletion();
    00114     comp->setMode( KURLCompletion::DirCompletion );
    00115     d->urlCombo->setCompletionObject( comp, true );
    00116     d->urlCombo->setAutoDeleteCompletionObject( true );
    00117     d->urlCombo->setDuplicatesEnabled( false );
    00118     connect( d->urlCombo, SIGNAL( textChanged( const QString& ) ),
    00119              SLOT( slotComboTextChanged( const QString& ) ));
    00120
    00121     m_contextMenu = new QPopupMenu( this );
    00122     KAction* newFolder = new KAction( i18n("New Folder..."), "folder_new", 0, this, SLOT( slotMkdir() ), this);
    00123     newFolder->plug(m_contextMenu);
    00124     m_contextMenu->insertSeparator();
    00125     m_showHiddenFolders = new KToggleAction ( i18n( "Show Hidden Folders" ), 0, this,
    00126                                         SLOT( slotShowHiddenFoldersToggled() ), this);
    00127     m_showHiddenFolders->plug(m_contextMenu);
    00128
    00129     d->startURL = KFileDialog::getStartURL( startDir, d->recentDirClass );
    00130     if ( localOnly && !d->startURL.isLocalFile() )
    00131     {
    00132         d->startURL = KURL();
    00133         QString docPath = KGlobalSettings::documentPath();
    00134         if (QDir(docPath).exists())
    00135             d->startURL.setPath( docPath );
    00136         else
    00137             d->startURL.setPath( QDir::homeDirPath() );
    00138     }
    00139
    00140     KURL root = rootUrl(d->startURL);
    00141
    00142     m_startDir = d->startURL.url();
    00143
    00144     d->branch = createBranch( root );
    00145
    00146     readConfig( KGlobal::config(), "DirSelect Dialog" );
    00147
    00148     m_mainLayout->addWidget( m_treeView, 1 );
    00149     m_mainLayout->addWidget( d->urlCombo, 0 );
    00150
    00151     connect( m_treeView, SIGNAL( currentChanged( QListViewItem * )),
    00152              SLOT( slotCurrentChanged() ));
    00153     connect( m_treeView, SIGNAL( contextMenu( KListView *, QListViewItem *, const QPoint & )),
    00154              SLOT( slotContextMenu( KListView *, QListViewItem *, const QPoint & )));
    00155
    00156     connect( d->urlCombo, SIGNAL( activated( const QString& )),
    00157              SLOT( slotURLActivated( const QString& )));
    00158     connect( d->urlCombo, SIGNAL( returnPressed( const QString& )),
    00159              SLOT( slotURLActivated( const QString& )));
    00160
    00161     setCurrentURL( d->startURL );
    00162 }
    00163
    00164
    00165 KDirSelectDialog::~KDirSelectDialog()
    00166 {
    00167     delete d;
    00168 }
    00169
    00170 void KDirSelectDialog::setCurrentURL( const KURL& url )
    00171 {
    00172     if ( !url.isValid() )
    00173         return;
    00174
    00175     KURL root = rootUrl(url);
    00176
    00177     d->startURL = url;
    00178     if ( !d->branch ||
    00179          url.protocol() != d->branch->url().protocol() ||
    00180          url.host() != d->branch->url().host() )
    00181     {
    00182         if ( d->branch )
    00183         {
    00184             // removing the root-item causes the currentChanged() signal to be
    00185             // emitted, but we don't want to update the location-combo yet.
    00186             d->comboLocked = true;
    00187             view()->removeBranch( d->branch );
    00188             d->comboLocked = false;
    00189         }
    00190
    00191         d->branch = createBranch( root );
    00192     }
    00193
    00194     d->branch->disconnect( SIGNAL( populateFinished( KFileTreeViewItem * )),
    00195                            this, SLOT( slotNextDirToList( KFileTreeViewItem *)));
    00196     connect( d->branch, SIGNAL( populateFinished( KFileTreeViewItem * )),
    00197              SLOT( slotNextDirToList( KFileTreeViewItem * ) ));
    00198
    00199     KURL dirToList = root;
    00200     d->dirsToList.clear();
    00201     QString path = url.path(+1);
    00202     int pos = path.length();
    00203
    00204     if ( path.isEmpty() ) // e.g. ftp://host.com/ -> just list the root dir
    00205         d->dirsToList.push( root );
    00206
    00207     else
    00208     {
    00209         while ( pos > 0 )
    00210         {
    00211             pos = path.findRev( '/', pos -1 );
    00212             if ( pos >= 0 )
    00213             {
    00214                 dirToList.setPath( path.left( pos +1 ) );
    00215                 d->dirsToList.push( dirToList );
    00216 //                 qDebug( "List: %s", dirToList.url().latin1());
    00217             }
    00218         }
    00219     }
    00220
    00221     if ( !d->dirsToList.isEmpty() )
    00222         openNextDir( d->branch->root() );
    00223 }
    00224
    00225 void KDirSelectDialog::openNextDir( KFileTreeViewItem * /*parent*/ )
    00226 {
    00227     if ( !d->branch )
    00228         return;
    00229
    00230     KURL url = d->dirsToList.pop();
    00231
    00232     KFileTreeViewItem *item = view()->findItem( d->branch, url.path().mid(1));
    00233     if ( item )
    00234     {
    00235         if ( !item->isOpen() )
    00236             item->setOpen( true );
    00237         else // already open -> go to next one
    00238             slotNextDirToList( item );
    00239     }
    00240 //     else
    00241 //         qDebug("###### openNextDir: item not found!");
    00242 }
    00243
    00244 void KDirSelectDialog::slotNextDirToList( KFileTreeViewItem *item )
    00245 {
    00246     // scroll to make item the topmost item
    00247     view()->ensureItemVisible( item );
    00248     QRect r = view()->itemRect( item );
    00249     if ( r.isValid() )
    00250     {
    00251         int x, y;
    00252         view()->viewportToContents( view()->contentsX(), r.y(), x, y );
    00253         view()->setContentsPos( x, y );
    00254     }
    00255
    00256     if ( !d->dirsToList.isEmpty() )
    00257         openNextDir( item );
    00258     else
    00259     {
    00260         d->branch->disconnect( SIGNAL( populateFinished( KFileTreeViewItem * )),
    00261                                this, SLOT( slotNextDirToList( KFileTreeViewItem *)));
    00262         view()->setCurrentItem( item );
    00263         item->setSelected( true );
    00264     }
    00265 }
    00266
    00267 void KDirSelectDialog::readConfig( KConfig *config, const QString& group )
    00268 {
    00269     d->urlCombo->clear();
    00270
    00271     KConfigGroup conf( config, group );
    00272     d->urlCombo->setHistoryItems( conf.readPathListEntry( "History Items" ));
    00273
    00274     QSize defaultSize( 400, 450 );
    00275     resize( conf.readSizeEntry( "DirSelectDialog Size", &defaultSize ));
    00276 }
    00277
    00278 void KDirSelectDialog::saveConfig( KConfig *config, const QString& group )
    00279 {
    00280     KConfigGroup conf( config, group );
    00281     conf.writePathEntry( "History Items", d->urlCombo->historyItems(), ',',
    00282                      true, true);
    00283     conf.writeEntry( "DirSelectDialog Size", size(), true, true );
    00284
    00285     d->speedBar->save( config );
    00286
    00287     config->sync();
    00288 }
    00289
    00290 void KDirSelectDialog::accept()
    00291 {
    00292     KFileTreeViewItem *item = m_treeView->currentKFileTreeViewItem();
    00293     if ( !item )
    00294         return;
    00295
    00296     if ( !d->recentDirClass.isEmpty() )
    00297     {
    00298         KURL dir = item->url();
    00299         if ( !item->isDir() )
    00300             dir = dir.upURL();
    00301
    00302         KRecentDirs::add(d->recentDirClass, dir.url());
    00303     }
    00304
    00305     d->urlCombo->addToHistory( item->url().prettyURL() );
    00306     KFileDialog::setStartDir( url() );
    00307
    00308     KDialogBase::accept();
    00309     saveConfig( KGlobal::config(), "DirSelect Dialog" );
    00310 }
    00311
    00312
    00313 KURL KDirSelectDialog::url() const
    00314 {
    00315     return m_treeView->currentURL();
    00316 }
    00317
    00318 void KDirSelectDialog::slotCurrentChanged()
    00319 {
    00320     if ( d->comboLocked )
    00321         return;
    00322
    00323     KFileTreeViewItem *current = view()->currentKFileTreeViewItem();
    00324     KURL u = current ? current->url() : (d->branch ? d->branch->rootUrl() : KURL());
    00325
    00326     if ( u.isValid() )
    00327     {
    00328         if ( u.isLocalFile() )
    00329             d->urlCombo->setEditText( u.path() );
    00330
    00331         else // remote url
    00332             d->urlCombo->setEditText( u.prettyURL() );
    00333     }
    00334     else
    00335         d->urlCombo->setEditText( QString::null );
    00336 }
    00337
    00338 void KDirSelectDialog::slotURLActivated( const QString& text )
    00339 {
    00340     if ( text.isEmpty() )
    00341         return;
    00342
    00343     KURL url = KURL::fromPathOrURL( text );
    00344     d->urlCombo->addToHistory( url.prettyURL() );
    00345
    00346     if ( localOnly() && !url.isLocalFile() )
    00347         return; // ### messagebox
    00348
    00349     KURL oldURL = m_treeView->currentURL();
    00350     if ( oldURL.isEmpty() )
    00351         oldURL = KURL::fromPathOrURL( m_startDir );
    00352
    00353     setCurrentURL( url );
    00354 }
    00355
    00356 KFileTreeBranch * KDirSelectDialog::createBranch( const KURL& url )
    00357 {
    00358     QString title = url.isLocalFile() ? url.path() : url.prettyURL();
    00359     KFileTreeBranch *branch = view()->addBranch( url, title, m_showHiddenFolders->isChecked() );
    00360     branch->setChildRecurse( false );
    00361     view()->setDirOnlyMode( branch, true );
    00362
    00363     return branch;
    00364 }
    00365
    00366 void KDirSelectDialog::slotComboTextChanged( const QString& text )
    00367 {
    00368     if ( d->branch )
    00369     {
    00370         KURL url = KURL::fromPathOrURL( text );
    00371         KFileTreeViewItem *item = d->branch->findTVIByURL( url );
    00372         if ( item )
    00373         {
    00374             view()->setCurrentItem( item );
    00375             view()->setSelected( item, true );
    00376             view()->ensureItemVisible( item );
    00377             return;
    00378         }
    00379     }
    00380
    00381     QListViewItem *item = view()->currentItem();
    00382     if ( item )
    00383     {
    00384         item->setSelected( false );
    00385         // 2002/12/27, deselected item is not repainted, so force it
    00386         item->repaint();
    00387     }
    00388 }
    00389
    00390 void KDirSelectDialog::slotContextMenu( KListView *, QListViewItem *, const QPoint& pos )
    00391 {
    00392     m_contextMenu->popup( pos );
    00393 }
    00394
    00395 void KDirSelectDialog::slotMkdir()
    00396 {
    00397     bool ok;
    00398     QString where = url().pathOrURL();
    00399     QString name = i18n( "New Folder" );
    00400     if ( url().isLocalFile() && QFileInfo( url().path(+1) + name ).exists() )
    00401         name = KIO::RenameDlg::suggestName( url(), name );
    00402
    00403     QString directory = KIO::encodeFileName( KInputDialog::getText( i18n( "New Folder" ),
    00404                                          i18n( "Create new folder in:\n%1" ).arg( where ),
    00405                                          name, &ok, this));
    00406     if (!ok)
    00407       return;
    00408
    00409     bool selectDirectory = true;
    00410     bool writeOk = false;
    00411     bool exists = false;
    00412     KURL folderurl( url() );
    00413
    00414     QStringList dirs = QStringList::split( QDir::separator(), directory );
    00415     QStringList::ConstIterator it = dirs.begin();
    00416
    00417     for ( ; it != dirs.end(); ++it )
    00418     {
    00419         folderurl.addPath( *it );
    00420         exists = KIO::NetAccess::exists( folderurl, false, 0 );
    00421         writeOk = !exists && KIO::NetAccess::mkdir( folderurl, topLevelWidget() );
    00422     }
    00423
    00424     if ( exists ) // url was already existant
    00425     {
    00426         QString which = folderurl.isLocalFile() ? folderurl.path() : folderurl.prettyURL();
    00427         KMessageBox::sorry(this, i18n("A file or folder named %1 already exists.").arg(which));
    00428         selectDirectory = false;
    00429     }
    00430     else if ( !writeOk ) {
    00431         KMessageBox::sorry(this, i18n("You do not have permission to create that folder." ));
    00432     }
    00433     else if ( selectDirectory ) {
    00434         setCurrentURL( folderurl );
    00435     }
    00436 }
    00437
    00438 void KDirSelectDialog::slotShowHiddenFoldersToggled()
    00439 {
    00440     KURL currentURL = url();
    00441
    00442     d->comboLocked = true;
    00443     view()->removeBranch( d->branch );
    00444     d->comboLocked = false;
    00445
    00446     KURL root = rootUrl(d->startURL);
    00447     d->branch = createBranch( root );
    00448
    00449     setCurrentURL( currentURL );
    00450 }
    00451
    00452 // static
    00453 KURL KDirSelectDialog::selectDirectory( const QString& startDir,
    00454                                         bool localOnly,
    00455                                         QWidget *parent,
    00456                                         const QString& caption)
    00457 {
    00458     KDirSelectDialog myDialog( startDir, localOnly, parent,
    00459                                "kdirselect dialog", true );
    00460
    00461     if ( !caption.isNull() )
    00462         myDialog.setCaption( caption );
    00463
    00464     if ( myDialog.exec() == QDialog::Accepted )
    00465         return myDialog.url();
    00466     else
    00467         return KURL();
    00468 }
    00469
    00470 void KDirSelectDialog::virtual_hook( int id, void* data )
    00471 { KDialogBase::virtual_hook( id, data ); }
    00472
    00473 #include "kdirselectdialog.moc"

This file is part of the documentation for kio Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:23:57 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003