00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <qdir.h>
00021 #include <qlayout.h>
00022 #include <qstringlist.h>
00023 #include <qvaluestack.h>
00024
00025 #include <kcombobox.h>
00026 #include <kconfig.h>
00027 #include <kfiledialog.h>
00028 #include <kfilespeedbar.h>
00029 #include <kglobalsettings.h>
00030 #include <kiconloader.h>
00031 #include <klocale.h>
00032 #include <kprotocolinfo.h>
00033 #include <krecentdirs.h>
00034 #include <kurl.h>
00035 #include <kurlcompletion.h>
00036 #include <kurlpixmapprovider.h>
00037
00038 #include "kfiletreeview.h"
00039 #include "kdirselectdialog.h"
00040
00041
00042
00043 class KDirSelectDialog::KDirSelectDialogPrivate
00044 {
00045 public:
00046 KDirSelectDialogPrivate()
00047 {
00048 urlCombo = 0L;
00049 branch = 0L;
00050 comboLocked = false;
00051 }
00052
00053 KFileSpeedBar *speedBar;
00054 KHistoryCombo *urlCombo;
00055 KFileTreeBranch *branch;
00056 QString recentDirClass;
00057 KURL startURL;
00058 QValueStack<KURL> dirsToList;
00059
00060 bool comboLocked : 1;
00061 };
00062
00063 KDirSelectDialog::KDirSelectDialog(const QString &startDir, bool localOnly,
00064 QWidget *parent, const char *name,
00065 bool modal)
00066 : KDialogBase( parent, name, modal, i18n("Select a Directory"), Ok|Cancel),
00067 m_localOnly( localOnly )
00068 {
00069 d = new KDirSelectDialogPrivate;
00070 d->branch = 0L;
00071
00072 QFrame *page = makeMainWidget();
00073 QHBoxLayout *hlay = new QHBoxLayout( page, 0, spacingHint() );
00074 m_mainLayout = new QVBoxLayout();
00075 d->speedBar = new KFileSpeedBar( page, "speedbar" );
00076 connect( d->speedBar, SIGNAL( activated( const KURL& )),
00077 SLOT( setCurrentURL( const KURL& )) );
00078 hlay->addWidget( d->speedBar, 0 );
00079 hlay->addLayout( m_mainLayout, 1 );
00080
00081
00082 m_treeView = new KFileTreeView( page );
00083 m_treeView->addColumn( i18n("Directory") );
00084 m_treeView->setColumnWidthMode( 0, QListView::Maximum );
00085 m_treeView->setResizeMode( QListView::AllColumns );
00086
00087 d->urlCombo = new KHistoryCombo( page, "url combo" );
00088 d->urlCombo->setTrapReturnKey( true );
00089 d->urlCombo->setPixmapProvider( new KURLPixmapProvider() );
00090 KURLCompletion *comp = new KURLCompletion();
00091 comp->setMode( KURLCompletion::DirCompletion );
00092 d->urlCombo->setCompletionObject( comp, true );
00093 d->urlCombo->setAutoDeleteCompletionObject( true );
00094 d->urlCombo->setDuplicatesEnabled( false );
00095 connect( d->urlCombo, SIGNAL( textChanged( const QString& ) ),
00096 SLOT( slotComboTextChanged( const QString& ) ));
00097
00098
00099 d->startURL = KFileDialog::getStartURL( startDir, d->recentDirClass );
00100 if ( localOnly && !d->startURL.isLocalFile() )
00101 d->startURL = KURL::fromPathOrURL( KGlobalSettings::documentPath() );
00102
00103 KURL root = d->startURL;
00104 root.setPath( "/" );
00105
00106 m_startDir = d->startURL.url();
00107
00108 d->branch = createBranch( root );
00109
00110 readConfig( KGlobal::config(), "DirSelect Dialog" );
00111
00112 m_mainLayout->addWidget(m_treeView, 1);
00113 m_mainLayout->addWidget(d->urlCombo, 0);
00114
00115 connect( m_treeView, SIGNAL( currentChanged( QListViewItem * )),
00116 SLOT( slotCurrentChanged() ));
00117
00118 connect( d->urlCombo, SIGNAL( activated( const QString& )),
00119 SLOT( slotURLActivated( const QString& )));
00120 connect( d->urlCombo, SIGNAL( returnPressed( const QString& )),
00121 SLOT( slotURLActivated( const QString& )));
00122
00123 setCurrentURL( d->startURL );
00124 }
00125
00126
00127 KDirSelectDialog::~KDirSelectDialog()
00128 {
00129 delete d;
00130 }
00131
00132 void KDirSelectDialog::setCurrentURL( const KURL& url )
00133 {
00134 if ( !url.isValid() )
00135 return;
00136
00137 KURL root = url;
00138 root.setPath( "/" );
00139
00140 d->startURL = url;
00141 if ( !d->branch ||
00142 url.protocol() != d->branch->url().protocol() ||
00143 url.host() != d->branch->url().host() )
00144 {
00145 if ( d->branch )
00146 {
00147
00148
00149 d->comboLocked = true;
00150 view()->removeBranch( d->branch );
00151 d->comboLocked = false;
00152 }
00153
00154 d->branch = createBranch( root );
00155 }
00156
00157 d->branch->disconnect( SIGNAL( populateFinished( KFileTreeViewItem * )),
00158 this, SLOT( slotNextDirToList( KFileTreeViewItem *)));
00159 connect( d->branch, SIGNAL( populateFinished( KFileTreeViewItem * )),
00160 SLOT( slotNextDirToList( KFileTreeViewItem * ) ));
00161
00162 KURL dirToList = root;
00163 d->dirsToList.clear();
00164 QString path = url.path(+1);
00165 int pos = path.length();
00166
00167 if ( path.isEmpty() )
00168 d->dirsToList.push( root );
00169
00170 else
00171 {
00172 while ( pos > 0 )
00173 {
00174 pos = path.findRev( '/', pos -1 );
00175 if ( pos >= 0 )
00176 {
00177 dirToList.setPath( path.left( pos +1 ) );
00178 d->dirsToList.push( dirToList );
00179
00180 }
00181 }
00182 }
00183
00184 if ( !d->dirsToList.isEmpty() )
00185 openNextDir( d->branch->root() );
00186 }
00187
00188 void KDirSelectDialog::openNextDir( KFileTreeViewItem * )
00189 {
00190 if ( !d->branch )
00191 return;
00192
00193 KURL url = d->dirsToList.pop();
00194
00195 KFileTreeViewItem *item = view()->findItem( d->branch, url.path().mid(1));
00196 if ( item )
00197 {
00198 if ( !item->isOpen() )
00199 item->setOpen( true );
00200 else
00201 slotNextDirToList( item );
00202 }
00203
00204
00205 }
00206
00207 void KDirSelectDialog::slotNextDirToList( KFileTreeViewItem *item )
00208 {
00209
00210 view()->ensureItemVisible( item );
00211 QRect r = view()->itemRect( item );
00212 if ( r.isValid() )
00213 {
00214 int x, y;
00215 view()->viewportToContents( view()->contentsX(), r.y(), x, y );
00216 view()->setContentsPos( x, y );
00217 }
00218
00219 if ( !d->dirsToList.isEmpty() )
00220 openNextDir( item );
00221 else
00222 {
00223 d->branch->disconnect( SIGNAL( populateFinished( KFileTreeViewItem * )),
00224 this, SLOT( slotNextDirToList( KFileTreeViewItem *)));
00225 view()->setCurrentItem( item );
00226 item->setSelected( true );
00227 }
00228 }
00229
00230 void KDirSelectDialog::readConfig( KConfig *config, const QString& group )
00231 {
00232 d->urlCombo->clear();
00233
00234 KConfigGroup conf( config, group );
00235 d->urlCombo->setHistoryItems( conf.readListEntry( "History Items" ));
00236
00237 QSize defaultSize( 400, 450 );
00238 resize( conf.readSizeEntry( "DirSelectDialog Size", &defaultSize ));
00239 }
00240
00241 void KDirSelectDialog::saveConfig( KConfig *config, const QString& group )
00242 {
00243 KConfigGroup conf( config, group );
00244 conf.writeEntry( "History Items", d->urlCombo->historyItems(), ',',
00245 true, true);
00246 conf.writeEntry( "DirSelectDialog Size", size(), true, true );
00247
00248 d->speedBar->save( config );
00249
00250 config->sync();
00251 }
00252
00253 void KDirSelectDialog::accept()
00254 {
00255 KFileTreeViewItem *item = m_treeView->currentKFileTreeViewItem();
00256 if ( !item )
00257 return;
00258
00259 if ( !d->recentDirClass.isEmpty() )
00260 {
00261 KURL dir = item->url();
00262 if ( !item->isDir() )
00263 dir = dir.upURL();
00264
00265 KRecentDirs::add(d->recentDirClass, dir.url());
00266 }
00267
00268 d->urlCombo->addToHistory( item->url().prettyURL() );
00269
00270 KDialogBase::accept();
00271 saveConfig( KGlobal::config(), "DirSelect Dialog" );
00272 }
00273
00274
00275 KURL KDirSelectDialog::url() const
00276 {
00277 return m_treeView->currentURL();
00278 }
00279
00280 void KDirSelectDialog::slotCurrentChanged()
00281 {
00282 if ( d->comboLocked )
00283 return;
00284
00285 KFileTreeViewItem *current = view()->currentKFileTreeViewItem();
00286 KURL u = current ? current->url() : (d->branch ? d->branch->rootUrl() : KURL());
00287
00288 if ( u.isValid() )
00289 {
00290 if ( u.isLocalFile() )
00291 d->urlCombo->setEditText( u.path() );
00292
00293 else
00294 d->urlCombo->setEditText( u.prettyURL() );
00295 }
00296 else
00297 d->urlCombo->setEditText( QString::null );
00298 }
00299
00300 void KDirSelectDialog::slotURLActivated( const QString& text )
00301 {
00302 if ( text.isEmpty() )
00303 return;
00304
00305 KURL url = KURL::fromPathOrURL( text );
00306 d->urlCombo->addToHistory( url.prettyURL() );
00307
00308 if ( localOnly() && !url.isLocalFile() )
00309 return;
00310
00311 KURL oldURL = m_treeView->currentURL();
00312 if ( oldURL.isEmpty() )
00313 oldURL = KURL::fromPathOrURL( m_startDir );
00314
00315 setCurrentURL( url );
00316 }
00317
00318 KFileTreeBranch * KDirSelectDialog::createBranch( const KURL& url )
00319 {
00320 QString title = url.isLocalFile() ? url.path() : url.prettyURL();
00321 KFileTreeBranch *branch = view()->addBranch( url, title );
00322 branch->setChildRecurse( false );
00323 view()->setDirOnlyMode( branch, true );
00324
00325 return branch;
00326 }
00327
00328 void KDirSelectDialog::slotComboTextChanged( const QString& text )
00329 {
00330 if ( d->branch )
00331 {
00332 KURL url = KURL::fromPathOrURL( text );
00333 KFileTreeViewItem *item = d->branch->findTVIByURL( url );
00334 if ( item )
00335 {
00336 view()->setCurrentItem( item );
00337 view()->setSelected( item, true );
00338 view()->ensureItemVisible( item );
00339 return;
00340 }
00341 }
00342
00343 QListViewItem *item = view()->currentItem();
00344 if ( item )
00345 {
00346 item->setSelected( false );
00347
00348 item->repaint();
00349 }
00350 }
00351
00352
00353
00354 KURL KDirSelectDialog::selectDirectory( const QString& startDir,
00355 bool localOnly,
00356 QWidget *parent,
00357 const QString& caption)
00358 {
00359 KDirSelectDialog myDialog( startDir, localOnly, parent,
00360 "kdirselect dialog", true );
00361
00362 if ( !caption.isNull() )
00363 myDialog.setCaption( caption );
00364
00365 if ( myDialog.exec() == QDialog::Accepted )
00366 return myDialog.url();
00367 else
00368 return KURL();
00369 }
00370
00371 void KDirSelectDialog::virtual_hook( int id, void* data )
00372 { KDialogBase::virtual_hook( id, data ); }
00373
00374 #include "kdirselectdialog.moc"