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