00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kdirselectdialog.h"
00021
00022 #include <QtCore/QDir>
00023 #include <QtCore/QStringList>
00024 #include <QtGui/QLayout>
00025 #include <QtGui/QMenu>
00026
00027 #include <kactioncollection.h>
00028 #include <kapplication.h>
00029 #include <kauthorized.h>
00030 #include <kconfig.h>
00031 #include <kconfiggroup.h>
00032 #include <khistorycombobox.h>
00033 #include <kfiledialog.h>
00034 #include <kfiletreeview.h>
00035 #include <kfileitemdelegate.h>
00036 #include <kglobalsettings.h>
00037 #include <kicon.h>
00038 #include <kinputdialog.h>
00039 #include <kio/netaccess.h>
00040 #include <kio/renamedialog.h>
00041 #include <klocale.h>
00042 #include <kmessagebox.h>
00043 #include <krecentdirs.h>
00044 #include <ktoggleaction.h>
00045 #include <kurlcompletion.h>
00046 #include <kurlpixmapprovider.h>
00047
00048 #include <kdebug.h>
00049
00050 #include "kfileplacesview.h"
00051 #include "kfileplacesmodel.h"
00052
00053
00054 class KDirSelectDialog::Private
00055 {
00056 public:
00057 Private( bool localOnly, KDirSelectDialog *parent )
00058 : m_parent( parent ),
00059 m_localOnly( localOnly ),
00060 m_comboLocked( false ),
00061 m_urlCombo(0)
00062 {
00063 }
00064
00065 void readConfig(const KSharedConfigPtr &config, const QString& group);
00066 void saveConfig(KSharedConfigPtr config, const QString& group);
00067 void slotMkdir();
00068
00069 void _k_slotCurrentChanged();
00070 void _k_slotExpand(const QModelIndex&);
00071 void _k_slotUrlActivated(const QString&);
00072 void _k_slotComboTextChanged(const QString&);
00073 void _k_slotContextMenu(const QPoint&);
00074 void _k_slotUser1();
00075
00076 KDirSelectDialog *m_parent;
00077 bool m_localOnly : 1;
00078 bool m_comboLocked : 1;
00079 KUrl m_rootUrl;
00080 KUrl m_startDir;
00081 KFileTreeView *m_treeView;
00082 QMenu *m_contextMenu;
00083 KActionCollection *m_actions;
00084 KFilePlacesView *m_placesView;
00085 KHistoryComboBox *m_urlCombo;
00086 QString m_recentDirClass;
00087 KUrl m_startURL;
00088
00089 };
00090
00091 void KDirSelectDialog::Private::readConfig(const KSharedConfig::Ptr &config, const QString& group)
00092 {
00093 m_urlCombo->clear();
00094
00095 KConfigGroup conf( config, group );
00096 m_urlCombo->setHistoryItems( conf.readPathEntry( "History Items", QStringList() ));
00097
00098 m_parent->resize( conf.readEntry( "DirSelectDialog Size", QSize( 400, 450 ) ) );
00099 }
00100
00101 void KDirSelectDialog::Private::saveConfig(KSharedConfig::Ptr config, const QString& group)
00102 {
00103 KConfigGroup conf( config, group );
00104 KConfigGroup::WriteConfigFlags flags(KConfigGroup::Persistent|KConfigGroup::Global);
00105 conf.writePathEntry( "History Items", m_urlCombo->historyItems(), flags );
00106 conf.writeEntry( "DirSelectDialog Size", m_parent->size(), flags );
00107
00108 config->sync();
00109 }
00110
00111 void KDirSelectDialog::Private::slotMkdir()
00112 {
00113 bool ok;
00114 QString where = m_parent->url().pathOrUrl();
00115 QString name = i18n( "New Folder" );
00116 if ( m_parent->url().isLocalFile() && QFileInfo( m_parent->url().path(KUrl::AddTrailingSlash) + name ).exists() )
00117 name = KIO::RenameDialog::suggestName( m_parent->url(), name );
00118
00119 QString directory = KIO::encodeFileName( KInputDialog::getText( i18nc("@title:window", "New Folder" ),
00120 i18nc("@label:textbox", "Create new folder in:\n%1" , where ),
00121 name, &ok, m_parent));
00122 if (!ok)
00123 return;
00124
00125 bool selectDirectory = true;
00126 bool writeOk = false;
00127 bool exists = false;
00128 KUrl folderurl( m_parent->url() );
00129
00130 const QStringList dirs = directory.split( QDir::separator(), QString::SkipEmptyParts );
00131 QStringList::ConstIterator it = dirs.begin();
00132
00133 for ( ; it != dirs.end(); ++it )
00134 {
00135 folderurl.addPath( *it );
00136 exists = KIO::NetAccess::exists( folderurl, KIO::NetAccess::DestinationSide, 0 );
00137 writeOk = !exists && KIO::NetAccess::mkdir( folderurl, m_parent->topLevelWidget() );
00138 }
00139
00140 if ( exists )
00141 {
00142 QString which = folderurl.isLocalFile() ? folderurl.path() : folderurl.prettyUrl();
00143 KMessageBox::sorry(m_parent, i18n("A file or folder named %1 already exists.", which));
00144 selectDirectory = false;
00145 }
00146 else if ( !writeOk ) {
00147 KMessageBox::sorry(m_parent, i18n("You do not have permission to create that folder." ));
00148 }
00149 else if ( selectDirectory ) {
00150 m_parent->setCurrentUrl( folderurl );
00151 }
00152 }
00153
00154 void KDirSelectDialog::Private::_k_slotCurrentChanged()
00155 {
00156 if ( m_comboLocked )
00157 return;
00158
00159 const KUrl u = m_treeView->currentUrl();
00160
00161 if ( u.isValid() )
00162 {
00163 if ( u.isLocalFile() )
00164 m_urlCombo->setEditText( u.path() );
00165
00166 else
00167 m_urlCombo->setEditText( u.prettyUrl() );
00168 }
00169 else
00170 m_urlCombo->setEditText( QString() );
00171 }
00172
00173 void KDirSelectDialog::Private::_k_slotUrlActivated( const QString& text )
00174 {
00175 if ( text.isEmpty() )
00176 return;
00177
00178 KUrl url( text );
00179 m_urlCombo->addToHistory( url.prettyUrl() );
00180
00181 if ( m_parent->localOnly() && !url.isLocalFile() )
00182 return;
00183
00184 KUrl oldUrl = m_treeView->currentUrl();
00185 if ( oldUrl.isEmpty() )
00186 oldUrl = m_startDir;
00187
00188 m_parent->setCurrentUrl( oldUrl );
00189 }
00190
00191 void KDirSelectDialog::Private::_k_slotComboTextChanged( const QString& text )
00192 {
00193 m_treeView->setCurrentUrl( KUrl( text ) );
00194 }
00195
00196 void KDirSelectDialog::Private::_k_slotContextMenu( const QPoint& pos )
00197 {
00198 m_contextMenu->popup( pos );
00199 }
00200
00201 void KDirSelectDialog::Private::_k_slotExpand(const QModelIndex &index)
00202 {
00203 m_treeView->setExpanded(index, !m_treeView->isExpanded(index));
00204 }
00205
00206 void KDirSelectDialog::Private::_k_slotUser1()
00207 {
00208 slotMkdir();
00209 }
00210
00211
00212
00213
00214 KDirSelectDialog::KDirSelectDialog(const KUrl &startDir, bool localOnly,
00215 QWidget *parent)
00216 #ifdef Q_WS_WIN
00217 : KDialog( parent , Qt::WindowMinMaxButtonsHint),
00218 #else
00219 : KDialog( parent ),
00220 #endif
00221 d( new Private( localOnly, this ) )
00222 {
00223 setCaption( i18nc("@title:window","Select Folder") );
00224 setButtons( Ok | Cancel | User1 );
00225 setButtonGuiItem( User1, KGuiItem( i18nc("@action:button","New Folder..."), "folder-new" ) );
00226 showButtonSeparator(false);
00227 setDefaultButton(Ok);
00228
00229 QFrame *page = new QFrame(this);
00230 setMainWidget(page);
00231 QHBoxLayout *hlay = new QHBoxLayout( page);
00232 hlay->setMargin(0);
00233 hlay->setSpacing(spacingHint());
00234 QVBoxLayout *mainLayout = new QVBoxLayout();
00235 d->m_actions=new KActionCollection(this);
00236 d->m_placesView = new KFilePlacesView( page );
00237 d->m_placesView->setModel(new KFilePlacesModel(d->m_placesView));
00238 d->m_placesView->setObjectName( QLatin1String( "speedbar" ) );
00239 d->m_placesView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
00240 d->m_placesView->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
00241 connect( d->m_placesView, SIGNAL( urlChanged( const KUrl& )),
00242 SLOT( setCurrentUrl( const KUrl& )) );
00243 hlay->addWidget( d->m_placesView );
00244 hlay->addLayout( mainLayout );
00245
00246 d->m_treeView = new KFileTreeView(page);
00247 d->m_treeView->setDirOnlyMode(true);
00248
00249 for (int i = 1; i < d->m_treeView->model()->columnCount(); ++i)
00250 d->m_treeView->hideColumn(i);
00251
00252 d->m_urlCombo = new KHistoryComboBox( page);
00253 d->m_urlCombo->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
00254 d->m_urlCombo->setTrapReturnKey( true );
00255 d->m_urlCombo->setPixmapProvider( new KUrlPixmapProvider() );
00256 KUrlCompletion *comp = new KUrlCompletion();
00257 comp->setMode( KUrlCompletion::DirCompletion );
00258 d->m_urlCombo->setCompletionObject( comp, true );
00259 d->m_urlCombo->setAutoDeleteCompletionObject( true );
00260 d->m_urlCombo->setDuplicatesEnabled( false );
00261
00262 d->m_contextMenu = new QMenu( this );
00263 KAction* newFolder = new KAction( i18nc("@action:inmenu","New Folder..."), this);
00264 d->m_actions->addAction(newFolder->objectName(), newFolder);
00265 newFolder->setIcon( KIcon( "folder-new" ) );
00266 connect( newFolder, SIGNAL( triggered( bool ) ), this, SLOT( _k_slotUser1() ) );
00267 d->m_contextMenu->addAction( newFolder );
00268 d->m_contextMenu->addSeparator();
00269
00270 KToggleAction *action = new KToggleAction( i18nc("@option:check", "Show Hidden Folders" ), this );
00271 d->m_actions->addAction( action->objectName(), action );
00272 connect( action, SIGNAL( triggered( bool ) ), d->m_treeView, SLOT( setShowHiddenFiles( bool ) ) );
00273 d->m_contextMenu->addAction( action );
00274
00275 d->m_startURL = KFileDialog::getStartUrl( startDir, d->m_recentDirClass );
00276 if ( localOnly && !d->m_startURL.isLocalFile() )
00277 {
00278 d->m_startURL = KUrl();
00279 QString docPath = KGlobalSettings::documentPath();
00280 if (QDir(docPath).exists())
00281 d->m_startURL.setPath( docPath );
00282 else
00283 d->m_startURL.setPath( QDir::homePath() );
00284 }
00285
00286 d->m_startDir = d->m_startURL;
00287 d->m_rootUrl = d->m_treeView->rootUrl();
00288
00289 d->readConfig( KGlobal::config(), "DirSelect Dialog" );
00290
00291 mainLayout->addWidget( d->m_treeView, 1 );
00292 mainLayout->addWidget( d->m_urlCombo, 0 );
00293
00294 connect( d->m_treeView, SIGNAL( currentChanged(const KUrl&)),
00295 SLOT( _k_slotCurrentChanged() ));
00296 connect( d->m_treeView, SIGNAL( activated(const QModelIndex&)),
00297 SLOT( _k_slotExpand(const QModelIndex&) ));
00298 connect( d->m_treeView, SIGNAL( customContextMenuRequested( const QPoint & )),
00299 SLOT( _k_slotContextMenu( const QPoint & )));
00300
00301 connect( d->m_urlCombo, SIGNAL( editTextChanged( const QString& ) ),
00302 SLOT( _k_slotComboTextChanged( const QString& ) ));
00303 connect( d->m_urlCombo, SIGNAL( activated( const QString& )),
00304 SLOT( _k_slotUrlActivated( const QString& )));
00305 connect( d->m_urlCombo, SIGNAL( returnPressed( const QString& )),
00306 SLOT( _k_slotUrlActivated( const QString& )));
00307
00308 connect(this, SIGNAL(user1Clicked()), this, SLOT(_k_slotUser1()));
00309
00310 setCurrentUrl(d->m_startURL);
00311 }
00312
00313
00314 KDirSelectDialog::~KDirSelectDialog()
00315 {
00316 delete d;
00317 }
00318
00319 KUrl KDirSelectDialog::url() const
00320 {
00321 KUrl comboUrl(d->m_urlCombo->currentText());
00322 if (comboUrl.isValid()) {
00323 return comboUrl;
00324 }
00325 kDebug() << comboUrl.path() << " is not valid";
00326 return d->m_treeView->currentUrl();
00327 }
00328
00329 QAbstractItemView* KDirSelectDialog::view() const
00330 {
00331 return d->m_treeView;
00332 }
00333
00334 bool KDirSelectDialog::localOnly() const
00335 {
00336 return d->m_localOnly;
00337 }
00338
00339 KUrl KDirSelectDialog::startDir() const
00340 {
00341 return d->m_startDir;
00342 }
00343
00344 void KDirSelectDialog::setCurrentUrl( const KUrl& url )
00345 {
00346 if ( !url.isValid() )
00347 return;
00348
00349 if (url.protocol() != d->m_rootUrl.protocol()) {
00350 KUrl u( url );
00351 u.cd("/");
00352 d->m_treeView->setRootUrl( u );
00353 d->m_rootUrl = u;
00354 }
00355
00356 d->m_treeView->setCurrentUrl( url );
00357 }
00358
00359 void KDirSelectDialog::accept()
00360 {
00361 const KUrl selectedUrl = d->m_treeView->selectedUrl();
00362 if (!selectedUrl.isValid())
00363 return;
00364
00365 if ( !d->m_recentDirClass.isEmpty() )
00366 {
00367 KRecentDirs::add(d->m_recentDirClass, selectedUrl.url());
00368 }
00369
00370 d->m_urlCombo->addToHistory( selectedUrl.prettyUrl() );
00371 KFileDialog::setStartDir( url() );
00372
00373 KDialog::accept();
00374 }
00375
00376 void KDirSelectDialog::hideEvent( QHideEvent *event )
00377 {
00378 d->saveConfig( KGlobal::config(), "DirSelect Dialog" );
00379
00380 KDialog::hideEvent(event);
00381 }
00382
00383
00384 KUrl KDirSelectDialog::selectDirectory( const KUrl& startDir,
00385 bool localOnly,
00386 QWidget *parent,
00387 const QString& caption)
00388 {
00389 KDirSelectDialog myDialog( startDir, localOnly, parent);
00390
00391 if ( !caption.isNull() )
00392 myDialog.setCaption( caption );
00393
00394 if ( myDialog.exec() == QDialog::Accepted )
00395 return KIO::NetAccess::mostLocalUrl(myDialog.url(),parent);
00396 else
00397 return KUrl();
00398 }
00399
00400 #include "kdirselectdialog.moc"