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