• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KFile

kdirselectdialog.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2001,2002 Carsten Pfeiffer <pfeiffer@kde.org>
00003     Copyright (C) 2001 Michael Jarrett <michaelj@corel.com>
00004     Copyright (C) 2009 Shaun Reich <shaun.reich@kdemail.net>
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License version 2 as published by the Free Software Foundation.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "kdirselectdialog.h"
00022 
00023 #include <QtCore/QDir>
00024 #include <QtCore/QStringList>
00025 #include <QtGui/QLayout>
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/job.h>
00040 #include <kio/deletejob.h>
00041 #include <kio/copyjob.h>
00042 #include <kio/netaccess.h>
00043 #include <kio/renamedialog.h>
00044 #include <jobuidelegate.h>
00045 #include <klocale.h>
00046 #include <kmessagebox.h>
00047 #include <krecentdirs.h>
00048 #include <ktoggleaction.h>
00049 #include <kurlcompletion.h>
00050 #include <kurlpixmapprovider.h>
00051 #include <kdebug.h>
00052 #include <kpropertiesdialog.h>
00053 #include <kpushbutton.h>
00054 #include <kmenu.h>
00055 
00056 #include "kfileplacesview.h"
00057 #include "kfileplacesmodel.h"
00058 // ### add mutator for treeview!
00059 
00060 
00061 
00062 class KDirSelectDialog::Private
00063 {
00064 public:
00065     Private( bool localOnly, KDirSelectDialog *parent )
00066         : m_parent( parent ),
00067           m_localOnly( localOnly ),
00068           m_comboLocked( false ),
00069           m_urlCombo(0)
00070     {
00071     }
00072 
00073     void readConfig(const KSharedConfigPtr &config, const QString& group);
00074     void saveConfig(KSharedConfigPtr config, const QString& group);
00075     void slotMkdir();
00076 
00077     void slotCurrentChanged();
00078     void slotExpand(const QModelIndex&);
00079     void slotUrlActivated(const QString&);
00080     void slotComboTextChanged(const QString&);
00081     void slotContextMenuRequested(const QPoint&);
00082     void slotNewFolder();
00083     void slotMoveToTrash();
00084     void slotDelete();
00085     void slotProperties();
00086 
00087     KDirSelectDialog *m_parent;
00088     bool m_localOnly : 1;
00089     bool m_comboLocked : 1;
00090     KUrl m_rootUrl;
00091     KUrl m_startDir;
00092     KFileTreeView *m_treeView;
00093     KMenu *m_contextMenu;
00094     KActionCollection *m_actions;
00095     KFilePlacesView *m_placesView;
00096     KHistoryComboBox *m_urlCombo;
00097     QString m_recentDirClass;
00098     KUrl m_startURL;
00099     KAction* moveToTrash;
00100     KAction* deleteAction;
00101     KAction* showHiddenFoldersAction;
00102 };
00103 
00104 void KDirSelectDialog::Private::readConfig(const KSharedConfig::Ptr &config, const QString& group)
00105 {
00106     m_urlCombo->clear();
00107 
00108     KConfigGroup conf( config, group );
00109     m_urlCombo->setHistoryItems( conf.readPathEntry( "History Items", QStringList() ));
00110 
00111     m_parent->resize( conf.readEntry( "DirSelectDialog Size", QSize( 400, 450 ) ) );
00112 }
00113 
00114 void KDirSelectDialog::Private::saveConfig(KSharedConfig::Ptr config, const QString& group)
00115 {
00116     KConfigGroup conf( config, group );
00117     KConfigGroup::WriteConfigFlags flags(KConfigGroup::Persistent|KConfigGroup::Global);
00118     conf.writePathEntry( "History Items", m_urlCombo->historyItems(), flags );
00119     conf.writeEntry( "DirSelectDialog Size", m_parent->size(), flags );
00120 
00121     config->sync();
00122 }
00123 
00124 void KDirSelectDialog::Private::slotMkdir()
00125 {
00126     bool ok;
00127     QString where = m_parent->url().pathOrUrl();
00128     QString name = i18nc("folder name", "New Folder" );
00129     if ( m_parent->url().isLocalFile() && QFileInfo( m_parent->url().path(KUrl::AddTrailingSlash) + name ).exists() )
00130         name = KIO::RenameDialog::suggestName( m_parent->url(), name );
00131 
00132     QString directory = KIO::encodeFileName( KInputDialog::getText( i18nc("@title:window", "New Folder" ),
00133                                          i18nc("@label:textbox", "Create new folder in:\n%1" ,  where ),
00134                                          name, &ok, m_parent));
00135     if (!ok)
00136       return;
00137 
00138     bool selectDirectory = true;
00139     bool writeOk = false;
00140     bool exists = false;
00141     KUrl folderurl( m_parent->url() );
00142 
00143     const QStringList dirs = directory.split( '/', QString::SkipEmptyParts );
00144     QStringList::ConstIterator it = dirs.begin();
00145 
00146     for ( ; it != dirs.end(); ++it )
00147     {
00148         folderurl.addPath( *it );
00149         exists = KIO::NetAccess::exists( folderurl, KIO::NetAccess::DestinationSide, 0 );
00150         writeOk = !exists && KIO::NetAccess::mkdir( folderurl, m_parent->topLevelWidget() );
00151     }
00152 
00153     if ( exists ) // url was already existent
00154     {
00155         QString which = folderurl.isLocalFile() ? folderurl.path() : folderurl.prettyUrl();
00156         KMessageBox::sorry(m_parent, i18n("A file or folder named %1 already exists.", which));
00157         selectDirectory = false;
00158     }
00159     else if ( !writeOk ) {
00160         KMessageBox::sorry(m_parent, i18n("You do not have permission to create that folder." ));
00161     }
00162     else if ( selectDirectory ) {
00163         m_parent->setCurrentUrl( folderurl );
00164     }
00165 }
00166 
00167 void KDirSelectDialog::Private::slotCurrentChanged()
00168 {
00169     if ( m_comboLocked )
00170         return;
00171 
00172     const KUrl u = m_treeView->currentUrl();
00173 
00174     if ( u.isValid() )
00175     {
00176         if ( u.isLocalFile() )
00177             m_urlCombo->setEditText( u.toLocalFile() );
00178 
00179         else // remote url
00180             m_urlCombo->setEditText( u.prettyUrl() );
00181     }
00182     else
00183         m_urlCombo->setEditText( QString() );
00184 }
00185 
00186 void KDirSelectDialog::Private::slotUrlActivated( const QString& text )
00187 {
00188     if ( text.isEmpty() )
00189         return;
00190 
00191     KUrl url( text );
00192     m_urlCombo->addToHistory( url.prettyUrl() );
00193 
00194     if ( m_parent->localOnly() && !url.isLocalFile() )
00195         return; //FIXME: messagebox for the user
00196 
00197     KUrl oldUrl = m_treeView->currentUrl();
00198     if ( oldUrl.isEmpty() )
00199         oldUrl = m_startDir;
00200 
00201     m_parent->setCurrentUrl( oldUrl );
00202 }
00203 
00204 void KDirSelectDialog::Private::slotComboTextChanged( const QString& text )
00205 {
00206     m_treeView->blockSignals(true);
00207     KUrl url( text );
00208 #ifdef Q_OS_WIN
00209     if( url.isLocalFile() && !m_treeView->rootUrl().isParentOf( url ) )
00210     {
00211         KUrl tmp = url.upUrl();
00212         while(tmp != KUrl("file:///")) {
00213             url = tmp; 
00214             tmp = url.upUrl();
00215         }
00216         m_treeView->setRootUrl( url );
00217     }
00218 #endif
00219     m_treeView->setCurrentUrl( url );
00220     m_treeView->blockSignals( false );
00221 }
00222 
00223 void KDirSelectDialog::Private::slotContextMenuRequested( const QPoint& pos )
00224 {
00225     m_contextMenu->popup( m_treeView->viewport()->mapToGlobal(pos) );
00226 }
00227 
00228 void KDirSelectDialog::Private::slotExpand(const QModelIndex &index)
00229 {
00230     m_treeView->setExpanded(index, !m_treeView->isExpanded(index));
00231 }
00232 
00233 void KDirSelectDialog::Private::slotNewFolder()
00234 {
00235     slotMkdir();
00236 }
00237 
00238 void KDirSelectDialog::Private::slotMoveToTrash()
00239 {
00240     const KUrl url = m_treeView->selectedUrl();
00241     KIO::JobUiDelegate job;
00242     if (job.askDeleteConfirmation(KUrl::List() << url, KIO::JobUiDelegate::Trash, KIO::JobUiDelegate::DefaultConfirmation)) {
00243         KIO::CopyJob* copyJob = KIO::trash(url);
00244         copyJob->ui()->setWindow(this->m_parent);
00245         copyJob->ui()->setAutoErrorHandlingEnabled(true);
00246     }
00247 }
00248 
00249 void KDirSelectDialog::Private::slotDelete()
00250 {
00251     const KUrl url = m_treeView->selectedUrl();
00252     KIO::JobUiDelegate job;
00253     if (job.askDeleteConfirmation(KUrl::List() << url, KIO::JobUiDelegate::Delete, KIO::JobUiDelegate::DefaultConfirmation)) {
00254         KIO::DeleteJob* deleteJob = KIO::del(url);
00255         deleteJob->ui()->setWindow(this->m_parent);
00256         deleteJob->ui()->setAutoErrorHandlingEnabled(true);
00257     }
00258 }
00259 
00260 void KDirSelectDialog::Private::slotProperties()
00261 {
00262     KPropertiesDialog* dialog = 0;
00263     dialog = new KPropertiesDialog(m_treeView->selectedUrl(), this->m_parent);
00264     dialog->setAttribute(Qt::WA_DeleteOnClose);
00265     dialog->show();
00266 }
00267 
00268 
00269 KDirSelectDialog::KDirSelectDialog(const KUrl &startDir, bool localOnly,
00270                                    QWidget *parent)
00271 #ifdef Q_WS_WIN
00272     : KDialog( parent , Qt::WindowMinMaxButtonsHint),
00273 #else
00274     : KDialog( parent ),
00275 #endif
00276       d( new Private( localOnly, this ) )
00277 {
00278     setCaption( i18nc("@title:window","Select Folder") );
00279     setButtons( Ok | Cancel | User1 );
00280     setButtonGuiItem( User1, KGuiItem( i18nc("@action:button","New Folder..."), "folder-new" ) );
00281     showButtonSeparator(false);
00282     setDefaultButton(Ok);
00283     button(Ok)->setFocus();
00284 
00285     QFrame *page = new QFrame(this);
00286     setMainWidget(page);
00287     QHBoxLayout *hlay = new QHBoxLayout( page);
00288     hlay->setMargin(0);
00289     QVBoxLayout *mainLayout = new QVBoxLayout();
00290     d->m_actions=new KActionCollection(this);
00291     d->m_placesView = new KFilePlacesView( page );
00292     d->m_placesView->setModel(new KFilePlacesModel(d->m_placesView));
00293     d->m_placesView->setObjectName( QLatin1String( "speedbar" ) );
00294     d->m_placesView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
00295     d->m_placesView->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
00296     connect( d->m_placesView, SIGNAL( urlChanged( const KUrl& )),
00297              SLOT( setCurrentUrl( const KUrl& )) );
00298     hlay->addWidget( d->m_placesView );
00299     hlay->addLayout( mainLayout );
00300 
00301     d->m_treeView = new KFileTreeView(page);
00302     d->m_treeView->setDirOnlyMode(true);
00303     d->m_treeView->setContextMenuPolicy(Qt::CustomContextMenu);
00304 
00305     for (int i = 1; i < d->m_treeView->model()->columnCount(); ++i)
00306         d->m_treeView->hideColumn(i);
00307 
00308     d->m_urlCombo = new KHistoryComboBox( page);
00309     d->m_urlCombo->setLayoutDirection( Qt::LeftToRight );
00310     d->m_urlCombo->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
00311     d->m_urlCombo->setTrapReturnKey( true );
00312     d->m_urlCombo->setPixmapProvider( new KUrlPixmapProvider() );
00313     KUrlCompletion *comp = new KUrlCompletion();
00314     comp->setMode( KUrlCompletion::DirCompletion );
00315     d->m_urlCombo->setCompletionObject( comp, true );
00316     d->m_urlCombo->setAutoDeleteCompletionObject( true );
00317     d->m_urlCombo->setDuplicatesEnabled( false );
00318 
00319     d->m_contextMenu = new KMenu( this );
00320 
00321     KAction* newFolder = new KAction( i18nc("@action:inmenu","New Folder..."), this);
00322     d->m_actions->addAction( newFolder->objectName(), newFolder );
00323     newFolder->setIcon( KIcon( "folder-new" ) );
00324     newFolder->setShortcut( Qt::Key_F10);
00325     connect( newFolder, SIGNAL( triggered( bool ) ), this, SLOT( slotNewFolder() ) );
00326     d->m_contextMenu->addAction( newFolder );
00327 
00328     d->moveToTrash = new KAction( i18nc( "@action:inmenu","Move to trash" ), this );
00329     d->m_actions->addAction( d->moveToTrash->objectName(), d->moveToTrash );
00330     d->moveToTrash->setIcon( KIcon( "user-trash" ) );
00331     d->moveToTrash->setShortcut(KShortcut(Qt::Key_Delete));
00332     connect( d->moveToTrash, SIGNAL( triggered( bool ) ), this, SLOT( slotMoveToTrash() ) );
00333     d->m_contextMenu->addAction( d->moveToTrash );
00334 
00335     d->deleteAction = new KAction( i18nc("@action:inmenu","Delete"), this );
00336     d->m_actions->addAction( d->deleteAction->objectName(), d->deleteAction );
00337     d->deleteAction->setIcon( KIcon( "edit-delete" ) );
00338     d->deleteAction->setShortcut( KShortcut( Qt::SHIFT + Qt::Key_Delete ) );
00339     connect( d->deleteAction, SIGNAL( triggered( bool ) ), this, SLOT( slotDelete() ) );
00340     d->m_contextMenu->addAction( d->deleteAction );
00341 
00342     d->m_contextMenu->addSeparator();
00343 
00344     d->showHiddenFoldersAction = new KToggleAction( i18nc("@option:check", "Show Hidden Folders"), this );
00345     d->m_actions->addAction( d->showHiddenFoldersAction->objectName(), d->showHiddenFoldersAction );
00346     d->showHiddenFoldersAction->setShortcut( Qt::Key_F8 );
00347     connect( d->showHiddenFoldersAction, SIGNAL( triggered( bool ) ), d->m_treeView, SLOT( setShowHiddenFiles( bool ) ) );
00348     d->m_contextMenu->addAction( d->showHiddenFoldersAction );
00349     d->m_contextMenu->addSeparator();
00350 
00351     KAction* propertiesAction = new KAction( i18nc("@action:inmenu","Properties"), this);
00352     d->m_actions->addAction(propertiesAction->objectName(), propertiesAction);
00353     propertiesAction->setIcon(KIcon("document-properties"));
00354     propertiesAction->setShortcut(KShortcut(Qt::ALT + Qt::Key_Return));
00355     connect( propertiesAction, SIGNAL( triggered( bool ) ), this, SLOT( slotProperties() ) );
00356     d->m_contextMenu->addAction( propertiesAction );
00357 
00358     d->m_startURL = KFileDialog::getStartUrl( startDir, d->m_recentDirClass );
00359     if ( localOnly && !d->m_startURL.isLocalFile() )
00360     {
00361         d->m_startURL = KUrl();
00362         QString docPath = KGlobalSettings::documentPath();
00363         if (QDir(docPath).exists())
00364             d->m_startURL.setPath( docPath );
00365         else
00366             d->m_startURL.setPath( QDir::homePath() );
00367     }
00368 
00369     d->m_startDir = d->m_startURL;
00370     d->m_rootUrl = d->m_treeView->rootUrl();
00371 
00372     d->readConfig( KGlobal::config(), "DirSelect Dialog" );
00373 
00374     mainLayout->addWidget( d->m_treeView, 1 );
00375     mainLayout->addWidget( d->m_urlCombo, 0 );
00376 
00377     connect( d->m_treeView, SIGNAL( currentChanged(const KUrl&)),
00378              SLOT( slotCurrentChanged() ));
00379     connect( d->m_treeView, SIGNAL( activated(const QModelIndex&)),
00380              SLOT( slotExpand(const QModelIndex&) ));
00381     connect( d->m_treeView, SIGNAL( customContextMenuRequested( const QPoint & )),
00382              SLOT( slotContextMenuRequested( const QPoint & )));
00383 
00384     connect( d->m_urlCombo, SIGNAL( editTextChanged( const QString& ) ),
00385              SLOT( slotComboTextChanged( const QString& ) ));
00386     connect( d->m_urlCombo, SIGNAL( activated( const QString& )),
00387              SLOT( slotUrlActivated( const QString& )));
00388     connect( d->m_urlCombo, SIGNAL( returnPressed( const QString& )),
00389              SLOT( slotUrlActivated( const QString& )));
00390 
00391     connect(this, SIGNAL(user1Clicked()), this, SLOT(slotNewFolder()));
00392 
00393     setCurrentUrl(d->m_startURL);
00394 }
00395 
00396 
00397 KDirSelectDialog::~KDirSelectDialog()
00398 {
00399     delete d;
00400 }
00401 
00402 KUrl KDirSelectDialog::url() const
00403 {
00404     KUrl comboUrl(d->m_urlCombo->currentText());
00405 
00406     if ( comboUrl.isValid() ) {
00407        KIO::StatJob *statJob = KIO::stat(comboUrl, KIO::HideProgressInfo);
00408        const bool ok = KIO::NetAccess::synchronousRun(statJob, 0);
00409        if (ok && statJob->statResult().isDir()) {
00410            return comboUrl;
00411        }
00412     }
00413 
00414     kDebug() << comboUrl.path() << " is not an accessible directory";
00415     return d->m_treeView->currentUrl();
00416 }
00417 
00418 QAbstractItemView* KDirSelectDialog::view() const
00419 {
00420     return d->m_treeView;
00421 }
00422 
00423 bool KDirSelectDialog::localOnly() const
00424 {
00425     return d->m_localOnly;
00426 }
00427 
00428 KUrl KDirSelectDialog::startDir() const
00429 {
00430     return d->m_startDir;
00431 }
00432 
00433 void KDirSelectDialog::setCurrentUrl( const KUrl& url )
00434 {
00435     if ( !url.isValid() )
00436         return;
00437 
00438     if (url.protocol() != d->m_rootUrl.protocol()) {
00439         KUrl u( url );
00440         u.cd("/");//NOTE portability?
00441         d->m_treeView->setRootUrl( u );
00442         d->m_rootUrl = u;
00443     }
00444 
00445     //Check if url represents a hidden folder and enable showing them
00446     QString fileName = url.fileName();
00447     //TODO a better hidden file check?
00448     bool isHidden = fileName.length() > 1 && fileName[0] == '.' && 
00449                                                 (fileName.length() > 2 ? fileName[1] != '.' : true);
00450     bool showHiddenFiles = isHidden && !d->m_treeView->showHiddenFiles();
00451     if (showHiddenFiles) {
00452         d->showHiddenFoldersAction->setChecked(true);
00453         d->m_treeView->setShowHiddenFiles(true);
00454     }
00455         
00456     d->m_treeView->setCurrentUrl( url );
00457 }
00458 
00459 void KDirSelectDialog::accept()
00460 {
00461     KUrl selectedUrl = url();
00462     if (!selectedUrl.isValid()) {
00463         return;
00464     }
00465 
00466     if (!d->m_recentDirClass.isEmpty()) {
00467         KRecentDirs::add(d->m_recentDirClass, selectedUrl.url());
00468     }
00469 
00470     d->m_urlCombo->addToHistory( selectedUrl.prettyUrl() );
00471     KFileDialog::setStartDir( url() );
00472 
00473     KDialog::accept();
00474 }
00475 
00476 void KDirSelectDialog::hideEvent( QHideEvent *event )
00477 {
00478     d->saveConfig( KGlobal::config(), "DirSelect Dialog" );
00479 
00480     KDialog::hideEvent(event);
00481 }
00482 
00483 // static
00484 KUrl KDirSelectDialog::selectDirectory( const KUrl& startDir,
00485                                         bool localOnly,
00486                                         QWidget *parent,
00487                                         const QString& caption)
00488 {
00489     KDirSelectDialog myDialog( startDir, localOnly, parent);
00490 
00491     if ( !caption.isNull() )
00492         myDialog.setCaption( caption );
00493 
00494     if ( myDialog.exec() == QDialog::Accepted )
00495         return KIO::NetAccess::mostLocalUrl(myDialog.url(),parent);
00496     else
00497         return KUrl();
00498 }
00499 
00500 #include "kdirselectdialog.moc"

KFile

Skip menu "KFile"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal