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 <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
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
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
00171
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() )
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
00203 }
00204 }
00205 }
00206
00207
if ( !d->dirsToList.isEmpty() )
00208 openNextDir( d->branch->root() );
00209 }
00210
00211
void KDirSelectDialog::openNextDir(
KFileTreeViewItem * )
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
00224 slotNextDirToList( item );
00225 }
00226
00227
00228 }
00229
00230
void KDirSelectDialog::slotNextDirToList(
KFileTreeViewItem *item )
00231 {
00232
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
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;
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
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
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"