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 Wed Mar 16 17:22:29 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003