• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kio

kdirselectdialog.cpp

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

kio

Skip menu "kio"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal