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