kio Library API Documentation

kopenwith.cpp

00001 /*  This file is part of the KDE libraries
00002 
00003     Copyright (C) 1997 Torben Weis <weis@stud.uni-frankfurt.de>
00004     Copyright (C) 1999 Dirk A. Mueller <dmuell@gmx.net>
00005     Portions copyright (C) 1999 Preston Brown <pbrown@kde.org>
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Library General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Library General Public License for more details.
00016 
00017     You should have received a copy of the GNU Library General Public License
00018     along with this library; see the file COPYING.LIB.  If not, write to
00019     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00020     Boston, MA 02111-1307, USA.
00021 */
00022 
00023 // $Id: kopenwith.cpp,v 1.66.2.2 2002/12/11 19:18:11 pfeiffer Exp $
00024 
00025 #include <qfile.h>
00026 #include <qdir.h>
00027 #include <qdialog.h>
00028 #include <qpixmap.h>
00029 #include <qlabel.h>
00030 #include <qlayout.h>
00031 #include <qpushbutton.h>
00032 #include <qtoolbutton.h>
00033 #include <qcheckbox.h>
00034 #include <qtooltip.h>
00035 #include <qstyle.h>
00036 
00037 #include <kapplication.h>
00038 #include <kbuttonbox.h>
00039 #include <kcombobox.h>
00040 #include <kdesktopfile.h>
00041 #include <kdialog.h>
00042 #include <kglobal.h>
00043 #include <klineedit.h>
00044 #include <klocale.h>
00045 #include <kiconloader.h>
00046 #include <kmimemagic.h>
00047 #include <krun.h>
00048 #include <kstandarddirs.h>
00049 #include <kstringhandler.h>
00050 #include <kuserprofile.h>
00051 #include <kurlcompletion.h>
00052 #include <kurlrequester.h>
00053 #include <dcopclient.h>
00054 #include <kmimetype.h>
00055 #include <kservicegroup.h>
00056 #include <klistview.h>
00057 #include <ksycoca.h>
00058 
00059 #include "kopenwith.h"
00060 #include "kopenwith_p.h"
00061 
00062 #include <kdebug.h>
00063 #include <assert.h>
00064 #include <stdlib.h>
00065 
00066 template class QPtrList<QString>;
00067 
00068 #define SORT_SPEC (QDir::DirsFirst | QDir::Name | QDir::IgnoreCase)
00069 
00070 
00071 // ----------------------------------------------------------------------
00072 
00073 KAppTreeListItem::KAppTreeListItem( KListView* parent, const QString & name,
00074                                     const QPixmap& pixmap, bool parse, bool dir, QString p, QString c )
00075     : QListViewItem( parent, name )
00076 {
00077     init(pixmap, parse, dir, p, c);
00078 }
00079 
00080 
00081 // ----------------------------------------------------------------------
00082 
00083 KAppTreeListItem::KAppTreeListItem( QListViewItem* parent, const QString & name,
00084                                     const QPixmap& pixmap, bool parse, bool dir, QString p, QString c )
00085     : QListViewItem( parent, name )
00086 {
00087     init(pixmap, parse, dir, p, c);
00088 }
00089 
00090 
00091 // ----------------------------------------------------------------------
00092 
00093 void KAppTreeListItem::init(const QPixmap& pixmap, bool parse, bool dir, QString _path, QString _exec)
00094 {
00095     setPixmap(0, pixmap);
00096     parsed = parse;
00097     directory = dir;
00098     path = _path; // relative path
00099     exec = _exec;
00100 }
00101 
00102 
00103 // ----------------------------------------------------------------------
00104 // Ensure that dirs are sorted in front of files and case is ignored
00105 
00106 QString KAppTreeListItem::key(int column, bool /*ascending*/) const
00107 {
00108     if (directory)
00109         return QString::fromLatin1(" ") + text(column).upper();
00110     else
00111         return text(column).upper();
00112 }
00113 
00114 void KAppTreeListItem::activate()
00115 {
00116     if ( directory )
00117         setOpen(!isOpen());
00118 }
00119 
00120 void KAppTreeListItem::setOpen( bool o )
00121 {
00122     if( o && !parsed ) { // fill the children before opening
00123         ((KApplicationTree *) parent())->addDesktopGroup( path, this );
00124         parsed = true;
00125     }
00126     QListViewItem::setOpen( o );
00127 }
00128 
00129 bool KAppTreeListItem::isDirectory()
00130 {
00131     return directory;
00132 }
00133 
00134 // ----------------------------------------------------------------------
00135 
00136 KApplicationTree::KApplicationTree( QWidget *parent )
00137     : KListView( parent ), currentitem(0)
00138 {
00139     addColumn( i18n("Known Applications") );
00140     setRootIsDecorated( true );
00141 
00142     addDesktopGroup( QString::null );
00143 
00144     connect( this, SIGNAL( currentChanged(QListViewItem*) ),
00145             SLOT( slotItemHighlighted(QListViewItem*) ) );
00146     connect( this, SIGNAL( selectionChanged(QListViewItem*) ),
00147             SLOT( slotSelectionChanged(QListViewItem*) ) );
00148 }
00149 
00150 // ----------------------------------------------------------------------
00151 
00152 bool KApplicationTree::isDirSel()
00153 {
00154     if (!currentitem) return false; // if currentitem isn't set
00155     return currentitem->isDirectory();
00156 }
00157 
00158 // ----------------------------------------------------------------------
00159 
00160 void KApplicationTree::addDesktopGroup( QString relPath, KAppTreeListItem *item)
00161 {
00162    KServiceGroup::Ptr root = KServiceGroup::group(relPath);
00163    if (!root || !root->isValid()) return;
00164 
00165    KServiceGroup::List list = root->entries();
00166 
00167    KAppTreeListItem * newItem;
00168    for( KServiceGroup::List::ConstIterator it = list.begin();
00169        it != list.end(); it++)
00170    {
00171       QString icon;
00172       QString text;
00173       QString relPath;
00174       QString exec;
00175       bool isDir = false;
00176       KSycocaEntry *p = (*it);
00177       if (p->isType(KST_KService))
00178       {
00179          KService *service = static_cast<KService *>(p);
00180 
00181          if (service->noDisplay())
00182             continue;
00183 
00184          icon = service->icon();
00185          text = service->name();
00186          exec = service->exec();
00187       }
00188       else if (p->isType(KST_KServiceGroup))
00189       {
00190          KServiceGroup *serviceGroup = static_cast<KServiceGroup *>(p);
00191 
00192          if (serviceGroup->noDisplay())
00193             continue;
00194 
00195          icon = serviceGroup->icon();
00196          text = serviceGroup->caption();
00197          relPath = serviceGroup->relPath();
00198          isDir = true;
00199          if ( text[0] == '.' ) // skip ".hidden" like kicker does
00200            continue;
00201       }
00202       else
00203       {
00204          kdWarning(250) << "KServiceGroup: Unexpected object in list!" << endl;
00205          continue;
00206       }
00207 
00208       QPixmap pixmap = SmallIcon( icon );
00209 
00210       if (item)
00211          newItem = new KAppTreeListItem( item, text, pixmap, false, isDir,
00212                                          relPath, exec );
00213       else
00214          newItem = new KAppTreeListItem( this, text, pixmap, false, isDir,
00215                                          relPath, exec );
00216       if (isDir)
00217          newItem->setExpandable( true );
00218    }
00219 }
00220 
00221 
00222 // ----------------------------------------------------------------------
00223 
00224 void KApplicationTree::slotItemHighlighted(QListViewItem* i)
00225 {
00226     // i may be 0 (see documentation)
00227     if(!i)
00228         return;
00229 
00230     KAppTreeListItem *item = (KAppTreeListItem *) i;
00231 
00232     currentitem = item;
00233 
00234     if( (!item->directory ) && (!item->exec.isEmpty()) )
00235         emit highlighted( item->text(0), item->exec );
00236 }
00237 
00238 
00239 // ----------------------------------------------------------------------
00240 
00241 void KApplicationTree::slotSelectionChanged(QListViewItem* i)
00242 {
00243     // i may be 0 (see documentation)
00244     if(!i)
00245         return;
00246 
00247     KAppTreeListItem *item = (KAppTreeListItem *) i;
00248 
00249     currentitem = item;
00250 
00251     if( ( !item->directory ) && (!item->exec.isEmpty() ) )
00252         emit selected( item->text(0), item->exec );
00253 }
00254 
00255 // ----------------------------------------------------------------------
00256 
00257 void KApplicationTree::resizeEvent( QResizeEvent * e)
00258 {
00259     setColumnWidth(0, width()-QApplication::style().pixelMetric(QStyle::PM_ScrollBarExtent)
00260                          -2*QApplication::style().pixelMetric(QStyle::PM_DefaultFrameWidth));
00261     KListView::resizeEvent(e);
00262 }
00263 
00264 
00265 /***************************************************************
00266  *
00267  * KOpenWithDlg
00268  *
00269  ***************************************************************/
00270 
00271 KOpenWithDlg::KOpenWithDlg( const KURL::List& _urls, QWidget* parent )
00272              :QDialog( parent, 0L, true )
00273 {
00274     setCaption( i18n( "Open With" ) );
00275     QString text;
00276     if( _urls.count() == 1 )
00277     {
00278         text = i18n("<qt>Select the program that should be used to open <b>%1</b>. "
00279                      "If the program is not listed, enter the name or click "
00280                      "the browse button.</qt>").arg( _urls.first().fileName() );
00281     }
00282     else
00283         // Should never happen ??
00284         text = i18n( "Choose the name of the program with which to open the selected files." );
00285     setServiceType( _urls );
00286     init( text, QString() );
00287 }
00288 
00289 KOpenWithDlg::KOpenWithDlg( const KURL::List& _urls, const QString&_text,
00290                             const QString& _value, QWidget *parent)
00291              :QDialog( parent, 0L, true )
00292 {
00293   QString caption = KStringHandler::csqueeze( _urls.first().prettyURL() );
00294   if (_urls.count() > 1)
00295       caption += QString::fromLatin1("...");
00296   setCaption(caption);
00297   setServiceType( _urls );
00298   init( _text, _value );
00299 }
00300 
00301 KOpenWithDlg::KOpenWithDlg( const QString &serviceType, const QString& value,
00302                             QWidget *parent)
00303              :QDialog( parent, 0L, true )
00304 {
00305   setCaption(i18n("Choose Application for %1").arg(serviceType));
00306   QString text = i18n("<qt>Select the program for the file type: <b>%1</b>. "
00307                       "If the program is not listed, enter the name or click "
00308                       "the browse button.</qt>").arg(serviceType);
00309   qServiceType = serviceType;
00310   init( text, value );
00311   if (remember)
00312   {
00313       remember->setChecked( true );
00314       remember->hide();
00315   }
00316 }
00317 
00318 KOpenWithDlg::KOpenWithDlg( QWidget *parent)
00319              :QDialog( parent, 0L, true )
00320 {
00321   setCaption(i18n("Choose Application"));
00322   QString text = i18n("<qt>Select a program. "
00323                       "If the program is not listed, enter the name or click "
00324                       "the browse button.</qt>");
00325   qServiceType = QString::null;
00326   init( text, QString::null );
00327 }
00328 
00329 void KOpenWithDlg::setServiceType( const KURL::List& _urls )
00330 {
00331   if ( _urls.count() == 1 )
00332   {
00333     qServiceType = KMimeType::findByURL( _urls.first())->name();
00334     if (qServiceType == QString::fromLatin1("application/octet-stream"))
00335       qServiceType = QString::null;
00336   }
00337   else
00338       qServiceType = QString::null;
00339 }
00340 
00341 void KOpenWithDlg::init( const QString& _text, const QString& _value )
00342 {
00343   bool bReadOnly = kapp && !kapp->authorize("shell_access");
00344   m_terminaldirty = false;
00345   m_pTree = 0L;
00346   m_pService = 0L;
00347 
00348   QBoxLayout *topLayout = new QVBoxLayout( this, KDialog::marginHint(),
00349           KDialog::spacingHint() );
00350   label = new QLabel( _text, this );
00351   topLayout->addWidget(label);
00352 
00353   QHBoxLayout* hbox = new QHBoxLayout(topLayout);
00354 
00355   QToolButton *clearButton = new QToolButton( this );
00356   clearButton->setIconSet( BarIcon( "locationbar_erase" ) );
00357   clearButton->setFixedSize( clearButton->sizeHint() );
00358   connect( clearButton, SIGNAL( pressed() ), SLOT( slotClear() ) );
00359   QToolTip::add( clearButton, i18n( "Clear input field" ) );
00360 
00361   hbox->addWidget( clearButton );
00362 
00363   if (!bReadOnly)
00364   {
00365     // init the history combo and insert it into the URL-Requester
00366     KHistoryCombo *combo = new KHistoryCombo();
00367     combo->setDuplicatesEnabled( false );
00368     KConfig *kc = KGlobal::config();
00369     KConfigGroupSaver ks( kc, QString::fromLatin1("Open-with settings") );
00370     int max = kc->readNumEntry( QString::fromLatin1("Maximum history"), 15 );
00371     combo->setMaxCount( max );
00372     int mode = kc->readNumEntry(QString::fromLatin1("CompletionMode"),
00373                 KGlobalSettings::completionMode());
00374     combo->setCompletionMode((KGlobalSettings::Completion)mode);
00375     QStringList list = kc->readListEntry( QString::fromLatin1("History") );
00376     combo->setHistoryItems( list, true );
00377     edit = new KURLRequester( combo, this );
00378   }
00379   else
00380   {
00381     clearButton->hide();
00382     edit = new KURLRequester( this );
00383     edit->lineEdit()->setReadOnly(true);
00384     edit->button()->hide();
00385   }
00386 
00387   edit->setURL( _value );
00388 
00389   hbox->addWidget(edit);
00390 
00391   if ( edit->comboBox() ) {
00392     KURLCompletion *comp = new KURLCompletion( KURLCompletion::ExeCompletion );
00393     edit->comboBox()->setCompletionObject( comp );
00394   }
00395 
00396   connect ( edit, SIGNAL(returnPressed()), SLOT(slotOK()) );
00397   connect ( edit, SIGNAL(textChanged(const QString&)), SLOT(slotTextChanged()) );
00398 
00399   m_pTree = new KApplicationTree( this );
00400   topLayout->addWidget(m_pTree);
00401 
00402   connect( m_pTree, SIGNAL( selected( const QString&, const QString& ) ),
00403            SLOT( slotSelected( const QString&, const QString& ) ) );
00404   connect( m_pTree, SIGNAL( highlighted( const QString&, const QString& ) ),
00405            SLOT( slotHighlighted( const QString&, const QString& ) ) );
00406   connect( m_pTree, SIGNAL( doubleClicked(QListViewItem*) ),
00407            SLOT( slotDbClick() ) );
00408 
00409   terminal = new QCheckBox( i18n("Run in &terminal"), this );
00410   if (bReadOnly)
00411      terminal->hide();
00412   connect(terminal, SIGNAL(toggled(bool)), SLOT(slotTerminalToggled(bool)));
00413 
00414   topLayout->addWidget(terminal);
00415 
00416   if (!qServiceType.isNull())
00417   {
00418     remember = new QCheckBox(i18n("&Remember application association for this type of file"), this);
00419     //    remember->setChecked(true);
00420     topLayout->addWidget(remember);
00421   }
00422   else
00423     remember = 0L;
00424 
00425   // Use KButtonBox for the aligning pushbuttons nicely
00426   KButtonBox* b = new KButtonBox( this );
00427   b->addStretch( 2 );
00428 
00429   ok = b->addButton(  i18n ( "&OK" ) );
00430   ok->setDefault( true );
00431   connect(  ok, SIGNAL( clicked() ), SLOT( slotOK() ) );
00432 
00433   cancel = b->addButton(  i18n( "&Cancel" ) );
00434   connect(  cancel, SIGNAL( clicked() ), SLOT( reject() ) );
00435 
00436   b->layout();
00437   topLayout->addWidget( b );
00438 
00439   //edit->setText( _value );
00440   // This is what caused "can't click on items before clicking on Name header".
00441   // Probably due to the resizeEvent handler using width().
00442   //resize( minimumWidth(), sizeHint().height() );
00443   edit->setFocus();
00444 }
00445 
00446 
00447 // ----------------------------------------------------------------------
00448 
00449 KOpenWithDlg::~KOpenWithDlg()
00450 {
00451 }
00452 
00453 // ----------------------------------------------------------------------
00454 
00455 void KOpenWithDlg::slotClear()
00456 {
00457     edit->setURL(QString::null);
00458     edit->setFocus();
00459 }
00460 
00461 
00462 // ----------------------------------------------------------------------
00463 
00464 void KOpenWithDlg::slotSelected( const QString& /*_name*/, const QString& _exec )
00465 {
00466     kdDebug(250)<<"KOpenWithDlg::slotSelected"<<endl;
00467     KService::Ptr pService = m_pService;
00468     edit->setURL( _exec ); // calls slotTextChanged :(
00469     m_pService = pService;
00470 }
00471 
00472 
00473 // ----------------------------------------------------------------------
00474 
00475 void KOpenWithDlg::slotHighlighted( const QString& _name, const QString& )
00476 {
00477     kdDebug(250)<<"KOpenWithDlg::slotHighlighted"<<endl;
00478     qName = _name;
00479     m_pService = KService::serviceByName( qName );
00480     if (!m_terminaldirty)
00481     {
00482         // ### indicate that default value was restored
00483         terminal->setChecked(m_pService->terminal());
00484         m_terminaldirty = false; // slotTerminalToggled changed it
00485     }
00486 }
00487 
00488 // ----------------------------------------------------------------------
00489 
00490 void KOpenWithDlg::slotTextChanged()
00491 {
00492     kdDebug(250)<<"KOpenWithDlg::slotTextChanged"<<endl;
00493     // Forget about the service
00494     m_pService = 0L;
00495 }
00496 
00497 // ----------------------------------------------------------------------
00498 
00499 void KOpenWithDlg::slotTerminalToggled(bool)
00500 {
00501     // ### indicate that default value was overridden
00502     m_terminaldirty = true;
00503 }
00504 
00505 // ----------------------------------------------------------------------
00506 
00507 void KOpenWithDlg::slotDbClick()
00508 {
00509    if (m_pTree->isDirSel() ) return; // check if a directory is selected
00510    slotOK();
00511 }
00512 
00513 void KOpenWithDlg::slotOK()
00514 {
00515   QString fullExec(edit->url());
00516 
00517   QString serviceName;
00518   QString pathName;
00519   QString initialServiceName;
00520   if (!m_pService) {
00521     // No service selected - check the command line
00522 
00523     // Find out the name of the service from the command line, removing args and paths
00524     serviceName = KRun::binaryName( fullExec, true );
00525     if (serviceName.isEmpty())
00526     {
00527       // TODO add a KMessageBox::error here after the end of the message freeze
00528       return;
00529     }
00530     initialServiceName = serviceName;
00531     int i = 1; // We have app, app-2, app-3... Looks better for the user.
00532     // Check if there's already a service by that name, with the same Exec line
00533     do {
00534         KService::Ptr serv = KService::serviceByDesktopName( serviceName );
00535         bool ok = !serv; // ok if no such service yet
00536         // also ok if we find the exact same service (well, "kwrite" == "kwrite %U"
00537         if ( serv &&
00538              serv->type() == "Application" && ( // only apps
00539                  serv->exec() == fullExec ||
00540                  serv->exec() == fullExec + " %u" ||
00541                  serv->exec() == fullExec + " %U" ||
00542                  serv->exec() == fullExec + " %f" ||
00543                  serv->exec() == fullExec + " %F"
00544                  ) )
00545         {
00546             ok = true;
00547             m_pService = serv;
00548         }
00549         if (!ok) // service was found, but it was different -> keep looking
00550         {
00551             ++i;
00552             serviceName = initialServiceName + "-" + QString::number(i);
00553         }
00554     }
00555     while (!ok);
00556     if ( !m_pService )
00557     {
00558         // Let's hide it to avoid cluttering the K menu.
00559         pathName = ".hidden/";
00560         pathName += serviceName;
00561     }
00562   }
00563   if ( m_pService )
00564   {
00565     // Existing service selected
00566     serviceName = m_pService->name();
00567     initialServiceName = serviceName;
00568     pathName = m_pService->desktopEntryPath();
00569   }
00570 
00571   if (terminal->isChecked()) {
00572     KSimpleConfig conf(QString::fromLatin1("konquerorrc"), true);
00573     conf.setGroup(QString::fromLatin1("Misc Defaults"));
00574     m_command = conf.readEntry(QString::fromLatin1("Terminal"), QString::fromLatin1("konsole"));
00575 
00576     m_command += QString::fromLatin1(" -e ");
00577     m_command += edit->url();
00578     kdDebug(250) << "Setting m_command to " << m_command << endl;
00579   }
00580   if ( m_pService && terminal->isChecked() != m_pService->terminal() )
00581       m_pService = 0L; // It's not exactly this service we're running
00582 
00583   if ( m_pService && ( !remember || !remember->isChecked() ) ) {
00584     accept();
00585     return;
00586   }
00587 
00588   // if we got here, we can't seem to find a service for what they
00589   // wanted.  The other possibility is that they have asked for the
00590   // association to be remembered.  Create/update service.
00591 
00592   kdDebug(250) << "service pathName=" << pathName << endl;
00593   if (pathName.right(8) != QString::fromLatin1(".desktop"))
00594     pathName += QString::fromLatin1(".desktop");
00595   QString path(locateLocal("apps", pathName));
00596 
00597   int maxPreference = 1;
00598   if (!qServiceType.isEmpty())
00599   {
00600     KServiceTypeProfile::OfferList offerList = KServiceTypeProfile::offers( qServiceType );
00601     if (!offerList.isEmpty())
00602       maxPreference = offerList.first().preference();
00603   }
00604 
00605   KDesktopFile desktop(path);
00606   desktop.writeEntry(QString::fromLatin1("Type"), QString::fromLatin1("Application"));
00607   desktop.writeEntry(QString::fromLatin1("Name"), initialServiceName);
00608   desktop.writeEntry(QString::fromLatin1("Exec"), fullExec);
00609   desktop.writeEntry(QString::fromLatin1("InitialPreference"), maxPreference + 1);
00610   if (remember)
00611     if (remember->isChecked()) {
00612       QStringList mimeList;
00613       KDesktopFile oldDesktop(locate("apps", pathName), true);
00614       mimeList = oldDesktop.readListEntry(QString::fromLatin1("MimeType"), ';');
00615       if (!qServiceType.isEmpty() && !mimeList.contains(qServiceType))
00616         mimeList.append(qServiceType);
00617       desktop.writeEntry(QString::fromLatin1("MimeType"), mimeList, ';');
00618       if (terminal->isChecked())
00619         desktop.writeEntry(QString::fromLatin1("Terminal"), true);
00620       else
00621         desktop.writeEntry(QString::fromLatin1("Terminal"), false);
00622 
00623       if ( !qServiceType.isEmpty() )
00624       {
00625         // Also make sure the "auto embed" setting for this mimetype is off
00626         KDesktopFile mimeDesktop( locateLocal( "mime", qServiceType + ".desktop" ) );
00627         mimeDesktop.writeEntry( QString::fromLatin1( "X-KDE-AutoEmbed" ), false );
00628         mimeDesktop.sync();
00629       }
00630     }
00631 
00632 
00633   // write it all out to the file
00634   desktop.sync();
00635 
00636   QApplication::setOverrideCursor( waitCursor );
00637 
00638   // rebuild the database
00639   QStringList args;
00640   args.append("--incremental");
00641   KApplication::kdeinitExecWait( "kbuildsycoca", args );
00642 
00643   // get the new service pointer
00644   kdDebug(250) << "kbuildsycoca finished, looking for service " << pathName << endl;
00645   // We need to read in the new database. It seems the databaseChanged()
00646   // signal hasn't been processed in this process yet, since we haven't been
00647   // to the event loop yet.
00648   QStringList lst;
00649   lst << QString::fromLatin1("apps");
00650   KSycoca::self()->notifyDatabaseChanged( lst );
00651 
00652   m_pService = KService::serviceByDesktopPath( pathName );
00653   QApplication::restoreOverrideCursor();
00654 
00655   Q_ASSERT( m_pService );
00656 
00657   accept();
00658 }
00659 
00660 QString KOpenWithDlg::text() const
00661 {
00662     if (!m_command.isEmpty())
00663         return m_command;
00664     else
00665         return edit->url();
00666 }
00667 
00668 void KOpenWithDlg::accept()
00669 {
00670     KHistoryCombo *combo = static_cast<KHistoryCombo*>( edit->comboBox() );
00671     if ( combo ) {
00672         combo->addToHistory( edit->url() );
00673 
00674         KConfig *kc = KGlobal::config();
00675         KConfigGroupSaver ks( kc, QString::fromLatin1("Open-with settings") );
00676         kc->writeEntry( QString::fromLatin1("History"), combo->historyItems() );
00677     kc->writeEntry(QString::fromLatin1("CompletionMode"),
00678                combo->completionMode());
00679         // don't store the completion-list, as it contains all of KURLCompletion's
00680         // executables
00681         kc->sync();
00682     }
00683 
00684     QDialog::accept();
00685 }
00686 
00687 
00689 
00690 #ifndef KDE_NO_COMPAT
00691 bool KFileOpenWithHandler::displayOpenWithDialog( const KURL::List& urls )
00692 {
00693     KOpenWithDlg l( urls, i18n("Open with:"), QString::null, 0L );
00694     if ( l.exec() )
00695     {
00696       KService::Ptr service = l.service();
00697       if ( !!service )
00698         return KRun::run( *service, urls );
00699 
00700       kdDebug(250) << "No service set, running " << l.text() << endl;
00701       return KRun::run( l.text(), urls );
00702     }
00703     return false;
00704 }
00705 #endif
00706 
00707 #include "kopenwith.moc"
00708 #include "kopenwith_p.moc"
00709 
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.0.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Oct 8 12:21:31 2003 by doxygen 1.2.18 written by Dimitri van Heesch, © 1997-2001