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 <kinputdialog.h>
00042
#include <kio/netaccess.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",
00123 0,
this, SLOT( slotMkdir() ),
this);
00124 newFolder->
plug(m_contextMenu);
00125 m_contextMenu->insertSeparator();
00126 m_showHiddenFiles =
new KToggleAction ( i18n(
"Show Hidden Files" ), 0,
this,
00127 SLOT( slotShowHiddenFilesToggled() ),
this);
00128 m_showHiddenFiles->
plug(m_contextMenu);
00129
00130 d->startURL = KFileDialog::getStartURL( startDir, d->recentDirClass );
00131
if ( localOnly && !d->startURL.isLocalFile() )
00132 d->startURL = KURL::fromPathOrURL( KGlobalSettings::documentPath() );
00133
00134
KURL root = rootUrl(d->startURL);
00135
00136 m_startDir = d->startURL.url();
00137
00138 d->branch = createBranch( root );
00139
00140 readConfig( KGlobal::config(),
"DirSelect Dialog" );
00141
00142 m_mainLayout->addWidget( m_treeView, 1 );
00143 m_mainLayout->addWidget( d->urlCombo, 0 );
00144
00145 connect( m_treeView, SIGNAL( currentChanged(
QListViewItem * )),
00146 SLOT( slotCurrentChanged() ));
00147 connect( m_treeView, SIGNAL( contextMenu(
KListView *,
QListViewItem *,
const QPoint & )),
00148 SLOT( slotContextMenu(
KListView *,
QListViewItem *,
const QPoint & )));
00149
00150 connect( d->urlCombo, SIGNAL( activated(
const QString& )),
00151 SLOT( slotURLActivated(
const QString& )));
00152 connect( d->urlCombo, SIGNAL( returnPressed(
const QString& )),
00153 SLOT( slotURLActivated(
const QString& )));
00154
00155 setCurrentURL( d->startURL );
00156 }
00157
00158
00159 KDirSelectDialog::~KDirSelectDialog()
00160 {
00161
delete d;
00162 }
00163
00164
void KDirSelectDialog::setCurrentURL(
const KURL& url )
00165 {
00166
if ( !url.
isValid() )
00167
return;
00168
00169
KURL root = rootUrl(url);
00170
00171 d->startURL = url;
00172
if ( !d->branch ||
00173 url.
protocol() != d->branch->url().protocol() ||
00174 url.
host() != d->branch->url().host() )
00175 {
00176
if ( d->branch )
00177 {
00178
00179
00180 d->comboLocked =
true;
00181 view()->
removeBranch( d->branch );
00182 d->comboLocked =
false;
00183 }
00184
00185 d->branch = createBranch( root );
00186 }
00187
00188 d->branch->disconnect( SIGNAL( populateFinished(
KFileTreeViewItem * )),
00189
this, SLOT( slotNextDirToList(
KFileTreeViewItem *)));
00190 connect( d->branch, SIGNAL( populateFinished(
KFileTreeViewItem * )),
00191 SLOT( slotNextDirToList(
KFileTreeViewItem * ) ));
00192
00193
KURL dirToList = root;
00194 d->dirsToList.clear();
00195
QString path = url.
path(+1);
00196
int pos = path.length();
00197
00198
if ( path.isEmpty() )
00199 d->dirsToList.push( root );
00200
00201
else
00202 {
00203
while ( pos > 0 )
00204 {
00205 pos = path.findRev(
'/', pos -1 );
00206
if ( pos >= 0 )
00207 {
00208 dirToList.
setPath( path.left( pos +1 ) );
00209 d->dirsToList.push( dirToList );
00210
00211 }
00212 }
00213 }
00214
00215
if ( !d->dirsToList.isEmpty() )
00216 openNextDir( d->branch->root() );
00217 }
00218
00219
void KDirSelectDialog::openNextDir(
KFileTreeViewItem * )
00220 {
00221
if ( !d->branch )
00222
return;
00223
00224
KURL url = d->dirsToList.pop();
00225
00226
KFileTreeViewItem *item = view()->
findItem( d->branch, url.
path().mid(1));
00227
if ( item )
00228 {
00229
if ( !item->isOpen() )
00230 item->setOpen(
true );
00231
else
00232 slotNextDirToList( item );
00233 }
00234
00235
00236 }
00237
00238
void KDirSelectDialog::slotNextDirToList(
KFileTreeViewItem *item )
00239 {
00240
00241 view()->ensureItemVisible( item );
00242
QRect r = view()->itemRect( item );
00243
if ( r.isValid() )
00244 {
00245
int x, y;
00246 view()->viewportToContents( view()->contentsX(), r.y(), x, y );
00247 view()->setContentsPos( x, y );
00248 }
00249
00250
if ( !d->dirsToList.isEmpty() )
00251 openNextDir( item );
00252
else
00253 {
00254 d->branch->disconnect( SIGNAL( populateFinished(
KFileTreeViewItem * )),
00255
this, SLOT( slotNextDirToList(
KFileTreeViewItem *)));
00256 view()->setCurrentItem( item );
00257 item->setSelected(
true );
00258 }
00259 }
00260
00261
void KDirSelectDialog::readConfig(
KConfig *config,
const QString& group )
00262 {
00263 d->urlCombo->clear();
00264
00265
KConfigGroup conf( config, group );
00266 d->urlCombo->setHistoryItems( conf.
readPathListEntry(
"History Items" ));
00267
00268
QSize defaultSize( 400, 450 );
00269 resize( conf.
readSizeEntry(
"DirSelectDialog Size", &defaultSize ));
00270 }
00271
00272
void KDirSelectDialog::saveConfig(
KConfig *config,
const QString& group )
00273 {
00274
KConfigGroup conf( config, group );
00275 conf.
writePathEntry(
"History Items", d->urlCombo->historyItems(),
',',
00276
true,
true);
00277 conf.
writeEntry(
"DirSelectDialog Size", size(),
true,
true );
00278
00279 d->speedBar->save( config );
00280
00281 config->
sync();
00282 }
00283
00284
void KDirSelectDialog::accept()
00285 {
00286
KFileTreeViewItem *item = m_treeView->
currentKFileTreeViewItem();
00287
if ( !item )
00288
return;
00289
00290
if ( !d->recentDirClass.isEmpty() )
00291 {
00292
KURL dir = item->
url();
00293
if ( !item->
isDir() )
00294 dir = dir.
upURL();
00295
00296
KRecentDirs::add(d->recentDirClass, dir.
url());
00297 }
00298
00299 d->urlCombo->addToHistory( item->
url().
prettyURL() );
00300 KFileDialog::setStartDir(
url() );
00301
00302 KDialogBase::accept();
00303 saveConfig( KGlobal::config(),
"DirSelect Dialog" );
00304 }
00305
00306
00307 KURL KDirSelectDialog::url()
const
00308
{
00309
return m_treeView->
currentURL();
00310 }
00311
00312
void KDirSelectDialog::slotCurrentChanged()
00313 {
00314
if ( d->comboLocked )
00315
return;
00316
00317
KFileTreeViewItem *current = view()->currentKFileTreeViewItem();
00318
KURL u = current ? current->
url() : (d->branch ? d->branch->rootUrl() :
KURL());
00319
00320
if ( u.
isValid() )
00321 {
00322
if ( u.
isLocalFile() )
00323 d->urlCombo->setEditText( u.
path() );
00324
00325
else
00326 d->urlCombo->setEditText( u.
prettyURL() );
00327 }
00328
else
00329 d->urlCombo->setEditText( QString::null );
00330 }
00331
00332
void KDirSelectDialog::slotURLActivated(
const QString& text )
00333 {
00334
if ( text.isEmpty() )
00335
return;
00336
00337
KURL url =
KURL::fromPathOrURL( text );
00338 d->urlCombo->addToHistory( url.
prettyURL() );
00339
00340
if ( localOnly() && !url.
isLocalFile() )
00341
return;
00342
00343
KURL oldURL = m_treeView->
currentURL();
00344
if ( oldURL.
isEmpty() )
00345 oldURL =
KURL::fromPathOrURL( m_startDir );
00346
00347 setCurrentURL( url );
00348 }
00349
00350
KFileTreeBranch * KDirSelectDialog::createBranch(
const KURL& url )
00351 {
00352
QString title = url.
isLocalFile() ? url.
path() : url.prettyURL();
00353
KFileTreeBranch *branch = view()->addBranch( url, title, m_showHiddenFiles->
isChecked() );
00354 branch->
setChildRecurse(
false );
00355 view()->
setDirOnlyMode( branch,
true );
00356
00357
return branch;
00358 }
00359
00360
void KDirSelectDialog::slotComboTextChanged(
const QString& text )
00361 {
00362
if ( d->branch )
00363 {
00364
KURL url =
KURL::fromPathOrURL( text );
00365
KFileTreeViewItem *item = d->branch->findTVIByURL( url );
00366
if ( item )
00367 {
00368 view()->setCurrentItem( item );
00369 view()->setSelected( item,
true );
00370 view()->ensureItemVisible( item );
00371
return;
00372 }
00373 }
00374
00375
QListViewItem *item = view()->currentItem();
00376
if ( item )
00377 {
00378 item->setSelected(
false );
00379
00380 item->repaint();
00381 }
00382 }
00383
00384
void KDirSelectDialog::slotContextMenu(
KListView *,
QListViewItem *,
const QPoint& pos )
00385 {
00386 m_contextMenu->popup( pos );
00387 }
00388
00389
void KDirSelectDialog::slotMkdir()
00390 {
00391
bool ok;
00392
QString where =
url().
prettyURL( +1, KURL::StripFileProtocol );
00393
QString directory =
KIO::encodeFileName( KInputDialog::getText( i18n(
"New Folder" ), i18n(
"Create new folder in:\n%1" ).arg( where ), i18n(
"New Folder"), &ok,
this));
00394
if (!ok)
00395
return;
00396
00397
bool selectDirectory =
true;
00398
bool writeOk =
false;
00399
bool exists =
false;
00400
KURL folderurl(
url() );
00401
00402
QStringList dirs = QStringList::split( QDir::separator(), directory );
00403 QStringList::ConstIterator it = dirs.begin();
00404
00405
for ( ; it != dirs.end(); ++it )
00406 {
00407 folderurl.
addPath( *it );
00408 exists =
KIO::NetAccess::exists( folderurl,
false, 0 );
00409 writeOk = !exists &&
KIO::NetAccess::mkdir( folderurl, topLevelWidget() );
00410 }
00411
00412
if ( exists )
00413 {
00414
QString which = folderurl.
isLocalFile() ? folderurl.
path() : folderurl.prettyURL();
00415
KMessageBox::sorry(
this, i18n(
"A file or folder named %1 already exists.").arg(which));
00416 selectDirectory =
false;
00417 }
00418
else if ( !writeOk ) {
00419
KMessageBox::sorry(
this, i18n(
"You do not have permission to create that folder." ));
00420 }
00421
else if ( selectDirectory ) {
00422 setCurrentURL( folderurl );
00423 }
00424 }
00425
00426
void KDirSelectDialog::slotShowHiddenFilesToggled()
00427 {
00428
KURL currentURL =
url();
00429
00430 d->comboLocked =
true;
00431 view()->removeBranch( d->branch );
00432 d->comboLocked =
false;
00433
00434
KURL root = rootUrl(d->startURL);
00435 d->branch = createBranch( root );
00436
00437 setCurrentURL( currentURL );
00438 }
00439
00440
00441 KURL KDirSelectDialog::selectDirectory(
const QString& startDir,
00442
bool localOnly,
00443
QWidget *parent,
00444
const QString& caption)
00445 {
00446
KDirSelectDialog myDialog( startDir, localOnly, parent,
00447
"kdirselect dialog",
true );
00448
00449
if ( !caption.isNull() )
00450 myDialog.
setCaption( caption );
00451
00452
if ( myDialog.exec() == QDialog::Accepted )
00453
return myDialog.
url();
00454
else
00455
return KURL();
00456 }
00457
00458
void KDirSelectDialog::virtual_hook(
int id,
void* data )
00459 { KDialogBase::virtual_hook(
id, data ); }
00460
00461
#include "kdirselectdialog.moc"