00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include <config.h>
00045 extern "C" {
00046 #include <pwd.h>
00047 #include <grp.h>
00048 #include <time.h>
00049 }
00050 #include <unistd.h>
00051 #include <errno.h>
00052 #include <assert.h>
00053
00054 #include <qfile.h>
00055 #include <qdir.h>
00056 #include <qlabel.h>
00057 #include <qpushbutton.h>
00058 #include <qcheckbox.h>
00059 #include <qstrlist.h>
00060 #include <qstringlist.h>
00061 #include <qtextstream.h>
00062 #include <qpainter.h>
00063 #include <qlayout.h>
00064 #include <qcombobox.h>
00065 #include <qgroupbox.h>
00066 #include <qwhatsthis.h>
00067 #include <qtooltip.h>
00068 #include <qstyle.h>
00069 #include <qprogressbar.h>
00070
00071 #include <kapplication.h>
00072 #include <kdialog.h>
00073 #include <kdirsize.h>
00074 #include <kdirwatch.h>
00075 #include <kdirnotify_stub.h>
00076 #include <kdiskfreesp.h>
00077 #include <kdebug.h>
00078 #include <kdesktopfile.h>
00079 #include <kicondialog.h>
00080 #include <kurl.h>
00081 #include <kurlrequester.h>
00082 #include <klocale.h>
00083 #include <kglobal.h>
00084 #include <kglobalsettings.h>
00085 #include <kstandarddirs.h>
00086 #include <kio/job.h>
00087 #include <kio/chmodjob.h>
00088 #include <kio/renamedlg.h>
00089 #include <kio/netaccess.h>
00090 #include <kio/kservicetypefactory.h>
00091 #include <kfiledialog.h>
00092 #include <kmimetype.h>
00093 #include <kmountpoint.h>
00094 #include <kiconloader.h>
00095 #include <kmessagebox.h>
00096 #include <kservice.h>
00097 #include <kcompletion.h>
00098 #include <klineedit.h>
00099 #include <kseparator.h>
00100 #include <ksqueezedtextlabel.h>
00101 #include <klibloader.h>
00102 #include <ktrader.h>
00103 #include <kparts/componentfactory.h>
00104 #include <kmetaprops.h>
00105 #include <kprocess.h>
00106 #include <krun.h>
00107 #include <klistview.h>
00108 #include "kfilesharedlg.h"
00109
00110 #include "kpropertiesdesktopbase.h"
00111 #include "kpropertiesdesktopadvbase.h"
00112 #include "kpropertiesmimetypebase.h"
00113
00114 #include "kpropertiesdialog.h"
00115
00116 #ifdef Q_WS_WIN
00117 # include <win32_utils.h>
00118 #endif
00119
00120 static QString nameFromFileName(QString nameStr)
00121 {
00122 if ( nameStr.endsWith(".desktop") )
00123 nameStr.truncate( nameStr.length() - 8 );
00124 if ( nameStr.endsWith(".kdelnk") )
00125 nameStr.truncate( nameStr.length() - 7 );
00126
00127 nameStr = KIO::decodeFileName( nameStr );
00128 return nameStr;
00129 }
00130
00131 mode_t KFilePermissionsPropsPlugin::fperm[3][4] = {
00132 {S_IRUSR, S_IWUSR, S_IXUSR, S_ISUID},
00133 {S_IRGRP, S_IWGRP, S_IXGRP, S_ISGID},
00134 {S_IROTH, S_IWOTH, S_IXOTH, S_ISVTX}
00135 };
00136
00137 class KPropertiesDialog::KPropertiesDialogPrivate
00138 {
00139 public:
00140 KPropertiesDialogPrivate()
00141 {
00142 m_aborted = false;
00143 fileSharePage = 0;
00144 }
00145 ~KPropertiesDialogPrivate()
00146 {
00147 }
00148 bool m_aborted:1;
00149 QWidget* fileSharePage;
00150 };
00151
00152 KPropertiesDialog::KPropertiesDialog (KFileItem* item,
00153 QWidget* parent, const char* name,
00154 bool modal, bool autoShow)
00155 : KDialogBase (KDialogBase::Tabbed, i18n( "Properties for %1" ).arg(KIO::decodeFileName(item->url().fileName())),
00156 KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok,
00157 parent, name, modal)
00158 {
00159 d = new KPropertiesDialogPrivate;
00160 assert( item );
00161 m_items.append( new KFileItem(*item) );
00162
00163 m_singleUrl = item->url();
00164 assert(!m_singleUrl.isEmpty());
00165
00166 init (modal, autoShow);
00167 }
00168
00169 KPropertiesDialog::KPropertiesDialog (const QString& title,
00170 QWidget* parent, const char* name, bool modal)
00171 : KDialogBase (KDialogBase::Tabbed, i18n ("Properties for %1").arg(title),
00172 KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok,
00173 parent, name, modal)
00174 {
00175 d = new KPropertiesDialogPrivate;
00176
00177 init (modal, false);
00178 }
00179
00180 KPropertiesDialog::KPropertiesDialog (KFileItemList _items,
00181 QWidget* parent, const char* name,
00182 bool modal, bool autoShow)
00183 : KDialogBase (KDialogBase::Tabbed,
00184
00185
00186 _items.count()>1 ? i18n( "<never used>","Properties for %n Selected Items",_items.count()) :
00187 i18n( "Properties for %1" ).arg(KIO::decodeFileName(_items.first()->url().fileName())),
00188 KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok,
00189 parent, name, modal)
00190 {
00191 d = new KPropertiesDialogPrivate;
00192
00193 assert( !_items.isEmpty() );
00194 m_singleUrl = _items.first()->url();
00195 assert(!m_singleUrl.isEmpty());
00196
00197 KFileItemListIterator it ( _items );
00198
00199 for ( ; it.current(); ++it )
00200 m_items.append( new KFileItem( **it ) );
00201
00202 init (modal, autoShow);
00203 }
00204
00205 #ifndef KDE_NO_COMPAT
00206 KPropertiesDialog::KPropertiesDialog (const KURL& _url, mode_t ,
00207 QWidget* parent, const char* name,
00208 bool modal, bool autoShow)
00209 : KDialogBase (KDialogBase::Tabbed,
00210 i18n( "Properties for %1" ).arg(KIO::decodeFileName(_url.fileName())),
00211 KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok,
00212 parent, name, modal),
00213 m_singleUrl( _url )
00214 {
00215 d = new KPropertiesDialogPrivate;
00216
00217 KIO::UDSEntry entry;
00218
00219 KIO::NetAccess::stat(_url, entry, parent);
00220
00221 m_items.append( new KFileItem( entry, _url ) );
00222 init (modal, autoShow);
00223 }
00224 #endif
00225
00226 KPropertiesDialog::KPropertiesDialog (const KURL& _url,
00227 QWidget* parent, const char* name,
00228 bool modal, bool autoShow)
00229 : KDialogBase (KDialogBase::Tabbed,
00230 i18n( "Properties for %1" ).arg(KIO::decodeFileName(_url.fileName())),
00231 KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok,
00232 parent, name, modal),
00233 m_singleUrl( _url )
00234 {
00235 d = new KPropertiesDialogPrivate;
00236
00237 KIO::UDSEntry entry;
00238
00239 KIO::NetAccess::stat(_url, entry, parent);
00240
00241 m_items.append( new KFileItem( entry, _url ) );
00242 init (modal, autoShow);
00243 }
00244
00245 KPropertiesDialog::KPropertiesDialog (const KURL& _tempUrl, const KURL& _currentDir,
00246 const QString& _defaultName,
00247 QWidget* parent, const char* name,
00248 bool modal, bool autoShow)
00249 : KDialogBase (KDialogBase::Tabbed,
00250 i18n( "Properties for %1" ).arg(KIO::decodeFileName(_tempUrl.fileName())),
00251 KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok,
00252 parent, name, modal),
00253
00254 m_singleUrl( _tempUrl ),
00255 m_defaultName( _defaultName ),
00256 m_currentDir( _currentDir )
00257 {
00258 d = new KPropertiesDialogPrivate;
00259
00260 assert(!m_singleUrl.isEmpty());
00261
00262
00263 m_items.append( new KFileItem( KFileItem::Unknown, KFileItem::Unknown, m_singleUrl ) );
00264 init (modal, autoShow);
00265 }
00266
00267 bool KPropertiesDialog::showDialog(KFileItem* item, QWidget* parent,
00268 const char* name, bool modal)
00269 {
00270 #ifdef Q_WS_WIN
00271 QString localPath = item->localPath();
00272 if (!localPath.isEmpty())
00273 return showWin32FilePropertyDialog(localPath);
00274 #endif
00275 new KPropertiesDialog(item, parent, name, modal);
00276 return true;
00277 }
00278
00279 bool KPropertiesDialog::showDialog(const KURL& _url, QWidget* parent,
00280 const char* name, bool modal)
00281 {
00282 #ifdef Q_WS_WIN
00283 if (_url.isLocalFile())
00284 return showWin32FilePropertyDialog( _url.path() );
00285 #endif
00286 new KPropertiesDialog(_url, parent, name, modal);
00287 return true;
00288 }
00289
00290 bool KPropertiesDialog::showDialog(const KFileItemList& _items, QWidget* parent,
00291 const char* name, bool modal)
00292 {
00293 if (_items.count()==1)
00294 return KPropertiesDialog::showDialog(_items.getFirst(), parent, name, modal);
00295 new KPropertiesDialog(_items, parent, name, modal);
00296 return true;
00297 }
00298
00299 void KPropertiesDialog::init (bool modal, bool autoShow)
00300 {
00301 m_pageList.setAutoDelete( true );
00302 m_items.setAutoDelete( true );
00303
00304 insertPages();
00305
00306 if (autoShow)
00307 {
00308 if (!modal)
00309 show();
00310 else
00311 exec();
00312 }
00313 }
00314
00315 void KPropertiesDialog::showFileSharingPage()
00316 {
00317 if (d->fileSharePage) {
00318 showPage( pageIndex( d->fileSharePage));
00319 }
00320 }
00321
00322 void KPropertiesDialog::setFileSharingPage(QWidget* page) {
00323 d->fileSharePage = page;
00324 }
00325
00326
00327 void KPropertiesDialog::setFileNameReadOnly( bool ro )
00328 {
00329 KPropsDlgPlugin *it;
00330
00331 for ( it=m_pageList.first(); it != 0L; it=m_pageList.next() )
00332 {
00333 KFilePropsPlugin* plugin = dynamic_cast<KFilePropsPlugin*>(it);
00334 if ( plugin ) {
00335 plugin->setFileNameReadOnly( ro );
00336 break;
00337 }
00338 }
00339 }
00340
00341 void KPropertiesDialog::slotStatResult( KIO::Job * )
00342 {
00343 }
00344
00345 KPropertiesDialog::~KPropertiesDialog()
00346 {
00347 m_pageList.clear();
00348 delete d;
00349 }
00350
00351 void KPropertiesDialog::insertPlugin (KPropsDlgPlugin* plugin)
00352 {
00353 connect (plugin, SIGNAL (changed ()),
00354 plugin, SLOT (setDirty ()));
00355
00356 m_pageList.append (plugin);
00357 }
00358
00359 bool KPropertiesDialog::canDisplay( KFileItemList _items )
00360 {
00361
00362 return KFilePropsPlugin::supports( _items ) ||
00363 KFilePermissionsPropsPlugin::supports( _items ) ||
00364 KDesktopPropsPlugin::supports( _items ) ||
00365 KBindingPropsPlugin::supports( _items ) ||
00366 KURLPropsPlugin::supports( _items ) ||
00367 KDevicePropsPlugin::supports( _items ) ||
00368 KFileMetaPropsPlugin::supports( _items );
00369 }
00370
00371 void KPropertiesDialog::slotOk()
00372 {
00373 KPropsDlgPlugin *page;
00374 d->m_aborted = false;
00375
00376 KFilePropsPlugin * filePropsPlugin = 0L;
00377 if ( m_pageList.first()->isA("KFilePropsPlugin") )
00378 filePropsPlugin = static_cast<KFilePropsPlugin *>(m_pageList.first());
00379
00380
00381
00382
00383 for ( page = m_pageList.first(); page != 0L; page = m_pageList.next() )
00384 if ( page->isDirty() && filePropsPlugin )
00385 {
00386 filePropsPlugin->setDirty();
00387 break;
00388 }
00389
00390
00391
00392
00393
00394 for ( page = m_pageList.first(); page != 0L && !d->m_aborted; page = m_pageList.next() )
00395 if ( page->isDirty() )
00396 {
00397 kdDebug( 250 ) << "applying changes for " << page->className() << endl;
00398 page->applyChanges();
00399
00400 }
00401 else
00402 kdDebug( 250 ) << "skipping page " << page->className() << endl;
00403
00404 if ( !d->m_aborted && filePropsPlugin )
00405 filePropsPlugin->postApplyChanges();
00406
00407 if ( !d->m_aborted )
00408 {
00409 emit applied();
00410 emit propertiesClosed();
00411 deleteLater();
00412 accept();
00413 }
00414 }
00415
00416 void KPropertiesDialog::slotCancel()
00417 {
00418 emit canceled();
00419 emit propertiesClosed();
00420
00421 deleteLater();
00422 done( Rejected );
00423 }
00424
00425 void KPropertiesDialog::insertPages()
00426 {
00427 if (m_items.isEmpty())
00428 return;
00429
00430 if ( KFilePropsPlugin::supports( m_items ) )
00431 {
00432 KPropsDlgPlugin *p = new KFilePropsPlugin( this );
00433 insertPlugin (p);
00434 }
00435
00436 if ( KFilePermissionsPropsPlugin::supports( m_items ) )
00437 {
00438 KPropsDlgPlugin *p = new KFilePermissionsPropsPlugin( this );
00439 insertPlugin (p);
00440 }
00441
00442 if ( KDesktopPropsPlugin::supports( m_items ) )
00443 {
00444 KPropsDlgPlugin *p = new KDesktopPropsPlugin( this );
00445 insertPlugin (p);
00446 }
00447
00448 if ( KBindingPropsPlugin::supports( m_items ) )
00449 {
00450 KPropsDlgPlugin *p = new KBindingPropsPlugin( this );
00451 insertPlugin (p);
00452 }
00453
00454 if ( KURLPropsPlugin::supports( m_items ) )
00455 {
00456 KPropsDlgPlugin *p = new KURLPropsPlugin( this );
00457 insertPlugin (p);
00458 }
00459
00460 if ( KDevicePropsPlugin::supports( m_items ) )
00461 {
00462 KPropsDlgPlugin *p = new KDevicePropsPlugin( this );
00463 insertPlugin (p);
00464 }
00465
00466 if ( KFileMetaPropsPlugin::supports( m_items ) )
00467 {
00468 KPropsDlgPlugin *p = new KFileMetaPropsPlugin( this );
00469 insertPlugin (p);
00470 }
00471
00472 if ( kapp->authorizeKAction("sharefile") &&
00473 KFileSharePropsPlugin::supports( m_items ) )
00474 {
00475 KPropsDlgPlugin *p = new KFileSharePropsPlugin( this );
00476 insertPlugin (p);
00477 }
00478
00479
00480
00481 if ( m_items.count() != 1 )
00482 return;
00483
00484 KFileItem *item = m_items.first();
00485 QString mimetype = item->mimetype();
00486
00487 if ( mimetype.isEmpty() )
00488 return;
00489
00490 QString query = QString::fromLatin1(
00491 "('KPropsDlg/Plugin' in ServiceTypes) and "
00492 "((not exist [X-KDE-Protocol]) or "
00493 " ([X-KDE-Protocol] == '%1' ) )" ).arg(item->url().protocol());
00494
00495 kdDebug( 250 ) << "trader query: " << query << endl;
00496 KTrader::OfferList offers = KTrader::self()->query( mimetype, query );
00497 KTrader::OfferList::ConstIterator it = offers.begin();
00498 KTrader::OfferList::ConstIterator end = offers.end();
00499 for (; it != end; ++it )
00500 {
00501 KPropsDlgPlugin *plugin = KParts::ComponentFactory
00502 ::createInstanceFromLibrary<KPropsDlgPlugin>( (*it)->library().local8Bit().data(),
00503 this,
00504 (*it)->name().latin1() );
00505 if ( !plugin )
00506 continue;
00507
00508 insertPlugin( plugin );
00509 }
00510 }
00511
00512 void KPropertiesDialog::updateUrl( const KURL& _newUrl )
00513 {
00514 Q_ASSERT( m_items.count() == 1 );
00515 kdDebug(250) << "KPropertiesDialog::updateUrl (pre)" << _newUrl.url() << endl;
00516 KURL newUrl = _newUrl;
00517 emit saveAs(m_singleUrl, newUrl);
00518 kdDebug(250) << "KPropertiesDialog::updateUrl (post)" << newUrl.url() << endl;
00519
00520 m_singleUrl = newUrl;
00521 m_items.first()->setURL( newUrl );
00522 assert(!m_singleUrl.isEmpty());
00523
00524
00525 for ( QPtrListIterator<KPropsDlgPlugin> it(m_pageList); it.current(); ++it )
00526 if ( it.current()->isA("KExecPropsPlugin") ||
00527 it.current()->isA("KURLPropsPlugin") ||
00528 it.current()->isA("KDesktopPropsPlugin"))
00529 {
00530
00531 it.current()->setDirty();
00532 break;
00533 }
00534 }
00535
00536 void KPropertiesDialog::rename( const QString& _name )
00537 {
00538 Q_ASSERT( m_items.count() == 1 );
00539 kdDebug(250) << "KPropertiesDialog::rename " << _name << endl;
00540 KURL newUrl;
00541
00542 if ( !m_currentDir.isEmpty() )
00543 {
00544 newUrl = m_currentDir;
00545 newUrl.addPath( _name );
00546 }
00547 else
00548 {
00549 QString tmpurl = m_singleUrl.url();
00550 if ( tmpurl.at(tmpurl.length() - 1) == '/')
00551
00552 tmpurl.truncate( tmpurl.length() - 1);
00553 newUrl = tmpurl;
00554 newUrl.setFileName( _name );
00555 }
00556 updateUrl( newUrl );
00557 }
00558
00559 void KPropertiesDialog::abortApplying()
00560 {
00561 d->m_aborted = true;
00562 }
00563
00564 class KPropsDlgPlugin::KPropsDlgPluginPrivate
00565 {
00566 public:
00567 KPropsDlgPluginPrivate()
00568 {
00569 }
00570 ~KPropsDlgPluginPrivate()
00571 {
00572 }
00573
00574 bool m_bDirty;
00575 };
00576
00577 KPropsDlgPlugin::KPropsDlgPlugin( KPropertiesDialog *_props )
00578 : QObject( _props, 0L )
00579 {
00580 d = new KPropsDlgPluginPrivate;
00581 properties = _props;
00582 fontHeight = 2*properties->fontMetrics().height();
00583 d->m_bDirty = false;
00584 }
00585
00586 KPropsDlgPlugin::~KPropsDlgPlugin()
00587 {
00588 delete d;
00589 }
00590
00591 bool KPropsDlgPlugin::isDesktopFile( KFileItem * _item )
00592 {
00593
00594 if ( !_item->isLocalFile() )
00595 return false;
00596
00597
00598 if ( !S_ISREG( _item->mode() ) )
00599 return false;
00600
00601 QString t( _item->url().path() );
00602
00603
00604 FILE *f = fopen( QFile::encodeName(t), "r" );
00605 if ( f == 0L )
00606 return false;
00607 fclose(f);
00608
00609
00610 return ( _item->mimetype() == "application/x-desktop" );
00611 }
00612
00613 void KPropsDlgPlugin::setDirty( bool b )
00614 {
00615 d->m_bDirty = b;
00616 }
00617
00618 void KPropsDlgPlugin::setDirty()
00619 {
00620 d->m_bDirty = true;
00621 }
00622
00623 bool KPropsDlgPlugin::isDirty() const
00624 {
00625 return d->m_bDirty;
00626 }
00627
00628 void KPropsDlgPlugin::applyChanges()
00629 {
00630 kdWarning(250) << "applyChanges() not implemented in page !" << endl;
00631 }
00632
00634
00635 class KFilePropsPlugin::KFilePropsPluginPrivate
00636 {
00637 public:
00638 KFilePropsPluginPrivate()
00639 {
00640 dirSizeJob = 0L;
00641 dirSizeUpdateTimer = 0L;
00642 m_lined = 0;
00643 }
00644 ~KFilePropsPluginPrivate()
00645 {
00646 if ( dirSizeJob )
00647 dirSizeJob->kill();
00648 }
00649
00650 KDirSize * dirSizeJob;
00651 QTimer *dirSizeUpdateTimer;
00652 QFrame *m_frame;
00653 bool bMultiple;
00654 bool bIconChanged;
00655 bool bKDesktopMode;
00656 bool bDesktopFile;
00657 QLabel *m_freeSpaceLabel;
00658 QString mimeType;
00659 QString oldFileName;
00660 KLineEdit* m_lined;
00661 };
00662
00663 KFilePropsPlugin::KFilePropsPlugin( KPropertiesDialog *_props )
00664 : KPropsDlgPlugin( _props )
00665 {
00666 d = new KFilePropsPluginPrivate;
00667 d->bMultiple = (properties->items().count() > 1);
00668 d->bIconChanged = false;
00669 d->bKDesktopMode = (QCString(qApp->name()) == "kdesktop");
00670 d->bDesktopFile = KDesktopPropsPlugin::supports(properties->items());
00671 kdDebug(250) << "KFilePropsPlugin::KFilePropsPlugin bMultiple=" << d->bMultiple << endl;
00672
00673
00674
00675 bool isLocal = properties->kurl().isLocalFile();
00676 KFileItem * item = properties->item();
00677 bool bDesktopFile = isDesktopFile(item);
00678 mode_t mode = item->mode();
00679 bool hasDirs = item->isDir() && !item->isLink();
00680 bool hasRoot = isLocal && properties->kurl().path() == QString::fromLatin1("/");
00681 QString iconStr = KMimeType::iconForURL(properties->kurl(), mode);
00682 QString directory = properties->kurl().directory();
00683 QString protocol = properties->kurl().protocol();
00684 QString mimeComment = item->mimeComment();
00685 d->mimeType = item->mimetype();
00686 KIO::filesize_t totalSize = item->size();
00687 QString magicMimeComment;
00688 if ( isLocal ) {
00689 KMimeType::Ptr magicMimeType = KMimeType::findByFileContent( properties->kurl().path() );
00690 if ( magicMimeType->name() != KMimeType::defaultMimeType() )
00691 magicMimeComment = magicMimeType->comment();
00692 }
00693
00694
00695 QString filename = QString::null;
00696 bool isTrash = false;
00697 bool isDevice = false;
00698 m_bFromTemplate = false;
00699
00700
00701 uint iDirCount = hasDirs ? 1 : 0;
00702 uint iFileCount = 1-iDirCount;
00703
00704 d->m_frame = properties->addPage (i18n("&General"));
00705
00706 QVBoxLayout *vbl = new QVBoxLayout( d->m_frame, 0,
00707 KDialog::spacingHint(), "vbl");
00708 QGridLayout *grid = new QGridLayout(0, 3);
00709 grid->setColStretch(0, 0);
00710 grid->setColStretch(1, 0);
00711 grid->setColStretch(2, 1);
00712 grid->addColSpacing(1, KDialog::spacingHint());
00713 vbl->addLayout(grid);
00714 int curRow = 0;
00715
00716 if ( !d->bMultiple )
00717 {
00718 QString path;
00719 if ( !m_bFromTemplate ) {
00720 isTrash = ( properties->kurl().protocol().find( "trash", 0, false)==0 );
00721 if ( properties->kurl().protocol().find("device", 0, false)==0)
00722 isDevice = true;
00723
00724 if ( isLocal )
00725 path = properties->kurl().path();
00726 else
00727 path = properties->kurl().prettyURL();
00728 } else {
00729 path = properties->currentDir().path(1) + properties->defaultName();
00730 directory = properties->currentDir().prettyURL();
00731 }
00732
00733 if (KExecPropsPlugin::supports(properties->items()) ||
00734 d->bDesktopFile ||
00735 KBindingPropsPlugin::supports(properties->items())) {
00736 determineRelativePath( path );
00737 }
00738
00739
00740 filename = properties->defaultName();
00741 if ( filename.isEmpty() ) {
00742 if ( isTrash || isDevice || hasRoot )
00743 filename = item->name();
00744 else
00745 filename = properties->kurl().fileName();
00746 } else {
00747 m_bFromTemplate = true;
00748 setDirty();
00749 }
00750 d->oldFileName = filename;
00751
00752
00753 filename = nameFromFileName( filename );
00754
00755 if ( d->bKDesktopMode && d->bDesktopFile ) {
00756 KDesktopFile config( properties->kurl().path(), true );
00757 if ( config.hasKey( "Name" ) ) {
00758 filename = config.readName();
00759 }
00760 }
00761
00762 oldName = filename;
00763 }
00764 else
00765 {
00766
00767 KFileItemList items = properties->items();
00768 KFileItemListIterator it( items );
00769 for ( ++it ; it.current(); ++it )
00770 {
00771 KURL url = (*it)->url();
00772 kdDebug(250) << "KFilePropsPlugin::KFilePropsPlugin " << url.prettyURL() << endl;
00773
00774
00775 if ( url.isLocalFile() != isLocal )
00776 isLocal = false;
00777 if ( bDesktopFile && isDesktopFile(*it) != bDesktopFile )
00778 bDesktopFile = false;
00779 if ( (*it)->mode() != mode )
00780 mode = (mode_t)0;
00781 if ( KMimeType::iconForURL(url, mode) != iconStr )
00782 iconStr = "kmultiple";
00783 if ( url.directory() != directory )
00784 directory = QString::null;
00785 if ( url.protocol() != protocol )
00786 protocol = QString::null;
00787 if ( !mimeComment.isNull() && (*it)->mimeComment() != mimeComment )
00788 mimeComment = QString::null;
00789 if ( isLocal && !magicMimeComment.isNull() ) {
00790 KMimeType::Ptr magicMimeType = KMimeType::findByFileContent( url.path() );
00791 if ( magicMimeType->comment() != magicMimeComment )
00792 magicMimeComment = QString::null;
00793 }
00794
00795 if ( isLocal && url.path() == QString::fromLatin1("/") )
00796 hasRoot = true;
00797 if ( (*it)->isDir() && !(*it)->isLink() )
00798 {
00799 iDirCount++;
00800 hasDirs = true;
00801 }
00802 else
00803 {
00804 iFileCount++;
00805 totalSize += (*it)->size();
00806 }
00807 }
00808 }
00809
00810 if (!isLocal && !protocol.isEmpty())
00811 {
00812 directory += ' ';
00813 directory += '(';
00814 directory += protocol;
00815 directory += ')';
00816 }
00817
00818 if ( !isDevice && !isTrash && (bDesktopFile || S_ISDIR(mode)) && !d->bMultiple )
00819 {
00820 KIconButton *iconButton = new KIconButton( d->m_frame );
00821 int bsize = 66 + 2 * iconButton->style().pixelMetric(QStyle::PM_ButtonMargin);
00822 iconButton->setFixedSize(bsize, bsize);
00823 iconButton->setIconSize(48);
00824 iconButton->setStrictIconSize(false);
00825
00826
00827 QString iconStr = KMimeType::findByURL( properties->kurl(),
00828 mode )->icon( properties->kurl(),
00829 isLocal );
00830 if ( bDesktopFile && isLocal )
00831 {
00832 KDesktopFile config( properties->kurl().path(), true );
00833 config.setDesktopGroup();
00834 iconStr = config.readEntry( "Icon" );
00835 if ( config.hasDeviceType() )
00836 iconButton->setIconType( KIcon::Desktop, KIcon::Device );
00837 else
00838 iconButton->setIconType( KIcon::Desktop, KIcon::Application );
00839 } else
00840 iconButton->setIconType( KIcon::Desktop, KIcon::FileSystem );
00841 iconButton->setIcon(iconStr);
00842 iconArea = iconButton;
00843 connect( iconButton, SIGNAL( iconChanged(QString) ),
00844 this, SLOT( slotIconChanged() ) );
00845 } else {
00846 QLabel *iconLabel = new QLabel( d->m_frame );
00847 int bsize = 66 + 2 * iconLabel->style().pixelMetric(QStyle::PM_ButtonMargin);
00848 iconLabel->setFixedSize(bsize, bsize);
00849 iconLabel->setPixmap( KGlobal::iconLoader()->loadIcon( iconStr, KIcon::Desktop, 48) );
00850 iconArea = iconLabel;
00851 }
00852 grid->addWidget(iconArea, curRow, 0, AlignLeft);
00853
00854 if (d->bMultiple || isTrash || isDevice || hasRoot)
00855 {
00856 QLabel *lab = new QLabel(d->m_frame );
00857 if ( d->bMultiple )
00858 lab->setText( KIO::itemsSummaryString( iFileCount + iDirCount, iFileCount, iDirCount, 0, false ) );
00859 else
00860 lab->setText( filename );
00861 nameArea = lab;
00862 } else
00863 {
00864 d->m_lined = new KLineEdit( d->m_frame );
00865 d->m_lined->setText(filename);
00866 nameArea = d->m_lined;
00867 d->m_lined->setFocus();
00868
00869
00870 QString pattern;
00871 KServiceTypeFactory::self()->findFromPattern( filename, &pattern );
00872 if (!pattern.isEmpty() && pattern.at(0)=='*' && pattern.find('*',1)==-1)
00873 d->m_lined->setSelection(0, filename.length()-pattern.stripWhiteSpace().length()+1);
00874 else
00875 {
00876 int lastDot = filename.findRev('.');
00877 if (lastDot > 0)
00878 d->m_lined->setSelection(0, lastDot);
00879 }
00880
00881 connect( d->m_lined, SIGNAL( textChanged( const QString & ) ),
00882 this, SLOT( nameFileChanged(const QString & ) ) );
00883 }
00884
00885 grid->addWidget(nameArea, curRow++, 2);
00886
00887 KSeparator* sep = new KSeparator( KSeparator::HLine, d->m_frame);
00888 grid->addMultiCellWidget(sep, curRow, curRow, 0, 2);
00889 ++curRow;
00890
00891 QLabel *l;
00892 if ( !mimeComment.isEmpty() && !isDevice && !isTrash)
00893 {
00894 l = new QLabel(i18n("Type:"), d->m_frame );
00895
00896 grid->addWidget(l, curRow, 0);
00897
00898 QHBox *box = new QHBox(d->m_frame);
00899 box->setSpacing(20);
00900 l = new QLabel(mimeComment, box );
00901
00902 #ifdef Q_WS_X11
00903
00904 QPushButton *button = new QPushButton(box);
00905
00906 QIconSet iconSet = SmallIconSet(QString::fromLatin1("configure"));
00907 QPixmap pixMap = iconSet.pixmap( QIconSet::Small, QIconSet::Normal );
00908 button->setIconSet( iconSet );
00909 button->setFixedSize( pixMap.width()+8, pixMap.height()+8 );
00910 QToolTip::add(button, i18n("Edit file type"));
00911
00912 connect( button, SIGNAL( clicked() ), SLOT( slotEditFileType() ));
00913
00914 if (!kapp->authorizeKAction("editfiletype"))
00915 button->hide();
00916 #endif
00917
00918 grid->addWidget(box, curRow++, 2);
00919 }
00920
00921 if ( !magicMimeComment.isEmpty() && magicMimeComment != mimeComment )
00922 {
00923 l = new QLabel(i18n("Contents:"), d->m_frame );
00924 grid->addWidget(l, curRow, 0);
00925
00926 l = new QLabel(magicMimeComment, d->m_frame );
00927 grid->addWidget(l, curRow++, 2);
00928 }
00929
00930 if ( !directory.isEmpty() )
00931 {
00932 l = new QLabel( i18n("Location:"), d->m_frame );
00933 grid->addWidget(l, curRow, 0);
00934
00935 l = new KSqueezedTextLabel( d->m_frame );
00936 l->setText( directory );
00937 grid->addWidget(l, curRow++, 2);
00938 }
00939
00940 l = new QLabel(i18n("Size:"), d->m_frame );
00941 grid->addWidget(l, curRow, 0);
00942
00943 m_sizeLabel = new QLabel( d->m_frame );
00944 grid->addWidget( m_sizeLabel, curRow++, 2 );
00945
00946 if ( !hasDirs )
00947 {
00948 m_sizeLabel->setText(QString::fromLatin1("%1 (%2)").arg(KIO::convertSize(totalSize))
00949 .arg(KGlobal::locale()->formatNumber(totalSize, 0)));
00950 m_sizeDetermineButton = 0L;
00951 m_sizeStopButton = 0L;
00952 }
00953 else
00954 {
00955 QHBoxLayout * sizelay = new QHBoxLayout(KDialog::spacingHint());
00956 grid->addLayout( sizelay, curRow++, 2 );
00957
00958
00959 m_sizeDetermineButton = new QPushButton( i18n("Calculate"), d->m_frame );
00960 m_sizeStopButton = new QPushButton( i18n("Stop"), d->m_frame );
00961 connect( m_sizeDetermineButton, SIGNAL( clicked() ), this, SLOT( slotSizeDetermine() ) );
00962 connect( m_sizeStopButton, SIGNAL( clicked() ), this, SLOT( slotSizeStop() ) );
00963 sizelay->addWidget(m_sizeDetermineButton, 0);
00964 sizelay->addWidget(m_sizeStopButton, 0);
00965 sizelay->addStretch(10);
00966
00967
00968 if ( isLocal && !hasRoot )
00969 {
00970 m_sizeDetermineButton->setText( i18n("Refresh") );
00971 slotSizeDetermine();
00972 }
00973 else
00974 m_sizeStopButton->setEnabled( false );
00975 }
00976
00977 if (!d->bMultiple && item->isLink()) {
00978 l = new QLabel(i18n("Points to:"), d->m_frame );
00979 grid->addWidget(l, curRow, 0);
00980
00981 l = new KSqueezedTextLabel(item->linkDest(), d->m_frame );
00982 grid->addWidget(l, curRow++, 2);
00983 }
00984
00985 if (!d->bMultiple)
00986 {
00987 QDateTime dt;
00988 time_t tim = item->time(KIO::UDS_CREATION_TIME);
00989 if ( tim )
00990 {
00991 l = new QLabel(i18n("Created:"), d->m_frame );
00992 grid->addWidget(l, curRow, 0);
00993
00994 dt.setTime_t( tim );
00995 l = new QLabel(KGlobal::locale()->formatDateTime(dt), d->m_frame );
00996 grid->addWidget(l, curRow++, 2);
00997 }
00998
00999 tim = item->time(KIO::UDS_MODIFICATION_TIME);
01000 if ( tim )
01001 {
01002 l = new QLabel(i18n("Modified:"), d->m_frame );
01003 grid->addWidget(l, curRow, 0);
01004
01005 dt.setTime_t( tim );
01006 l = new QLabel(KGlobal::locale()->formatDateTime(dt), d->m_frame );
01007 grid->addWidget(l, curRow++, 2);
01008 }
01009
01010 tim = item->time(KIO::UDS_ACCESS_TIME);
01011 if ( tim )
01012 {
01013 l = new QLabel(i18n("Accessed:"), d->m_frame );
01014 grid->addWidget(l, curRow, 0);
01015
01016 dt.setTime_t( tim );
01017 l = new QLabel(KGlobal::locale()->formatDateTime(dt), d->m_frame );
01018 grid->addWidget(l, curRow++, 2);
01019 }
01020 }
01021
01022 if ( isLocal && hasDirs )
01023 {
01024 sep = new KSeparator( KSeparator::HLine, d->m_frame);
01025 grid->addMultiCellWidget(sep, curRow, curRow, 0, 2);
01026 ++curRow;
01027
01028 QString mountPoint = KIO::findPathMountPoint( properties->item()->url().path() );
01029
01030 if (mountPoint != "/")
01031 {
01032 l = new QLabel(i18n("Mounted on:"), d->m_frame );
01033 grid->addWidget(l, curRow, 0);
01034
01035 l = new KSqueezedTextLabel( mountPoint, d->m_frame );
01036 grid->addWidget( l, curRow++, 2 );
01037 }
01038
01039 l = new QLabel(i18n("Free disk space:"), d->m_frame );
01040 grid->addWidget(l, curRow, 0);
01041
01042 d->m_freeSpaceLabel = new QLabel( d->m_frame );
01043 grid->addWidget( d->m_freeSpaceLabel, curRow++, 2 );
01044
01045 KDiskFreeSp * job = new KDiskFreeSp;
01046 connect( job, SIGNAL( foundMountPoint( const unsigned long&, const unsigned long&,
01047 const unsigned long&, const QString& ) ),
01048 this, SLOT( slotFoundMountPoint( const unsigned long&, const unsigned long&,
01049 const unsigned long&, const QString& ) ) );
01050 job->readDF( mountPoint );
01051 }
01052
01053 vbl->addStretch(1);
01054 }
01055
01056
01057
01058
01059
01060
01061 void KFilePropsPlugin::setFileNameReadOnly( bool ro )
01062 {
01063 if ( d->m_lined )
01064 {
01065 d->m_lined->setReadOnly( ro );
01066 if (ro)
01067 {
01068
01069 QPushButton *button = properties->actionButton(KDialogBase::Ok);
01070 if (button)
01071 button->setFocus();
01072 }
01073 }
01074 }
01075
01076 void KFilePropsPlugin::slotEditFileType()
01077 {
01078 #ifdef Q_WS_X11
01079
01080 QString keditfiletype = QString::fromLatin1("keditfiletype");
01081 KRun::runCommand( keditfiletype
01082 + " --parent " + QString::number( (ulong)properties->topLevelWidget()->winId())
01083 + " " + KProcess::quote(d->mimeType),
01084 keditfiletype, keditfiletype );
01085 #endif
01086 }
01087
01088 void KFilePropsPlugin::slotIconChanged()
01089 {
01090 d->bIconChanged = true;
01091 emit changed();
01092 }
01093
01094 void KFilePropsPlugin::nameFileChanged(const QString &text )
01095 {
01096 properties->enableButtonOK(!text.isEmpty());
01097 emit changed();
01098 }
01099
01100 void KFilePropsPlugin::determineRelativePath( const QString & path )
01101 {
01102
01103 QStringList dirs;
01104 if (KBindingPropsPlugin::supports(properties->items()))
01105 {
01106 m_sRelativePath =KGlobal::dirs()->relativeLocation("mime", path);
01107 if (m_sRelativePath.startsWith("/"))
01108 m_sRelativePath = QString::null;
01109 }
01110 else
01111 {
01112 m_sRelativePath =KGlobal::dirs()->relativeLocation("apps", path);
01113 if (m_sRelativePath.startsWith("/"))
01114 {
01115 m_sRelativePath =KGlobal::dirs()->relativeLocation("xdgdata-apps", path);
01116 if (m_sRelativePath.startsWith("/"))
01117 m_sRelativePath = QString::null;
01118 else
01119 m_sRelativePath = path;
01120 }
01121 }
01122 if ( m_sRelativePath.isEmpty() )
01123 {
01124 if (KBindingPropsPlugin::supports(properties->items()))
01125 kdWarning(250) << "Warning : editing a mimetype file out of the mimetype dirs!" << endl;
01126 }
01127 }
01128
01129 void KFilePropsPlugin::slotFoundMountPoint( const QString&,
01130 unsigned long kBSize,
01131 unsigned long ,
01132 unsigned long kBAvail )
01133 {
01134 d->m_freeSpaceLabel->setText(
01135 i18n("Available space out of total partition size (percent used)", "%1 out of %2 (%3% used)")
01136 .arg(KIO::convertSizeFromKB(kBAvail))
01137 .arg(KIO::convertSizeFromKB(kBSize))
01138 .arg( 100 - (int)(100.0 * kBAvail / kBSize) ));
01139 }
01140
01141
01142
01143 void KFilePropsPlugin::slotFoundMountPoint( const unsigned long& kBSize,
01144 const unsigned long& ,
01145 const unsigned long& kBAvail,
01146 const QString& )
01147 {
01148 d->m_freeSpaceLabel->setText(
01149 i18n("Available space out of total partition size (percent used)", "%1 out of %2 (%3% used)")
01150 .arg(KIO::convertSizeFromKB(kBAvail))
01151 .arg(KIO::convertSizeFromKB(kBSize))
01152 .arg( 100 - (int)(100.0 * kBAvail / kBSize) ));
01153 }
01154
01155 void KFilePropsPlugin::slotDirSizeUpdate()
01156 {
01157 KIO::filesize_t totalSize = d->dirSizeJob->totalSize();
01158 KIO::filesize_t totalFiles = d->dirSizeJob->totalFiles();
01159 KIO::filesize_t totalSubdirs = d->dirSizeJob->totalSubdirs();
01160 m_sizeLabel->setText( i18n("Calculating... %1 (%2)\n%3, %4")
01161 .arg(KIO::convertSize(totalSize))
01162 .arg(KGlobal::locale()->formatNumber(totalSize, 0))
01163 .arg(i18n("1 file","%n files",totalFiles))
01164 .arg(i18n("1 sub-folder","%n sub-folders",totalSubdirs)));
01165 }
01166
01167 void KFilePropsPlugin::slotDirSizeFinished( KIO::Job * job )
01168 {
01169 if (job->error())
01170 m_sizeLabel->setText( job->errorString() );
01171 else
01172 {
01173 KIO::filesize_t totalSize = static_cast<KDirSize*>(job)->totalSize();
01174 KIO::filesize_t totalFiles = static_cast<KDirSize*>(job)->totalFiles();
01175 KIO::filesize_t totalSubdirs = static_cast<KDirSize*>(job)->totalSubdirs();
01176 m_sizeLabel->setText( QString::fromLatin1("%1 (%2)\n%3, %4")
01177 .arg(KIO::convertSize(totalSize))
01178 .arg(KGlobal::locale()->formatNumber(totalSize, 0))
01179 .arg(i18n("1 file","%n files",totalFiles))
01180 .arg(i18n("1 sub-folder","%n sub-folders",totalSubdirs)));
01181 }
01182 m_sizeStopButton->setEnabled(false);
01183
01184 m_sizeDetermineButton->setText( i18n("Refresh") );
01185 m_sizeDetermineButton->setEnabled(true);
01186 d->dirSizeJob = 0L;
01187 delete d->dirSizeUpdateTimer;
01188 d->dirSizeUpdateTimer = 0L;
01189 }
01190
01191 void KFilePropsPlugin::slotSizeDetermine()
01192 {
01193 m_sizeLabel->setText( i18n("Calculating...") );
01194 kdDebug(250) << " KFilePropsPlugin::slotSizeDetermine() properties->item()=" << properties->item() << endl;
01195 kdDebug(250) << " URL=" << properties->item()->url().url() << endl;
01196 d->dirSizeJob = KDirSize::dirSizeJob( properties->items() );
01197 d->dirSizeUpdateTimer = new QTimer(this);
01198 connect( d->dirSizeUpdateTimer, SIGNAL( timeout() ),
01199 SLOT( slotDirSizeUpdate() ) );
01200 d->dirSizeUpdateTimer->start(500);
01201 connect( d->dirSizeJob, SIGNAL( result( KIO::Job * ) ),
01202 SLOT( slotDirSizeFinished( KIO::Job * ) ) );
01203 m_sizeStopButton->setEnabled(true);
01204 m_sizeDetermineButton->setEnabled(false);
01205 }
01206
01207 void KFilePropsPlugin::slotSizeStop()
01208 {
01209 if ( d->dirSizeJob )
01210 {
01211 m_sizeLabel->setText( i18n("Stopped") );
01212 d->dirSizeJob->kill();
01213 d->dirSizeJob = 0;
01214 }
01215 if ( d->dirSizeUpdateTimer )
01216 d->dirSizeUpdateTimer->stop();
01217
01218 m_sizeStopButton->setEnabled(false);
01219 m_sizeDetermineButton->setEnabled(true);
01220 }
01221
01222 KFilePropsPlugin::~KFilePropsPlugin()
01223 {
01224 delete d;
01225 }
01226
01227 bool KFilePropsPlugin::supports( KFileItemList )
01228 {
01229 return true;
01230 }
01231
01232
01233 void qt_enter_modal( QWidget *widget );
01234 void qt_leave_modal( QWidget *widget );
01235
01236 void KFilePropsPlugin::applyChanges()
01237 {
01238 if ( d->dirSizeJob )
01239 slotSizeStop();
01240
01241 kdDebug(250) << "KFilePropsPlugin::applyChanges" << endl;
01242
01243 if (nameArea->inherits("QLineEdit"))
01244 {
01245 QString n = ((QLineEdit *) nameArea)->text();
01246
01247 while ( n[n.length()-1].isSpace() )
01248 n.truncate( n.length() - 1 );
01249 if ( n.isEmpty() )
01250 {
01251 KMessageBox::sorry( properties, i18n("The new file name is empty."));
01252 properties->abortApplying();
01253 return;
01254 }
01255
01256
01257 kdDebug(250) << "oldname = " << oldName << endl;
01258 kdDebug(250) << "newname = " << n << endl;
01259 if ( oldName != n || m_bFromTemplate ) {
01260 KIO::Job * job = 0L;
01261 KURL oldurl = properties->kurl();
01262
01263 QString newFileName = KIO::encodeFileName(n);
01264 if (d->bDesktopFile && !newFileName.endsWith(".desktop") && !newFileName.endsWith(".kdelnk"))
01265 newFileName += ".desktop";
01266
01267
01268 properties->rename( newFileName );
01269
01270
01271 if ( !m_sRelativePath.isEmpty() )
01272 determineRelativePath( properties->kurl().path() );
01273
01274 kdDebug(250) << "New URL = " << properties->kurl().url() << endl;
01275 kdDebug(250) << "old = " << oldurl.url() << endl;
01276
01277
01278 if ( !m_bFromTemplate )
01279 job = KIO::move( oldurl, properties->kurl() );
01280 else
01281 job = KIO::copy( oldurl, properties->kurl() );
01282
01283 connect( job, SIGNAL( result( KIO::Job * ) ),
01284 SLOT( slotCopyFinished( KIO::Job * ) ) );
01285 connect( job, SIGNAL( renamed( KIO::Job *, const KURL &, const KURL & ) ),
01286 SLOT( slotFileRenamed( KIO::Job *, const KURL &, const KURL & ) ) );
01287
01288 QWidget dummy(0,0,WType_Dialog|WShowModal);
01289 qt_enter_modal(&dummy);
01290 qApp->enter_loop();
01291 qt_leave_modal(&dummy);
01292 return;
01293 }
01294 properties->updateUrl(properties->kurl());
01295
01296 if ( !m_sRelativePath.isEmpty() )
01297 determineRelativePath( properties->kurl().path() );
01298 }
01299
01300
01301 slotCopyFinished( 0L );
01302 }
01303
01304 void KFilePropsPlugin::slotCopyFinished( KIO::Job * job )
01305 {
01306 kdDebug(250) << "KFilePropsPlugin::slotCopyFinished" << endl;
01307 if (job)
01308 {
01309
01310 qApp->exit_loop();
01311 if ( job->error() )
01312 {
01313 job->showErrorDialog( d->m_frame );
01314
01315 properties->updateUrl( static_cast<KIO::CopyJob*>(job)->srcURLs().first() );
01316 properties->abortApplying();
01317 return;
01318 }
01319 }
01320
01321 assert( properties->item() );
01322 assert( !properties->item()->url().isEmpty() );
01323
01324
01325 if (KBindingPropsPlugin::supports(properties->items()) && !m_sRelativePath.isEmpty())
01326 {
01327 KURL newURL;
01328 newURL.setPath( locateLocal("mime", m_sRelativePath) );
01329 properties->updateUrl( newURL );
01330 }
01331 else if (d->bDesktopFile && !m_sRelativePath.isEmpty())
01332 {
01333 kdDebug(250) << "KFilePropsPlugin::slotCopyFinished " << m_sRelativePath << endl;
01334 KURL newURL;
01335 newURL.setPath( KDesktopFile::locateLocal(m_sRelativePath) );
01336 kdDebug(250) << "KFilePropsPlugin::slotCopyFinished path=" << newURL.path() << endl;
01337 properties->updateUrl( newURL );
01338 }
01339
01340 if ( d->bKDesktopMode && d->bDesktopFile ) {
01341
01342 if ( d->oldFileName != properties->kurl().fileName() || m_bFromTemplate ) {
01343 KDesktopFile config( properties->kurl().path() );
01344 QString nameStr = nameFromFileName(properties->kurl().fileName());
01345 config.writeEntry( "Name", nameStr );
01346 config.writeEntry( "Name", nameStr, true, false, true );
01347 }
01348 }
01349 }
01350
01351 void KFilePropsPlugin::applyIconChanges()
01352 {
01353
01354
01355 if (iconArea->isA("KIconButton") && properties->kurl().isLocalFile()) {
01356 KIconButton *iconButton = (KIconButton *) iconArea;
01357 QString path;
01358
01359 if (S_ISDIR(properties->item()->mode()))
01360 {
01361 path = properties->kurl().path(1) + QString::fromLatin1(".directory");
01362
01363
01364 }
01365 else
01366 path = properties->kurl().path();
01367
01368
01369 QString str = KMimeType::findByURL( properties->kurl(),
01370 properties->item()->mode(),
01371 true )->KServiceType::icon();
01372
01373 QString sIcon;
01374 if ( str != iconButton->icon() )
01375 sIcon = iconButton->icon();
01376
01377
01378 kdDebug(250) << "**" << path << "**" << endl;
01379 QFile f( path );
01380
01381
01382 if ( !sIcon.isEmpty() || f.exists() )
01383 {
01384 if ( !f.open( IO_ReadWrite ) ) {
01385 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not "
01386 "have sufficient access to write to <b>%1</b>.</qt>").arg(path));
01387 return;
01388 }
01389 f.close();
01390
01391 KDesktopFile cfg(path);
01392 kdDebug(250) << "sIcon = " << (sIcon) << endl;
01393 kdDebug(250) << "str = " << (str) << endl;
01394 cfg.writeEntry( "Icon", sIcon );
01395 cfg.sync();
01396 }
01397 }
01398 }
01399
01400 void KFilePropsPlugin::slotFileRenamed( KIO::Job *, const KURL &, const KURL & newUrl )
01401 {
01402
01403
01404 properties->updateUrl( newUrl );
01405 }
01406
01407 void KFilePropsPlugin::postApplyChanges()
01408 {
01409
01410 applyIconChanges();
01411
01412 KURL::List lst;
01413 KFileItemList items = properties->items();
01414 for ( KFileItemListIterator it( items ); it.current(); ++it )
01415 lst.append((*it)->url());
01416 KDirNotify_stub allDirNotify("*", "KDirNotify*");
01417 allDirNotify.FilesChanged( lst );
01418 }
01419
01420 class KFilePermissionsPropsPlugin::KFilePermissionsPropsPluginPrivate
01421 {
01422 public:
01423 KFilePermissionsPropsPluginPrivate()
01424 {
01425 }
01426 ~KFilePermissionsPropsPluginPrivate()
01427 {
01428 }
01429
01430 QFrame *m_frame;
01431 QCheckBox *cbRecursive;
01432 QLabel *explanationLabel;
01433 QComboBox *ownerPermCombo, *groupPermCombo, *othersPermCombo;
01434 QCheckBox *extraCheckbox;
01435 mode_t partialPermissions;
01436 KFilePermissionsPropsPlugin::PermissionsMode pmode;
01437 bool canChangePermissions;
01438 bool isIrregular;
01439 };
01440
01441 #define UniOwner (S_IRUSR|S_IWUSR|S_IXUSR)
01442 #define UniGroup (S_IRGRP|S_IWGRP|S_IXGRP)
01443 #define UniOthers (S_IROTH|S_IWOTH|S_IXOTH)
01444 #define UniRead (S_IRUSR|S_IRGRP|S_IROTH)
01445 #define UniWrite (S_IWUSR|S_IWGRP|S_IWOTH)
01446 #define UniExec (S_IXUSR|S_IXGRP|S_IXOTH)
01447 #define UniSpecial (S_ISUID|S_ISGID|S_ISVTX)
01448
01449
01450 const mode_t KFilePermissionsPropsPlugin::permissionsMasks[3] = {UniOwner, UniGroup, UniOthers};
01451 const mode_t KFilePermissionsPropsPlugin::standardPermissions[4] = { 0, UniRead, UniRead|UniWrite, (mode_t)-1 };
01452
01453
01454 const char *KFilePermissionsPropsPlugin::permissionsTexts[4][4] = {
01455 { I18N_NOOP("Forbidden"),
01456 I18N_NOOP("Can Read"),
01457 I18N_NOOP("Can Read & Write"),
01458 0 },
01459 { I18N_NOOP("Forbidden"),
01460 I18N_NOOP("Can View Content"),
01461 I18N_NOOP("Can View & Modify Content"),
01462 0 },
01463 { 0, 0, 0, 0},
01464 { I18N_NOOP("Forbidden"),
01465 I18N_NOOP("Can View Content & Read"),
01466 I18N_NOOP("Can View/Read & Modify/Write"),
01467 0 }
01468 };
01469
01470
01471 KFilePermissionsPropsPlugin::KFilePermissionsPropsPlugin( KPropertiesDialog *_props )
01472 : KPropsDlgPlugin( _props )
01473 {
01474 d = new KFilePermissionsPropsPluginPrivate;
01475 d->cbRecursive = 0L;
01476 grpCombo = 0L; grpEdit = 0;
01477 usrEdit = 0L;
01478 QString path = properties->kurl().path(-1);
01479 QString fname = properties->kurl().fileName();
01480 bool isLocal = properties->kurl().isLocalFile();
01481 bool isTrash = ( properties->kurl().protocol().find("trash", 0, false)==0 );
01482 bool IamRoot = (geteuid() == 0);
01483
01484 KFileItem * item = properties->item();
01485 bool isLink = item->isLink();
01486 bool isDir = item->isDir();
01487 bool hasDir = item->isDir();
01488 permissions = item->permissions();
01489 d->partialPermissions = permissions;
01490 d->isIrregular = isIrregular(permissions, isDir, isLink);
01491 strOwner = item->user();
01492 strGroup = item->group();
01493
01494 if ( properties->items().count() > 1 )
01495 {
01496
01497 KFileItemList items = properties->items();
01498 KFileItemListIterator it( items );
01499 for ( ++it ; it.current(); ++it )
01500 {
01501 if (!d->isIrregular)
01502 d->isIrregular |= isIrregular((*it)->permissions(),
01503 (*it)->isDir() == isDir,
01504 (*it)->isLink() == isLink);
01505 if ( (*it)->isLink() != isLink )
01506 isLink = false;
01507 if ( (*it)->isDir() != isDir )
01508 isDir = false;
01509 hasDir |= (*it)->isDir();
01510 if ( (*it)->permissions() != permissions )
01511 {
01512 permissions &= (*it)->permissions();
01513 d->partialPermissions |= (*it)->permissions();
01514 }
01515 if ( (*it)->user() != strOwner )
01516 strOwner = QString::null;
01517 if ( (*it)->group() != strGroup )
01518 strGroup = QString::null;
01519 }
01520 }
01521
01522 if (isLink)
01523 d->pmode = PermissionsOnlyLinks;
01524 else if (isDir)
01525 d->pmode = PermissionsOnlyDirs;
01526 else if (hasDir)
01527 d->pmode = PermissionsMixed;
01528 else
01529 d->pmode = PermissionsOnlyFiles;
01530
01531
01532 d->partialPermissions = d->partialPermissions & ~permissions;
01533
01534 bool isMyFile = false;
01535
01536 if (isLocal && !strOwner.isEmpty()) {
01537 struct passwd *myself = getpwuid( geteuid() );
01538 if ( myself != 0L )
01539 {
01540 isMyFile = (strOwner == QString::fromLocal8Bit(myself->pw_name));
01541 } else
01542 kdWarning() << "I don't exist ?! geteuid=" << geteuid() << endl;
01543 } else {
01544
01545
01546
01547 isMyFile = true;
01548 }
01549
01550 d->canChangePermissions = (isMyFile || IamRoot) && (!isLink);
01551
01552
01553
01554
01555 d->m_frame = properties->addPage(i18n("&Permissions"));
01556
01557 QBoxLayout *box = new QVBoxLayout( d->m_frame, 0, KDialog::spacingHint() );
01558
01559 QWidget *l;
01560 QLabel *lbl;
01561 QGroupBox *gb;
01562 QGridLayout *gl;
01563 QPushButton* pbAdvancedPerm = 0;
01564
01565
01566 gb = new QGroupBox ( 0, Qt::Vertical, i18n("Access Permissions"), d->m_frame );
01567 gb->layout()->setSpacing(KDialog::spacingHint());
01568 gb->layout()->setMargin(KDialog::marginHint());
01569 box->addWidget (gb);
01570
01571 gl = new QGridLayout (gb->layout(), 7, 2);
01572 gl->setColStretch(1, 1);
01573
01574 l = d->explanationLabel = new QLabel( "", gb );
01575 if (isLink)
01576 d->explanationLabel->setText(i18n("This file is a link and does not have permissions.",
01577 "All files are links and do not have permissions.",
01578 properties->items().count()));
01579 else if (!d->canChangePermissions)
01580 d->explanationLabel->setText(i18n("Only the owner can change permissions."));
01581 gl->addMultiCellWidget(l, 0, 0, 0, 1);
01582
01583 lbl = new QLabel( i18n("O&wner:"), gb);
01584 gl->addWidget(lbl, 1, 0);
01585 l = d->ownerPermCombo = new QComboBox(gb);
01586 lbl->setBuddy(l);
01587 gl->addWidget(l, 1, 1);
01588 connect(l, SIGNAL( highlighted(int) ), this, SIGNAL( changed() ));
01589 QWhatsThis::add(l, i18n("Specifies the actions that the owner is allowed to do."));
01590
01591 lbl = new QLabel( i18n("Gro&up:"), gb);
01592 gl->addWidget(lbl, 2, 0);
01593 l = d->groupPermCombo = new QComboBox(gb);
01594 lbl->setBuddy(l);
01595 gl->addWidget(l, 2, 1);
01596 connect(l, SIGNAL( highlighted(int) ), this, SIGNAL( changed() ));
01597 QWhatsThis::add(l, i18n("Specifies the actions that the members of the group are allowed to do."));
01598
01599 lbl = new QLabel( i18n("O&thers:"), gb);
01600 gl->addWidget(lbl, 3, 0);
01601 l = d->othersPermCombo = new QComboBox(gb);
01602 lbl->setBuddy(l);
01603 gl->addWidget(l, 3, 1);
01604 connect(l, SIGNAL( highlighted(int) ), this, SIGNAL( changed() ));
01605 QWhatsThis::add(l, i18n("Specifies the actions that all users, who are neither "
01606 "owner nor in the group, are allowed to do."));
01607
01608 if (!isLink) {
01609 l = d->extraCheckbox = new QCheckBox(hasDir ?
01610 i18n("Only own&er can rename and delete folder content") :
01611 i18n("Is &executable"),
01612 gb );
01613 connect( d->extraCheckbox, SIGNAL( clicked() ), this, SIGNAL( changed() ) );
01614 gl->addWidget(l, 4, 1);
01615 QWhatsThis::add(l, hasDir ? i18n("Enable this option to allow only the folder's owner to "
01616 "delete or rename the contained files and folders. Other "
01617 "users can only add new files, which requires the 'Modify "
01618 "Content' permission.")
01619 : i18n("Enable this option to mark the file as executable. This only makes "
01620 "sense for programs and scripts. It is required when you want to "
01621 "execute them."));
01622
01623 QLayoutItem *spacer = new QSpacerItem(0, 20, QSizePolicy::Minimum, QSizePolicy::Expanding);
01624 gl->addMultiCell(spacer, 5, 5, 0, 1);
01625
01626 pbAdvancedPerm = new QPushButton(i18n("A&dvanced Permissions"), gb);
01627 gl->addMultiCellWidget(pbAdvancedPerm, 6, 6, 0, 1, AlignRight);
01628 connect(pbAdvancedPerm, SIGNAL( clicked() ), this, SLOT( slotShowAdvancedPermissions() ));
01629 }
01630 else
01631 d->extraCheckbox = 0;
01632
01633
01634
01635 gb = new QGroupBox ( 0, Qt::Vertical, i18n("Ownership"), d->m_frame );
01636 gb->layout()->setSpacing(KDialog::spacingHint());
01637 gb->layout()->setMargin(KDialog::marginHint());
01638 box->addWidget (gb);
01639
01640 gl = new QGridLayout (gb->layout(), 4, 3);
01641 gl->addRowSpacing(0, 10);
01642
01643
01644 l = new QLabel( i18n("User:"), gb );
01645 gl->addWidget (l, 1, 0);
01646
01647
01648
01649
01650
01651
01652 int i, maxEntries = 1000;
01653 struct passwd *user;
01654 struct group *ge;
01655
01656
01657
01658
01659 if (IamRoot && isLocal)
01660 {
01661 usrEdit = new KLineEdit( gb );
01662 KCompletion *kcom = usrEdit->completionObject();
01663 kcom->setOrder(KCompletion::Sorted);
01664 setpwent();
01665 for (i=0; ((user = getpwent()) != 0L) && (i < maxEntries); i++)
01666 kcom->addItem(QString::fromLatin1(user->pw_name));
01667 endpwent();
01668 usrEdit->setCompletionMode((i < maxEntries) ? KGlobalSettings::CompletionAuto :
01669 KGlobalSettings::CompletionNone);
01670 usrEdit->setText(strOwner);
01671 gl->addWidget(usrEdit, 1, 1);
01672 connect( usrEdit, SIGNAL( textChanged( const QString & ) ),
01673 this, SIGNAL( changed() ) );
01674 }
01675 else
01676 {
01677 l = new QLabel(strOwner, gb);
01678 gl->addWidget(l, 1, 1);
01679 }
01680
01681
01682
01683 QStringList groupList;
01684 QCString strUser;
01685 user = getpwuid(geteuid());
01686 if (user != 0L)
01687 strUser = user->pw_name;
01688
01689 #ifdef Q_OS_UNIX
01690 setgrent();
01691 for (i=0; ((ge = getgrent()) != 0L) && (i < maxEntries); i++)
01692 {
01693 if (IamRoot)
01694 groupList += QString::fromLatin1(ge->gr_name);
01695 else
01696 {
01697
01698 char ** members = ge->gr_mem;
01699 char * member;
01700 while ((member = *members) != 0L) {
01701 if (strUser == member) {
01702 groupList += QString::fromLocal8Bit(ge->gr_name);
01703 break;
01704 }
01705 ++members;
01706 }
01707 }
01708 }
01709 endgrent();
01710 #endif //Q_OS_UNIX
01711
01712
01713 ge = getgrgid (getegid());
01714 if (ge) {
01715 QString name = QString::fromLatin1(ge->gr_name);
01716 if (name.isEmpty())
01717 name.setNum(ge->gr_gid);
01718 if (groupList.find(name) == groupList.end())
01719 groupList += name;
01720 }
01721
01722 bool isMyGroup = groupList.contains(strGroup);
01723
01724
01725
01726
01727 if (!isMyGroup)
01728 groupList += strGroup;
01729
01730 l = new QLabel( i18n("Group:"), gb );
01731 gl->addWidget (l, 2, 0);
01732
01733
01734
01735
01736
01737
01738
01739 if (IamRoot && isLocal)
01740 {
01741 grpEdit = new KLineEdit(gb);
01742 KCompletion *kcom = new KCompletion;
01743 kcom->setItems(groupList);
01744 grpEdit->setCompletionObject(kcom, true);
01745 grpEdit->setAutoDeleteCompletionObject( true );
01746 grpEdit->setCompletionMode(KGlobalSettings::CompletionAuto);
01747 grpEdit->setText(strGroup);
01748 gl->addWidget(grpEdit, 2, 1);
01749 connect( grpEdit, SIGNAL( textChanged( const QString & ) ),
01750 this, SIGNAL( changed() ) );
01751 }
01752 else if ((groupList.count() > 1) && isMyFile && isLocal)
01753 {
01754 grpCombo = new QComboBox(gb, "combogrouplist");
01755 grpCombo->insertStringList(groupList);
01756 grpCombo->setCurrentItem(groupList.findIndex(strGroup));
01757 gl->addWidget(grpCombo, 2, 1);
01758 connect( grpCombo, SIGNAL( activated( int ) ),
01759 this, SIGNAL( changed() ) );
01760 }
01761 else
01762 {
01763 l = new QLabel(strGroup, gb);
01764 gl->addWidget(l, 2, 1);
01765 }
01766
01767 gl->setColStretch(2, 10);
01768
01769
01770 if ( hasDir && !isLink && !isTrash )
01771 {
01772 d->cbRecursive = new QCheckBox( i18n("Apply changes to all subfolders and their contents"), d->m_frame );
01773 connect( d->cbRecursive, SIGNAL( clicked() ), this, SIGNAL( changed() ) );
01774 box->addWidget( d->cbRecursive );
01775 }
01776
01777 updateAccessControls();
01778
01779
01780 if ( isTrash )
01781 {
01782
01783 enableAccessControls(false);
01784 if ( pbAdvancedPerm)
01785 pbAdvancedPerm->setEnabled(false);
01786 }
01787
01788 box->addStretch (10);
01789 }
01790
01791 void KFilePermissionsPropsPlugin::slotShowAdvancedPermissions() {
01792
01793 bool isDir = (d->pmode == PermissionsOnlyDirs) || (d->pmode == PermissionsMixed);
01794 KDialogBase dlg(properties, 0, true, i18n("Advanced Permissions"),
01795 KDialogBase::Ok|KDialogBase::Cancel);
01796
01797 QLabel *l, *cl[3];
01798 QGroupBox *gb;
01799 QGridLayout *gl;
01800
01801
01802 gb = new QGroupBox ( 0, Qt::Vertical, i18n("Access Permissions"), &dlg );
01803 gb->layout()->setSpacing(KDialog::spacingHint());
01804 gb->layout()->setMargin(KDialog::marginHint());
01805 dlg.setMainWidget(gb);
01806
01807 gl = new QGridLayout (gb->layout(), 6, 6);
01808 gl->addRowSpacing(0, 10);
01809
01810 l = new QLabel(i18n("Class"), gb);
01811 gl->addWidget(l, 1, 0);
01812
01813 if (isDir)
01814 l = new QLabel( i18n("Show\nEntries"), gb );
01815 else
01816 l = new QLabel( i18n("Read"), gb );
01817 gl->addWidget (l, 1, 1);
01818 QString readWhatsThis;
01819 if (isDir)
01820 readWhatsThis = i18n("This flag allows viewing the content of the folder.");
01821 else
01822 readWhatsThis = i18n("The Read flag allows viewing the content of the file.");
01823 QWhatsThis::add(l, readWhatsThis);
01824
01825 if (isDir)
01826 l = new QLabel( i18n("Write\nEntries"), gb );
01827 else
01828 l = new QLabel( i18n("Write"), gb );
01829 gl->addWidget (l, 1, 2);
01830 QString writeWhatsThis;
01831 if (isDir)
01832 writeWhatsThis = i18n("This flag allows adding, renaming and deleting of files. "
01833 "Note that deleting and renaming can be limited using the Sticky flag.");
01834 else
01835 writeWhatsThis = i18n("The Write flag allows modifying the content of the file.");
01836 QWhatsThis::add(l, writeWhatsThis);
01837
01838 QString execWhatsThis;
01839 if (isDir) {
01840 l = new QLabel( i18n("Enter folder", "Enter"), gb );
01841 execWhatsThis = i18n("Enable this flag to allow entering the folder.");
01842 }
01843 else {
01844 l = new QLabel( i18n("Exec"), gb );
01845 execWhatsThis = i18n("Enable this flag to allow executing the file as a program.");
01846 }
01847 QWhatsThis::add(l, execWhatsThis);
01848
01849 QSize size = l->sizeHint();
01850 size.setWidth(size.width() + 15);
01851 l->setFixedSize(size);
01852 gl->addWidget (l, 1, 3);
01853
01854 l = new QLabel( i18n("Special"), gb );
01855 gl->addMultiCellWidget(l, 1, 1, 4, 5);
01856 QString specialWhatsThis;
01857 if (isDir)
01858 specialWhatsThis = i18n("Special flag. Valid for the whole folder, the exact "
01859 "meaning of the flag can be seen in the right hand column.");
01860 else
01861 specialWhatsThis = i18n("Special flag. The exact meaning of the flag can be seen "
01862 "in the right hand column.");
01863 QWhatsThis::add(l, specialWhatsThis);
01864
01865 cl[0] = new QLabel( i18n("User"), gb );
01866 gl->addWidget (cl[0], 2, 0);
01867
01868 cl[1] = new QLabel( i18n("Group"), gb );
01869 gl->addWidget (cl[1], 3, 0);
01870
01871 cl[2] = new QLabel( i18n("Others"), gb );
01872 gl->addWidget (cl[2], 4, 0);
01873
01874 l = new QLabel(i18n("Set UID"), gb);
01875 gl->addWidget(l, 2, 5);
01876 QString setUidWhatsThis;
01877 if (isDir)
01878 setUidWhatsThis = i18n("If this flag is set, the owner of this folder will be "
01879 "the owner of all new files.");
01880 else
01881 setUidWhatsThis = i18n("If this file is an executable and the flag is set, it will "
01882 "be executed with the permissions of the owner.");
01883 QWhatsThis::add(l, setUidWhatsThis);
01884
01885 l = new QLabel(i18n("Set GID"), gb);
01886 gl->addWidget(l, 3, 5);
01887 QString setGidWhatsThis;
01888 if (isDir)
01889 setGidWhatsThis = i18n("If this flag is set, the group of this folder will be "
01890 "set for all new files.");
01891 else
01892 setGidWhatsThis = i18n("If this file is an executable and the flag is set, it will "
01893 "be executed with the permissions of the group.");
01894 QWhatsThis::add(l, setGidWhatsThis);
01895
01896 l = new QLabel(i18n("File permission", "Sticky"), gb);
01897 gl->addWidget(l, 4, 5);
01898 QString stickyWhatsThis;
01899 if (isDir)
01900 stickyWhatsThis = i18n("If the Sticky flag is set on a folder, only the owner "
01901 "and root can delete or rename files. Otherwise everybody "
01902 "with write permissions can do this.");
01903 else
01904 stickyWhatsThis = i18n("The Sticky flag on a file is ignored on Linux, but may "
01905 "be used on some systems");
01906 QWhatsThis::add(l, stickyWhatsThis);
01907
01908 mode_t aPermissions, aPartialPermissions;
01909 mode_t dummy1, dummy2;
01910
01911 if (!d->isIrregular) {
01912 switch (d->pmode) {
01913 case PermissionsOnlyFiles:
01914 getPermissionMasks(aPartialPermissions,
01915 dummy1,
01916 aPermissions,
01917 dummy2);
01918 break;
01919 case PermissionsOnlyDirs:
01920 case PermissionsMixed:
01921 getPermissionMasks(dummy1,
01922 aPartialPermissions,
01923 dummy2,
01924 aPermissions);
01925 break;
01926 case PermissionsOnlyLinks:
01927 aPermissions = UniRead | UniWrite | UniExec | UniSpecial;
01928 aPartialPermissions = 0;
01929 break;
01930 }
01931 }
01932 else {
01933 aPermissions = permissions;
01934 aPartialPermissions = d->partialPermissions;
01935 }
01936
01937
01938 QCheckBox *cba[3][4];
01939 for (int row = 0; row < 3 ; ++row) {
01940 for (int col = 0; col < 4; ++col) {
01941 QCheckBox *cb = new QCheckBox(gb);
01942 cba[row][col] = cb;
01943 cb->setChecked(aPermissions & fperm[row][col]);
01944 if ( aPartialPermissions & fperm[row][col] )
01945 {
01946 cb->setTristate();
01947 cb->setNoChange();
01948 }
01949 else if (d->cbRecursive && d->cbRecursive->isChecked())
01950 cb->setTristate();
01951
01952 cb->setEnabled( d->canChangePermissions );
01953 gl->addWidget (cb, row+2, col+1);
01954 switch(col) {
01955 case 0:
01956 QWhatsThis::add(cb, readWhatsThis);
01957 break;
01958 case 1:
01959 QWhatsThis::add(cb, writeWhatsThis);
01960 break;
01961 case 2:
01962 QWhatsThis::add(cb, execWhatsThis);
01963 break;
01964 case 3:
01965 switch(row) {
01966 case 0:
01967 QWhatsThis::add(cb, setUidWhatsThis);
01968 break;
01969 case 1:
01970 QWhatsThis::add(cb, setGidWhatsThis);
01971 break;
01972 case 2:
01973 QWhatsThis::add(cb, stickyWhatsThis);
01974 break;
01975 }
01976 break;
01977 }
01978 }
01979 }
01980 gl->setColStretch(6, 10);
01981
01982 if (dlg.exec() != KDialogBase::Accepted)
01983 return;
01984
01985 mode_t andPermissions = mode_t(~0);
01986 mode_t orPermissions = 0;
01987 for (int row = 0; row < 3; ++row)
01988 for (int col = 0; col < 4; ++col) {
01989 switch (cba[row][col]->state())
01990 {
01991 case QCheckBox::On:
01992 orPermissions |= fperm[row][col];
01993
01994 case QCheckBox::Off:
01995 andPermissions &= ~fperm[row][col];
01996 break;
01997 default:
01998 break;
01999 }
02000 }
02001
02002 d->isIrregular = false;
02003 KFileItemList items = properties->items();
02004 for (KFileItemListIterator it(items); it.current(); ++it) {
02005 if (isIrregular(((*it)->permissions() & andPermissions) | orPermissions,
02006 (*it)->isDir(), (*it)->isLink())) {
02007 d->isIrregular = true;
02008 break;
02009 }
02010 }
02011
02012 permissions = orPermissions;
02013 d->partialPermissions = andPermissions;
02014
02015 emit changed();
02016 updateAccessControls();
02017 }
02018
02019
02020
02021
02022
02023
02024 KFilePermissionsPropsPlugin::~KFilePermissionsPropsPlugin()
02025 {
02026 delete d;
02027 }
02028
02029 bool KFilePermissionsPropsPlugin::supports( KFileItemList )
02030 {
02031 return true;
02032 }
02033
02034
02035 void KFilePermissionsPropsPlugin::setComboContent(QComboBox *combo, PermissionsTarget target,
02036 mode_t permissions, mode_t partial) {
02037 combo->clear();
02038 if (d->pmode == PermissionsOnlyLinks) {
02039 combo->insertItem(i18n("Link"));
02040 combo->setCurrentItem(0);
02041 return;
02042 }
02043
02044 mode_t tMask = permissionsMasks[target];
02045 int textIndex;
02046 for (textIndex = 0; standardPermissions[textIndex] != (mode_t)-1; textIndex++)
02047 if ((standardPermissions[textIndex]&tMask) == (permissions&tMask&(UniRead|UniWrite)))
02048 break;
02049 Q_ASSERT(standardPermissions[textIndex] != (mode_t)-1);
02050
02051 for (int i = 0; permissionsTexts[(int)d->pmode][i]; i++)
02052 combo->insertItem(i18n(permissionsTexts[(int)d->pmode][i]));
02053
02054 if (partial & tMask & ~UniExec) {
02055 combo->insertItem(i18n("Varying (No Change)"));
02056 combo->setCurrentItem(3);
02057 }
02058 else
02059 combo->setCurrentItem(textIndex);
02060 }
02061
02062
02063 bool KFilePermissionsPropsPlugin::isIrregular(mode_t permissions, bool isDir, bool isLink) {
02064 if (isLink)
02065 return false;
02066
02067 mode_t p = permissions;
02068 if (p & (S_ISUID | S_ISGID))
02069 return true;
02070 if (isDir) {
02071 p &= ~S_ISVTX;
02072
02073
02074 mode_t p0 = p & UniOwner;
02075 if ((p0 != 0) && (p0 != (S_IRUSR | S_IXUSR)) && (p0 != UniOwner))
02076 return true;
02077 p0 = p & UniGroup;
02078 if ((p0 != 0) && (p0 != (S_IRGRP | S_IXGRP)) && (p0 != UniGroup))
02079 return true;
02080 p0 = p & UniOthers;
02081 if ((p0 != 0) && (p0 != (S_IROTH | S_IXOTH)) && (p0 != UniOthers))
02082 return true;
02083 return false;
02084 }
02085 if (p & S_ISVTX)
02086 return true;
02087
02088
02089 mode_t p0 = p & UniOwner;
02090 bool usrXPossible = !p0;
02091 if (p0 & S_IXUSR) {
02092 if ((p0 == S_IXUSR) || (p0 == (S_IWUSR | S_IXUSR)))
02093 return true;
02094 usrXPossible = true;
02095 }
02096 else if (p0 == S_IWUSR)
02097 return true;
02098
02099 p0 = p & UniGroup;
02100 bool grpXPossible = !p0;
02101 if (p0 & S_IXGRP) {
02102 if ((p0 == S_IXGRP) || (p0 == (S_IWGRP | S_IXGRP)))
02103 return true;
02104 grpXPossible = true;
02105 }
02106 else if (p0 == S_IWGRP)
02107 return true;
02108 if (p0 == 0)
02109 grpXPossible = true;
02110
02111 p0 = p & UniOthers;
02112 bool othXPossible = !p0;
02113 if (p0 & S_IXOTH) {
02114 if ((p0 == S_IXOTH) || (p0 == (S_IWOTH | S_IXOTH)))
02115 return true;
02116 othXPossible = true;
02117 }
02118 else if (p0 == S_IWOTH)
02119 return true;
02120
02121
02122 return (p & UniExec) && !(usrXPossible && grpXPossible && othXPossible);
02123 }
02124
02125
02126 void KFilePermissionsPropsPlugin::enableAccessControls(bool enable) {
02127 d->ownerPermCombo->setEnabled(enable);
02128 d->groupPermCombo->setEnabled(enable);
02129 d->othersPermCombo->setEnabled(enable);
02130 if (d->extraCheckbox)
02131 d->extraCheckbox->setEnabled(enable);
02132 if ( d->cbRecursive )
02133 d->cbRecursive->setEnabled(enable);
02134 }
02135
02136
02137 void KFilePermissionsPropsPlugin::updateAccessControls() {
02138 setComboContent(d->ownerPermCombo, PermissionsOwner,
02139 permissions, d->partialPermissions);
02140 setComboContent(d->groupPermCombo, PermissionsGroup,
02141 permissions, d->partialPermissions);
02142 setComboContent(d->othersPermCombo, PermissionsOthers,
02143 permissions, d->partialPermissions);
02144
02145 switch(d->pmode) {
02146 case PermissionsOnlyLinks:
02147 enableAccessControls(false);
02148 break;
02149 case PermissionsOnlyFiles:
02150 enableAccessControls(d->canChangePermissions && !d->isIrregular);
02151 if (d->canChangePermissions)
02152 d->explanationLabel->setText(d->isIrregular ?
02153 i18n("This file uses advanced permissions",
02154 "These files use advanced permissions.",
02155 properties->items().count()) : "");
02156 if (d->partialPermissions & UniExec) {
02157 d->extraCheckbox->setTristate();
02158 d->extraCheckbox->setNoChange();
02159 }
02160 else {
02161 d->extraCheckbox->setTristate(false);
02162 d->extraCheckbox->setChecked(permissions & UniExec);
02163 }
02164 break;
02165 case PermissionsOnlyDirs:
02166 enableAccessControls(d->canChangePermissions && !d->isIrregular);
02167 if (d->canChangePermissions)
02168 d->explanationLabel->setText(d->isIrregular ?
02169 i18n("This folder uses advanced permissions.",
02170 "These folders use advanced permissions.",
02171 properties->items().count()) : "");
02172 if (d->partialPermissions & S_ISVTX) {
02173 d->extraCheckbox->setTristate();
02174 d->extraCheckbox->setNoChange();
02175 }
02176 else {
02177 d->extraCheckbox->setTristate(false);
02178 d->extraCheckbox->setChecked(permissions & S_ISVTX);
02179 }
02180 break;
02181 case PermissionsMixed:
02182 enableAccessControls(d->canChangePermissions && !d->isIrregular);
02183 if (d->canChangePermissions)
02184 d->explanationLabel->setText(d->isIrregular ?
02185 i18n("These files use advanced permissions.") : "");
02186 break;
02187 if (d->partialPermissions & S_ISVTX) {
02188 d->extraCheckbox->setTristate();
02189 d->extraCheckbox->setNoChange();
02190 }
02191 else {
02192 d->extraCheckbox->setTristate(false);
02193 d->extraCheckbox->setChecked(permissions & S_ISVTX);
02194 }
02195 break;
02196 }
02197 }
02198
02199
02200 void KFilePermissionsPropsPlugin::getPermissionMasks(mode_t &andFilePermissions,
02201 mode_t &andDirPermissions,
02202 mode_t &orFilePermissions,
02203 mode_t &orDirPermissions) {
02204 andFilePermissions = mode_t(~UniSpecial);
02205 andDirPermissions = mode_t(~(S_ISUID|S_ISGID));
02206 orFilePermissions = 0;
02207 orDirPermissions = 0;
02208 if (d->isIrregular)
02209 return;
02210
02211 mode_t m = standardPermissions[d->ownerPermCombo->currentItem()];
02212 if (m != (mode_t) -1) {
02213 orFilePermissions |= m & UniOwner;
02214 if ((m & UniOwner) &&
02215 ((d->pmode == PermissionsMixed) ||
02216 ((d->pmode == PermissionsOnlyFiles) && (d->extraCheckbox->state() == QButton::NoChange))))
02217 andFilePermissions &= ~(S_IRUSR | S_IWUSR);
02218 else {
02219 andFilePermissions &= ~(S_IRUSR | S_IWUSR | S_IXUSR);
02220 if ((m & S_IRUSR) && (d->extraCheckbox->state() == QButton::On))
02221 orFilePermissions |= S_IXUSR;
02222 }
02223
02224 orDirPermissions |= m & UniOwner;
02225 if (m & S_IRUSR)
02226 orDirPermissions |= S_IXUSR;
02227 andDirPermissions &= ~(S_IRUSR | S_IWUSR | S_IXUSR);
02228 }
02229
02230 m = standardPermissions[d->groupPermCombo->currentItem()];
02231 if (m != (mode_t) -1) {
02232 orFilePermissions |= m & UniGroup;
02233 if ((m & UniGroup) &&
02234 ((d->pmode == PermissionsMixed) ||
02235 ((d->pmode == PermissionsOnlyFiles) && (d->extraCheckbox->state() == QButton::NoChange))))
02236 andFilePermissions &= ~(S_IRGRP | S_IWGRP);
02237 else {
02238 andFilePermissions &= ~(S_IRGRP | S_IWGRP | S_IXGRP);
02239 if ((m & S_IRGRP) && (d->extraCheckbox->state() == QButton::On))
02240 orFilePermissions |= S_IXGRP;
02241 }
02242
02243 orDirPermissions |= m & UniGroup;
02244 if (m & S_IRGRP)
02245 orDirPermissions |= S_IXGRP;
02246 andDirPermissions &= ~(S_IRGRP | S_IWGRP | S_IXGRP);
02247 }
02248
02249 m = standardPermissions[d->othersPermCombo->currentItem()];
02250 if (m != (mode_t) -1) {
02251 orFilePermissions |= m & UniOthers;
02252 if ((m & UniOthers) &&
02253 ((d->pmode == PermissionsMixed) ||
02254 ((d->pmode == PermissionsOnlyFiles) && (d->extraCheckbox->state() == QButton::NoChange))))
02255 andFilePermissions &= ~(S_IROTH | S_IWOTH);
02256 else {
02257 andFilePermissions &= ~(S_IROTH | S_IWOTH | S_IXOTH);
02258 if ((m & S_IROTH) && (d->extraCheckbox->state() == QButton::On))
02259 orFilePermissions |= S_IXOTH;
02260 }
02261
02262 orDirPermissions |= m & UniOthers;
02263 if (m & S_IROTH)
02264 orDirPermissions |= S_IXOTH;
02265 andDirPermissions &= ~(S_IROTH | S_IWOTH | S_IXOTH);
02266 }
02267
02268 if (((d->pmode == PermissionsMixed) || (d->pmode == PermissionsOnlyDirs)) &&
02269 (d->extraCheckbox->state() != QButton::NoChange)) {
02270 andDirPermissions &= ~S_ISVTX;
02271 if (d->extraCheckbox->state() == QButton::On)
02272 orDirPermissions |= S_ISVTX;
02273 }
02274 }
02275
02276 void KFilePermissionsPropsPlugin::applyChanges()
02277 {
02278 mode_t orFilePermissions;
02279 mode_t orDirPermissions;
02280 mode_t andFilePermissions;
02281 mode_t andDirPermissions;
02282
02283 if (!d->canChangePermissions)
02284 return;
02285
02286 if (!d->isIrregular)
02287 getPermissionMasks(andFilePermissions,
02288 andDirPermissions,
02289 orFilePermissions,
02290 orDirPermissions);
02291 else {
02292 orFilePermissions = permissions;
02293 andFilePermissions = d->partialPermissions;
02294 orDirPermissions = permissions;
02295 andDirPermissions = d->partialPermissions;
02296 }
02297
02298 QString owner, group;
02299 if (usrEdit)
02300 owner = usrEdit->text();
02301 if (grpEdit)
02302 group = grpEdit->text();
02303 else if (grpCombo)
02304 group = grpCombo->currentText();
02305
02306 if (owner == strOwner)
02307 owner = QString::null;
02308
02309 if (group == strGroup)
02310 group = QString::null;
02311
02312 bool recursive = d->cbRecursive && d->cbRecursive->isChecked();
02313 bool permissionChange = false;
02314
02315 KFileItemList files, dirs;
02316 KFileItemList items = properties->items();
02317 for (KFileItemListIterator it(items); it.current(); ++it) {
02318 if ((*it)->isDir()) {
02319 dirs.append(*it);
02320 if ((*it)->permissions() != (((*it)->permissions() & andDirPermissions) | orDirPermissions))
02321 permissionChange = true;
02322 }
02323 else if ((*it)->isFile()) {
02324 files.append(*it);
02325 if ((*it)->permissions() != (((*it)->permissions() & andFilePermissions) | orFilePermissions))
02326 permissionChange = true;
02327 }
02328 }
02329
02330 if ( !owner.isEmpty() || !group.isEmpty() || recursive || permissionChange)
02331 {
02332 KIO::Job * job;
02333 if (files.count() > 0) {
02334 job = KIO::chmod( files, orFilePermissions, ~andFilePermissions,
02335 owner, group, false );
02336 connect( job, SIGNAL( result( KIO::Job * ) ),
02337 SLOT( slotChmodResult( KIO::Job * ) ) );
02338
02339 QWidget dummy(0,0,WType_Dialog|WShowModal);
02340 qt_enter_modal(&dummy);
02341 qApp->enter_loop();
02342 qt_leave_modal(&dummy);
02343 }
02344 if (dirs.count() > 0) {
02345 job = KIO::chmod( dirs, orDirPermissions, ~andDirPermissions,
02346 owner, group, recursive );
02347 connect( job, SIGNAL( result( KIO::Job * ) ),
02348 SLOT( slotChmodResult( KIO::Job * ) ) );
02349
02350 QWidget dummy(0,0,WType_Dialog|WShowModal);
02351 qt_enter_modal(&dummy);
02352 qApp->enter_loop();
02353 qt_leave_modal(&dummy);
02354 }
02355 }
02356 }
02357
02358 void KFilePermissionsPropsPlugin::slotChmodResult( KIO::Job * job )
02359 {
02360 kdDebug(250) << "KFilePermissionsPropsPlugin::slotChmodResult" << endl;
02361 if (job->error())
02362 job->showErrorDialog( d->m_frame );
02363
02364 qApp->exit_loop();
02365 }
02366
02367
02368
02369
02370 class KURLPropsPlugin::KURLPropsPluginPrivate
02371 {
02372 public:
02373 KURLPropsPluginPrivate()
02374 {
02375 }
02376 ~KURLPropsPluginPrivate()
02377 {
02378 }
02379
02380 QFrame *m_frame;
02381 };
02382
02383 KURLPropsPlugin::KURLPropsPlugin( KPropertiesDialog *_props )
02384 : KPropsDlgPlugin( _props )
02385 {
02386 d = new KURLPropsPluginPrivate;
02387 d->m_frame = properties->addPage(i18n("U&RL"));
02388 QVBoxLayout *layout = new QVBoxLayout(d->m_frame, 0, KDialog::spacingHint());
02389
02390 QLabel *l;
02391 l = new QLabel( d->m_frame, "Label_1" );
02392 l->setText( i18n("URL:") );
02393 layout->addWidget(l);
02394
02395 URLEdit = new KURLRequester( d->m_frame, "URL Requester" );
02396 layout->addWidget(URLEdit);
02397
02398 QString path = properties->kurl().path();
02399
02400 QFile f( path );
02401 if ( !f.open( IO_ReadOnly ) )
02402 return;
02403 f.close();
02404
02405 KSimpleConfig config( path );
02406 config.setDesktopGroup();
02407 URLStr = config.readPathEntry( "URL" );
02408
02409 if ( !URLStr.isNull() )
02410 URLEdit->setURL( URLStr );
02411
02412 connect( URLEdit, SIGNAL( textChanged( const QString & ) ),
02413 this, SIGNAL( changed() ) );
02414
02415 layout->addStretch (1);
02416 }
02417
02418 KURLPropsPlugin::~KURLPropsPlugin()
02419 {
02420 delete d;
02421 }
02422
02423
02424
02425
02426
02427
02428 bool KURLPropsPlugin::supports( KFileItemList _items )
02429 {
02430 if ( _items.count() != 1 )
02431 return false;
02432 KFileItem * item = _items.first();
02433
02434 if ( !KPropsDlgPlugin::isDesktopFile( item ) )
02435 return false;
02436
02437
02438 KDesktopFile config( item->url().path(), true );
02439 return config.hasLinkType();
02440 }
02441
02442 void KURLPropsPlugin::applyChanges()
02443 {
02444 QString path = properties->kurl().path();
02445
02446 QFile f( path );
02447 if ( !f.open( IO_ReadWrite ) ) {
02448 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have "
02449 "sufficient access to write to <b>%1</b>.</qt>").arg(path));
02450 return;
02451 }
02452 f.close();
02453
02454 KSimpleConfig config( path );
02455 config.setDesktopGroup();
02456 config.writeEntry( "Type", QString::fromLatin1("Link"));
02457 config.writePathEntry( "URL", URLEdit->url() );
02458
02459
02460 if ( config.hasKey("Name") )
02461 {
02462 QString nameStr = nameFromFileName(properties->kurl().fileName());
02463 config.writeEntry( "Name", nameStr );
02464 config.writeEntry( "Name", nameStr, true, false, true );
02465
02466 }
02467 }
02468
02469
02470
02471
02472
02473
02474
02475
02476 class KBindingPropsPlugin::KBindingPropsPluginPrivate
02477 {
02478 public:
02479 KBindingPropsPluginPrivate()
02480 {
02481 }
02482 ~KBindingPropsPluginPrivate()
02483 {
02484 }
02485
02486 QFrame *m_frame;
02487 };
02488
02489 KBindingPropsPlugin::KBindingPropsPlugin( KPropertiesDialog *_props ) : KPropsDlgPlugin( _props )
02490 {
02491 d = new KBindingPropsPluginPrivate;
02492 d->m_frame = properties->addPage(i18n("A&ssociation"));
02493 patternEdit = new KLineEdit( d->m_frame, "LineEdit_1" );
02494 commentEdit = new KLineEdit( d->m_frame, "LineEdit_2" );
02495 mimeEdit = new KLineEdit( d->m_frame, "LineEdit_3" );
02496
02497 QBoxLayout *mainlayout = new QVBoxLayout(d->m_frame, 0, KDialog::spacingHint());
02498 QLabel* tmpQLabel;
02499
02500 tmpQLabel = new QLabel( d->m_frame, "Label_1" );
02501 tmpQLabel->setText( i18n("Pattern ( example: *.html;*.htm )") );
02502 tmpQLabel->setMinimumSize(tmpQLabel->sizeHint());
02503 mainlayout->addWidget(tmpQLabel, 1);
02504
02505
02506
02507 patternEdit->setMaxLength( 512 );
02508 patternEdit->setMinimumSize( patternEdit->sizeHint() );
02509 patternEdit->setFixedHeight( fontHeight );
02510 mainlayout->addWidget(patternEdit, 1);
02511
02512 tmpQLabel = new QLabel( d->m_frame, "Label_2" );
02513 tmpQLabel->setText( i18n("Mime Type") );
02514 tmpQLabel->setMinimumSize(tmpQLabel->sizeHint());
02515 mainlayout->addWidget(tmpQLabel, 1);
02516
02517
02518 mimeEdit->setMaxLength( 256 );
02519 mimeEdit->setMinimumSize( mimeEdit->sizeHint() );
02520 mimeEdit->setFixedHeight( fontHeight );
02521 mainlayout->addWidget(mimeEdit, 1);
02522
02523 tmpQLabel = new QLabel( d->m_frame, "Label_3" );
02524 tmpQLabel->setText( i18n("Comment") );
02525 tmpQLabel->setMinimumSize(tmpQLabel->sizeHint());
02526 mainlayout->addWidget(tmpQLabel, 1);
02527
02528
02529 commentEdit->setMaxLength( 256 );
02530 commentEdit->setMinimumSize( commentEdit->sizeHint() );
02531 commentEdit->setFixedHeight( fontHeight );
02532 mainlayout->addWidget(commentEdit, 1);
02533
02534 cbAutoEmbed = new QCheckBox( i18n("Left click previews"), d->m_frame, "cbAutoEmbed" );
02535 mainlayout->addWidget(cbAutoEmbed, 1);
02536
02537 mainlayout->addStretch (10);
02538 mainlayout->activate();
02539
02540 QFile f( _props->kurl().path() );
02541 if ( !f.open( IO_ReadOnly ) )
02542 return;
02543 f.close();
02544
02545 KSimpleConfig config( _props->kurl().path() );
02546 config.setDesktopGroup();
02547 QString patternStr = config.readEntry( "Patterns" );
02548 QString iconStr = config.readEntry( "Icon" );
02549 QString commentStr = config.readEntry( "Comment" );
02550 m_sMimeStr = config.readEntry( "MimeType" );
02551
02552 if ( !patternStr.isEmpty() )
02553 patternEdit->setText( patternStr );
02554 if ( !commentStr.isEmpty() )
02555 commentEdit->setText( commentStr );
02556 if ( !m_sMimeStr.isEmpty() )
02557 mimeEdit->setText( m_sMimeStr );
02558 cbAutoEmbed->setTristate();
02559 if ( config.hasKey( "X-KDE-AutoEmbed" ) )
02560 cbAutoEmbed->setChecked( config.readBoolEntry( "X-KDE-AutoEmbed" ) );
02561 else
02562 cbAutoEmbed->setNoChange();
02563
02564 connect( patternEdit, SIGNAL( textChanged( const QString & ) ),
02565 this, SIGNAL( changed() ) );
02566 connect( commentEdit, SIGNAL( textChanged( const QString & ) ),
02567 this, SIGNAL( changed() ) );
02568 connect( mimeEdit, SIGNAL( textChanged( const QString & ) ),
02569 this, SIGNAL( changed() ) );
02570 connect( cbAutoEmbed, SIGNAL( toggled( bool ) ),
02571 this, SIGNAL( changed() ) );
02572 }
02573
02574 KBindingPropsPlugin::~KBindingPropsPlugin()
02575 {
02576 delete d;
02577 }
02578
02579
02580
02581
02582
02583
02584 bool KBindingPropsPlugin::supports( KFileItemList _items )
02585 {
02586 if ( _items.count() != 1 )
02587 return false;
02588 KFileItem * item = _items.first();
02589
02590 if ( !KPropsDlgPlugin::isDesktopFile( item ) )
02591 return false;
02592
02593
02594 KDesktopFile config( item->url().path(), true );
02595 return config.hasMimeTypeType();
02596 }
02597
02598 void KBindingPropsPlugin::applyChanges()
02599 {
02600 QString path = properties->kurl().path();
02601 QFile f( path );
02602
02603 if ( !f.open( IO_ReadWrite ) )
02604 {
02605 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have "
02606 "sufficient access to write to <b>%1</b>.</qt>").arg(path));
02607 return;
02608 }
02609 f.close();
02610
02611 KSimpleConfig config( path );
02612 config.setDesktopGroup();
02613 config.writeEntry( "Type", QString::fromLatin1("MimeType") );
02614
02615 config.writeEntry( "Patterns", patternEdit->text() );
02616 config.writeEntry( "Comment", commentEdit->text() );
02617 config.writeEntry( "Comment",
02618 commentEdit->text(), true, false, true );
02619 config.writeEntry( "MimeType", mimeEdit->text() );
02620 if ( cbAutoEmbed->state() == QButton::NoChange )
02621 config.deleteEntry( "X-KDE-AutoEmbed", false );
02622 else
02623 config.writeEntry( "X-KDE-AutoEmbed", cbAutoEmbed->isChecked() );
02624 config.sync();
02625 }
02626
02627
02628
02629
02630
02631
02632
02633 class KDevicePropsPlugin::KDevicePropsPluginPrivate
02634 {
02635 public:
02636 KDevicePropsPluginPrivate()
02637 {
02638 }
02639 ~KDevicePropsPluginPrivate()
02640 {
02641 }
02642
02643 QFrame *m_frame;
02644 QStringList mountpointlist;
02645 QLabel *m_freeSpaceText;
02646 QLabel *m_freeSpaceLabel;
02647 QProgressBar *m_freeSpaceBar;
02648 };
02649
02650 KDevicePropsPlugin::KDevicePropsPlugin( KPropertiesDialog *_props ) : KPropsDlgPlugin( _props )
02651 {
02652 d = new KDevicePropsPluginPrivate;
02653 d->m_frame = properties->addPage(i18n("De&vice"));
02654
02655 QStringList devices;
02656 KMountPoint::List mountPoints = KMountPoint::possibleMountPoints();
02657
02658 for(KMountPoint::List::ConstIterator it = mountPoints.begin();
02659 it != mountPoints.end(); ++it)
02660 {
02661 KMountPoint *mp = *it;
02662 QString mountPoint = mp->mountPoint();
02663 QString device = mp->mountedFrom();
02664 kdDebug()<<"mountPoint :"<<mountPoint<<" device :"<<device<<" mp->mountType() :"<<mp->mountType()<<endl;
02665
02666 if ((mountPoint != "-") && (mountPoint != "none") && !mountPoint.isEmpty()
02667 && device != "none")
02668 {
02669 devices.append( device + QString::fromLatin1(" (")
02670 + mountPoint + QString::fromLatin1(")") );
02671 m_devicelist.append(device);
02672 d->mountpointlist.append(mountPoint);
02673 }
02674 }
02675
02676 QGridLayout *layout = new QGridLayout( d->m_frame, 0, 2, 0,
02677 KDialog::spacingHint());
02678 layout->setColStretch(1, 1);
02679
02680 QLabel* label;
02681 label = new QLabel( d->m_frame );
02682 label->setText( devices.count() == 0 ?
02683 i18n("Device (/dev/fd0):") :
02684 i18n("Device:") );
02685 layout->addWidget(label, 0, 0);
02686
02687 device = new QComboBox( true, d->m_frame, "ComboBox_device" );
02688 device->insertStringList( devices );
02689 layout->addWidget(device, 0, 1);
02690 connect( device, SIGNAL( activated( int ) ),
02691 this, SLOT( slotActivated( int ) ) );
02692
02693 readonly = new QCheckBox( d->m_frame, "CheckBox_readonly" );
02694 readonly->setText( i18n("Read only") );
02695 layout->addWidget(readonly, 1, 1);
02696
02697 label = new QLabel( d->m_frame );
02698 label->setText( i18n("File system:") );
02699 layout->addWidget(label, 2, 0);
02700
02701 QLabel *fileSystem = new QLabel( d->m_frame );
02702 layout->addWidget(fileSystem, 2, 1);
02703
02704 label = new QLabel( d->m_frame );
02705 label->setText( devices.count()==0 ?
02706 i18n("Mount point (/mnt/floppy):") :
02707 i18n("Mount point:"));
02708 layout->addWidget(label, 3, 0);
02709
02710 mountpoint = new QLabel( d->m_frame, "LineEdit_mountpoint" );
02711
02712 layout->addWidget(mountpoint, 3, 1);
02713
02714
02715 d->m_freeSpaceText = new QLabel(i18n("Free disk space:"), d->m_frame );
02716 layout->addWidget(d->m_freeSpaceText, 4, 0);
02717
02718 d->m_freeSpaceLabel = new QLabel( d->m_frame );
02719 layout->addWidget( d->m_freeSpaceLabel, 4, 1 );
02720
02721 d->m_freeSpaceBar = new QProgressBar( d->m_frame, "freeSpaceBar" );
02722 layout->addMultiCellWidget(d->m_freeSpaceBar, 5, 5, 0, 1);
02723
02724
02725 d->m_freeSpaceText->hide();
02726 d->m_freeSpaceLabel->hide();
02727 d->m_freeSpaceBar->hide();
02728
02729 KSeparator* sep = new KSeparator( KSeparator::HLine, d->m_frame);
02730 layout->addMultiCellWidget(sep, 6, 6, 0, 1);
02731
02732 unmounted = new KIconButton( d->m_frame );
02733 int bsize = 66 + 2 * unmounted->style().pixelMetric(QStyle::PM_ButtonMargin);
02734 unmounted->setFixedSize(bsize, bsize);
02735 unmounted->setIconType(KIcon::Desktop, KIcon::Device);
02736 layout->addWidget(unmounted, 7, 0);
02737
02738 label = new QLabel( i18n("Unmounted Icon"), d->m_frame );
02739 layout->addWidget(label, 7, 1);
02740
02741 layout->setRowStretch(8, 1);
02742
02743 QString path( _props->kurl().path() );
02744
02745 QFile f( path );
02746 if ( !f.open( IO_ReadOnly ) )
02747 return;
02748 f.close();
02749
02750 KSimpleConfig config( path );
02751 config.setDesktopGroup();
02752 QString deviceStr = config.readEntry( "Dev" );
02753 QString mountPointStr = config.readEntry( "MountPoint" );
02754 bool ro = config.readBoolEntry( "ReadOnly", false );
02755 QString unmountedStr = config.readEntry( "UnmountIcon" );
02756
02757 fileSystem->setText( i18n(config.readEntry("FSType").local8Bit()) );
02758
02759 device->setEditText( deviceStr );
02760 if ( !deviceStr.isEmpty() ) {
02761
02762 int index = m_devicelist.findIndex(deviceStr);
02763 if (index != -1)
02764 {
02765
02766 slotActivated( index );
02767 }
02768 }
02769
02770 if ( !mountPointStr.isEmpty() )
02771 {
02772 mountpoint->setText( mountPointStr );
02773 updateInfo();
02774 }
02775
02776 readonly->setChecked( ro );
02777
02778 if ( unmountedStr.isEmpty() )
02779 unmountedStr = KMimeType::mimeType(QString::fromLatin1("application/octet-stream"))->KServiceType::icon();
02780
02781 unmounted->setIcon( unmountedStr );
02782
02783 connect( device, SIGNAL( activated( int ) ),
02784 this, SIGNAL( changed() ) );
02785 connect( device, SIGNAL( textChanged( const QString & ) ),
02786 this, SIGNAL( changed() ) );
02787 connect( readonly, SIGNAL( toggled( bool ) ),
02788 this, SIGNAL( changed() ) );
02789 connect( unmounted, SIGNAL( iconChanged( QString ) ),
02790 this, SIGNAL( changed() ) );
02791
02792 connect( device, SIGNAL( textChanged( const QString & ) ),
02793 this, SLOT( slotDeviceChanged() ) );
02794 }
02795
02796 KDevicePropsPlugin::~KDevicePropsPlugin()
02797 {
02798 delete d;
02799 }
02800
02801
02802
02803
02804
02805
02806 void KDevicePropsPlugin::updateInfo()
02807 {
02808
02809 d->m_freeSpaceText->hide();
02810 d->m_freeSpaceLabel->hide();
02811 d->m_freeSpaceBar->hide();
02812
02813 if ( !mountpoint->text().isEmpty() )
02814 {
02815 KDiskFreeSp * job = new KDiskFreeSp;
02816 connect( job, SIGNAL( foundMountPoint( const unsigned long&, const unsigned long&,
02817 const unsigned long&, const QString& ) ),
02818 this, SLOT( slotFoundMountPoint( const unsigned long&, const unsigned long&,
02819 const unsigned long&, const QString& ) ) );
02820
02821 job->readDF( mountpoint->text() );
02822 }
02823 }
02824
02825 void KDevicePropsPlugin::slotActivated( int index )
02826 {
02827
02828 device->setEditText( m_devicelist[index] );
02829 mountpoint->setText( d->mountpointlist[index] );
02830
02831 updateInfo();
02832 }
02833
02834 void KDevicePropsPlugin::slotDeviceChanged()
02835 {
02836
02837 int index = m_devicelist.findIndex( device->currentText() );
02838 if ( index != -1 )
02839 mountpoint->setText( d->mountpointlist[index] );
02840 else
02841 mountpoint->setText( QString::null );
02842
02843 updateInfo();
02844 }
02845
02846 void KDevicePropsPlugin::slotFoundMountPoint( const unsigned long& kBSize,
02847 const unsigned long& ,
02848 const unsigned long& kBAvail,
02849 const QString& )
02850 {
02851 d->m_freeSpaceText->show();
02852 d->m_freeSpaceLabel->show();
02853
02854 int percUsed = 100 - (int)(100.0 * kBAvail / kBSize);
02855
02856 d->m_freeSpaceLabel->setText(
02857 i18n("Available space out of total partition size (percent used)", "%1 out of %2 (%3% used)")
02858 .arg(KIO::convertSizeFromKB(kBAvail))
02859 .arg(KIO::convertSizeFromKB(kBSize))
02860 .arg( 100 - (int)(100.0 * kBAvail / kBSize) ));
02861
02862 d->m_freeSpaceBar->setProgress(percUsed, 100);
02863 d->m_freeSpaceBar->show();
02864 }
02865
02866 bool KDevicePropsPlugin::supports( KFileItemList _items )
02867 {
02868 if ( _items.count() != 1 )
02869 return false;
02870 KFileItem * item = _items.first();
02871
02872 if ( !KPropsDlgPlugin::isDesktopFile( item ) )
02873 return false;
02874
02875 KDesktopFile config( item->url().path(), true );
02876 return config.hasDeviceType();
02877 }
02878
02879 void KDevicePropsPlugin::applyChanges()
02880 {
02881 QString path = properties->kurl().path();
02882 QFile f( path );
02883 if ( !f.open( IO_ReadWrite ) )
02884 {
02885 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have sufficient "
02886 "access to write to <b>%1</b>.</qt>").arg(path));
02887 return;
02888 }
02889 f.close();
02890
02891 KSimpleConfig config( path );
02892 config.setDesktopGroup();
02893 config.writeEntry( "Type", QString::fromLatin1("FSDevice") );
02894
02895 config.writeEntry( "Dev", device->currentText() );
02896 config.writeEntry( "MountPoint", mountpoint->text() );
02897
02898 config.writeEntry( "UnmountIcon", unmounted->icon() );
02899 kdDebug(250) << "unmounted->icon() = " << unmounted->icon() << endl;
02900
02901 config.writeEntry( "ReadOnly", readonly->isChecked() );
02902
02903 config.sync();
02904 }
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914 KDesktopPropsPlugin::KDesktopPropsPlugin( KPropertiesDialog *_props )
02915 : KPropsDlgPlugin( _props )
02916 {
02917 QFrame *frame = properties->addPage(i18n("&Application"));
02918 QVBoxLayout *mainlayout = new QVBoxLayout( frame, 0, KDialog::spacingHint() );
02919
02920 w = new KPropertiesDesktopBase(frame);
02921 mainlayout->addWidget(w);
02922
02923 bool bKDesktopMode = (QCString(qApp->name()) == "kdesktop");
02924
02925 if (bKDesktopMode)
02926 {
02927
02928 w->nameEdit->hide();
02929 w->nameLabel->hide();
02930 }
02931
02932 w->pathEdit->setMode(KFile::Directory | KFile::LocalOnly);
02933 w->pathEdit->lineEdit()->setAcceptDrops(false);
02934
02935 connect( w->nameEdit, SIGNAL( textChanged( const QString & ) ), this, SIGNAL( changed() ) );
02936 connect( w->genNameEdit, SIGNAL( textChanged( const QString & ) ), this, SIGNAL( changed() ) );
02937 connect( w->commentEdit, SIGNAL( textChanged( const QString & ) ), this, SIGNAL( changed() ) );
02938 connect( w->commandEdit, SIGNAL( textChanged( const QString & ) ), this, SIGNAL( changed() ) );
02939 connect( w->pathEdit, SIGNAL( textChanged( const QString & ) ), this, SIGNAL( changed() ) );
02940
02941 connect( w->browseButton, SIGNAL( clicked() ), this, SLOT( slotBrowseExec() ) );
02942 connect( w->addFiletypeButton, SIGNAL( clicked() ), this, SLOT( slotAddFiletype() ) );
02943 connect( w->delFiletypeButton, SIGNAL( clicked() ), this, SLOT( slotDelFiletype() ) );
02944 connect( w->advancedButton, SIGNAL( clicked() ), this, SLOT( slotAdvanced() ) );
02945
02946
02947 QString path = _props->kurl().path();
02948 QFile f( path );
02949 if ( !f.open( IO_ReadOnly ) )
02950 return;
02951 f.close();
02952
02953 KSimpleConfig config( path );
02954 config.setDollarExpansion( false );
02955 config.setDesktopGroup();
02956 QString nameStr = config.readEntry( "Name" );
02957 QString genNameStr = config.readEntry( "GenericName" );
02958 QString commentStr = config.readEntry( "Comment" );
02959 QString commandStr = config.readPathEntry( "Exec" );
02960 if (commandStr.left(12) == "ksystraycmd ")
02961 {
02962 commandStr.remove(0, 12);
02963 m_systrayBool = true;
02964 }
02965 else
02966 m_systrayBool = false;
02967
02968 m_origCommandStr = commandStr;
02969 QString pathStr = config.readPathEntry( "Path" );
02970 m_terminalBool = config.readBoolEntry( "Terminal" );
02971 m_terminalOptionStr = config.readEntry( "TerminalOptions" );
02972 m_suidBool = config.readBoolEntry( "X-KDE-SubstituteUID" );
02973 m_suidUserStr = config.readEntry( "X-KDE-Username" );
02974 if( config.hasKey( "StartupNotify" ))
02975 m_startupBool = config.readBoolEntry( "StartupNotify", true );
02976 else
02977 m_startupBool = config.readBoolEntry( "X-KDE-StartupNotify", true );
02978 m_dcopServiceType = config.readEntry("X-DCOP-ServiceType").lower();
02979
02980 QStringList mimeTypes = config.readListEntry( "MimeType", ';' );
02981
02982 if ( nameStr.isEmpty() || bKDesktopMode ) {
02983
02984
02985
02986 setDirty();
02987 }
02988 if ( !bKDesktopMode )
02989 w->nameEdit->setText(nameStr);
02990
02991 w->genNameEdit->setText( genNameStr );
02992 w->commentEdit->setText( commentStr );
02993 w->commandEdit->setText( commandStr );
02994 w->pathEdit->lineEdit()->setText( pathStr );
02995 w->filetypeList->setAllColumnsShowFocus(true);
02996
02997 KMimeType::Ptr defaultMimetype = KMimeType::defaultMimeTypePtr();
02998 for(QStringList::ConstIterator it = mimeTypes.begin();
02999 it != mimeTypes.end(); )
03000 {
03001 KMimeType::Ptr p = KMimeType::mimeType(*it);
03002 ++it;
03003 QString preference;
03004 if (it != mimeTypes.end())
03005 {
03006 bool numeric;
03007 (*it).toInt(&numeric);
03008 if (numeric)
03009 {
03010 preference = *it;
03011 ++it;
03012 }
03013 }
03014 if (p && (p != defaultMimetype))
03015 {
03016 new QListViewItem(w->filetypeList, p->name(), p->comment(), preference);
03017 }
03018 }
03019
03020 }
03021
03022 KDesktopPropsPlugin::~KDesktopPropsPlugin()
03023 {
03024 }
03025
03026 void KDesktopPropsPlugin::slotSelectMimetype()
03027 {
03028 QListView *w = (QListView*)sender();
03029 QListViewItem *item = w->firstChild();
03030 while(item)
03031 {
03032 if (item->isSelected())
03033 w->setSelected(item, false);
03034 item = item->nextSibling();
03035 }
03036 }
03037
03038 void KDesktopPropsPlugin::slotAddFiletype()
03039 {
03040 KDialogBase dlg(w, "KPropertiesMimetypes", true,
03041 i18n("Add File Type for %1").arg(properties->kurl().fileName()),
03042 KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok);
03043
03044 KGuiItem okItem(i18n("&Add"), QString::null ,
03045 i18n("Add the selected file types to\nthe list of supported file types."),
03046 i18n("Add the selected file types to\nthe list of supported file types."));
03047 dlg.setButtonOK(okItem);
03048
03049 KPropertiesMimetypeBase *mw = new KPropertiesMimetypeBase(&dlg);
03050
03051 dlg.setMainWidget(mw);
03052
03053 {
03054 mw->listView->setRootIsDecorated(true);
03055 mw->listView->setSelectionMode(QListView::Extended);
03056 mw->listView->setAllColumnsShowFocus(true);
03057 mw->listView->setFullWidth(true);
03058 mw->listView->setMinimumSize(500,400);
03059
03060 connect(mw->listView, SIGNAL(selectionChanged()),
03061 this, SLOT(slotSelectMimetype()));
03062 connect(mw->listView, SIGNAL(doubleClicked( QListViewItem *, const QPoint &, int )),
03063 &dlg, SLOT( slotOk()));
03064
03065 QMap<QString,QListViewItem*> majorMap;
03066 QListViewItem *majorGroup;
03067 KMimeType::List mimetypes = KMimeType::allMimeTypes();
03068 QValueListIterator<KMimeType::Ptr> it(mimetypes.begin());
03069 for (; it != mimetypes.end(); ++it) {
03070 QString mimetype = (*it)->name();
03071 if (mimetype == "application/octet-stream")
03072 continue;
03073 int index = mimetype.find("/");
03074 QString maj = mimetype.left(index);
03075 QString min = mimetype.mid(index+1);
03076
03077 QMapIterator<QString,QListViewItem*> mit = majorMap.find( maj );
03078 if ( mit == majorMap.end() ) {
03079 majorGroup = new QListViewItem( mw->listView, maj );
03080 majorGroup->setExpandable(true);
03081 mw->listView->setOpen(majorGroup, true);
03082 majorMap.insert( maj, majorGroup );
03083 }
03084 else
03085 {
03086 majorGroup = mit.data();
03087 }
03088
03089 QListViewItem *item = new QListViewItem(majorGroup, min, (*it)->comment());
03090 item->setPixmap(0, (*it)->pixmap(KIcon::Small, IconSize(KIcon::Small)));
03091 }
03092 QMapIterator<QString,QListViewItem*> mit = majorMap.find( "all" );
03093 if ( mit != majorMap.end())
03094 {
03095 mw->listView->setCurrentItem(mit.data());
03096 mw->listView->ensureItemVisible(mit.data());
03097 }
03098 }
03099
03100 if (dlg.exec() == KDialogBase::Accepted)
03101 {
03102 KMimeType::Ptr defaultMimetype = KMimeType::defaultMimeTypePtr();
03103 QListViewItem *majorItem = mw->listView->firstChild();
03104 while(majorItem)
03105 {
03106 QString major = majorItem->text(0);
03107
03108 QListViewItem *minorItem = majorItem->firstChild();
03109 while(minorItem)
03110 {
03111 if (minorItem->isSelected())
03112 {
03113 QString mimetype = major + "/" + minorItem->text(0);
03114 KMimeType::Ptr p = KMimeType::mimeType(mimetype);
03115 if (p && (p != defaultMimetype))
03116 {
03117 mimetype = p->name();
03118 bool found = false;
03119 QListViewItem *item = w->filetypeList->firstChild();
03120 while (item)
03121 {
03122 if (mimetype == item->text(0))
03123 {
03124 found = true;
03125 break;
03126 }
03127 item = item->nextSibling();
03128 }
03129 if (!found)
03130 new QListViewItem(w->filetypeList, p->name(), p->comment());
03131 }
03132 }
03133 minorItem = minorItem->nextSibling();
03134 }
03135
03136 majorItem = majorItem->nextSibling();
03137 }
03138
03139 }
03140 }
03141
03142 void KDesktopPropsPlugin::slotDelFiletype()
03143 {
03144 delete w->filetypeList->currentItem();
03145 }
03146
03147 void KDesktopPropsPlugin::checkCommandChanged()
03148 {
03149 if (KRun::binaryName(w->commandEdit->text(), true) !=
03150 KRun::binaryName(m_origCommandStr, true))
03151 {
03152 QString m_origCommandStr = w->commandEdit->text();
03153 m_dcopServiceType= QString::null;
03154 }
03155 }
03156
03157 void KDesktopPropsPlugin::applyChanges()
03158 {
03159 kdDebug(250) << "KDesktopPropsPlugin::applyChanges" << endl;
03160 QString path = properties->kurl().path();
03161
03162 QFile f( path );
03163
03164 if ( !f.open( IO_ReadWrite ) ) {
03165 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have "
03166 "sufficient access to write to <b>%1</b>.</qt>").arg(path));
03167 return;
03168 }
03169 f.close();
03170
03171
03172
03173 checkCommandChanged();
03174
03175 KSimpleConfig config( path );
03176 config.setDesktopGroup();
03177 config.writeEntry( "Type", QString::fromLatin1("Application"));
03178 config.writeEntry( "Comment", w->commentEdit->text() );
03179 config.writeEntry( "Comment", w->commentEdit->text(), true, false, true );
03180 config.writeEntry( "GenericName", w->genNameEdit->text() );
03181 config.writeEntry( "GenericName", w->genNameEdit->text(), true, false, true );
03182
03183 if (m_systrayBool)
03184 config.writePathEntry( "Exec", w->commandEdit->text().prepend("ksystraycmd ") );
03185 else
03186 config.writePathEntry( "Exec", w->commandEdit->text() );
03187 config.writePathEntry( "Path", w->pathEdit->lineEdit()->text() );
03188
03189
03190 QStringList mimeTypes;
03191 for( QListViewItem *item = w->filetypeList->firstChild();
03192 item; item = item->nextSibling() )
03193 {
03194 QString preference = item->text(2);
03195 mimeTypes.append(item->text(0));
03196 if (!preference.isEmpty())
03197 mimeTypes.append(preference);
03198 }
03199
03200 config.writeEntry( "MimeType", mimeTypes, ';' );
03201
03202 if ( !w->nameEdit->isHidden() ) {
03203 QString nameStr = w->nameEdit->text();
03204 config.writeEntry( "Name", nameStr );
03205 config.writeEntry( "Name", nameStr, true, false, true );
03206 }
03207
03208 config.writeEntry("Terminal", m_terminalBool);
03209 config.writeEntry("TerminalOptions", m_terminalOptionStr);
03210 config.writeEntry("X-KDE-SubstituteUID", m_suidBool);
03211 config.writeEntry("X-KDE-Username", m_suidUserStr);
03212 config.writeEntry("StartupNotify", m_startupBool);
03213 config.writeEntry("X-DCOP-ServiceType", m_dcopServiceType);
03214 config.sync();
03215
03216
03217 QString sycocaPath = KGlobal::dirs()->relativeLocation("apps", path);
03218 bool updateNeeded = !sycocaPath.startsWith("/");
03219 if (!updateNeeded)
03220 {
03221 sycocaPath = KGlobal::dirs()->relativeLocation("xdgdata-apps", path);
03222 updateNeeded = !sycocaPath.startsWith("/");
03223 }
03224 if (updateNeeded)
03225 KService::rebuildKSycoca(w);
03226 }
03227
03228
03229 void KDesktopPropsPlugin::slotBrowseExec()
03230 {
03231 KURL f = KFileDialog::getOpenURL( QString::null,
03232 QString::null, w );
03233 if ( f.isEmpty() )
03234 return;
03235
03236 if ( !f.isLocalFile()) {
03237 KMessageBox::sorry(w, i18n("Only executables on local file systems are supported."));
03238 return;
03239 }
03240
03241 QString path = f.path();
03242 KRun::shellQuote( path );
03243 w->commandEdit->setText( path );
03244 }
03245
03246 void KDesktopPropsPlugin::slotAdvanced()
03247 {
03248 KDialogBase dlg(w, "KPropertiesDesktopAdv", true,
03249 i18n("Advanced Options for %1").arg(properties->kurl().fileName()),
03250 KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok);
03251 KPropertiesDesktopAdvBase *w = new KPropertiesDesktopAdvBase(&dlg);
03252
03253 dlg.setMainWidget(w);
03254
03255
03256
03257 checkCommandChanged();
03258
03259
03260
03261 KConfigGroup confGroup( KGlobal::config(), QString::fromLatin1("General") );
03262 QString preferredTerminal = confGroup.readPathEntry("TerminalApplication",
03263 QString::fromLatin1("konsole"));
03264
03265 bool terminalCloseBool = false;
03266
03267 if (preferredTerminal == "konsole")
03268 {
03269 terminalCloseBool = (m_terminalOptionStr.contains( "--noclose" ) > 0);
03270 w->terminalCloseCheck->setChecked(terminalCloseBool);
03271 m_terminalOptionStr.replace( "--noclose", "");
03272 }
03273 else
03274 {
03275 w->terminalCloseCheck->hide();
03276 }
03277
03278 w->terminalCheck->setChecked(m_terminalBool);
03279 w->terminalEdit->setText(m_terminalOptionStr);
03280 w->terminalCloseCheck->setEnabled(m_terminalBool);
03281 w->terminalEdit->setEnabled(m_terminalBool);
03282 w->terminalEditLabel->setEnabled(m_terminalBool);
03283
03284 w->suidCheck->setChecked(m_suidBool);
03285 w->suidEdit->setText(m_suidUserStr);
03286 w->suidEdit->setEnabled(m_suidBool);
03287 w->suidEditLabel->setEnabled(m_suidBool);
03288
03289 w->startupInfoCheck->setChecked(m_startupBool);
03290 w->systrayCheck->setChecked(m_systrayBool);
03291
03292 if (m_dcopServiceType == "unique")
03293 w->dcopCombo->setCurrentItem(2);
03294 else if (m_dcopServiceType == "multi")
03295 w->dcopCombo->setCurrentItem(1);
03296 else if (m_dcopServiceType == "wait")
03297 w->dcopCombo->setCurrentItem(3);
03298 else
03299 w->dcopCombo->setCurrentItem(0);
03300
03301
03302 KCompletion *kcom = new KCompletion;
03303 kcom->setOrder(KCompletion::Sorted);
03304 struct passwd *pw;
03305 int i, maxEntries = 1000;
03306 setpwent();
03307 for (i=0; ((pw = getpwent()) != 0L) && (i < maxEntries); i++)
03308 kcom->addItem(QString::fromLatin1(pw->pw_name));
03309 endpwent();
03310 if (i < maxEntries)
03311 {
03312 w->suidEdit->setCompletionObject(kcom, true);
03313 w->suidEdit->setAutoDeleteCompletionObject( true );
03314 w->suidEdit->setCompletionMode(KGlobalSettings::CompletionAuto);
03315 }
03316 else
03317 {
03318 delete kcom;
03319 }
03320
03321 connect( w->terminalEdit, SIGNAL( textChanged( const QString & ) ),
03322 this, SIGNAL( changed() ) );
03323 connect( w->terminalCloseCheck, SIGNAL( toggled( bool ) ),
03324 this, SIGNAL( changed() ) );
03325 connect( w->terminalCheck, SIGNAL( toggled( bool ) ),
03326 this, SIGNAL( changed() ) );
03327 connect( w->suidCheck, SIGNAL( toggled( bool ) ),
03328 this, SIGNAL( changed() ) );
03329 connect( w->suidEdit, SIGNAL( textChanged( const QString & ) ),
03330 this, SIGNAL( changed() ) );
03331 connect( w->startupInfoCheck, SIGNAL( toggled( bool ) ),
03332 this, SIGNAL( changed() ) );
03333 connect( w->systrayCheck, SIGNAL( toggled( bool ) ),
03334 this, SIGNAL( changed() ) );
03335 connect( w->dcopCombo, SIGNAL( highlighted( int ) ),
03336 this, SIGNAL( changed() ) );
03337
03338 if ( dlg.exec() == QDialog::Accepted )
03339 {
03340 m_terminalOptionStr = w->terminalEdit->text().stripWhiteSpace();
03341 m_terminalBool = w->terminalCheck->isChecked();
03342 m_suidBool = w->suidCheck->isChecked();
03343 m_suidUserStr = w->suidEdit->text().stripWhiteSpace();
03344 m_startupBool = w->startupInfoCheck->isChecked();
03345 m_systrayBool = w->systrayCheck->isChecked();
03346
03347 if (w->terminalCloseCheck->isChecked())
03348 {
03349 m_terminalOptionStr.append(" --noclose");
03350 }
03351
03352 switch(w->dcopCombo->currentItem())
03353 {
03354 case 1: m_dcopServiceType = "multi"; break;
03355 case 2: m_dcopServiceType = "unique"; break;
03356 case 3: m_dcopServiceType = "wait"; break;
03357 default: m_dcopServiceType = "none"; break;
03358 }
03359 }
03360 }
03361
03362 bool KDesktopPropsPlugin::supports( KFileItemList _items )
03363 {
03364 if ( _items.count() != 1 )
03365 return false;
03366 KFileItem * item = _items.first();
03367
03368 if ( !KPropsDlgPlugin::isDesktopFile( item ) )
03369 return false;
03370
03371 KDesktopFile config( item->url().path(), true );
03372 return config.hasApplicationType() && kapp->authorize("run_desktop_files") && kapp->authorize("shell_access");
03373 }
03374
03375 void KPropertiesDialog::virtual_hook( int id, void* data )
03376 { KDialogBase::virtual_hook( id, data ); }
03377
03378 void KPropsDlgPlugin::virtual_hook( int, void* )
03379 { }
03380
03381
03382
03383
03384
03390 class KExecPropsPlugin::KExecPropsPluginPrivate
03391 {
03392 public:
03393 KExecPropsPluginPrivate()
03394 {
03395 }
03396 ~KExecPropsPluginPrivate()
03397 {
03398 }
03399
03400 QFrame *m_frame;
03401 QCheckBox *nocloseonexitCheck;
03402 };
03403
03404 KExecPropsPlugin::KExecPropsPlugin( KPropertiesDialog *_props )
03405 : KPropsDlgPlugin( _props )
03406 {
03407 d = new KExecPropsPluginPrivate;
03408 d->m_frame = properties->addPage(i18n("E&xecute"));
03409 QVBoxLayout * mainlayout = new QVBoxLayout( d->m_frame, 0,
03410 KDialog::spacingHint());
03411
03412
03413
03414 QLabel* l;
03415 l = new QLabel( i18n( "Comman&d:" ), d->m_frame );
03416 mainlayout->addWidget(l);
03417
03418 QHBoxLayout * hlayout;
03419 hlayout = new QHBoxLayout(KDialog::spacingHint());
03420 mainlayout->addLayout(hlayout);
03421
03422 execEdit = new KLineEdit( d->m_frame );
03423 QWhatsThis::add(execEdit,i18n(
03424 "Following the command, you can have several place holders which will be replaced "
03425 "with the actual values when the actual program is run:\n"
03426 "%f - a single file name\n"
03427 "%F - a list of files; use for applications that can open several local files at once\n"
03428 "%u - a single URL\n"
03429 "%U - a list of URLs\n"
03430 "%d - the folder of the file to open\n"
03431 "%D - a list of folders\n"
03432 "%i - the icon\n"
03433 "%m - the mini-icon\n"
03434 "%c - the caption"));
03435 hlayout->addWidget(execEdit, 1);
03436
03437 l->setBuddy( execEdit );
03438
03439 execBrowse = new QPushButton( d->m_frame );
03440 execBrowse->setText( i18n("&Browse...") );
03441 hlayout->addWidget(execBrowse);
03442
03443
03444 QGroupBox* tmpQGroupBox;
03445 tmpQGroupBox = new QGroupBox( i18n("Panel Embedding"), d->m_frame );
03446 tmpQGroupBox->setColumnLayout( 0, Qt::Horizontal );
03447
03448 mainlayout->addWidget(tmpQGroupBox);
03449
03450 QGridLayout *grid = new QGridLayout(tmpQGroupBox->layout(), 2, 2);
03451 grid->setSpacing( KDialog::spacingHint() );
03452 grid->setColStretch(1, 1);
03453
03454 l = new QLabel( i18n( "&Execute on click:" ), tmpQGroupBox );
03455 grid->addWidget(l, 0, 0);
03456
03457 swallowExecEdit = new KLineEdit( tmpQGroupBox );
03458 grid->addWidget(swallowExecEdit, 0, 1);
03459
03460 l->setBuddy( swallowExecEdit );
03461
03462 l = new QLabel( i18n( "&Window title:" ), tmpQGroupBox );
03463 grid->addWidget(l, 1, 0);
03464
03465 swallowTitleEdit = new KLineEdit( tmpQGroupBox );
03466 grid->addWidget(swallowTitleEdit, 1, 1);
03467
03468 l->setBuddy( swallowTitleEdit );
03469
03470
03471
03472 tmpQGroupBox = new QGroupBox( d->m_frame );
03473 tmpQGroupBox->setColumnLayout( 0, Qt::Horizontal );
03474
03475 mainlayout->addWidget(tmpQGroupBox);
03476
03477 grid = new QGridLayout(tmpQGroupBox->layout(), 3, 2);
03478 grid->setSpacing( KDialog::spacingHint() );
03479 grid->setColStretch(1, 1);
03480
03481 terminalCheck = new QCheckBox( tmpQGroupBox );
03482 terminalCheck->setText( i18n("&Run in terminal") );
03483 grid->addMultiCellWidget(terminalCheck, 0, 0, 0, 1);
03484
03485
03486
03487 KConfigGroup confGroup( KGlobal::config(), QString::fromLatin1("General") );
03488 QString preferredTerminal = confGroup.readPathEntry("TerminalApplication",
03489 QString::fromLatin1("konsole"));
03490
03491 int posOptions = 1;
03492 d->nocloseonexitCheck = 0L;
03493 if (preferredTerminal == "konsole")
03494 {
03495 posOptions = 2;
03496 d->nocloseonexitCheck = new QCheckBox( tmpQGroupBox );
03497 d->nocloseonexitCheck->setText( i18n("Do not &close when command exits") );
03498 grid->addMultiCellWidget(d->nocloseonexitCheck, 1, 1, 0, 1);
03499 }
03500
03501 terminalLabel = new QLabel( i18n( "&Terminal options:" ), tmpQGroupBox );
03502 grid->addWidget(terminalLabel, posOptions, 0);
03503
03504 terminalEdit = new KLineEdit( tmpQGroupBox );
03505 grid->addWidget(terminalEdit, posOptions, 1);
03506
03507 terminalLabel->setBuddy( terminalEdit );
03508
03509
03510
03511 tmpQGroupBox = new QGroupBox( d->m_frame );
03512 tmpQGroupBox->setColumnLayout( 0, Qt::Horizontal );
03513
03514 mainlayout->addWidget(tmpQGroupBox);
03515
03516 grid = new QGridLayout(tmpQGroupBox->layout(), 2, 2);
03517 grid->setSpacing(KDialog::spacingHint());
03518 grid->setColStretch(1, 1);
03519
03520 suidCheck = new QCheckBox(tmpQGroupBox);
03521 suidCheck->setText(i18n("Ru&n as a different user"));
03522 grid->addMultiCellWidget(suidCheck, 0, 0, 0, 1);
03523
03524 suidLabel = new QLabel(i18n( "&Username:" ), tmpQGroupBox);
03525 grid->addWidget(suidLabel, 1, 0);
03526
03527 suidEdit = new KLineEdit(tmpQGroupBox);
03528 grid->addWidget(suidEdit, 1, 1);
03529
03530 suidLabel->setBuddy( suidEdit );
03531
03532 mainlayout->addStretch(1);
03533
03534
03535 QString path = _props->kurl().path();
03536 QFile f( path );
03537 if ( !f.open( IO_ReadOnly ) )
03538 return;
03539 f.close();
03540
03541 KSimpleConfig config( path );
03542 config.setDollarExpansion( false );
03543 config.setDesktopGroup();
03544 execStr = config.readPathEntry( "Exec" );
03545 swallowExecStr = config.readPathEntry( "SwallowExec" );
03546 swallowTitleStr = config.readEntry( "SwallowTitle" );
03547 termBool = config.readBoolEntry( "Terminal" );
03548 termOptionsStr = config.readEntry( "TerminalOptions" );
03549 suidBool = config.readBoolEntry( "X-KDE-SubstituteUID" );
03550 suidUserStr = config.readEntry( "X-KDE-Username" );
03551
03552 if ( !swallowExecStr.isNull() )
03553 swallowExecEdit->setText( swallowExecStr );
03554 if ( !swallowTitleStr.isNull() )
03555 swallowTitleEdit->setText( swallowTitleStr );
03556
03557 if ( !execStr.isNull() )
03558 execEdit->setText( execStr );
03559
03560 if ( d->nocloseonexitCheck )
03561 {
03562 d->nocloseonexitCheck->setChecked( (termOptionsStr.contains( "--noclose" ) > 0) );
03563 termOptionsStr.replace( "--noclose", "");
03564 }
03565 if ( !termOptionsStr.isNull() )
03566 terminalEdit->setText( termOptionsStr );
03567
03568 terminalCheck->setChecked( termBool );
03569 enableCheckedEdit();
03570
03571 suidCheck->setChecked( suidBool );
03572 suidEdit->setText( suidUserStr );
03573 enableSuidEdit();
03574
03575
03576 KCompletion *kcom = new KCompletion;
03577 kcom->setOrder(KCompletion::Sorted);
03578 struct passwd *pw;
03579 int i, maxEntries = 1000;
03580 setpwent();
03581 for (i=0; ((pw = getpwent()) != 0L) && (i < maxEntries); i++)
03582 kcom->addItem(QString::fromLatin1(pw->pw_name));
03583 endpwent();
03584 if (i < maxEntries)
03585 {
03586 suidEdit->setCompletionObject(kcom, true);
03587 suidEdit->setAutoDeleteCompletionObject( true );
03588 suidEdit->setCompletionMode(KGlobalSettings::CompletionAuto);
03589 }
03590 else
03591 {
03592 delete kcom;
03593 }
03594
03595 connect( swallowExecEdit, SIGNAL( textChanged( const QString & ) ),
03596 this, SIGNAL( changed() ) );
03597 connect( swallowTitleEdit, SIGNAL( textChanged( const QString & ) ),
03598 this, SIGNAL( changed() ) );
03599 connect( execEdit, SIGNAL( textChanged( const QString & ) ),
03600 this, SIGNAL( changed() ) );
03601 connect( terminalEdit, SIGNAL( textChanged( const QString & ) ),
03602 this, SIGNAL( changed() ) );
03603 if (d->nocloseonexitCheck)
03604 connect( d->nocloseonexitCheck, SIGNAL( toggled( bool ) ),
03605 this, SIGNAL( changed() ) );
03606 connect( terminalCheck, SIGNAL( toggled( bool ) ),
03607 this, SIGNAL( changed() ) );
03608 connect( suidCheck, SIGNAL( toggled( bool ) ),
03609 this, SIGNAL( changed() ) );
03610 connect( suidEdit, SIGNAL( textChanged( const QString & ) ),
03611 this, SIGNAL( changed() ) );
03612
03613 connect( execBrowse, SIGNAL( clicked() ), this, SLOT( slotBrowseExec() ) );
03614 connect( terminalCheck, SIGNAL( clicked() ), this, SLOT( enableCheckedEdit() ) );
03615 connect( suidCheck, SIGNAL( clicked() ), this, SLOT( enableSuidEdit() ) );
03616
03617 }
03618
03619 KExecPropsPlugin::~KExecPropsPlugin()
03620 {
03621 delete d;
03622 }
03623
03624 void KExecPropsPlugin::enableCheckedEdit()
03625 {
03626 bool checked = terminalCheck->isChecked();
03627 terminalLabel->setEnabled( checked );
03628 if (d->nocloseonexitCheck)
03629 d->nocloseonexitCheck->setEnabled( checked );
03630 terminalEdit->setEnabled( checked );
03631 }
03632
03633 void KExecPropsPlugin::enableSuidEdit()
03634 {
03635 bool checked = suidCheck->isChecked();
03636 suidLabel->setEnabled( checked );
03637 suidEdit->setEnabled( checked );
03638 }
03639
03640 bool KExecPropsPlugin::supports( KFileItemList _items )
03641 {
03642 if ( _items.count() != 1 )
03643 return false;
03644 KFileItem * item = _items.first();
03645
03646 if ( !KPropsDlgPlugin::isDesktopFile( item ) )
03647 return false;
03648
03649 KDesktopFile config( item->url().path(), true );
03650 return config.hasApplicationType() && kapp->authorize("run_desktop_files") && kapp->authorize("shell_access");
03651 }
03652
03653 void KExecPropsPlugin::applyChanges()
03654 {
03655 kdDebug(250) << "KExecPropsPlugin::applyChanges" << endl;
03656 QString path = properties->kurl().path();
03657
03658 QFile f( path );
03659
03660 if ( !f.open( IO_ReadWrite ) ) {
03661 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have "
03662 "sufficient access to write to <b>%1</b>.</qt>").arg(path));
03663 return;
03664 }
03665 f.close();
03666
03667 KSimpleConfig config( path );
03668 config.setDesktopGroup();
03669 config.writeEntry( "Type", QString::fromLatin1("Application"));
03670 config.writePathEntry( "Exec", execEdit->text() );
03671 config.writePathEntry( "SwallowExec", swallowExecEdit->text() );
03672 config.writeEntry( "SwallowTitle", swallowTitleEdit->text() );
03673 config.writeEntry( "Terminal", terminalCheck->isChecked() );
03674 QString temp = terminalEdit->text();
03675 if (d->nocloseonexitCheck )
03676 if ( d->nocloseonexitCheck->isChecked() )
03677 temp += QString::fromLatin1("--noclose ");
03678 temp = temp.stripWhiteSpace();
03679 config.writeEntry( "TerminalOptions", temp );
03680 config.writeEntry( "X-KDE-SubstituteUID", suidCheck->isChecked() );
03681 config.writeEntry( "X-KDE-Username", suidEdit->text() );
03682 }
03683
03684
03685 void KExecPropsPlugin::slotBrowseExec()
03686 {
03687 KURL f = KFileDialog::getOpenURL( QString::null,
03688 QString::null, d->m_frame );
03689 if ( f.isEmpty() )
03690 return;
03691
03692 if ( !f.isLocalFile()) {
03693 KMessageBox::sorry(d->m_frame, i18n("Only executables on local file systems are supported."));
03694 return;
03695 }
03696
03697 QString path = f.path();
03698 KRun::shellQuote( path );
03699 execEdit->setText( path );
03700 }
03701
03702 class KApplicationPropsPlugin::KApplicationPropsPluginPrivate
03703 {
03704 public:
03705 KApplicationPropsPluginPrivate()
03706 {
03707 m_kdesktopMode = QCString(qApp->name()) == "kdesktop";
03708 }
03709 ~KApplicationPropsPluginPrivate()
03710 {
03711 }
03712
03713 QFrame *m_frame;
03714 bool m_kdesktopMode;
03715 };
03716
03717 KApplicationPropsPlugin::KApplicationPropsPlugin( KPropertiesDialog *_props )
03718 : KPropsDlgPlugin( _props )
03719 {
03720 d = new KApplicationPropsPluginPrivate;
03721 d->m_frame = properties->addPage(i18n("&Application"));
03722 QVBoxLayout *toplayout = new QVBoxLayout( d->m_frame, 0, KDialog::spacingHint());
03723
03724 QIconSet iconSet;
03725 QPixmap pixMap;
03726
03727 addExtensionButton = new QPushButton( QString::null, d->m_frame );
03728 iconSet = SmallIconSet( "back" );
03729 addExtensionButton->setIconSet( iconSet );
03730 pixMap = iconSet.pixmap( QIconSet::Small, QIconSet::Normal );
03731 addExtensionButton->setFixedSize( pixMap.width()+8, pixMap.height()+8 );
03732 connect( addExtensionButton, SIGNAL( clicked() ),
03733 SLOT( slotAddExtension() ) );
03734
03735 delExtensionButton = new QPushButton( QString::null, d->m_frame );
03736 iconSet = SmallIconSet( "forward" );
03737 delExtensionButton->setIconSet( iconSet );
03738 delExtensionButton->setFixedSize( pixMap.width()+8, pixMap.height()+8 );
03739 connect( delExtensionButton, SIGNAL( clicked() ),
03740 SLOT( slotDelExtension() ) );
03741
03742 QLabel *l;
03743
03744 QGridLayout *grid = new QGridLayout(2, 2);
03745 grid->setColStretch(1, 1);
03746 toplayout->addLayout(grid);
03747
03748 if ( d->m_kdesktopMode )
03749 {
03750
03751 nameEdit = 0L;
03752 }
03753 else
03754 {
03755 l = new QLabel(i18n("Name:"), d->m_frame, "Label_4" );
03756 grid->addWidget(l, 0, 0);
03757
03758 nameEdit = new KLineEdit( d->m_frame, "LineEdit_3" );
03759 grid->addWidget(nameEdit, 0, 1);
03760 }
03761
03762 l = new QLabel(i18n("Description:"), d->m_frame, "Label_5" );
03763 grid->addWidget(l, 1, 0);
03764
03765 genNameEdit = new KLineEdit( d->m_frame, "LineEdit_4" );
03766 grid->addWidget(genNameEdit, 1, 1);
03767
03768 l = new QLabel(i18n("Comment:"), d->m_frame, "Label_3" );
03769 grid->addWidget(l, 2, 0);
03770
03771 commentEdit = new KLineEdit( d->m_frame, "LineEdit_2" );
03772 grid->addWidget(commentEdit, 2, 1);
03773
03774 l = new QLabel(i18n("File types:"), d->m_frame);
03775 toplayout->addWidget(l, 0, AlignLeft);
03776
03777 grid = new QGridLayout(4, 3);
03778 grid->setColStretch(0, 1);
03779 grid->setColStretch(2, 1);
03780 grid->setRowStretch( 0, 1 );
03781 grid->setRowStretch( 3, 1 );
03782 toplayout->addLayout(grid, 2);
03783
03784 extensionsList = new QListBox( d->m_frame );
03785 extensionsList->setSelectionMode( QListBox::Extended );
03786 grid->addMultiCellWidget(extensionsList, 0, 3, 0, 0);
03787
03788 grid->addWidget(addExtensionButton, 1, 1);
03789 grid->addWidget(delExtensionButton, 2, 1);
03790
03791 availableExtensionsList = new QListBox( d->m_frame );
03792 availableExtensionsList->setSelectionMode( QListBox::Extended );
03793 grid->addMultiCellWidget(availableExtensionsList, 0, 3, 2, 2);
03794
03795 QString path = properties->kurl().path() ;
03796 QFile f( path );
03797 if ( !f.open( IO_ReadOnly ) )
03798 return;
03799 f.close();
03800
03801 KSimpleConfig config( path );
03802 config.setDesktopGroup();
03803 QString commentStr = config.readEntry( "Comment" );
03804 QString genNameStr = config.readEntry( "GenericName" );
03805
03806 QStringList selectedTypes = config.readListEntry( "ServiceTypes" );
03807
03808 selectedTypes += config.readListEntry( "MimeType", ';' );
03809
03810 QString nameStr = config.readEntry( QString::fromLatin1("Name") );
03811 if ( nameStr.isEmpty() || d->m_kdesktopMode ) {
03812
03813
03814
03815 setDirty();
03816 }
03817
03818 commentEdit->setText( commentStr );
03819 genNameEdit->setText( genNameStr );
03820 if ( nameEdit )
03821 nameEdit->setText( nameStr );
03822
03823 selectedTypes.sort();
03824 QStringList::Iterator sit = selectedTypes.begin();
03825 for( ; sit != selectedTypes.end(); ++sit ) {
03826 if ( !((*sit).isEmpty()) )
03827 extensionsList->insertItem( *sit );
03828 }
03829
03830 KMimeType::List mimeTypes = KMimeType::allMimeTypes();
03831 QValueListIterator<KMimeType::Ptr> it2 = mimeTypes.begin();
03832 for ( ; it2 != mimeTypes.end(); ++it2 )
03833 addMimeType ( (*it2)->name() );
03834
03835 updateButton();
03836
03837 connect( extensionsList, SIGNAL( highlighted( int ) ),
03838 this, SLOT( updateButton() ) );
03839 connect( availableExtensionsList, SIGNAL( highlighted( int ) ),
03840 this, SLOT( updateButton() ) );
03841
03842 connect( addExtensionButton, SIGNAL( clicked() ),
03843 this, SIGNAL( changed() ) );
03844 connect( delExtensionButton, SIGNAL( clicked() ),
03845 this, SIGNAL( changed() ) );
03846 if ( nameEdit )
03847 connect( nameEdit, SIGNAL( textChanged( const QString & ) ),
03848 this, SIGNAL( changed() ) );
03849 connect( commentEdit, SIGNAL( textChanged( const QString & ) ),
03850 this, SIGNAL( changed() ) );
03851 connect( genNameEdit, SIGNAL( textChanged( const QString & ) ),
03852 this, SIGNAL( changed() ) );
03853 connect( availableExtensionsList, SIGNAL( selected( int ) ),
03854 this, SIGNAL( changed() ) );
03855 connect( extensionsList, SIGNAL( selected( int ) ),
03856 this, SIGNAL( changed() ) );
03857 }
03858
03859 KApplicationPropsPlugin::~KApplicationPropsPlugin()
03860 {
03861 delete d;
03862 }
03863
03864
03865
03866
03867
03868
03869 void KApplicationPropsPlugin::updateButton()
03870 {
03871 addExtensionButton->setEnabled(availableExtensionsList->currentItem()>-1);
03872 delExtensionButton->setEnabled(extensionsList->currentItem()>-1);
03873 }
03874
03875 void KApplicationPropsPlugin::addMimeType( const QString & name )
03876 {
03877
03878
03879 bool insert = true;
03880
03881 for ( uint i = 0; i < extensionsList->count(); i++ )
03882 if ( extensionsList->text( i ) == name )
03883 insert = false;
03884
03885 if ( insert )
03886 {
03887 availableExtensionsList->insertItem( name );
03888 availableExtensionsList->sort();
03889 }
03890 }
03891
03892 bool KApplicationPropsPlugin::supports( KFileItemList _items )
03893 {
03894
03895 return KExecPropsPlugin::supports( _items );
03896 }
03897
03898 void KApplicationPropsPlugin::applyChanges()
03899 {
03900 QString path = properties->kurl().path();
03901
03902 QFile f( path );
03903
03904 if ( !f.open( IO_ReadWrite ) ) {
03905 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not "
03906 "have sufficient access to write to <b>%1</b>.</qt>").arg(path));
03907 return;
03908 }
03909 f.close();
03910
03911 KSimpleConfig config( path );
03912 config.setDesktopGroup();
03913 config.writeEntry( "Type", QString::fromLatin1("Application"));
03914 config.writeEntry( "Comment", commentEdit->text() );
03915 config.writeEntry( "Comment", commentEdit->text(), true, false, true );
03916 config.writeEntry( "GenericName", genNameEdit->text() );
03917 config.writeEntry( "GenericName", genNameEdit->text(), true, false, true );
03918
03919 QStringList selectedTypes;
03920 for ( uint i = 0; i < extensionsList->count(); i++ )
03921 selectedTypes.append( extensionsList->text( i ) );
03922
03923 config.writeEntry( "MimeType", selectedTypes, ';' );
03924 config.writeEntry( "ServiceTypes", "" );
03925
03926
03927 QString nameStr = nameEdit ? nameEdit->text() : QString::null;
03928 if ( nameStr.isEmpty() )
03929 nameStr = nameFromFileName(properties->kurl().fileName());
03930
03931 config.writeEntry( "Name", nameStr );
03932 config.writeEntry( "Name", nameStr, true, false, true );
03933
03934 config.sync();
03935 }
03936
03937 void KApplicationPropsPlugin::slotAddExtension()
03938 {
03939 QListBoxItem *item = availableExtensionsList->firstItem();
03940 QListBoxItem *nextItem;
03941
03942 while ( item )
03943 {
03944 nextItem = item->next();
03945
03946 if ( item->isSelected() )
03947 {
03948 extensionsList->insertItem( item->text() );
03949 availableExtensionsList->removeItem( availableExtensionsList->index( item ) );
03950 }
03951
03952 item = nextItem;
03953 }
03954
03955 extensionsList->sort();
03956 updateButton();
03957 }
03958
03959 void KApplicationPropsPlugin::slotDelExtension()
03960 {
03961 QListBoxItem *item = extensionsList->firstItem();
03962 QListBoxItem *nextItem;
03963
03964 while ( item )
03965 {
03966 nextItem = item->next();
03967
03968 if ( item->isSelected() )
03969 {
03970 availableExtensionsList->insertItem( item->text() );
03971 extensionsList->removeItem( extensionsList->index( item ) );
03972 }
03973
03974 item = nextItem;
03975 }
03976
03977 availableExtensionsList->sort();
03978 updateButton();
03979 }
03980
03981
03982
03983 #include "kpropertiesdialog.moc"