kurlrequester.cpp

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