00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <qfile.h>
00024 #include <qdir.h>
00025 #include <qdialog.h>
00026 #include <qimage.h>
00027 #include <qpixmap.h>
00028 #include <qlabel.h>
00029 #include <qlayout.h>
00030 #include <qpushbutton.h>
00031 #include <qtoolbutton.h>
00032 #include <qcheckbox.h>
00033 #include <qtooltip.h>
00034 #include <qstyle.h>
00035 #include <qwhatsthis.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 #include <kstdguiitem.h>
00059
00060 #include "kopenwith.h"
00061 #include "kopenwith_p.h"
00062
00063 #include <kdebug.h>
00064 #include <assert.h>
00065 #include <stdlib.h>
00066
00067 template class QPtrList<QString>;
00068
00069 #define SORT_SPEC (QDir::DirsFirst | QDir::Name | QDir::IgnoreCase)
00070
00071
00072
00073
00074 KAppTreeListItem::KAppTreeListItem( KListView* parent, const QString & name,
00075 const QPixmap& pixmap, bool parse, bool dir, const QString &p, const QString &c )
00076 : QListViewItem( parent, name )
00077 {
00078 init(pixmap, parse, dir, p, c);
00079 }
00080
00081
00082
00083
00084 KAppTreeListItem::KAppTreeListItem( QListViewItem* parent, const QString & name,
00085 const QPixmap& pixmap, bool parse, bool dir, const QString &p, const QString &c )
00086 : QListViewItem( parent, name )
00087 {
00088 init(pixmap, parse, dir, p, c);
00089 }
00090
00091
00092
00093
00094 void KAppTreeListItem::init(const QPixmap& pixmap, bool parse, bool dir, const QString &_path, const QString &_exec)
00095 {
00096 setPixmap(0, pixmap);
00097 parsed = parse;
00098 directory = dir;
00099 path = _path;
00100 exec = _exec;
00101 }
00102
00103
00104
00105 int KAppTreeListItem::compare(QListViewItem *i, int col, bool ascending) const
00106 {
00107 KAppTreeListItem *other = dynamic_cast<KAppTreeListItem *>(i);
00108
00109
00110 if (directory && !other->directory)
00111 return -1;
00112
00113 else if (!directory && other->directory)
00114 return 1;
00115
00116 else
00117 return QListViewItem::compare(i, col, ascending);
00118 }
00119
00120
00121
00122 QString KAppTreeListItem::key(int column, bool ) const
00123 {
00124 return text(column).upper();
00125 }
00126
00127 void KAppTreeListItem::activate()
00128 {
00129 if ( directory )
00130 setOpen(!isOpen());
00131 }
00132
00133 void KAppTreeListItem::setOpen( bool o )
00134 {
00135 if( o && !parsed ) {
00136 ((KApplicationTree *) parent())->addDesktopGroup( path, this );
00137 parsed = true;
00138 }
00139 QListViewItem::setOpen( o );
00140 }
00141
00142 bool KAppTreeListItem::isDirectory()
00143 {
00144 return directory;
00145 }
00146
00147
00148
00149 KApplicationTree::KApplicationTree( QWidget *parent )
00150 : KListView( parent ), currentitem(0)
00151 {
00152 addColumn( i18n("Known Applications") );
00153 setRootIsDecorated( true );
00154
00155 addDesktopGroup( QString::null );
00156 cleanupTree();
00157
00158 connect( this, SIGNAL( currentChanged(QListViewItem*) ),
00159 SLOT( slotItemHighlighted(QListViewItem*) ) );
00160 connect( this, SIGNAL( selectionChanged(QListViewItem*) ),
00161 SLOT( slotSelectionChanged(QListViewItem*) ) );
00162 }
00163
00164
00165
00166 bool KApplicationTree::isDirSel()
00167 {
00168 if (!currentitem) return false;
00169 return currentitem->isDirectory();
00170 }
00171
00172
00173
00174 static QPixmap appIcon(const QString &iconName)
00175 {
00176 QPixmap normal = KGlobal::iconLoader()->loadIcon(iconName, KIcon::Small, 0, KIcon::DefaultState, 0L, true);
00177
00178 if (normal.width() > 20 || normal.height() > 20)
00179 {
00180 QImage tmp = normal.convertToImage();
00181 tmp = tmp.smoothScale(20, 20);
00182 normal.convertFromImage(tmp);
00183 }
00184 return normal;
00185 }
00186
00187 void KApplicationTree::addDesktopGroup( const QString &relPath, KAppTreeListItem *item)
00188 {
00189 KServiceGroup::Ptr root = KServiceGroup::group(relPath);
00190 KServiceGroup::List list = root->entries();
00191
00192 KAppTreeListItem * newItem;
00193 for( KServiceGroup::List::ConstIterator it = list.begin();
00194 it != list.end(); it++)
00195 {
00196 QString icon;
00197 QString text;
00198 QString relPath;
00199 QString exec;
00200 bool isDir = false;
00201 KSycocaEntry *p = (*it);
00202 if (p->isType(KST_KService))
00203 {
00204 KService *service = static_cast<KService *>(p);
00205
00206 if (service->noDisplay())
00207 continue;
00208
00209 icon = service->icon();
00210 text = service->name();
00211 exec = service->exec();
00212 }
00213 else if (p->isType(KST_KServiceGroup))
00214 {
00215 KServiceGroup *serviceGroup = static_cast<KServiceGroup *>(p);
00216
00217 if (serviceGroup->noDisplay())
00218 continue;
00219
00220 icon = serviceGroup->icon();
00221 text = serviceGroup->caption();
00222 relPath = serviceGroup->relPath();
00223 isDir = true;
00224
00225
00226 }
00227 else
00228 {
00229 kdWarning(250) << "KServiceGroup: Unexpected object in list!" << endl;
00230 continue;
00231 }
00232
00233 QPixmap pixmap = appIcon( icon );
00234
00235 if (item)
00236 newItem = new KAppTreeListItem( item, text, pixmap, false, isDir,
00237 relPath, exec );
00238 else
00239 newItem = new KAppTreeListItem( this, text, pixmap, false, isDir,
00240 relPath, exec );
00241 if (isDir)
00242 newItem->setExpandable( true );
00243 }
00244 }
00245
00246
00247
00248
00249 void KApplicationTree::slotItemHighlighted(QListViewItem* i)
00250 {
00251
00252 if(!i)
00253 return;
00254
00255 KAppTreeListItem *item = (KAppTreeListItem *) i;
00256
00257 currentitem = item;
00258
00259 if( (!item->directory ) && (!item->exec.isEmpty()) )
00260 emit highlighted( item->text(0), item->exec );
00261 }
00262
00263
00264
00265
00266 void KApplicationTree::slotSelectionChanged(QListViewItem* i)
00267 {
00268
00269 if(!i)
00270 return;
00271
00272 KAppTreeListItem *item = (KAppTreeListItem *) i;
00273
00274 currentitem = item;
00275
00276 if( ( !item->directory ) && (!item->exec.isEmpty() ) )
00277 emit selected( item->text(0), item->exec );
00278 }
00279
00280
00281
00282 void KApplicationTree::resizeEvent( QResizeEvent * e)
00283 {
00284 setColumnWidth(0, width()-QApplication::style().pixelMetric(QStyle::PM_ScrollBarExtent)
00285 -2*QApplication::style().pixelMetric(QStyle::PM_DefaultFrameWidth));
00286 KListView::resizeEvent(e);
00287 }
00288
00289
00290 void KApplicationTree::cleanupTree()
00291 {
00292 QListViewItem *item=firstChild();
00293 while(item!=0)
00294 {
00295 if(item->isExpandable())
00296 {
00297 item->setOpen(true);
00298 if(item->childCount()==0) {
00299 QListViewItem *current=item;
00300 item=item->itemBelow();
00301 delete current;
00302 continue;
00303 }
00304 item=item->itemBelow();
00305 continue;
00306 }
00307 item=item->itemBelow();
00308 }
00309 item=firstChild();
00310 while(item!=0)
00311 {
00312 if(item->isExpandable())
00313 {
00314 QListViewItem *temp=item->itemBelow();
00315 if(item->text(0)!=i18n("Applications"))
00316 item->setOpen(false);
00317 item=temp;
00318 continue;
00319 }
00320 item=item->itemBelow();
00321 }
00322 }
00323
00324
00325
00326
00327
00328
00329 class KOpenWithDlgPrivate
00330 {
00331 public:
00332 KOpenWithDlgPrivate() : saveNewApps(false) { };
00333 QPushButton* ok;
00334 bool saveNewApps;
00335 KService::Ptr curService;
00336 };
00337
00338 KOpenWithDlg::KOpenWithDlg( const KURL::List& _urls, QWidget* parent )
00339 :QDialog( parent, "openwith", true )
00340 {
00341 setCaption( i18n( "Open With" ) );
00342 QString text;
00343 if( _urls.count() == 1 )
00344 {
00345 text = i18n("<qt>Select the program that should be used to open <b>%1</b>. "
00346 "If the program is not listed, enter the name or click "
00347 "the browse button.</qt>").arg( _urls.first().fileName() );
00348 }
00349 else
00350
00351 text = i18n( "Choose the name of the program with which to open the selected files." );
00352 setServiceType( _urls );
00353 init( text, QString() );
00354 }
00355
00356 KOpenWithDlg::KOpenWithDlg( const KURL::List& _urls, const QString&_text,
00357 const QString& _value, QWidget *parent)
00358 :QDialog( parent, "openwith", true )
00359 {
00360 QString caption = KStringHandler::csqueeze( _urls.first().prettyURL() );
00361 if (_urls.count() > 1)
00362 caption += QString::fromLatin1("...");
00363 setCaption(caption);
00364 setServiceType( _urls );
00365 init( _text, _value );
00366 }
00367
00368 KOpenWithDlg::KOpenWithDlg( const QString &serviceType, const QString& value,
00369 QWidget *parent)
00370 :QDialog( parent, "openwith", true )
00371 {
00372 setCaption(i18n("Choose Application for %1").arg(serviceType));
00373 QString text = i18n("<qt>Select the program for the file type: <b>%1</b>. "
00374 "If the program is not listed, enter the name or click "
00375 "the browse button.</qt>").arg(serviceType);
00376 qServiceType = serviceType;
00377 init( text, value );
00378 if (remember)
00379 remember->hide();
00380 }
00381
00382 KOpenWithDlg::KOpenWithDlg( QWidget *parent)
00383 :QDialog( parent, "openwith", true )
00384 {
00385 setCaption(i18n("Choose Application"));
00386 QString text = i18n("<qt>Select a program. "
00387 "If the program is not listed, enter the name or click "
00388 "the browse button.</qt>");
00389 qServiceType = QString::null;
00390 init( text, QString::null );
00391 }
00392
00393 void KOpenWithDlg::setServiceType( const KURL::List& _urls )
00394 {
00395 if ( _urls.count() == 1 )
00396 {
00397 qServiceType = KMimeType::findByURL( _urls.first())->name();
00398 if (qServiceType == QString::fromLatin1("application/octet-stream"))
00399 qServiceType = QString::null;
00400 }
00401 else
00402 qServiceType = QString::null;
00403 }
00404
00405 void KOpenWithDlg::init( const QString& _text, const QString& _value )
00406 {
00407 d = new KOpenWithDlgPrivate;
00408 bool bReadOnly = kapp && !kapp->authorize("shell_access");
00409 m_terminaldirty = false;
00410 m_pTree = 0L;
00411 m_pService = 0L;
00412 d->curService = 0L;
00413
00414 QBoxLayout *topLayout = new QVBoxLayout( this, KDialog::marginHint(),
00415 KDialog::spacingHint() );
00416 label = new QLabel( _text, this );
00417 topLayout->addWidget(label);
00418
00419 QHBoxLayout* hbox = new QHBoxLayout(topLayout);
00420
00421 QToolButton *clearButton = new QToolButton( this );
00422 clearButton->setIconSet( BarIcon( "locationbar_erase" ) );
00423 clearButton->setFixedSize( clearButton->sizeHint() );
00424 connect( clearButton, SIGNAL( clicked() ), SLOT( slotClear() ) );
00425 QToolTip::add( clearButton, i18n( "Clear input field" ) );
00426
00427 hbox->addWidget( clearButton );
00428
00429 if (!bReadOnly)
00430 {
00431
00432 KHistoryCombo *combo = new KHistoryCombo();
00433 combo->setDuplicatesEnabled( false );
00434 KConfig *kc = KGlobal::config();
00435 KConfigGroupSaver ks( kc, QString::fromLatin1("Open-with settings") );
00436 int max = kc->readNumEntry( QString::fromLatin1("Maximum history"), 15 );
00437 combo->setMaxCount( max );
00438 int mode = kc->readNumEntry(QString::fromLatin1("CompletionMode"),
00439 KGlobalSettings::completionMode());
00440 combo->setCompletionMode((KGlobalSettings::Completion)mode);
00441 QStringList list = kc->readListEntry( QString::fromLatin1("History") );
00442 combo->setHistoryItems( list, true );
00443 edit = new KURLRequester( combo, this );
00444 }
00445 else
00446 {
00447 clearButton->hide();
00448 edit = new KURLRequester( this );
00449 edit->lineEdit()->setReadOnly(true);
00450 edit->button()->hide();
00451 }
00452
00453 edit->setURL( _value );
00454 QWhatsThis::add(edit,i18n(
00455 "Following the command, you can have several place holders which will be replaced "
00456 "with the actual values when the actual program is run:\n"
00457 "%f - a single file name\n"
00458 "%F - a list of files; use for applications that can open several local files at once\n"
00459 "%u - a single URL\n"
00460 "%U - a list of URLs\n"
00461 "%d - the directory of the file to open\n"
00462 "%D - a list of directories\n"
00463 "%i - the icon\n"
00464 "%m - the mini-icon\n"
00465 "%c - the comment"));
00466
00467 hbox->addWidget(edit);
00468
00469 if ( edit->comboBox() ) {
00470 KURLCompletion *comp = new KURLCompletion( KURLCompletion::ExeCompletion );
00471 edit->comboBox()->setCompletionObject( comp );
00472 edit->comboBox()->setAutoDeleteCompletionObject( true );
00473 }
00474
00475 connect ( edit, SIGNAL(returnPressed()), SLOT(slotOK()) );
00476 connect ( edit, SIGNAL(textChanged(const QString&)), SLOT(slotTextChanged()) );
00477
00478 m_pTree = new KApplicationTree( this );
00479 topLayout->addWidget(m_pTree);
00480
00481 connect( m_pTree, SIGNAL( selected( const QString&, const QString& ) ),
00482 SLOT( slotSelected( const QString&, const QString& ) ) );
00483 connect( m_pTree, SIGNAL( highlighted( const QString&, const QString& ) ),
00484 SLOT( slotHighlighted( const QString&, const QString& ) ) );
00485 connect( m_pTree, SIGNAL( doubleClicked(QListViewItem*) ),
00486 SLOT( slotDbClick() ) );
00487
00488 terminal = new QCheckBox( i18n("Run in &terminal"), this );
00489 if (bReadOnly)
00490 terminal->hide();
00491 connect(terminal, SIGNAL(toggled(bool)), SLOT(slotTerminalToggled(bool)));
00492
00493 topLayout->addWidget(terminal);
00494
00495 QBoxLayout* nocloseonexitLayout = new QHBoxLayout( 0, 0, KDialog::spacingHint() );
00496 QSpacerItem* spacer = new QSpacerItem( 20, 0, QSizePolicy::Fixed, QSizePolicy::Minimum );
00497 nocloseonexitLayout->addItem( spacer );
00498
00499 nocloseonexit = new QCheckBox( i18n("&Do not close when command exits"), this );
00500 nocloseonexit->setChecked( false );
00501 nocloseonexit->setDisabled( true );
00502
00503
00504
00505 KConfigGroup confGroup( KGlobal::config(), QString::fromLatin1("General") );
00506 QString preferredTerminal = confGroup.readPathEntry("TerminalApplication", QString::fromLatin1("konsole"));
00507
00508 if (bReadOnly || preferredTerminal != "konsole")
00509 nocloseonexit->hide();
00510
00511 nocloseonexitLayout->addWidget( nocloseonexit );
00512 topLayout->addLayout( nocloseonexitLayout );
00513
00514 if (!qServiceType.isNull())
00515 {
00516 remember = new QCheckBox(i18n("&Remember application association for this type of file"), this);
00517
00518 topLayout->addWidget(remember);
00519 }
00520 else
00521 remember = 0L;
00522
00523
00524 KButtonBox* b = new KButtonBox( this );
00525 b->addStretch( 2 );
00526
00527 d->ok = b->addButton( KStdGuiItem::ok() );
00528 d->ok->setDefault( true );
00529 connect( d->ok, SIGNAL( clicked() ), SLOT( slotOK() ) );
00530
00531 QPushButton* cancel = b->addButton( KStdGuiItem::cancel() );
00532 connect( cancel, SIGNAL( clicked() ), SLOT( reject() ) );
00533
00534 b->layout();
00535 topLayout->addWidget( b );
00536
00537
00538
00539
00540
00541 edit->setFocus();
00542 slotTextChanged();
00543 }
00544
00545
00546
00547
00548 KOpenWithDlg::~KOpenWithDlg()
00549 {
00550 delete d;
00551 d = 0;
00552 }
00553
00554
00555
00556 void KOpenWithDlg::slotClear()
00557 {
00558 edit->setURL(QString::null);
00559 edit->setFocus();
00560 }
00561
00562
00563
00564
00565 void KOpenWithDlg::slotSelected( const QString& , const QString& _exec )
00566 {
00567 kdDebug(250)<<"KOpenWithDlg::slotSelected"<<endl;
00568 KService::Ptr pService = d->curService;
00569 edit->setURL( _exec );
00570 d->curService = pService;
00571 }
00572
00573
00574
00575
00576 void KOpenWithDlg::slotHighlighted( const QString& _name, const QString& )
00577 {
00578 kdDebug(250)<<"KOpenWithDlg::slotHighlighted"<<endl;
00579 qName = _name;
00580 d->curService = KService::serviceByName( qName );
00581 if (!m_terminaldirty)
00582 {
00583
00584 terminal->setChecked(d->curService->terminal());
00585 QString terminalOptions = d->curService->terminalOptions();
00586 nocloseonexit->setChecked( (terminalOptions.contains( "--noclose" ) > 0) );
00587 m_terminaldirty = false;
00588 }
00589 }
00590
00591
00592
00593 void KOpenWithDlg::slotTextChanged()
00594 {
00595 kdDebug(250)<<"KOpenWithDlg::slotTextChanged"<<endl;
00596
00597 d->curService = 0L;
00598 d->ok->setEnabled( !edit->url().isEmpty());
00599 }
00600
00601
00602
00603 void KOpenWithDlg::slotTerminalToggled(bool)
00604 {
00605
00606 m_terminaldirty = true;
00607 nocloseonexit->setDisabled( ! terminal->isChecked() );
00608 }
00609
00610
00611
00612 void KOpenWithDlg::slotDbClick()
00613 {
00614 if (m_pTree->isDirSel() ) return;
00615 slotOK();
00616 }
00617
00618 void KOpenWithDlg::setSaveNewApplications(bool b)
00619 {
00620 d->saveNewApps = b;
00621 }
00622
00623 void KOpenWithDlg::slotOK()
00624 {
00625 QString fullExec(edit->url());
00626
00627 QString serviceName;
00628 QString initialServiceName;
00629 QString preferredTerminal;
00630 m_pService = d->curService;
00631 if (!m_pService) {
00632
00633
00634
00635 serviceName = KRun::binaryName( fullExec, true );
00636 if (serviceName.isEmpty())
00637 {
00638
00639 return;
00640 }
00641 initialServiceName = serviceName;
00642 kdDebug(250) << "initialServiceName=" << initialServiceName << endl;
00643 int i = 1;
00644 bool ok = false;
00645
00646 do {
00647 kdDebug(250) << "looking for service " << serviceName << endl;
00648 KService::Ptr serv = KService::serviceByDesktopName( serviceName );
00649 ok = !serv;
00650
00651 if ( serv && serv->type() == "Application")
00652 {
00653 QString exec = serv->exec();
00654 exec.replace("%u", "", false);
00655 exec.replace("%f", "", false);
00656 exec.replace("-caption %c", "");
00657 exec.replace("-caption \"%c\"", "");
00658 exec.replace("%i", "");
00659 exec.replace("%m", "");
00660 exec = exec.simplifyWhiteSpace();
00661 if (exec == fullExec)
00662 {
00663 ok = true;
00664 m_pService = serv;
00665 kdDebug(250) << k_funcinfo << "OK, found identical service: " << serv->desktopEntryPath() << endl;
00666 }
00667 }
00668 if (!ok)
00669 {
00670 ++i;
00671 serviceName = initialServiceName + "-" + QString::number(i);
00672 }
00673 }
00674 while (!ok);
00675 }
00676 if ( m_pService )
00677 {
00678
00679 serviceName = m_pService->name();
00680 initialServiceName = serviceName;
00681 }
00682
00683 if (terminal->isChecked())
00684 {
00685 KConfigGroup confGroup( KGlobal::config(), QString::fromLatin1("General") );
00686 preferredTerminal = confGroup.readPathEntry("TerminalApplication", QString::fromLatin1("konsole"));
00687 m_command = preferredTerminal;
00688
00689 if (preferredTerminal == "konsole" && nocloseonexit->isChecked())
00690 m_command += QString::fromLatin1(" --noclose");
00691 m_command += QString::fromLatin1(" -e ");
00692 m_command += edit->url();
00693 kdDebug(250) << "Setting m_command to " << m_command << endl;
00694 }
00695 if ( m_pService && terminal->isChecked() != m_pService->terminal() )
00696 m_pService = 0L;
00697
00698 bool bRemember = remember && remember->isChecked();
00699
00700 if ( !bRemember && m_pService)
00701 {
00702 accept();
00703 return;
00704 }
00705
00706 if (!bRemember && !d->saveNewApps)
00707 {
00708
00709 m_pService = new KService(initialServiceName, fullExec, QString::null);
00710 if (terminal->isChecked())
00711 {
00712 m_pService->setTerminal(true);
00713
00714 if (preferredTerminal == "konsole" && nocloseonexit->isChecked())
00715 m_pService->setTerminalOptions("--noclose");
00716 }
00717 accept();
00718 return;
00719 }
00720
00721
00722
00723
00724
00725 QString newPath;
00726 QString oldPath;
00727 QString menuId;
00728 if (m_pService)
00729 {
00730 oldPath = m_pService->desktopEntryPath();
00731 newPath = m_pService->locateLocal();
00732 menuId = m_pService->menuId();
00733 kdDebug(250) << "Updating exitsing service " << m_pService->desktopEntryPath() << " ( " << newPath << " ) " << endl;
00734 }
00735 else
00736 {
00737 newPath = KService::newServicePath(false , serviceName, &menuId);
00738 kdDebug(250) << "Creating new service " << serviceName << " ( " << newPath << " ) " << endl;
00739 }
00740
00741 int maxPreference = 1;
00742 if (!qServiceType.isEmpty())
00743 {
00744 KServiceTypeProfile::OfferList offerList = KServiceTypeProfile::offers( qServiceType );
00745 if (!offerList.isEmpty())
00746 maxPreference = offerList.first().preference();
00747 }
00748 QString menuElement;
00749 menuElement="?package(menu): needs=\"x11\" section=\".hidden\" ";
00750 KDesktopFile *desktop = 0;
00751 if (!oldPath.isEmpty() && (oldPath != newPath))
00752 {
00753 KDesktopFile orig(oldPath, true);
00754 if ( m_pService )
00755 desktop = orig.copyTo( pathToCopyEntry(newPath, m_pService->menuId() ) );
00756 else
00757 desktop = orig.copyTo(newPath);
00758 }
00759 else
00760 {
00761 if ( m_pService )
00762 desktop = new KDesktopFile(pathToCopyEntry(newPath, m_pService->menuId() ) );
00763 else
00764 desktop = new KDesktopFile(newPath);
00765 }
00766 desktop->writeEntry("Type", QString::fromLatin1("Application"));
00767 desktop->writeEntry("Name", initialServiceName);
00768 desktop->writePathEntry("Exec", fullExec);
00769 menuElement+="command=\"";
00770 menuElement+=fullExec+"\" ";
00771 menuElement+="title=\"";
00772 menuElement+=initialServiceName+"\" ";
00773 QString kdeOpt = "kde_opt=\"";
00774 if (terminal->isChecked())
00775 {
00776 desktop->writeEntry("Terminal", true);
00777 kdeOpt+="Terminal=1\\\\n";
00778
00779 if (preferredTerminal == "konsole" && nocloseonexit->isChecked())
00780 {
00781 desktop->writeEntry("TerminalOptions", "--noclose");
00782 kdeOpt+=" TerminalOptions=--noclose\\\\n";
00783 }
00784 }
00785 else
00786 {
00787 desktop->writeEntry("Terminal", false);
00788 }
00789 desktop->writeEntry("InitialPreference", maxPreference + 1);
00790 kdeOpt+=QString( "InitialPreference=%1\\\\n" ).arg( maxPreference + 1 );
00791
00792 if (bRemember || d->saveNewApps)
00793 {
00794 QStringList mimeList = desktop->readListEntry("MimeType", ';');
00795 if (!qServiceType.isEmpty() && !mimeList.contains(qServiceType))
00796 mimeList.append(qServiceType);
00797 desktop->writeEntry("MimeType", mimeList, ';');
00798 menuElement+=QString( "mimetypes=\"%1\"" ).arg( mimeList.join( ";") );
00799 if ( !qServiceType.isEmpty() )
00800 {
00801
00802 KDesktopFile mimeDesktop( locateLocal( "mime", qServiceType + ".desktop" ) );
00803 mimeDesktop.writeEntry( "X-KDE-AutoEmbed", false );
00804 mimeDesktop.sync();
00805 }
00806 }
00807
00808 if ( newPath.contains( "Mandrakelinux/.hidden" ) && ( KStandardDirs::menu_type_by_version()!="kde" ))
00809 {
00810 QStringList categorieList = desktop->readListEntry("Categories", ';');
00811 if ( !categorieList.contains("X-Mandrakelinux-.hidden"))
00812 categorieList.append("X-Mandrakelinux-.hidden");
00813 desktop->writeEntry( "Categories", categorieList, ";" );
00814
00815 menuElement+=" " +kdeOpt+"\"";
00816 saveInMDKMenuStructure( initialServiceName,menuElement );
00817 }
00818
00819 desktop->sync();
00820 delete desktop;
00821
00822 KService::rebuildKSycoca(this);
00823
00824 m_pService = KService::serviceByMenuId( menuId );
00825
00826 Q_ASSERT( m_pService );
00827
00828 accept();
00829 }
00830
00831 void KOpenWithDlg::saveInMDKMenuStructure( const QString & filename, const QString &menuElement )
00832 {
00833 QString menuPath;
00834 QString tmp =KStandardDirs::menu_type_by_version();
00835 if( tmp=="kde")
00836 return;
00837 else if ( tmp=="mdk" )
00838 {
00839 menuPath=".menu/";
00840 }
00841 else if ( tmp == "mdk-simplified" )
00842 {
00843 menuPath=".menu-simplified/";
00844 }
00845 else
00846 {
00847 kdDebug()<<" Error in type of menu\n";
00848 return;
00849 }
00850 QFile menuStamp(QDir::homeDirPath ()+"/.menu-updates.stamp");
00851 if( menuStamp.exists())
00852 menuStamp.remove();
00853 QDir dir;
00854 dir.mkdir( QDir::homeDirPath ()+"/"+menuPath );
00855 QFile saveMenuMDK( QDir::homeDirPath ()+"/"+menuPath+filename );
00856 if ( saveMenuMDK.open( IO_WriteOnly ) ) {
00857 QTextStream stream( &saveMenuMDK );
00858 stream<<menuElement<<"\n";
00859 saveMenuMDK.close();
00860 }
00861 }
00862
00863 QString KOpenWithDlg::pathToCopyEntry( QString path, QString menuId )
00864 {
00865 if( KStandardDirs::menu_type_by_version()=="kde")
00866 return path;
00867 QString tmpPath = path.remove( menuId );
00868 QString element;
00869 element = menuId.remove( "Mandrakelinux-" );
00870 element=element.replace( QChar( '-' ), "/" );
00871 QString newPath = tmpPath+"Mandrakelinux/"+element;
00872 KURL url(newPath);
00873 KStandardDirs::makeDir( url.directory() );
00874 return newPath;
00875 }
00876
00877 QString KOpenWithDlg::text() const
00878 {
00879 if (!m_command.isEmpty())
00880 return m_command;
00881 else
00882 return edit->url();
00883 }
00884
00885 void KOpenWithDlg::hideNoCloseOnExit()
00886 {
00887
00888 nocloseonexit->setChecked( false );
00889 nocloseonexit->hide();
00890 }
00891
00892 void KOpenWithDlg::hideRunInTerminal()
00893 {
00894 terminal->hide();
00895 hideNoCloseOnExit();
00896 }
00897
00898 void KOpenWithDlg::accept()
00899 {
00900 KHistoryCombo *combo = static_cast<KHistoryCombo*>( edit->comboBox() );
00901 if ( combo ) {
00902 combo->addToHistory( edit->url() );
00903
00904 KConfig *kc = KGlobal::config();
00905 KConfigGroupSaver ks( kc, QString::fromLatin1("Open-with settings") );
00906 kc->writeEntry( QString::fromLatin1("History"), combo->historyItems() );
00907 kc->writeEntry(QString::fromLatin1("CompletionMode"),
00908 combo->completionMode());
00909
00910
00911 kc->sync();
00912 }
00913
00914 QDialog::accept();
00915 }
00916
00917
00919
00920 #ifndef KDE_NO_COMPAT
00921 bool KFileOpenWithHandler::displayOpenWithDialog( const KURL::List& urls )
00922 {
00923 KOpenWithDlg l( urls, i18n("Open with:"), QString::null, 0L );
00924 if ( l.exec() )
00925 {
00926 KService::Ptr service = l.service();
00927 if ( !!service )
00928 return KRun::run( *service, urls );
00929
00930 kdDebug(250) << "No service set, running " << l.text() << endl;
00931 return KRun::run( l.text(), urls );
00932 }
00933 return false;
00934 }
00935 #endif
00936
00937 #include "kopenwith.moc"
00938 #include "kopenwith_p.moc"
00939