KIO
kurlrequester.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 1999,2000,2001 Carsten Pfeiffer <pfeiffer@kde.org> 00003 00004 library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License version 2, as published by the Free Software Foundation. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00016 Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "kurlrequester.h" 00020 00021 #include <kcombobox.h> 00022 #include <kfiledialog.h> 00023 #include <klineedit.h> 00024 #include <klocale.h> 00025 #include <kurlcompletion.h> 00026 #include <kprotocolmanager.h> 00027 #include <khbox.h> 00028 #include <kstandardshortcut.h> 00029 #include <kdebug.h> 00030 00031 #include <QEvent> 00032 #include <QDrag> 00033 #include <QMimeData> 00034 #include <QAction> 00035 #include <QApplication> 00036 00037 class KUrlDragPushButton : public KPushButton 00038 { 00039 public: 00040 KUrlDragPushButton( QWidget *parent) 00041 : KPushButton( parent) 00042 { 00043 setDragEnabled( true ); 00044 } 00045 ~KUrlDragPushButton() {} 00046 00047 void setURL( const KUrl& url ) 00048 { 00049 m_urls.clear(); 00050 m_urls.append( url ); 00051 } 00052 00053 protected: 00054 virtual QDrag *dragObject() 00055 { 00056 if (m_urls.isEmpty()) 00057 return 0; 00058 00059 QDrag *drag = new QDrag(this); 00060 QMimeData *mimeData = new QMimeData; 00061 m_urls.populateMimeData(mimeData); 00062 drag->setMimeData(mimeData); 00063 return drag; 00064 } 00065 00066 private: 00067 KUrl::List m_urls; 00068 00069 }; 00070 00071 00072 class KUrlRequester::KUrlRequesterPrivate 00073 { 00074 public: 00075 KUrlRequesterPrivate(KUrlRequester *parent) 00076 : m_parent(parent), 00077 edit(0), 00078 combo(0), 00079 fileDialogMode(KFile::File | KFile::ExistingOnly | KFile::LocalOnly) 00080 { 00081 } 00082 00083 ~KUrlRequesterPrivate() 00084 { 00085 delete myCompletion; 00086 delete myFileDialog; 00087 } 00088 00089 void init(); 00090 00091 void setText( const QString& text ) { 00092 if ( combo ) 00093 { 00094 if (combo->isEditable()) 00095 { 00096 combo->setEditText( text ); 00097 } 00098 else 00099 { 00100 int i = combo->findText( text ); 00101 if ( i == -1 ) 00102 { 00103 combo->addItem( text ); 00104 combo->setCurrentIndex( combo->count()-1 ); 00105 } 00106 else 00107 { 00108 combo->setCurrentIndex( i ); 00109 } 00110 } 00111 } 00112 else 00113 { 00114 edit->setText( text ); 00115 } 00116 } 00117 00118 void connectSignals( QObject *receiver ) 00119 { 00120 QObject *sender; 00121 if ( combo ) 00122 sender = combo; 00123 else 00124 sender = edit; 00125 00126 if (combo ) 00127 connect( sender, SIGNAL( editTextChanged( const QString& )), 00128 receiver, SIGNAL( textChanged( const QString& ))); 00129 else 00130 connect( sender, SIGNAL( textChanged( const QString& )), 00131 receiver, SIGNAL( textChanged( const QString& ))); 00132 00133 connect( sender, SIGNAL( returnPressed() ), 00134 receiver, SIGNAL( returnPressed() )); 00135 connect( sender, SIGNAL( returnPressed( const QString& ) ), 00136 receiver, SIGNAL( returnPressed( const QString& ) )); 00137 } 00138 00139 void setCompletionObject( KCompletion *comp ) 00140 { 00141 if ( combo ) 00142 combo->setCompletionObject( comp ); 00143 else 00144 edit->setCompletionObject( comp ); 00145 } 00146 00147 QString text() const { 00148 return combo ? combo->currentText() : edit->text(); 00149 } 00150 00154 KUrl url() const { 00155 const QString txt = text(); 00156 KUrlCompletion *comp; 00157 if ( combo ) 00158 comp = qobject_cast<KUrlCompletion*>(combo->completionObject()); 00159 else 00160 comp = qobject_cast<KUrlCompletion*>(edit->completionObject()); 00161 00162 if ( comp ) 00163 return KUrl( comp->replacedPath( txt ) ); 00164 else 00165 return KUrl( txt ); 00166 } 00167 00168 // slots 00169 void _k_slotUpdateUrl(); 00170 void _k_slotOpenDialog(); 00171 void _k_slotFileDialogFinished(); 00172 00173 KUrl m_startDir; 00174 KUrlRequester *m_parent; 00175 KLineEdit *edit; 00176 KComboBox *combo; 00177 KFile::Modes fileDialogMode; 00178 QString fileDialogFilter; 00179 #ifndef KDE_NO_DEPRECATED 00180 KEditListBox::CustomEditor editor; 00181 #else 00182 KEditListWidget::CustomEditor editor; 00183 #endif 00184 KUrlDragPushButton *myButton; 00185 KFileDialog *myFileDialog; 00186 KUrlCompletion *myCompletion; 00187 Qt::WindowModality fileDialogModality; 00188 }; 00189 00190 00191 00192 KUrlRequester::KUrlRequester( QWidget *editWidget, QWidget *parent) 00193 : KHBox( parent),d(new KUrlRequesterPrivate(this)) 00194 { 00195 // must have this as parent 00196 editWidget->setParent( this ); 00197 d->combo = qobject_cast<KComboBox*>( editWidget ); 00198 d->edit = qobject_cast<KLineEdit*>( editWidget ); 00199 if ( d->edit ) { 00200 d->edit->setClearButtonShown( true ); 00201 } 00202 00203 d->init(); 00204 } 00205 00206 00207 KUrlRequester::KUrlRequester( QWidget *parent) 00208 : KHBox( parent),d(new KUrlRequesterPrivate(this)) 00209 { 00210 d->init(); 00211 } 00212 00213 00214 KUrlRequester::KUrlRequester( const KUrl& url, QWidget *parent) 00215 : KHBox( parent),d(new KUrlRequesterPrivate(this)) 00216 { 00217 d->init(); 00218 setUrl( url ); 00219 } 00220 00221 KUrlRequester::~KUrlRequester() 00222 { 00223 delete d; 00224 } 00225 00226 00227 void KUrlRequester::KUrlRequesterPrivate::init() 00228 { 00229 m_parent->setMargin(0); 00230 m_parent->setSpacing(-1); // use default spacing 00231 00232 myFileDialog = 0L; 00233 fileDialogModality = Qt::ApplicationModal; 00234 00235 if ( !combo && !edit ) { 00236 edit = new KLineEdit( m_parent ); 00237 edit->setClearButtonShown( true ); 00238 } 00239 00240 QWidget *widget = combo ? (QWidget*) combo : (QWidget*) edit; 00241 00242 myButton = new KUrlDragPushButton(m_parent); 00243 myButton->setIcon(KIcon("document-open")); 00244 int buttonSize = widget->sizeHint().height(); 00245 myButton->setFixedSize(buttonSize, buttonSize); 00246 myButton->setToolTip(i18n("Open file dialog")); 00247 00248 m_parent->connect(myButton, SIGNAL(pressed()), SLOT(_k_slotUpdateUrl())); 00249 00250 widget->installEventFilter( m_parent ); 00251 m_parent->setFocusProxy( widget ); 00252 m_parent->setFocusPolicy(Qt::StrongFocus); 00253 00254 connectSignals( m_parent ); 00255 m_parent->connect(myButton, SIGNAL(clicked()), m_parent, SLOT(_k_slotOpenDialog())); 00256 00257 myCompletion = new KUrlCompletion(); 00258 setCompletionObject( myCompletion ); 00259 00260 QAction* openAction = new QAction(m_parent); 00261 openAction->setShortcut(KStandardShortcut::Open); 00262 m_parent->connect(openAction, SIGNAL(triggered(bool)), SLOT( _k_slotOpenDialog() )); 00263 } 00264 00265 void KUrlRequester::setUrl( const KUrl& url ) 00266 { 00267 d->setText( url.pathOrUrl() ); 00268 } 00269 00270 #ifndef KDE_NO_DEPRECATED 00271 void KUrlRequester::setPath( const QString& path ) 00272 { 00273 d->setText( path ); 00274 } 00275 #endif 00276 00277 void KUrlRequester::setText(const QString& text) 00278 { 00279 d->setText(text); 00280 } 00281 00282 void KUrlRequester::setStartDir(const KUrl& startDir) 00283 { 00284 d->m_startDir = startDir; 00285 if (startDir.isLocalFile()) 00286 d->myCompletion->setDir(startDir.toLocalFile()); 00287 } 00288 00289 void KUrlRequester::changeEvent(QEvent *e) 00290 { 00291 if (e->type()==QEvent::WindowTitleChange) { 00292 if (d->myFileDialog) { 00293 d->myFileDialog->setCaption(windowTitle()); 00294 } 00295 } 00296 KHBox::changeEvent(e); 00297 } 00298 00299 KUrl KUrlRequester::url() const 00300 { 00301 return d->url(); 00302 } 00303 00304 KUrl KUrlRequester::startDir() const 00305 { 00306 return d->m_startDir; 00307 } 00308 00309 QString KUrlRequester::text() const 00310 { 00311 return d->text(); 00312 } 00313 00314 void KUrlRequester::KUrlRequesterPrivate::_k_slotOpenDialog() 00315 { 00316 if ( myFileDialog ) 00317 if ( myFileDialog->isVisible() ) 00318 { 00319 //The file dialog is already being shown, raise it and exit 00320 myFileDialog->raise(); 00321 myFileDialog->activateWindow(); 00322 return; 00323 } 00324 00325 if ( ((fileDialogMode & KFile::Directory) && !(fileDialogMode & KFile::File)) || 00326 /* catch possible fileDialog()->setMode( KFile::Directory ) changes */ 00327 (myFileDialog && (myFileDialog->mode() & KFile::Directory) && 00328 (myFileDialog->mode() & (KFile::File | KFile::Files)) == 0) ) 00329 { 00330 const KUrl openUrl = (!m_parent->url().isEmpty() && !m_parent->url().isRelative() ) 00331 ? m_parent->url() : m_startDir; 00332 00333 /* FIXME We need a new abstract interface for using KDirSelectDialog in a non-modal way */ 00334 00335 KUrl newurl; 00336 if (fileDialogMode & KFile::LocalOnly) 00337 newurl = KFileDialog::getExistingDirectory( openUrl, m_parent); 00338 else 00339 newurl = KFileDialog::getExistingDirectoryUrl( openUrl, m_parent); 00340 00341 if ( newurl.isValid() ) 00342 { 00343 m_parent->setUrl( newurl ); 00344 emit m_parent->urlSelected( url() ); 00345 } 00346 } 00347 else 00348 { 00349 emit m_parent->openFileDialog( m_parent ); 00350 00351 //Creates the fileDialog if it doesn't exist yet 00352 KFileDialog *dlg = m_parent->fileDialog(); 00353 00354 if ( !url().isEmpty() && !url().isRelative() ) { 00355 KUrl u( url() ); 00356 // If we won't be able to list it (e.g. http), then don't try :) 00357 if ( KProtocolManager::supportsListing( u ) ) 00358 dlg->setSelection( u.url() ); 00359 } else { 00360 dlg->setUrl(m_startDir); 00361 } 00362 00363 //Update the file dialog window modality 00364 if ( dlg->windowModality() != fileDialogModality ) 00365 dlg->setWindowModality(fileDialogModality); 00366 00367 if ( fileDialogModality == Qt::NonModal ) 00368 { 00369 dlg->show(); 00370 } else { 00371 dlg->exec(); 00372 } 00373 } 00374 } 00375 00376 void KUrlRequester::KUrlRequesterPrivate::_k_slotFileDialogFinished() 00377 { 00378 if ( !myFileDialog ) 00379 return; 00380 00381 if ( myFileDialog->result() == QDialog::Accepted ) 00382 { 00383 KUrl newUrl = myFileDialog->selectedUrl(); 00384 if ( newUrl.isValid() ) 00385 { 00386 m_parent->setUrl( newUrl ); 00387 emit m_parent->urlSelected( url() ); 00388 } 00389 } 00390 } 00391 00392 void KUrlRequester::setMode( KFile::Modes mode) 00393 { 00394 Q_ASSERT( (mode & KFile::Files) == 0 ); 00395 d->fileDialogMode = mode; 00396 if ( (mode & KFile::Directory) && !(mode & KFile::File) ) 00397 d->myCompletion->setMode( KUrlCompletion::DirCompletion ); 00398 00399 if (d->myFileDialog) { 00400 d->myFileDialog->setMode(d->fileDialogMode); 00401 } 00402 } 00403 00404 KFile::Modes KUrlRequester::mode() const 00405 { 00406 return d->fileDialogMode; 00407 } 00408 00409 void KUrlRequester::setFilter(const QString &filter) 00410 { 00411 d->fileDialogFilter = filter; 00412 if (d->myFileDialog) { 00413 d->myFileDialog->setFilter(d->fileDialogFilter); 00414 } 00415 } 00416 00417 QString KUrlRequester::filter( ) const 00418 { 00419 return d->fileDialogFilter; 00420 } 00421 00422 KFileDialog * KUrlRequester::fileDialog() const 00423 { 00424 if (!d->myFileDialog) { 00425 QWidget *p = parentWidget(); 00426 d->myFileDialog = new KFileDialog(QString(), d->fileDialogFilter, p); 00427 d->myFileDialog->setMode(d->fileDialogMode); 00428 d->myFileDialog->setCaption(windowTitle()); 00429 d->myFileDialog->setWindowModality(d->fileDialogModality); 00430 connect(d->myFileDialog, SIGNAL(finished()), SLOT(_k_slotFileDialogFinished())); 00431 } 00432 00433 return d->myFileDialog; 00434 } 00435 00436 void KUrlRequester::clear() 00437 { 00438 d->setText( QString() ); 00439 } 00440 00441 KLineEdit * KUrlRequester::lineEdit() const 00442 { 00443 return d->edit; 00444 } 00445 00446 KComboBox * KUrlRequester::comboBox() const 00447 { 00448 return d->combo; 00449 } 00450 00451 void KUrlRequester::KUrlRequesterPrivate::_k_slotUpdateUrl() 00452 { 00453 KUrl u( KUrl::fromPath( QDir::currentPath() + '/' ), url().url() ); 00454 myButton->setURL( u ); 00455 } 00456 00457 bool KUrlRequester::eventFilter( QObject *obj, QEvent *ev ) 00458 { 00459 if ( ( d->edit == obj ) || ( d->combo == obj ) ) 00460 { 00461 if (( ev->type() == QEvent::FocusIn ) || ( ev->type() == QEvent::FocusOut )) 00462 // Forward focusin/focusout events to the urlrequester; needed by file form element in khtml 00463 QApplication::sendEvent( this, ev ); 00464 } 00465 return QWidget::eventFilter( obj, ev ); 00466 } 00467 00468 KPushButton * KUrlRequester::button() const 00469 { 00470 return d->myButton; 00471 } 00472 00473 KUrlCompletion *KUrlRequester::completionObject() const 00474 { 00475 return d->myCompletion; 00476 } 00477 00478 void KUrlRequester::setClickMessage(const QString& msg) 00479 { 00480 if(d->edit) 00481 d->edit->setClickMessage(msg); 00482 } 00483 00484 QString KUrlRequester::clickMessage() const 00485 { 00486 if(d->edit) 00487 return d->edit->clickMessage(); 00488 else 00489 return QString(); 00490 } 00491 00492 Qt::WindowModality KUrlRequester::fileDialogModality() const 00493 { 00494 return d->fileDialogModality; 00495 } 00496 00497 void KUrlRequester::setFileDialogModality(Qt::WindowModality modality) 00498 { 00499 d->fileDialogModality = modality; 00500 } 00501 00502 #ifndef KDE_NO_DEPRECATED 00503 const KEditListBox::CustomEditor &KUrlRequester::customEditor() 00504 #else 00505 const KEditListWidget::CustomEditor &KUrlRequester::customEditor() 00506 #endif 00507 { 00508 setSizePolicy(QSizePolicy( QSizePolicy::Preferred, 00509 QSizePolicy::Fixed)); 00510 00511 KLineEdit *edit = d->edit; 00512 if ( !edit && d->combo ) 00513 edit = qobject_cast<KLineEdit*>( d->combo->lineEdit() ); 00514 00515 #ifndef NDEBUG 00516 if ( !edit ) { 00517 kWarning() << "KUrlRequester's lineedit is not a KLineEdit!??\n"; 00518 } 00519 #endif 00520 00521 d->editor.setRepresentationWidget(this); 00522 d->editor.setLineEdit(edit); 00523 return d->editor; 00524 } 00525 00526 KUrlComboRequester::KUrlComboRequester( QWidget *parent) 00527 : KUrlRequester( new KComboBox(false), parent), d(0) 00528 { 00529 } 00530 00531 #include "kurlrequester.moc"
KDE 4.6 API Reference