00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <sys/stat.h>
00021 #include <unistd.h>
00022
00023 #include <qstring.h>
00024 #include <qtooltip.h>
00025 #include <qapplication.h>
00026
00027 #include <kaccel.h>
00028 #include <kcombobox.h>
00029 #include <kdebug.h>
00030 #include <kdialog.h>
00031 #include <kdirselectdialog.h>
00032 #include <kfiledialog.h>
00033 #include <kglobal.h>
00034 #include <kiconloader.h>
00035 #include <klineedit.h>
00036 #include <klocale.h>
00037 #include <kurlcompletion.h>
00038 #include <kurldrag.h>
00039 #include <kprotocolinfo.h>
00040
00041 #include "kurlrequester.h"
00042
00043
00044 class KURLDragPushButton : public KPushButton
00045 {
00046 public:
00047 KURLDragPushButton( QWidget *parent, const char *name=0 )
00048 : KPushButton( parent, name ) {
00049 setDragEnabled( true );
00050 }
00051 ~KURLDragPushButton() {}
00052
00053 void setURL( const KURL& url ) {
00054 m_urls.clear();
00055 m_urls.append( url );
00056 }
00057
00058
00059
00060
00061
00062
00063
00064
00065 protected:
00066 virtual QDragObject *dragObject() {
00067 if ( m_urls.isEmpty() )
00068 return 0L;
00069
00070 QDragObject *drag = new KURLDrag( m_urls, this, "url drag" );
00071 return drag;
00072 }
00073
00074 private:
00075 KURL::List m_urls;
00076
00077 };
00078
00079
00080
00081
00082
00083
00084 class KURLRequester::KURLRequesterPrivate
00085 {
00086 public:
00087 KURLRequesterPrivate() {
00088 edit = 0L;
00089 combo = 0L;
00090 fileDialogMode = KFile::File | KFile::ExistingOnly | KFile::LocalOnly;
00091 }
00092
00093 void setText( const QString& text ) {
00094 if ( combo )
00095 {
00096 if (combo->editable())
00097 {
00098 combo->setEditText( text );
00099 }
00100 else
00101 {
00102 combo->insertItem( text );
00103 combo->setCurrentItem( combo->count()-1 );
00104 }
00105 }
00106 else
00107 {
00108 edit->setText( text );
00109 }
00110 }
00111
00112 void connectSignals( QObject *receiver ) {
00113 QObject *sender;
00114 if ( combo )
00115 sender = combo;
00116 else
00117 sender = edit;
00118
00119 connect( sender, SIGNAL( textChanged( const QString& )),
00120 receiver, SIGNAL( textChanged( const QString& )));
00121 connect( sender, SIGNAL( returnPressed() ),
00122 receiver, SIGNAL( returnPressed() ));
00123 connect( sender, SIGNAL( returnPressed( const QString& ) ),
00124 receiver, SIGNAL( returnPressed( const QString& ) ));
00125 }
00126
00127 void setCompletionObject( KCompletion *comp ) {
00128 if ( combo )
00129 combo->setCompletionObject( comp );
00130 else
00131 edit->setCompletionObject( comp );
00132 }
00133
00137 QString url() {
00138 QString txt = combo ? combo->currentText() : edit->text();
00139 KURLCompletion *comp;
00140 if ( combo )
00141 comp = dynamic_cast<KURLCompletion*>(combo->completionObject());
00142 else
00143 comp = dynamic_cast<KURLCompletion*>(edit->completionObject());
00144
00145 if ( comp )
00146 return comp->replacedPath( txt );
00147 else
00148 return txt;
00149 }
00150
00151 KLineEdit *edit;
00152 KComboBox *combo;
00153 int fileDialogMode;
00154 QString fileDialogFilter;
00155 };
00156
00157
00158
00159 KURLRequester::KURLRequester( QWidget *editWidget, QWidget *parent,
00160 const char *name )
00161 : QHBox( parent, name )
00162 {
00163 d = new KURLRequesterPrivate;
00164
00165
00166 editWidget->reparent( this, 0, QPoint(0,0) );
00167 d->edit = dynamic_cast<KLineEdit*>( editWidget );
00168 d->combo = dynamic_cast<KComboBox*>( editWidget );
00169
00170 init();
00171 }
00172
00173
00174 KURLRequester::KURLRequester( QWidget *parent, const char *name )
00175 : QHBox( parent, name )
00176 {
00177 d = new KURLRequesterPrivate;
00178 init();
00179 }
00180
00181
00182 KURLRequester::KURLRequester( const QString& url, QWidget *parent,
00183 const char *name )
00184 : QHBox( parent, name )
00185 {
00186 d = new KURLRequesterPrivate;
00187 init();
00188 setKURL( KURL::fromPathOrURL( url ) );
00189 }
00190
00191
00192 KURLRequester::~KURLRequester()
00193 {
00194 delete myCompletion;
00195 delete myFileDialog;
00196 delete d;
00197 }
00198
00199
00200 void KURLRequester::init()
00201 {
00202 myFileDialog = 0L;
00203 myShowLocalProt = false;
00204
00205 if ( !d->combo && !d->edit )
00206 d->edit = new KLineEdit( this, "line edit" );
00207
00208 myButton = new KURLDragPushButton( this, "kfile button");
00209 QIconSet iconSet = SmallIconSet(QString::fromLatin1("fileopen"));
00210 QPixmap pixMap = iconSet.pixmap( QIconSet::Small, QIconSet::Normal );
00211 myButton->setIconSet( iconSet );
00212 myButton->setFixedSize( pixMap.width()+8, pixMap.height()+8 );
00213 QToolTip::add(myButton, i18n("Open file dialog"));
00214
00215 connect( myButton, SIGNAL( pressed() ), SLOT( slotUpdateURL() ));
00216
00217 setSpacing( KDialog::spacingHint() );
00218
00219 QWidget *widget = d->combo ? (QWidget*) d->combo : (QWidget*) d->edit;
00220 widget->installEventFilter( this );
00221 setFocusProxy( widget );
00222
00223 d->connectSignals( this );
00224 connect( myButton, SIGNAL( clicked() ), this, SLOT( slotOpenDialog() ));
00225
00226 myCompletion = new KURLCompletion();
00227 d->setCompletionObject( myCompletion );
00228
00229 KAccel *accel = new KAccel( this );
00230 accel->insert( KStdAccel::Open, this, SLOT( slotOpenDialog() ));
00231 accel->readSettings();
00232 }
00233
00234
00235 void KURLRequester::setURL( const QString& url )
00236 {
00237 if ( myShowLocalProt )
00238 {
00239 d->setText( url );
00240 }
00241 else
00242 {
00243
00244 if ( url.startsWith("file://") )
00245 d->setText( url.mid( 7 ) );
00246 else if ( url.startsWith("file:") )
00247 d->setText( url.mid( 5 ) );
00248 else
00249 d->setText( url );
00250 }
00251 }
00252
00253 void KURLRequester::setKURL( const KURL& url )
00254 {
00255 if ( myShowLocalProt )
00256 d->setText( url.url() );
00257 else
00258 d->setText( url.pathOrURL() );
00259 }
00260
00261 void KURLRequester::setCaption( const QString& caption )
00262 {
00263 QWidget::setCaption( caption );
00264 if (myFileDialog)
00265 myFileDialog->setCaption( caption );
00266 }
00267
00268 QString KURLRequester::url() const
00269 {
00270 return d->url();
00271 }
00272
00273 void KURLRequester::slotOpenDialog()
00274 {
00275 KURL newurl;
00276 if ( (d->fileDialogMode & KFile::Directory) && !(d->fileDialogMode & KFile::File) ||
00277
00278 (myFileDialog && ( (myFileDialog->mode() & KFile::Directory) &&
00279 (myFileDialog->mode() & (KFile::File | KFile::Files)) == 0 ) ) )
00280 {
00281 newurl = KDirSelectDialog::selectDirectory(url(), d->fileDialogMode & KFile::LocalOnly);
00282 if ( !newurl.isValid() )
00283 {
00284 return;
00285 }
00286 }
00287 else
00288 {
00289 emit openFileDialog( this );
00290
00291 KFileDialog *dlg = fileDialog();
00292 if ( !d->url().isEmpty() ) {
00293 KURL u( url() );
00294
00295 if ( KProtocolInfo::supportsListing( u ) )
00296 dlg->setSelection( u.url() );
00297 }
00298
00299 if ( dlg->exec() != QDialog::Accepted )
00300 {
00301 return;
00302 }
00303
00304 newurl = dlg->selectedURL();
00305 }
00306
00307 setKURL( newurl );
00308 emit urlSelected( d->url() );
00309 }
00310
00311 void KURLRequester::setMode(uint mode)
00312 {
00313 Q_ASSERT( (mode & KFile::Files) == 0 );
00314 d->fileDialogMode = mode;
00315 if ( (mode & KFile::Directory) && !(mode & KFile::File) )
00316 myCompletion->setMode( KURLCompletion::DirCompletion );
00317
00318 if (myFileDialog)
00319 myFileDialog->setMode( d->fileDialogMode );
00320 }
00321
00322 unsigned int KURLRequester::mode() const
00323 {
00324 return d->fileDialogMode;
00325 }
00326
00327 void KURLRequester::setFilter(const QString &filter)
00328 {
00329 d->fileDialogFilter = filter;
00330 if (myFileDialog)
00331 myFileDialog->setFilter( d->fileDialogFilter );
00332 }
00333
00334 QString KURLRequester::filter( ) const
00335 {
00336 return d->fileDialogFilter;
00337 }
00338
00339
00340 KFileDialog * KURLRequester::fileDialog() const
00341 {
00342 if ( !myFileDialog ) {
00343 QWidget *p = parentWidget();
00344 myFileDialog = new KFileDialog( QString::null, d->fileDialogFilter, p,
00345 "file dialog", true );
00346
00347 myFileDialog->setMode( d->fileDialogMode );
00348 myFileDialog->setCaption( caption() );
00349 }
00350
00351 return myFileDialog;
00352 }
00353
00354
00355 void KURLRequester::setShowLocalProtocol( bool b )
00356 {
00357 if ( myShowLocalProt == b )
00358 return;
00359
00360 myShowLocalProt = b;
00361 setKURL( url() );
00362 }
00363
00364 void KURLRequester::clear()
00365 {
00366 d->setText( QString::null );
00367 }
00368
00369 KLineEdit * KURLRequester::lineEdit() const
00370 {
00371 return d->edit;
00372 }
00373
00374 KComboBox * KURLRequester::comboBox() const
00375 {
00376 return d->combo;
00377 }
00378
00379 void KURLRequester::slotUpdateURL()
00380 {
00381
00382 KURL u;
00383 u = KURL( KURL( QDir::currentDirPath() + '/' ), url() );
00384 (static_cast<KURLDragPushButton *>( myButton ))->setURL( u );
00385 }
00386
00387 bool KURLRequester::eventFilter( QObject *obj, QEvent *ev )
00388 {
00389 if ( ( d->edit == obj ) || ( d->combo == obj ) )
00390 {
00391 if (( ev->type() == QEvent::FocusIn ) || ( ev->type() == QEvent::FocusOut ))
00392
00393 QApplication::sendEvent( this, ev );
00394 }
00395 return QWidget::eventFilter( obj, ev );
00396 }
00397
00398 KPushButton * KURLRequester::button() const
00399 {
00400 return myButton;
00401 }
00402
00403 KEditListBox::CustomEditor KURLRequester::customEditor()
00404 {
00405 setSizePolicy(QSizePolicy( QSizePolicy::Preferred,
00406 QSizePolicy::Fixed));
00407
00408 KLineEdit *edit = d->edit;
00409 if ( !edit && d->combo )
00410 edit = dynamic_cast<KLineEdit*>( d->combo->lineEdit() );
00411
00412 #ifndef NDEBUG
00413 if ( !edit )
00414 kdWarning() << "KURLRequester's lineedit is not a KLineEdit!??\n";
00415 #endif
00416
00417 KEditListBox::CustomEditor editor( this, edit );
00418 return editor;
00419 }
00420
00421 void KURLRequester::virtual_hook( int, void* )
00422 { }
00423
00424 KURLComboRequester::KURLComboRequester( QWidget *parent,
00425 const char *name )
00426 : KURLRequester( new KComboBox(false), parent, name)
00427 {
00428 }
00429
00430 #include "kurlrequester.moc"