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 bool allDisable = true;
01939 QCheckBox *cba[3][4];
01940 for (int row = 0; row < 3 ; ++row) {
01941 for (int col = 0; col < 4; ++col) {
01942 QCheckBox *cb = new QCheckBox(gb);
01943 cba[row][col] = cb;
01944 cb->setChecked(aPermissions & fperm[row][col]);
01945 if ( aPartialPermissions & fperm[row][col] )
01946 {
01947 cb->setTristate();
01948 cb->setNoChange();
01949 }
01950 else if (d->cbRecursive && d->cbRecursive->isChecked())
01951 cb->setTristate();
01952
01953 if( d->canChangePermissions)
01954 allDisable = false;
01955 cb->setEnabled( d->canChangePermissions );
01956 gl->addWidget (cb, row+2, col+1);
01957 switch(col) {
01958 case 0:
01959 QWhatsThis::add(cb, readWhatsThis);
01960 break;
01961 case 1:
01962 QWhatsThis::add(cb, writeWhatsThis);
01963 break;
01964 case 2:
01965 QWhatsThis::add(cb, execWhatsThis);
01966 break;
01967 case 3:
01968 switch(row) {
01969 case 0:
01970 QWhatsThis::add(cb, setUidWhatsThis);
01971 break;
01972 case 1:
01973 QWhatsThis::add(cb, setGidWhatsThis);
01974 break;
01975 case 2:
01976 QWhatsThis::add(cb, stickyWhatsThis);
01977 break;
01978 }
01979 break;
01980 }
01981 }
01982 }
01983 gl->setColStretch(6, 10);
01984
01985 if( allDisable )
01986 dlg.enableButtonOK(false );
01987 if (dlg.exec() != KDialogBase::Accepted)
01988 return;
01989
01990 mode_t andPermissions = mode_t(~0);
01991 mode_t orPermissions = 0;
01992 for (int row = 0; row < 3; ++row)
01993 for (int col = 0; col < 4; ++col) {
01994 switch (cba[row][col]->state())
01995 {
01996 case QCheckBox::On:
01997 orPermissions |= fperm[row][col];
01998
01999 case QCheckBox::Off:
02000 andPermissions &= ~fperm[row][col];
02001 break;
02002 default:
02003 break;
02004 }
02005 }
02006
02007 d->isIrregular = false;
02008 KFileItemList items = properties->items();
02009 for (KFileItemListIterator it(items); it.current(); ++it) {
02010 if (isIrregular(((*it)->permissions() & andPermissions) | orPermissions,
02011 (*it)->isDir(), (*it)->isLink())) {
02012 d->isIrregular = true;
02013 break;
02014 }
02015 }
02016
02017 permissions = orPermissions;
02018 d->partialPermissions = andPermissions;
02019
02020 emit changed();
02021 updateAccessControls();
02022 }
02023
02024
02025
02026
02027
02028
02029 KFilePermissionsPropsPlugin::~KFilePermissionsPropsPlugin()
02030 {
02031 delete d;
02032 }
02033
02034 bool KFilePermissionsPropsPlugin::supports( KFileItemList _items )
02035 {
02036 for (KFileItemListIterator it(_items); it.current(); ++it) {
02037 if ( (*it)->url().protocol().find("device", 0, false)!=-1)
02038 return false;
02039 }
02040
02041 return true;
02042 }
02043
02044
02045 void KFilePermissionsPropsPlugin::setComboContent(QComboBox *combo, PermissionsTarget target,
02046 mode_t permissions, mode_t partial) {
02047 combo->clear();
02048 if (d->pmode == PermissionsOnlyLinks) {
02049 combo->insertItem(i18n("Link"));
02050 combo->setCurrentItem(0);
02051 return;
02052 }
02053
02054 mode_t tMask = permissionsMasks[target];
02055 int textIndex;
02056 for (textIndex = 0; standardPermissions[textIndex] != (mode_t)-1; textIndex++)
02057 if ((standardPermissions[textIndex]&tMask) == (permissions&tMask&(UniRead|UniWrite)))
02058 break;
02059 Q_ASSERT(standardPermissions[textIndex] != (mode_t)-1);
02060
02061 for (int i = 0; permissionsTexts[(int)d->pmode][i]; i++)
02062 combo->insertItem(i18n(permissionsTexts[(int)d->pmode][i]));
02063
02064 if (partial & tMask & ~UniExec) {
02065 combo->insertItem(i18n("Varying (No Change)"));
02066 combo->setCurrentItem(3);
02067 }
02068 else
02069 combo->setCurrentItem(textIndex);
02070 }
02071
02072
02073 bool KFilePermissionsPropsPlugin::isIrregular(mode_t permissions, bool isDir, bool isLink) {
02074 if (isLink)
02075 return false;
02076
02077 mode_t p = permissions;
02078 if (p & (S_ISUID | S_ISGID))
02079 return true;
02080 if (isDir) {
02081 p &= ~S_ISVTX;
02082
02083
02084 mode_t p0 = p & UniOwner;
02085 if ((p0 != 0) && (p0 != (S_IRUSR | S_IXUSR)) && (p0 != UniOwner))
02086 return true;
02087 p0 = p & UniGroup;
02088 if ((p0 != 0) && (p0 != (S_IRGRP | S_IXGRP)) && (p0 != UniGroup))
02089 return true;
02090 p0 = p & UniOthers;
02091 if ((p0 != 0) && (p0 != (S_IROTH | S_IXOTH)) && (p0 != UniOthers))
02092 return true;
02093 return false;
02094 }
02095 if (p & S_ISVTX)
02096 return true;
02097
02098
02099 mode_t p0 = p & UniOwner;
02100 bool usrXPossible = !p0;
02101 if (p0 & S_IXUSR) {
02102 if ((p0 == S_IXUSR) || (p0 == (S_IWUSR | S_IXUSR)))
02103 return true;
02104 usrXPossible = true;
02105 }
02106 else if (p0 == S_IWUSR)
02107 return true;
02108
02109 p0 = p & UniGroup;
02110 bool grpXPossible = !p0;
02111 if (p0 & S_IXGRP) {
02112 if ((p0 == S_IXGRP) || (p0 == (S_IWGRP | S_IXGRP)))
02113 return true;
02114 grpXPossible = true;
02115 }
02116 else if (p0 == S_IWGRP)
02117 return true;
02118 if (p0 == 0)
02119 grpXPossible = true;
02120
02121 p0 = p & UniOthers;
02122 bool othXPossible = !p0;
02123 if (p0 & S_IXOTH) {
02124 if ((p0 == S_IXOTH) || (p0 == (S_IWOTH | S_IXOTH)))
02125 return true;
02126 othXPossible = true;
02127 }
02128 else if (p0 == S_IWOTH)
02129 return true;
02130
02131
02132 return (p & UniExec) && !(usrXPossible && grpXPossible && othXPossible);
02133 }
02134
02135
02136 void KFilePermissionsPropsPlugin::enableAccessControls(bool enable) {
02137 d->ownerPermCombo->setEnabled(enable);
02138 d->groupPermCombo->setEnabled(enable);
02139 d->othersPermCombo->setEnabled(enable);
02140 if (d->extraCheckbox)
02141 d->extraCheckbox->setEnabled(enable);
02142 if ( d->cbRecursive )
02143 d->cbRecursive->setEnabled(enable);
02144 }
02145
02146
02147 void KFilePermissionsPropsPlugin::updateAccessControls() {
02148 setComboContent(d->ownerPermCombo, PermissionsOwner,
02149 permissions, d->partialPermissions);
02150 setComboContent(d->groupPermCombo, PermissionsGroup,
02151 permissions, d->partialPermissions);
02152 setComboContent(d->othersPermCombo, PermissionsOthers,
02153 permissions, d->partialPermissions);
02154
02155 switch(d->pmode) {
02156 case PermissionsOnlyLinks:
02157 enableAccessControls(false);
02158 break;
02159 case PermissionsOnlyFiles:
02160 enableAccessControls(d->canChangePermissions && !d->isIrregular);
02161 if (d->canChangePermissions)
02162 d->explanationLabel->setText(d->isIrregular ?
02163 i18n("This file uses advanced permissions",
02164 "These files use advanced permissions.",
02165 properties->items().count()) : "");
02166 if (d->partialPermissions & UniExec) {
02167 d->extraCheckbox->setTristate();
02168 d->extraCheckbox->setNoChange();
02169 }
02170 else {
02171 d->extraCheckbox->setTristate(false);
02172 d->extraCheckbox->setChecked(permissions & UniExec);
02173 }
02174 break;
02175 case PermissionsOnlyDirs:
02176 enableAccessControls(d->canChangePermissions && !d->isIrregular);
02177 if (d->canChangePermissions)
02178 d->explanationLabel->setText(d->isIrregular ?
02179 i18n("This folder uses advanced permissions.",
02180 "These folders use advanced permissions.",
02181 properties->items().count()) : "");
02182 if (d->partialPermissions & S_ISVTX) {
02183 d->extraCheckbox->setTristate();
02184 d->extraCheckbox->setNoChange();
02185 }
02186 else {
02187 d->extraCheckbox->setTristate(false);
02188 d->extraCheckbox->setChecked(permissions & S_ISVTX);
02189 }
02190 break;
02191 case PermissionsMixed:
02192 enableAccessControls(d->canChangePermissions && !d->isIrregular);
02193 if (d->canChangePermissions)
02194 d->explanationLabel->setText(d->isIrregular ?
02195 i18n("These files use advanced permissions.") : "");
02196 break;
02197 if (d->partialPermissions & S_ISVTX) {
02198 d->extraCheckbox->setTristate();
02199 d->extraCheckbox->setNoChange();
02200 }
02201 else {
02202 d->extraCheckbox->setTristate(false);
02203 d->extraCheckbox->setChecked(permissions & S_ISVTX);
02204 }
02205 break;
02206 }
02207 }
02208
02209
02210 void KFilePermissionsPropsPlugin::getPermissionMasks(mode_t &andFilePermissions,
02211 mode_t &andDirPermissions,
02212 mode_t &orFilePermissions,
02213 mode_t &orDirPermissions) {
02214 andFilePermissions = mode_t(~UniSpecial);
02215 andDirPermissions = mode_t(~(S_ISUID|S_ISGID));
02216 orFilePermissions = 0;
02217 orDirPermissions = 0;
02218 if (d->isIrregular)
02219 return;
02220
02221 mode_t m = standardPermissions[d->ownerPermCombo->currentItem()];
02222 if (m != (mode_t) -1) {
02223 orFilePermissions |= m & UniOwner;
02224 if ((m & UniOwner) &&
02225 ((d->pmode == PermissionsMixed) ||
02226 ((d->pmode == PermissionsOnlyFiles) && (d->extraCheckbox->state() == QButton::NoChange))))
02227 andFilePermissions &= ~(S_IRUSR | S_IWUSR);
02228 else {
02229 andFilePermissions &= ~(S_IRUSR | S_IWUSR | S_IXUSR);
02230 if ((m & S_IRUSR) && (d->extraCheckbox->state() == QButton::On))
02231 orFilePermissions |= S_IXUSR;
02232 }
02233
02234 orDirPermissions |= m & UniOwner;
02235 if (m & S_IRUSR)
02236 orDirPermissions |= S_IXUSR;
02237 andDirPermissions &= ~(S_IRUSR | S_IWUSR | S_IXUSR);
02238 }
02239
02240 m = standardPermissions[d->groupPermCombo->currentItem()];
02241 if (m != (mode_t) -1) {
02242 orFilePermissions |= m & UniGroup;
02243 if ((m & UniGroup) &&
02244 ((d->pmode == PermissionsMixed) ||
02245 ((d->pmode == PermissionsOnlyFiles) && (d->extraCheckbox->state() == QButton::NoChange))))
02246 andFilePermissions &= ~(S_IRGRP | S_IWGRP);
02247 else {
02248 andFilePermissions &= ~(S_IRGRP | S_IWGRP | S_IXGRP);
02249 if ((m & S_IRGRP) && (d->extraCheckbox->state() == QButton::On))
02250 orFilePermissions |= S_IXGRP;
02251 }
02252
02253 orDirPermissions |= m & UniGroup;
02254 if (m & S_IRGRP)
02255 orDirPermissions |= S_IXGRP;
02256 andDirPermissions &= ~(S_IRGRP | S_IWGRP | S_IXGRP);
02257 }
02258
02259 m = standardPermissions[d->othersPermCombo->currentItem()];
02260 if (m != (mode_t) -1) {
02261 orFilePermissions |= m & UniOthers;
02262 if ((m & UniOthers) &&
02263 ((d->pmode == PermissionsMixed) ||
02264 ((d->pmode == PermissionsOnlyFiles) && (d->extraCheckbox->state() == QButton::NoChange))))
02265 andFilePermissions &= ~(S_IROTH | S_IWOTH);
02266 else {
02267 andFilePermissions &= ~(S_IROTH | S_IWOTH | S_IXOTH);
02268 if ((m & S_IROTH) && (d->extraCheckbox->state() == QButton::On))
02269 orFilePermissions |= S_IXOTH;
02270 }
02271
02272 orDirPermissions |= m & UniOthers;
02273 if (m & S_IROTH)
02274 orDirPermissions |= S_IXOTH;
02275 andDirPermissions &= ~(S_IROTH | S_IWOTH | S_IXOTH);
02276 }
02277
02278 if (((d->pmode == PermissionsMixed) || (d->pmode == PermissionsOnlyDirs)) &&
02279 (d->extraCheckbox->state() != QButton::NoChange)) {
02280 andDirPermissions &= ~S_ISVTX;
02281 if (d->extraCheckbox->state() == QButton::On)
02282 orDirPermissions |= S_ISVTX;
02283 }
02284 }
02285
02286 void KFilePermissionsPropsPlugin::applyChanges()
02287 {
02288 mode_t orFilePermissions;
02289 mode_t orDirPermissions;
02290 mode_t andFilePermissions;
02291 mode_t andDirPermissions;
02292
02293 if (!d->canChangePermissions)
02294 return;
02295
02296 if (!d->isIrregular)
02297 getPermissionMasks(andFilePermissions,
02298 andDirPermissions,
02299 orFilePermissions,
02300 orDirPermissions);
02301 else {
02302 orFilePermissions = permissions;
02303 andFilePermissions = d->partialPermissions;
02304 orDirPermissions = permissions;
02305 andDirPermissions = d->partialPermissions;
02306 }
02307
02308 QString owner, group;
02309 if (usrEdit)
02310 owner = usrEdit->text();
02311 if (grpEdit)
02312 group = grpEdit->text();
02313 else if (grpCombo)
02314 group = grpCombo->currentText();
02315
02316 if (owner == strOwner)
02317 owner = QString::null;
02318
02319 if (group == strGroup)
02320 group = QString::null;
02321
02322 bool recursive = d->cbRecursive && d->cbRecursive->isChecked();
02323 bool permissionChange = false;
02324
02325 KFileItemList files, dirs;
02326 KFileItemList items = properties->items();
02327 for (KFileItemListIterator it(items); it.current(); ++it) {
02328 if ((*it)->isDir()) {
02329 dirs.append(*it);
02330 if ((*it)->permissions() != (((*it)->permissions() & andDirPermissions) | orDirPermissions))
02331 permissionChange = true;
02332 }
02333 else if ((*it)->isFile()) {
02334 files.append(*it);
02335 if ((*it)->permissions() != (((*it)->permissions() & andFilePermissions) | orFilePermissions))
02336 permissionChange = true;
02337 }
02338 }
02339
02340 if ( !owner.isEmpty() || !group.isEmpty() || recursive || permissionChange)
02341 {
02342 KIO::Job * job;
02343 if (files.count() > 0) {
02344 job = KIO::chmod( files, orFilePermissions, ~andFilePermissions,
02345 owner, group, false );
02346 connect( job, SIGNAL( result( KIO::Job * ) ),
02347 SLOT( slotChmodResult( KIO::Job * ) ) );
02348
02349 QWidget dummy(0,0,WType_Dialog|WShowModal);
02350 qt_enter_modal(&dummy);
02351 qApp->enter_loop();
02352 qt_leave_modal(&dummy);
02353 }
02354 if (dirs.count() > 0) {
02355 job = KIO::chmod( dirs, orDirPermissions, ~andDirPermissions,
02356 owner, group, recursive );
02357 connect( job, SIGNAL( result( KIO::Job * ) ),
02358 SLOT( slotChmodResult( KIO::Job * ) ) );
02359
02360 QWidget dummy(0,0,WType_Dialog|WShowModal);
02361 qt_enter_modal(&dummy);
02362 qApp->enter_loop();
02363 qt_leave_modal(&dummy);
02364 }
02365 }
02366 }
02367
02368 void KFilePermissionsPropsPlugin::slotChmodResult( KIO::Job * job )
02369 {
02370 kdDebug(250) << "KFilePermissionsPropsPlugin::slotChmodResult" << endl;
02371 if (job->error())
02372 job->showErrorDialog( d->m_frame );
02373
02374 qApp->exit_loop();
02375 }
02376
02377
02378
02379
02380 class KURLPropsPlugin::KURLPropsPluginPrivate
02381 {
02382 public:
02383 KURLPropsPluginPrivate()
02384 {
02385 }
02386 ~KURLPropsPluginPrivate()
02387 {
02388 }
02389
02390 QFrame *m_frame;
02391 };
02392
02393 KURLPropsPlugin::KURLPropsPlugin( KPropertiesDialog *_props )
02394 : KPropsDlgPlugin( _props )
02395 {
02396 d = new KURLPropsPluginPrivate;
02397 d->m_frame = properties->addPage(i18n("U&RL"));
02398 QVBoxLayout *layout = new QVBoxLayout(d->m_frame, 0, KDialog::spacingHint());
02399
02400 QLabel *l;
02401 l = new QLabel( d->m_frame, "Label_1" );
02402 l->setText( i18n("URL:") );
02403 layout->addWidget(l);
02404
02405 URLEdit = new KURLRequester( d->m_frame, "URL Requester" );
02406 layout->addWidget(URLEdit);
02407
02408 QString path = properties->kurl().path();
02409
02410 QFile f( path );
02411 if ( !f.open( IO_ReadOnly ) )
02412 return;
02413 f.close();
02414
02415 KSimpleConfig config( path );
02416 config.setDesktopGroup();
02417 URLStr = config.readPathEntry( "URL" );
02418
02419 if ( !URLStr.isNull() )
02420 URLEdit->setURL( URLStr );
02421
02422 connect( URLEdit, SIGNAL( textChanged( const QString & ) ),
02423 this, SIGNAL( changed() ) );
02424
02425 layout->addStretch (1);
02426 }
02427
02428 KURLPropsPlugin::~KURLPropsPlugin()
02429 {
02430 delete d;
02431 }
02432
02433
02434
02435
02436
02437
02438 bool KURLPropsPlugin::supports( KFileItemList _items )
02439 {
02440 if ( _items.count() != 1 )
02441 return false;
02442 KFileItem * item = _items.first();
02443
02444 if ( !KPropsDlgPlugin::isDesktopFile( item ) )
02445 return false;
02446
02447
02448 KDesktopFile config( item->url().path(), true );
02449 return config.hasLinkType();
02450 }
02451
02452 void KURLPropsPlugin::applyChanges()
02453 {
02454 QString path = properties->kurl().path();
02455
02456 QFile f( path );
02457 if ( !f.open( IO_ReadWrite ) ) {
02458 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have "
02459 "sufficient access to write to <b>%1</b>.</qt>").arg(path));
02460 return;
02461 }
02462 f.close();
02463
02464 KSimpleConfig config( path );
02465 config.setDesktopGroup();
02466 config.writeEntry( "Type", QString::fromLatin1("Link"));
02467 config.writePathEntry( "URL", URLEdit->url() );
02468
02469
02470 if ( config.hasKey("Name") )
02471 {
02472 QString nameStr = nameFromFileName(properties->kurl().fileName());
02473 config.writeEntry( "Name", nameStr );
02474 config.writeEntry( "Name", nameStr, true, false, true );
02475
02476 }
02477 }
02478
02479
02480
02481
02482
02483
02484
02485
02486 class KBindingPropsPlugin::KBindingPropsPluginPrivate
02487 {
02488 public:
02489 KBindingPropsPluginPrivate()
02490 {
02491 }
02492 ~KBindingPropsPluginPrivate()
02493 {
02494 }
02495
02496 QFrame *m_frame;
02497 };
02498
02499 KBindingPropsPlugin::KBindingPropsPlugin( KPropertiesDialog *_props ) : KPropsDlgPlugin( _props )
02500 {
02501 d = new KBindingPropsPluginPrivate;
02502 d->m_frame = properties->addPage(i18n("A&ssociation"));
02503 patternEdit = new KLineEdit( d->m_frame, "LineEdit_1" );
02504 commentEdit = new KLineEdit( d->m_frame, "LineEdit_2" );
02505 mimeEdit = new KLineEdit( d->m_frame, "LineEdit_3" );
02506
02507 QBoxLayout *mainlayout = new QVBoxLayout(d->m_frame, 0, KDialog::spacingHint());
02508 QLabel* tmpQLabel;
02509
02510 tmpQLabel = new QLabel( d->m_frame, "Label_1" );
02511 tmpQLabel->setText( i18n("Pattern ( example: *.html;*.htm )") );
02512 tmpQLabel->setMinimumSize(tmpQLabel->sizeHint());
02513 mainlayout->addWidget(tmpQLabel, 1);
02514
02515
02516
02517 patternEdit->setMaxLength( 512 );
02518 patternEdit->setMinimumSize( patternEdit->sizeHint() );
02519 patternEdit->setFixedHeight( fontHeight );
02520 mainlayout->addWidget(patternEdit, 1);
02521
02522 tmpQLabel = new QLabel( d->m_frame, "Label_2" );
02523 tmpQLabel->setText( i18n("Mime Type") );
02524 tmpQLabel->setMinimumSize(tmpQLabel->sizeHint());
02525 mainlayout->addWidget(tmpQLabel, 1);
02526
02527
02528 mimeEdit->setMaxLength( 256 );
02529 mimeEdit->setMinimumSize( mimeEdit->sizeHint() );
02530 mimeEdit->setFixedHeight( fontHeight );
02531 mainlayout->addWidget(mimeEdit, 1);
02532
02533 tmpQLabel = new QLabel( d->m_frame, "Label_3" );
02534 tmpQLabel->setText( i18n("Comment") );
02535 tmpQLabel->setMinimumSize(tmpQLabel->sizeHint());
02536 mainlayout->addWidget(tmpQLabel, 1);
02537
02538
02539 commentEdit->setMaxLength( 256 );
02540 commentEdit->setMinimumSize( commentEdit->sizeHint() );
02541 commentEdit->setFixedHeight( fontHeight );
02542 mainlayout->addWidget(commentEdit, 1);
02543
02544 cbAutoEmbed = new QCheckBox( i18n("Left click previews"), d->m_frame, "cbAutoEmbed" );
02545 mainlayout->addWidget(cbAutoEmbed, 1);
02546
02547 mainlayout->addStretch (10);
02548 mainlayout->activate();
02549
02550 QFile f( _props->kurl().path() );
02551 if ( !f.open( IO_ReadOnly ) )
02552 return;
02553 f.close();
02554
02555 KSimpleConfig config( _props->kurl().path() );
02556 config.setDesktopGroup();
02557 QString patternStr = config.readEntry( "Patterns" );
02558 QString iconStr = config.readEntry( "Icon" );
02559 QString commentStr = config.readEntry( "Comment" );
02560 m_sMimeStr = config.readEntry( "MimeType" );
02561
02562 if ( !patternStr.isEmpty() )
02563 patternEdit->setText( patternStr );
02564 if ( !commentStr.isEmpty() )
02565 commentEdit->setText( commentStr );
02566 if ( !m_sMimeStr.isEmpty() )
02567 mimeEdit->setText( m_sMimeStr );
02568 cbAutoEmbed->setTristate();
02569 if ( config.hasKey( "X-KDE-AutoEmbed" ) )
02570 cbAutoEmbed->setChecked( config.readBoolEntry( "X-KDE-AutoEmbed" ) );
02571 else
02572 cbAutoEmbed->setNoChange();
02573
02574 connect( patternEdit, SIGNAL( textChanged( const QString & ) ),
02575 this, SIGNAL( changed() ) );
02576 connect( commentEdit, SIGNAL( textChanged( const QString & ) ),
02577 this, SIGNAL( changed() ) );
02578 connect( mimeEdit, SIGNAL( textChanged( const QString & ) ),
02579 this, SIGNAL( changed() ) );
02580 connect( cbAutoEmbed, SIGNAL( toggled( bool ) ),
02581 this, SIGNAL( changed() ) );
02582 }
02583
02584 KBindingPropsPlugin::~KBindingPropsPlugin()
02585 {
02586 delete d;
02587 }
02588
02589
02590
02591
02592
02593
02594 bool KBindingPropsPlugin::supports( KFileItemList _items )
02595 {
02596 if ( _items.count() != 1 )
02597 return false;
02598 KFileItem * item = _items.first();
02599
02600 if ( !KPropsDlgPlugin::isDesktopFile( item ) )
02601 return false;
02602
02603
02604 KDesktopFile config( item->url().path(), true );
02605 return config.hasMimeTypeType();
02606 }
02607
02608 void KBindingPropsPlugin::applyChanges()
02609 {
02610 QString path = properties->kurl().path();
02611 QFile f( path );
02612
02613 if ( !f.open( IO_ReadWrite ) )
02614 {
02615 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have "
02616 "sufficient access to write to <b>%1</b>.</qt>").arg(path));
02617 return;
02618 }
02619 f.close();
02620
02621 KSimpleConfig config( path );
02622 config.setDesktopGroup();
02623 config.writeEntry( "Type", QString::fromLatin1("MimeType") );
02624
02625 config.writeEntry( "Patterns", patternEdit->text() );
02626 config.writeEntry( "Comment", commentEdit->text() );
02627 config.writeEntry( "Comment",
02628 commentEdit->text(), true, false, true );
02629 config.writeEntry( "MimeType", mimeEdit->text() );
02630 if ( cbAutoEmbed->state() == QButton::NoChange )
02631 config.deleteEntry( "X-KDE-AutoEmbed", false );
02632 else
02633 config.writeEntry( "X-KDE-AutoEmbed", cbAutoEmbed->isChecked() );
02634 config.sync();
02635 }
02636
02637
02638
02639
02640
02641
02642
02643 class KDevicePropsPlugin::KDevicePropsPluginPrivate
02644 {
02645 public:
02646 KDevicePropsPluginPrivate()
02647 {
02648 }
02649 ~KDevicePropsPluginPrivate()
02650 {
02651 }
02652
02653 QFrame *m_frame;
02654 QStringList mountpointlist;
02655 QLabel *m_freeSpaceText;
02656 QLabel *m_freeSpaceLabel;
02657 QProgressBar *m_freeSpaceBar;
02658 };
02659
02660 KDevicePropsPlugin::KDevicePropsPlugin( KPropertiesDialog *_props ) : KPropsDlgPlugin( _props )
02661 {
02662 d = new KDevicePropsPluginPrivate;
02663 d->m_frame = properties->addPage(i18n("De&vice"));
02664
02665 QStringList devices;
02666 KMountPoint::List mountPoints = KMountPoint::possibleMountPoints();
02667
02668 for(KMountPoint::List::ConstIterator it = mountPoints.begin();
02669 it != mountPoints.end(); ++it)
02670 {
02671 KMountPoint *mp = *it;
02672 QString mountPoint = mp->mountPoint();
02673 QString device = mp->mountedFrom();
02674 kdDebug()<<"mountPoint :"<<mountPoint<<" device :"<<device<<" mp->mountType() :"<<mp->mountType()<<endl;
02675
02676 if ((mountPoint != "-") && (mountPoint != "none") && !mountPoint.isEmpty()
02677 && device != "none")
02678 {
02679 devices.append( device + QString::fromLatin1(" (")
02680 + mountPoint + QString::fromLatin1(")") );
02681 m_devicelist.append(device);
02682 d->mountpointlist.append(mountPoint);
02683 }
02684 }
02685
02686 QGridLayout *layout = new QGridLayout( d->m_frame, 0, 2, 0,
02687 KDialog::spacingHint());
02688 layout->setColStretch(1, 1);
02689
02690 QLabel* label;
02691 label = new QLabel( d->m_frame );
02692 label->setText( devices.count() == 0 ?
02693 i18n("Device (/dev/fd0):") :
02694 i18n("Device:") );
02695 layout->addWidget(label, 0, 0);
02696
02697 device = new QComboBox( true, d->m_frame, "ComboBox_device" );
02698 device->insertStringList( devices );
02699 layout->addWidget(device, 0, 1);
02700 connect( device, SIGNAL( activated( int ) ),
02701 this, SLOT( slotActivated( int ) ) );
02702
02703 readonly = new QCheckBox( d->m_frame, "CheckBox_readonly" );
02704 readonly->setText( i18n("Read only") );
02705 layout->addWidget(readonly, 1, 1);
02706
02707 label = new QLabel( d->m_frame );
02708 label->setText( i18n("File system:") );
02709 layout->addWidget(label, 2, 0);
02710
02711 QLabel *fileSystem = new QLabel( d->m_frame );
02712 layout->addWidget(fileSystem, 2, 1);
02713
02714 label = new QLabel( d->m_frame );
02715 label->setText( devices.count()==0 ?
02716 i18n("Mount point (/mnt/floppy):") :
02717 i18n("Mount point:"));
02718 layout->addWidget(label, 3, 0);
02719
02720 mountpoint = new QLabel( d->m_frame, "LineEdit_mountpoint" );
02721
02722 layout->addWidget(mountpoint, 3, 1);
02723
02724
02725 d->m_freeSpaceText = new QLabel(i18n("Free disk space:"), d->m_frame );
02726 layout->addWidget(d->m_freeSpaceText, 4, 0);
02727
02728 d->m_freeSpaceLabel = new QLabel( d->m_frame );
02729 layout->addWidget( d->m_freeSpaceLabel, 4, 1 );
02730
02731 d->m_freeSpaceBar = new QProgressBar( d->m_frame, "freeSpaceBar" );
02732 layout->addMultiCellWidget(d->m_freeSpaceBar, 5, 5, 0, 1);
02733
02734
02735 d->m_freeSpaceText->hide();
02736 d->m_freeSpaceLabel->hide();
02737 d->m_freeSpaceBar->hide();
02738
02739 KSeparator* sep = new KSeparator( KSeparator::HLine, d->m_frame);
02740 layout->addMultiCellWidget(sep, 6, 6, 0, 1);
02741
02742 unmounted = new KIconButton( d->m_frame );
02743 int bsize = 66 + 2 * unmounted->style().pixelMetric(QStyle::PM_ButtonMargin);
02744 unmounted->setFixedSize(bsize, bsize);
02745 unmounted->setIconType(KIcon::Desktop, KIcon::Device);
02746 layout->addWidget(unmounted, 7, 0);
02747
02748 label = new QLabel( i18n("Unmounted Icon"), d->m_frame );
02749 layout->addWidget(label, 7, 1);
02750
02751 layout->setRowStretch(8, 1);
02752
02753 QString path( _props->kurl().path() );
02754
02755 QFile f( path );
02756 if ( !f.open( IO_ReadOnly ) )
02757 return;
02758 f.close();
02759
02760 KSimpleConfig config( path );
02761 config.setDesktopGroup();
02762 QString deviceStr = config.readEntry( "Dev" );
02763 QString mountPointStr = config.readEntry( "MountPoint" );
02764 bool ro = config.readBoolEntry( "ReadOnly", false );
02765 QString unmountedStr = config.readEntry( "UnmountIcon" );
02766
02767 fileSystem->setText( i18n(config.readEntry("FSType").local8Bit()) );
02768
02769 device->setEditText( deviceStr );
02770 if ( !deviceStr.isEmpty() ) {
02771
02772 int index = m_devicelist.findIndex(deviceStr);
02773 if (index != -1)
02774 {
02775
02776 slotActivated( index );
02777 }
02778 }
02779
02780 if ( !mountPointStr.isEmpty() )
02781 {
02782 mountpoint->setText( mountPointStr );
02783 updateInfo();
02784 }
02785
02786 readonly->setChecked( ro );
02787
02788 if ( unmountedStr.isEmpty() )
02789 unmountedStr = KMimeType::mimeType(QString::fromLatin1("application/octet-stream"))->KServiceType::icon();
02790
02791 unmounted->setIcon( unmountedStr );
02792
02793 connect( device, SIGNAL( activated( int ) ),
02794 this, SIGNAL( changed() ) );
02795 connect( device, SIGNAL( textChanged( const QString & ) ),
02796 this, SIGNAL( changed() ) );
02797 connect( readonly, SIGNAL( toggled( bool ) ),
02798 this, SIGNAL( changed() ) );
02799 connect( unmounted, SIGNAL( iconChanged( QString ) ),
02800 this, SIGNAL( changed() ) );
02801
02802 connect( device, SIGNAL( textChanged( const QString & ) ),
02803 this, SLOT( slotDeviceChanged() ) );
02804 }
02805
02806 KDevicePropsPlugin::~KDevicePropsPlugin()
02807 {
02808 delete d;
02809 }
02810
02811
02812
02813
02814
02815
02816 void KDevicePropsPlugin::updateInfo()
02817 {
02818
02819 d->m_freeSpaceText->hide();
02820 d->m_freeSpaceLabel->hide();
02821 d->m_freeSpaceBar->hide();
02822
02823 if ( !mountpoint->text().isEmpty() )
02824 {
02825 KDiskFreeSp * job = new KDiskFreeSp;
02826 connect( job, SIGNAL( foundMountPoint( const unsigned long&, const unsigned long&,
02827 const unsigned long&, const QString& ) ),
02828 this, SLOT( slotFoundMountPoint( const unsigned long&, const unsigned long&,
02829 const unsigned long&, const QString& ) ) );
02830
02831 job->readDF( mountpoint->text() );
02832 }
02833 }
02834
02835 void KDevicePropsPlugin::slotActivated( int index )
02836 {
02837
02838 device->setEditText( m_devicelist[index] );
02839 mountpoint->setText( d->mountpointlist[index] );
02840
02841 updateInfo();
02842 }
02843
02844 void KDevicePropsPlugin::slotDeviceChanged()
02845 {
02846
02847 int index = m_devicelist.findIndex( device->currentText() );
02848 if ( index != -1 )
02849 mountpoint->setText( d->mountpointlist[index] );
02850 else
02851 mountpoint->setText( QString::null );
02852
02853 updateInfo();
02854 }
02855
02856 void KDevicePropsPlugin::slotFoundMountPoint( const unsigned long& kBSize,
02857 const unsigned long& ,
02858 const unsigned long& kBAvail,
02859 const QString& )
02860 {
02861 d->m_freeSpaceText->show();
02862 d->m_freeSpaceLabel->show();
02863
02864 int percUsed = 100 - (int)(100.0 * kBAvail / kBSize);
02865
02866 d->m_freeSpaceLabel->setText(
02867 i18n("Available space out of total partition size (percent used)", "%1 out of %2 (%3% used)")
02868 .arg(KIO::convertSizeFromKB(kBAvail))
02869 .arg(KIO::convertSizeFromKB(kBSize))
02870 .arg( 100 - (int)(100.0 * kBAvail / kBSize) ));
02871
02872 d->m_freeSpaceBar->setProgress(percUsed, 100);
02873 d->m_freeSpaceBar->show();
02874 }
02875
02876 bool KDevicePropsPlugin::supports( KFileItemList _items )
02877 {
02878 if ( _items.count() != 1 )
02879 return false;
02880 KFileItem * item = _items.first();
02881
02882 if ( !KPropsDlgPlugin::isDesktopFile( item ) )
02883 return false;
02884
02885 KDesktopFile config( item->url().path(), true );
02886 return config.hasDeviceType();
02887 }
02888
02889 void KDevicePropsPlugin::applyChanges()
02890 {
02891 QString path = properties->kurl().path();
02892 QFile f( path );
02893 if ( !f.open( IO_ReadWrite ) )
02894 {
02895 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have sufficient "
02896 "access to write to <b>%1</b>.</qt>").arg(path));
02897 return;
02898 }
02899 f.close();
02900
02901 KSimpleConfig config( path );
02902 config.setDesktopGroup();
02903 config.writeEntry( "Type", QString::fromLatin1("FSDevice") );
02904
02905 config.writeEntry( "Dev", device->currentText() );
02906 config.writeEntry( "MountPoint", mountpoint->text() );
02907
02908 config.writeEntry( "UnmountIcon", unmounted->icon() );
02909 kdDebug(250) << "unmounted->icon() = " << unmounted->icon() << endl;
02910
02911 config.writeEntry( "ReadOnly", readonly->isChecked() );
02912
02913 config.sync();
02914 }
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924 KDesktopPropsPlugin::KDesktopPropsPlugin( KPropertiesDialog *_props )
02925 : KPropsDlgPlugin( _props )
02926 {
02927 QFrame *frame = properties->addPage(i18n("&Application"));
02928 QVBoxLayout *mainlayout = new QVBoxLayout( frame, 0, KDialog::spacingHint() );
02929
02930 w = new KPropertiesDesktopBase(frame);
02931 mainlayout->addWidget(w);
02932
02933 bool bKDesktopMode = (QCString(qApp->name()) == "kdesktop");
02934
02935 if (bKDesktopMode)
02936 {
02937
02938 w->nameEdit->hide();
02939 w->nameLabel->hide();
02940 }
02941
02942 w->pathEdit->setMode(KFile::Directory | KFile::LocalOnly);
02943 w->pathEdit->lineEdit()->setAcceptDrops(false);
02944
02945 connect( w->nameEdit, SIGNAL( textChanged( const QString & ) ), this, SIGNAL( changed() ) );
02946 connect( w->genNameEdit, SIGNAL( textChanged( const QString & ) ), this, SIGNAL( changed() ) );
02947 connect( w->commentEdit, SIGNAL( textChanged( const QString & ) ), this, SIGNAL( changed() ) );
02948 connect( w->commandEdit, SIGNAL( textChanged( const QString & ) ), this, SIGNAL( changed() ) );
02949 connect( w->pathEdit, SIGNAL( textChanged( const QString & ) ), this, SIGNAL( changed() ) );
02950
02951 connect( w->browseButton, SIGNAL( clicked() ), this, SLOT( slotBrowseExec() ) );
02952 connect( w->addFiletypeButton, SIGNAL( clicked() ), this, SLOT( slotAddFiletype() ) );
02953 connect( w->delFiletypeButton, SIGNAL( clicked() ), this, SLOT( slotDelFiletype() ) );
02954 connect( w->advancedButton, SIGNAL( clicked() ), this, SLOT( slotAdvanced() ) );
02955
02956
02957 QString path = _props->kurl().path();
02958 QFile f( path );
02959 if ( !f.open( IO_ReadOnly ) )
02960 return;
02961 f.close();
02962
02963 KSimpleConfig config( path );
02964 config.setDollarExpansion( false );
02965 config.setDesktopGroup();
02966 QString nameStr = config.readEntry( "Name" );
02967 QString genNameStr = config.readEntry( "GenericName" );
02968 QString commentStr = config.readEntry( "Comment" );
02969 QString commandStr = config.readPathEntry( "Exec" );
02970 if (commandStr.left(12) == "ksystraycmd ")
02971 {
02972 commandStr.remove(0, 12);
02973 m_systrayBool = true;
02974 }
02975 else
02976 m_systrayBool = false;
02977
02978 m_origCommandStr = commandStr;
02979 QString pathStr = config.readPathEntry( "Path" );
02980 m_terminalBool = config.readBoolEntry( "Terminal" );
02981 m_terminalOptionStr = config.readEntry( "TerminalOptions" );
02982 m_suidBool = config.readBoolEntry( "X-KDE-SubstituteUID" );
02983 m_suidUserStr = config.readEntry( "X-KDE-Username" );
02984 if( config.hasKey( "StartupNotify" ))
02985 m_startupBool = config.readBoolEntry( "StartupNotify", true );
02986 else
02987 m_startupBool = config.readBoolEntry( "X-KDE-StartupNotify", true );
02988 m_dcopServiceType = config.readEntry("X-DCOP-ServiceType").lower();
02989
02990 QStringList mimeTypes = config.readListEntry( "MimeType", ';' );
02991
02992 if ( nameStr.isEmpty() || bKDesktopMode ) {
02993
02994
02995
02996 setDirty();
02997 }
02998 if ( !bKDesktopMode )
02999 w->nameEdit->setText(nameStr);
03000
03001 w->genNameEdit->setText( genNameStr );
03002 w->commentEdit->setText( commentStr );
03003 w->commandEdit->setText( commandStr );
03004 w->pathEdit->lineEdit()->setText( pathStr );
03005 w->filetypeList->setAllColumnsShowFocus(true);
03006
03007 KMimeType::Ptr defaultMimetype = KMimeType::defaultMimeTypePtr();
03008 for(QStringList::ConstIterator it = mimeTypes.begin();
03009 it != mimeTypes.end(); )
03010 {
03011 KMimeType::Ptr p = KMimeType::mimeType(*it);
03012 ++it;
03013 QString preference;
03014 if (it != mimeTypes.end())
03015 {
03016 bool numeric;
03017 (*it).toInt(&numeric);
03018 if (numeric)
03019 {
03020 preference = *it;
03021 ++it;
03022 }
03023 }
03024 if (p && (p != defaultMimetype))
03025 {
03026 new QListViewItem(w->filetypeList, p->name(), p->comment(), preference);
03027 }
03028 }
03029
03030 }
03031
03032 KDesktopPropsPlugin::~KDesktopPropsPlugin()
03033 {
03034 }
03035
03036 void KDesktopPropsPlugin::slotSelectMimetype()
03037 {
03038 QListView *w = (QListView*)sender();
03039 QListViewItem *item = w->firstChild();
03040 while(item)
03041 {
03042 if (item->isSelected())
03043 w->setSelected(item, false);
03044 item = item->nextSibling();
03045 }
03046 }
03047
03048 void KDesktopPropsPlugin::slotAddFiletype()
03049 {
03050 KDialogBase dlg(w, "KPropertiesMimetypes", true,
03051 i18n("Add File Type for %1").arg(properties->kurl().fileName()),
03052 KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok);
03053
03054 KGuiItem okItem(i18n("&Add"), QString::null ,
03055 i18n("Add the selected file types to\nthe list of supported file types."),
03056 i18n("Add the selected file types to\nthe list of supported file types."));
03057 dlg.setButtonOK(okItem);
03058
03059 KPropertiesMimetypeBase *mw = new KPropertiesMimetypeBase(&dlg);
03060
03061 dlg.setMainWidget(mw);
03062
03063 {
03064 mw->listView->setRootIsDecorated(true);
03065 mw->listView->setSelectionMode(QListView::Extended);
03066 mw->listView->setAllColumnsShowFocus(true);
03067 mw->listView->setFullWidth(true);
03068 mw->listView->setMinimumSize(500,400);
03069
03070 connect(mw->listView, SIGNAL(selectionChanged()),
03071 this, SLOT(slotSelectMimetype()));
03072 connect(mw->listView, SIGNAL(doubleClicked( QListViewItem *, const QPoint &, int )),
03073 &dlg, SLOT( slotOk()));
03074
03075 QMap<QString,QListViewItem*> majorMap;
03076 QListViewItem *majorGroup;
03077 KMimeType::List mimetypes = KMimeType::allMimeTypes();
03078 QValueListIterator<KMimeType::Ptr> it(mimetypes.begin());
03079 for (; it != mimetypes.end(); ++it) {
03080 QString mimetype = (*it)->name();
03081 if (mimetype == "application/octet-stream")
03082 continue;
03083 int index = mimetype.find("/");
03084 QString maj = mimetype.left(index);
03085 QString min = mimetype.mid(index+1);
03086
03087 QMapIterator<QString,QListViewItem*> mit = majorMap.find( maj );
03088 if ( mit == majorMap.end() ) {
03089 majorGroup = new QListViewItem( mw->listView, maj );
03090 majorGroup->setExpandable(true);
03091 mw->listView->setOpen(majorGroup, true);
03092 majorMap.insert( maj, majorGroup );
03093 }
03094 else
03095 {
03096 majorGroup = mit.data();
03097 }
03098
03099 QListViewItem *item = new QListViewItem(majorGroup, min, (*it)->comment());
03100 item->setPixmap(0, (*it)->pixmap(KIcon::Small, IconSize(KIcon::Small)));
03101 }
03102 QMapIterator<QString,QListViewItem*> mit = majorMap.find( "all" );
03103 if ( mit != majorMap.end())
03104 {
03105 mw->listView->setCurrentItem(mit.data());
03106 mw->listView->ensureItemVisible(mit.data());
03107 }
03108 }
03109
03110 if (dlg.exec() == KDialogBase::Accepted)
03111 {
03112 KMimeType::Ptr defaultMimetype = KMimeType::defaultMimeTypePtr();
03113 QListViewItem *majorItem = mw->listView->firstChild();
03114 while(majorItem)
03115 {
03116 QString major = majorItem->text(0);
03117
03118 QListViewItem *minorItem = majorItem->firstChild();
03119 while(minorItem)
03120 {
03121 if (minorItem->isSelected())
03122 {
03123 QString mimetype = major + "/" + minorItem->text(0);
03124 KMimeType::Ptr p = KMimeType::mimeType(mimetype);
03125 if (p && (p != defaultMimetype))
03126 {
03127 mimetype = p->name();
03128 bool found = false;
03129 QListViewItem *item = w->filetypeList->firstChild();
03130 while (item)
03131 {
03132 if (mimetype == item->text(0))
03133 {
03134 found = true;
03135 break;
03136 }
03137 item = item->nextSibling();
03138 }
03139 if (!found)
03140 new QListViewItem(w->filetypeList, p->name(), p->comment());
03141 }
03142 }
03143 minorItem = minorItem->nextSibling();
03144 }
03145
03146 majorItem = majorItem->nextSibling();
03147 }
03148
03149 }
03150 }
03151
03152 void KDesktopPropsPlugin::slotDelFiletype()
03153 {
03154 delete w->filetypeList->currentItem();
03155 }
03156
03157 void KDesktopPropsPlugin::checkCommandChanged()
03158 {
03159 if (KRun::binaryName(w->commandEdit->text(), true) !=
03160 KRun::binaryName(m_origCommandStr, true))
03161 {
03162 QString m_origCommandStr = w->commandEdit->text();
03163 m_dcopServiceType= QString::null;
03164 }
03165 }
03166
03167 void KDesktopPropsPlugin::applyChanges()
03168 {
03169 kdDebug(250) << "KDesktopPropsPlugin::applyChanges" << endl;
03170 QString path = properties->kurl().path();
03171
03172 QFile f( path );
03173
03174 if ( !f.open( IO_ReadWrite ) ) {
03175 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have "
03176 "sufficient access to write to <b>%1</b>.</qt>").arg(path));
03177 return;
03178 }
03179 f.close();
03180
03181
03182
03183 checkCommandChanged();
03184
03185 KSimpleConfig config( path );
03186 config.setDesktopGroup();
03187 config.writeEntry( "Type", QString::fromLatin1("Application"));
03188 config.writeEntry( "Comment", w->commentEdit->text() );
03189 config.writeEntry( "Comment", w->commentEdit->text(), true, false, true );
03190 config.writeEntry( "GenericName", w->genNameEdit->text() );
03191 config.writeEntry( "GenericName", w->genNameEdit->text(), true, false, true );
03192
03193 if (m_systrayBool)
03194 config.writePathEntry( "Exec", w->commandEdit->text().prepend("ksystraycmd ") );
03195 else
03196 config.writePathEntry( "Exec", w->commandEdit->text() );
03197 config.writePathEntry( "Path", w->pathEdit->lineEdit()->text() );
03198
03199
03200 QStringList mimeTypes;
03201 for( QListViewItem *item = w->filetypeList->firstChild();
03202 item; item = item->nextSibling() )
03203 {
03204 QString preference = item->text(2);
03205 mimeTypes.append(item->text(0));
03206 if (!preference.isEmpty())
03207 mimeTypes.append(preference);
03208 }
03209
03210 config.writeEntry( "MimeType", mimeTypes, ';' );
03211
03212 if ( !w->nameEdit->isHidden() ) {
03213 QString nameStr = w->nameEdit->text();
03214 config.writeEntry( "Name", nameStr );
03215 config.writeEntry( "Name", nameStr, true, false, true );
03216 }
03217
03218 config.writeEntry("Terminal", m_terminalBool);
03219 config.writeEntry("TerminalOptions", m_terminalOptionStr);
03220 config.writeEntry("X-KDE-SubstituteUID", m_suidBool);
03221 config.writeEntry("X-KDE-Username", m_suidUserStr);
03222 config.writeEntry("StartupNotify", m_startupBool);
03223 config.writeEntry("X-DCOP-ServiceType", m_dcopServiceType);
03224 config.sync();
03225
03226
03227 QString sycocaPath = KGlobal::dirs()->relativeLocation("apps", path);
03228 bool updateNeeded = !sycocaPath.startsWith("/");
03229 if (!updateNeeded)
03230 {
03231 sycocaPath = KGlobal::dirs()->relativeLocation("xdgdata-apps", path);
03232 updateNeeded = !sycocaPath.startsWith("/");
03233 }
03234 if (updateNeeded)
03235 KService::rebuildKSycoca(w);
03236 }
03237
03238
03239 void KDesktopPropsPlugin::slotBrowseExec()
03240 {
03241 KURL f = KFileDialog::getOpenURL( QString::null,
03242 QString::null, w );
03243 if ( f.isEmpty() )
03244 return;
03245
03246 if ( !f.isLocalFile()) {
03247 KMessageBox::sorry(w, i18n("Only executables on local file systems are supported."));
03248 return;
03249 }
03250
03251 QString path = f.path();
03252 KRun::shellQuote( path );
03253 w->commandEdit->setText( path );
03254 }
03255
03256 void KDesktopPropsPlugin::slotAdvanced()
03257 {
03258 KDialogBase dlg(w, "KPropertiesDesktopAdv", true,
03259 i18n("Advanced Options for %1").arg(properties->kurl().fileName()),
03260 KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok);
03261 KPropertiesDesktopAdvBase *w = new KPropertiesDesktopAdvBase(&dlg);
03262
03263 dlg.setMainWidget(w);
03264
03265
03266
03267 checkCommandChanged();
03268
03269
03270
03271 KConfigGroup confGroup( KGlobal::config(), QString::fromLatin1("General") );
03272 QString preferredTerminal = confGroup.readPathEntry("TerminalApplication",
03273 QString::fromLatin1("konsole"));
03274
03275 bool terminalCloseBool = false;
03276
03277 if (preferredTerminal == "konsole")
03278 {
03279 terminalCloseBool = (m_terminalOptionStr.contains( "--noclose" ) > 0);
03280 w->terminalCloseCheck->setChecked(terminalCloseBool);
03281 m_terminalOptionStr.replace( "--noclose", "");
03282 }
03283 else
03284 {
03285 w->terminalCloseCheck->hide();
03286 }
03287
03288 w->terminalCheck->setChecked(m_terminalBool);
03289 w->terminalEdit->setText(m_terminalOptionStr);
03290 w->terminalCloseCheck->setEnabled(m_terminalBool);
03291 w->terminalEdit->setEnabled(m_terminalBool);
03292 w->terminalEditLabel->setEnabled(m_terminalBool);
03293
03294 w->suidCheck->setChecked(m_suidBool);
03295 w->suidEdit->setText(m_suidUserStr);
03296 w->suidEdit->setEnabled(m_suidBool);
03297 w->suidEditLabel->setEnabled(m_suidBool);
03298
03299 w->startupInfoCheck->setChecked(m_startupBool);
03300 w->systrayCheck->setChecked(m_systrayBool);
03301
03302 if (m_dcopServiceType == "unique")
03303 w->dcopCombo->setCurrentItem(2);
03304 else if (m_dcopServiceType == "multi")
03305 w->dcopCombo->setCurrentItem(1);
03306 else if (m_dcopServiceType == "wait")
03307 w->dcopCombo->setCurrentItem(3);
03308 else
03309 w->dcopCombo->setCurrentItem(0);
03310
03311
03312 KCompletion *kcom = new KCompletion;
03313 kcom->setOrder(KCompletion::Sorted);
03314 struct passwd *pw;
03315 int i, maxEntries = 1000;
03316 setpwent();
03317 for (i=0; ((pw = getpwent()) != 0L) && (i < maxEntries); i++)
03318 kcom->addItem(QString::fromLatin1(pw->pw_name));
03319 endpwent();
03320 if (i < maxEntries)
03321 {
03322 w->suidEdit->setCompletionObject(kcom, true);
03323 w->suidEdit->setAutoDeleteCompletionObject( true );
03324 w->suidEdit->setCompletionMode(KGlobalSettings::CompletionAuto);
03325 }
03326 else
03327 {
03328 delete kcom;
03329 }
03330
03331 connect( w->terminalEdit, SIGNAL( textChanged( const QString & ) ),
03332 this, SIGNAL( changed() ) );
03333 connect( w->terminalCloseCheck, SIGNAL( toggled( bool ) ),
03334 this, SIGNAL( changed() ) );
03335 connect( w->terminalCheck, SIGNAL( toggled( bool ) ),
03336 this, SIGNAL( changed() ) );
03337 connect( w->suidCheck, SIGNAL( toggled( bool ) ),
03338 this, SIGNAL( changed() ) );
03339 connect( w->suidEdit, SIGNAL( textChanged( const QString & ) ),
03340 this, SIGNAL( changed() ) );
03341 connect( w->startupInfoCheck, SIGNAL( toggled( bool ) ),
03342 this, SIGNAL( changed() ) );
03343 connect( w->systrayCheck, SIGNAL( toggled( bool ) ),
03344 this, SIGNAL( changed() ) );
03345 connect( w->dcopCombo, SIGNAL( highlighted( int ) ),
03346 this, SIGNAL( changed() ) );
03347
03348 if ( dlg.exec() == QDialog::Accepted )
03349 {
03350 m_terminalOptionStr = w->terminalEdit->text().stripWhiteSpace();
03351 m_terminalBool = w->terminalCheck->isChecked();
03352 m_suidBool = w->suidCheck->isChecked();
03353 m_suidUserStr = w->suidEdit->text().stripWhiteSpace();
03354 m_startupBool = w->startupInfoCheck->isChecked();
03355 m_systrayBool = w->systrayCheck->isChecked();
03356
03357 if (w->terminalCloseCheck->isChecked())
03358 {
03359 m_terminalOptionStr.append(" --noclose");
03360 }
03361
03362 switch(w->dcopCombo->currentItem())
03363 {
03364 case 1: m_dcopServiceType = "multi"; break;
03365 case 2: m_dcopServiceType = "unique"; break;
03366 case 3: m_dcopServiceType = "wait"; break;
03367 default: m_dcopServiceType = "none"; break;
03368 }
03369 }
03370 }
03371
03372 bool KDesktopPropsPlugin::supports( KFileItemList _items )
03373 {
03374 if ( _items.count() != 1 )
03375 return false;
03376 KFileItem * item = _items.first();
03377
03378 if ( !KPropsDlgPlugin::isDesktopFile( item ) )
03379 return false;
03380
03381 KDesktopFile config( item->url().path(), true );
03382 return config.hasApplicationType() && kapp->authorize("run_desktop_files") && kapp->authorize("shell_access");
03383 }
03384
03385 void KPropertiesDialog::virtual_hook( int id, void* data )
03386 { KDialogBase::virtual_hook( id, data ); }
03387
03388 void KPropsDlgPlugin::virtual_hook( int, void* )
03389 { }
03390
03391
03392
03393
03394
03400 class KExecPropsPlugin::KExecPropsPluginPrivate
03401 {
03402 public:
03403 KExecPropsPluginPrivate()
03404 {
03405 }
03406 ~KExecPropsPluginPrivate()
03407 {
03408 }
03409
03410 QFrame *m_frame;
03411 QCheckBox *nocloseonexitCheck;
03412 };
03413
03414 KExecPropsPlugin::KExecPropsPlugin( KPropertiesDialog *_props )
03415 : KPropsDlgPlugin( _props )
03416 {
03417 d = new KExecPropsPluginPrivate;
03418 d->m_frame = properties->addPage(i18n("E&xecute"));
03419 QVBoxLayout * mainlayout = new QVBoxLayout( d->m_frame, 0,
03420 KDialog::spacingHint());
03421
03422
03423
03424 QLabel* l;
03425 l = new QLabel( i18n( "Comman&d:" ), d->m_frame );
03426 mainlayout->addWidget(l);
03427
03428 QHBoxLayout * hlayout;
03429 hlayout = new QHBoxLayout(KDialog::spacingHint());
03430 mainlayout->addLayout(hlayout);
03431
03432 execEdit = new KLineEdit( d->m_frame );
03433 QWhatsThis::add(execEdit,i18n(
03434 "Following the command, you can have several place holders which will be replaced "
03435 "with the actual values when the actual program is run:\n"
03436 "%f - a single file name\n"
03437 "%F - a list of files; use for applications that can open several local files at once\n"
03438 "%u - a single URL\n"
03439 "%U - a list of URLs\n"
03440 "%d - the folder of the file to open\n"
03441 "%D - a list of folders\n"
03442 "%i - the icon\n"
03443 "%m - the mini-icon\n"
03444 "%c - the caption"));
03445 hlayout->addWidget(execEdit, 1);
03446
03447 l->setBuddy( execEdit );
03448
03449 execBrowse = new QPushButton( d->m_frame );
03450 execBrowse->setText( i18n("&Browse...") );
03451 hlayout->addWidget(execBrowse);
03452
03453
03454 QGroupBox* tmpQGroupBox;
03455 tmpQGroupBox = new QGroupBox( i18n("Panel Embedding"), d->m_frame );
03456 tmpQGroupBox->setColumnLayout( 0, Qt::Horizontal );
03457
03458 mainlayout->addWidget(tmpQGroupBox);
03459
03460 QGridLayout *grid = new QGridLayout(tmpQGroupBox->layout(), 2, 2);
03461 grid->setSpacing( KDialog::spacingHint() );
03462 grid->setColStretch(1, 1);
03463
03464 l = new QLabel( i18n( "&Execute on click:" ), tmpQGroupBox );
03465 grid->addWidget(l, 0, 0);
03466
03467 swallowExecEdit = new KLineEdit( tmpQGroupBox );
03468 grid->addWidget(swallowExecEdit, 0, 1);
03469
03470 l->setBuddy( swallowExecEdit );
03471
03472 l = new QLabel( i18n( "&Window title:" ), tmpQGroupBox );
03473 grid->addWidget(l, 1, 0);
03474
03475 swallowTitleEdit = new KLineEdit( tmpQGroupBox );
03476 grid->addWidget(swallowTitleEdit, 1, 1);
03477
03478 l->setBuddy( swallowTitleEdit );
03479
03480
03481
03482 tmpQGroupBox = new QGroupBox( d->m_frame );
03483 tmpQGroupBox->setColumnLayout( 0, Qt::Horizontal );
03484
03485 mainlayout->addWidget(tmpQGroupBox);
03486
03487 grid = new QGridLayout(tmpQGroupBox->layout(), 3, 2);
03488 grid->setSpacing( KDialog::spacingHint() );
03489 grid->setColStretch(1, 1);
03490
03491 terminalCheck = new QCheckBox( tmpQGroupBox );
03492 terminalCheck->setText( i18n("&Run in terminal") );
03493 grid->addMultiCellWidget(terminalCheck, 0, 0, 0, 1);
03494
03495
03496
03497 KConfigGroup confGroup( KGlobal::config(), QString::fromLatin1("General") );
03498 QString preferredTerminal = confGroup.readPathEntry("TerminalApplication",
03499 QString::fromLatin1("konsole"));
03500
03501 int posOptions = 1;
03502 d->nocloseonexitCheck = 0L;
03503 if (preferredTerminal == "konsole")
03504 {
03505 posOptions = 2;
03506 d->nocloseonexitCheck = new QCheckBox( tmpQGroupBox );
03507 d->nocloseonexitCheck->setText( i18n("Do not &close when command exits") );
03508 grid->addMultiCellWidget(d->nocloseonexitCheck, 1, 1, 0, 1);
03509 }
03510
03511 terminalLabel = new QLabel( i18n( "&Terminal options:" ), tmpQGroupBox );
03512 grid->addWidget(terminalLabel, posOptions, 0);
03513
03514 terminalEdit = new KLineEdit( tmpQGroupBox );
03515 grid->addWidget(terminalEdit, posOptions, 1);
03516
03517 terminalLabel->setBuddy( terminalEdit );
03518
03519
03520
03521 tmpQGroupBox = new QGroupBox( d->m_frame );
03522 tmpQGroupBox->setColumnLayout( 0, Qt::Horizontal );
03523
03524 mainlayout->addWidget(tmpQGroupBox);
03525
03526 grid = new QGridLayout(tmpQGroupBox->layout(), 2, 2);
03527 grid->setSpacing(KDialog::spacingHint());
03528 grid->setColStretch(1, 1);
03529
03530 suidCheck = new QCheckBox(tmpQGroupBox);
03531 suidCheck->setText(i18n("Ru&n as a different user"));
03532 grid->addMultiCellWidget(suidCheck, 0, 0, 0, 1);
03533
03534 suidLabel = new QLabel(i18n( "&Username:" ), tmpQGroupBox);
03535 grid->addWidget(suidLabel, 1, 0);
03536
03537 suidEdit = new KLineEdit(tmpQGroupBox);
03538 grid->addWidget(suidEdit, 1, 1);
03539
03540 suidLabel->setBuddy( suidEdit );
03541
03542 mainlayout->addStretch(1);
03543
03544
03545 QString path = _props->kurl().path();
03546 QFile f( path );
03547 if ( !f.open( IO_ReadOnly ) )
03548 return;
03549 f.close();
03550
03551 KSimpleConfig config( path );
03552 config.setDollarExpansion( false );
03553 config.setDesktopGroup();
03554 execStr = config.readPathEntry( "Exec" );
03555 swallowExecStr = config.readPathEntry( "SwallowExec" );
03556 swallowTitleStr = config.readEntry( "SwallowTitle" );
03557 termBool = config.readBoolEntry( "Terminal" );
03558 termOptionsStr = config.readEntry( "TerminalOptions" );
03559 suidBool = config.readBoolEntry( "X-KDE-SubstituteUID" );
03560 suidUserStr = config.readEntry( "X-KDE-Username" );
03561
03562 if ( !swallowExecStr.isNull() )
03563 swallowExecEdit->setText( swallowExecStr );
03564 if ( !swallowTitleStr.isNull() )
03565 swallowTitleEdit->setText( swallowTitleStr );
03566
03567 if ( !execStr.isNull() )
03568 execEdit->setText( execStr );
03569
03570 if ( d->nocloseonexitCheck )
03571 {
03572 d->nocloseonexitCheck->setChecked( (termOptionsStr.contains( "--noclose" ) > 0) );
03573 termOptionsStr.replace( "--noclose", "");
03574 }
03575 if ( !termOptionsStr.isNull() )
03576 terminalEdit->setText( termOptionsStr );
03577
03578 terminalCheck->setChecked( termBool );
03579 enableCheckedEdit();
03580
03581 suidCheck->setChecked( suidBool );
03582 suidEdit->setText( suidUserStr );
03583 enableSuidEdit();
03584
03585
03586 KCompletion *kcom = new KCompletion;
03587 kcom->setOrder(KCompletion::Sorted);
03588 struct passwd *pw;
03589 int i, maxEntries = 1000;
03590 setpwent();
03591 for (i=0; ((pw = getpwent()) != 0L) && (i < maxEntries); i++)
03592 kcom->addItem(QString::fromLatin1(pw->pw_name));
03593 endpwent();
03594 if (i < maxEntries)
03595 {
03596 suidEdit->setCompletionObject(kcom, true);
03597 suidEdit->setAutoDeleteCompletionObject( true );
03598 suidEdit->setCompletionMode(KGlobalSettings::CompletionAuto);
03599 }
03600 else
03601 {
03602 delete kcom;
03603 }
03604
03605 connect( swallowExecEdit, SIGNAL( textChanged( const QString & ) ),
03606 this, SIGNAL( changed() ) );
03607 connect( swallowTitleEdit, SIGNAL( textChanged( const QString & ) ),
03608 this, SIGNAL( changed() ) );
03609 connect( execEdit, SIGNAL( textChanged( const QString & ) ),
03610 this, SIGNAL( changed() ) );
03611 connect( terminalEdit, SIGNAL( textChanged( const QString & ) ),
03612 this, SIGNAL( changed() ) );
03613 if (d->nocloseonexitCheck)
03614 connect( d->nocloseonexitCheck, SIGNAL( toggled( bool ) ),
03615 this, SIGNAL( changed() ) );
03616 connect( terminalCheck, SIGNAL( toggled( bool ) ),
03617 this, SIGNAL( changed() ) );
03618 connect( suidCheck, SIGNAL( toggled( bool ) ),
03619 this, SIGNAL( changed() ) );
03620 connect( suidEdit, SIGNAL( textChanged( const QString & ) ),
03621 this, SIGNAL( changed() ) );
03622
03623 connect( execBrowse, SIGNAL( clicked() ), this, SLOT( slotBrowseExec() ) );
03624 connect( terminalCheck, SIGNAL( clicked() ), this, SLOT( enableCheckedEdit() ) );
03625 connect( suidCheck, SIGNAL( clicked() ), this, SLOT( enableSuidEdit() ) );
03626
03627 }
03628
03629 KExecPropsPlugin::~KExecPropsPlugin()
03630 {
03631 delete d;
03632 }
03633
03634 void KExecPropsPlugin::enableCheckedEdit()
03635 {
03636 bool checked = terminalCheck->isChecked();
03637 terminalLabel->setEnabled( checked );
03638 if (d->nocloseonexitCheck)
03639 d->nocloseonexitCheck->setEnabled( checked );
03640 terminalEdit->setEnabled( checked );
03641 }
03642
03643 void KExecPropsPlugin::enableSuidEdit()
03644 {
03645 bool checked = suidCheck->isChecked();
03646 suidLabel->setEnabled( checked );
03647 suidEdit->setEnabled( checked );
03648 }
03649
03650 bool KExecPropsPlugin::supports( KFileItemList _items )
03651 {
03652 if ( _items.count() != 1 )
03653 return false;
03654 KFileItem * item = _items.first();
03655
03656 if ( !KPropsDlgPlugin::isDesktopFile( item ) )
03657 return false;
03658
03659 KDesktopFile config( item->url().path(), true );
03660 return config.hasApplicationType() && kapp->authorize("run_desktop_files") && kapp->authorize("shell_access");
03661 }
03662
03663 void KExecPropsPlugin::applyChanges()
03664 {
03665 kdDebug(250) << "KExecPropsPlugin::applyChanges" << endl;
03666 QString path = properties->kurl().path();
03667
03668 QFile f( path );
03669
03670 if ( !f.open( IO_ReadWrite ) ) {
03671 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have "
03672 "sufficient access to write to <b>%1</b>.</qt>").arg(path));
03673 return;
03674 }
03675 f.close();
03676
03677 KSimpleConfig config( path );
03678 config.setDesktopGroup();
03679 config.writeEntry( "Type", QString::fromLatin1("Application"));
03680 config.writePathEntry( "Exec", execEdit->text() );
03681 config.writePathEntry( "SwallowExec", swallowExecEdit->text() );
03682 config.writeEntry( "SwallowTitle", swallowTitleEdit->text() );
03683 config.writeEntry( "Terminal", terminalCheck->isChecked() );
03684 QString temp = terminalEdit->text();
03685 if (d->nocloseonexitCheck )
03686 if ( d->nocloseonexitCheck->isChecked() )
03687 temp += QString::fromLatin1("--noclose ");
03688 temp = temp.stripWhiteSpace();
03689 config.writeEntry( "TerminalOptions", temp );
03690 config.writeEntry( "X-KDE-SubstituteUID", suidCheck->isChecked() );
03691 config.writeEntry( "X-KDE-Username", suidEdit->text() );
03692 }
03693
03694
03695 void KExecPropsPlugin::slotBrowseExec()
03696 {
03697 KURL f = KFileDialog::getOpenURL( QString::null,
03698 QString::null, d->m_frame );
03699 if ( f.isEmpty() )
03700 return;
03701
03702 if ( !f.isLocalFile()) {
03703 KMessageBox::sorry(d->m_frame, i18n("Only executables on local file systems are supported."));
03704 return;
03705 }
03706
03707 QString path = f.path();
03708 KRun::shellQuote( path );
03709 execEdit->setText( path );
03710 }
03711
03712 class KApplicationPropsPlugin::KApplicationPropsPluginPrivate
03713 {
03714 public:
03715 KApplicationPropsPluginPrivate()
03716 {
03717 m_kdesktopMode = QCString(qApp->name()) == "kdesktop";
03718 }
03719 ~KApplicationPropsPluginPrivate()
03720 {
03721 }
03722
03723 QFrame *m_frame;
03724 bool m_kdesktopMode;
03725 };
03726
03727 KApplicationPropsPlugin::KApplicationPropsPlugin( KPropertiesDialog *_props )
03728 : KPropsDlgPlugin( _props )
03729 {
03730 d = new KApplicationPropsPluginPrivate;
03731 d->m_frame = properties->addPage(i18n("&Application"));
03732 QVBoxLayout *toplayout = new QVBoxLayout( d->m_frame, 0, KDialog::spacingHint());
03733
03734 QIconSet iconSet;
03735 QPixmap pixMap;
03736
03737 addExtensionButton = new QPushButton( QString::null, d->m_frame );
03738 iconSet = SmallIconSet( "back" );
03739 addExtensionButton->setIconSet( iconSet );
03740 pixMap = iconSet.pixmap( QIconSet::Small, QIconSet::Normal );
03741 addExtensionButton->setFixedSize( pixMap.width()+8, pixMap.height()+8 );
03742 connect( addExtensionButton, SIGNAL( clicked() ),
03743 SLOT( slotAddExtension() ) );
03744
03745 delExtensionButton = new QPushButton( QString::null, d->m_frame );
03746 iconSet = SmallIconSet( "forward" );
03747 delExtensionButton->setIconSet( iconSet );
03748 delExtensionButton->setFixedSize( pixMap.width()+8, pixMap.height()+8 );
03749 connect( delExtensionButton, SIGNAL( clicked() ),
03750 SLOT( slotDelExtension() ) );
03751
03752 QLabel *l;
03753
03754 QGridLayout *grid = new QGridLayout(2, 2);
03755 grid->setColStretch(1, 1);
03756 toplayout->addLayout(grid);
03757
03758 if ( d->m_kdesktopMode )
03759 {
03760
03761 nameEdit = 0L;
03762 }
03763 else
03764 {
03765 l = new QLabel(i18n("Name:"), d->m_frame, "Label_4" );
03766 grid->addWidget(l, 0, 0);
03767
03768 nameEdit = new KLineEdit( d->m_frame, "LineEdit_3" );
03769 grid->addWidget(nameEdit, 0, 1);
03770 }
03771
03772 l = new QLabel(i18n("Description:"), d->m_frame, "Label_5" );
03773 grid->addWidget(l, 1, 0);
03774
03775 genNameEdit = new KLineEdit( d->m_frame, "LineEdit_4" );
03776 grid->addWidget(genNameEdit, 1, 1);
03777
03778 l = new QLabel(i18n("Comment:"), d->m_frame, "Label_3" );
03779 grid->addWidget(l, 2, 0);
03780
03781 commentEdit = new KLineEdit( d->m_frame, "LineEdit_2" );
03782 grid->addWidget(commentEdit, 2, 1);
03783
03784 l = new QLabel(i18n("File types:"), d->m_frame);
03785 toplayout->addWidget(l, 0, AlignLeft);
03786
03787 grid = new QGridLayout(4, 3);
03788 grid->setColStretch(0, 1);
03789 grid->setColStretch(2, 1);
03790 grid->setRowStretch( 0, 1 );
03791 grid->setRowStretch( 3, 1 );
03792 toplayout->addLayout(grid, 2);
03793
03794 extensionsList = new QListBox( d->m_frame );
03795 extensionsList->setSelectionMode( QListBox::Extended );
03796 grid->addMultiCellWidget(extensionsList, 0, 3, 0, 0);
03797
03798 grid->addWidget(addExtensionButton, 1, 1);
03799 grid->addWidget(delExtensionButton, 2, 1);
03800
03801 availableExtensionsList = new QListBox( d->m_frame );
03802 availableExtensionsList->setSelectionMode( QListBox::Extended );
03803 grid->addMultiCellWidget(availableExtensionsList, 0, 3, 2, 2);
03804
03805 QString path = properties->kurl().path() ;
03806 QFile f( path );
03807 if ( !f.open( IO_ReadOnly ) )
03808 return;
03809 f.close();
03810
03811 KSimpleConfig config( path );
03812 config.setDesktopGroup();
03813 QString commentStr = config.readEntry( "Comment" );
03814 QString genNameStr = config.readEntry( "GenericName" );
03815
03816 QStringList selectedTypes = config.readListEntry( "ServiceTypes" );
03817
03818 selectedTypes += config.readListEntry( "MimeType", ';' );
03819
03820 QString nameStr = config.readEntry( QString::fromLatin1("Name") );
03821 if ( nameStr.isEmpty() || d->m_kdesktopMode ) {
03822
03823
03824
03825 setDirty();
03826 }
03827
03828 commentEdit->setText( commentStr );
03829 genNameEdit->setText( genNameStr );
03830 if ( nameEdit )
03831 nameEdit->setText( nameStr );
03832
03833 selectedTypes.sort();
03834 QStringList::Iterator sit = selectedTypes.begin();
03835 for( ; sit != selectedTypes.end(); ++sit ) {
03836 if ( !((*sit).isEmpty()) )
03837 extensionsList->insertItem( *sit );
03838 }
03839
03840 KMimeType::List mimeTypes = KMimeType::allMimeTypes();
03841 QValueListIterator<KMimeType::Ptr> it2 = mimeTypes.begin();
03842 for ( ; it2 != mimeTypes.end(); ++it2 )
03843 addMimeType ( (*it2)->name() );
03844
03845 updateButton();
03846
03847 connect( extensionsList, SIGNAL( highlighted( int ) ),
03848 this, SLOT( updateButton() ) );
03849 connect( availableExtensionsList, SIGNAL( highlighted( int ) ),
03850 this, SLOT( updateButton() ) );
03851
03852 connect( addExtensionButton, SIGNAL( clicked() ),
03853 this, SIGNAL( changed() ) );
03854 connect( delExtensionButton, SIGNAL( clicked() ),
03855 this, SIGNAL( changed() ) );
03856 if ( nameEdit )
03857 connect( nameEdit, SIGNAL( textChanged( const QString & ) ),
03858 this, SIGNAL( changed() ) );
03859 connect( commentEdit, SIGNAL( textChanged( const QString & ) ),
03860 this, SIGNAL( changed() ) );
03861 connect( genNameEdit, SIGNAL( textChanged( const QString & ) ),
03862 this, SIGNAL( changed() ) );
03863 connect( availableExtensionsList, SIGNAL( selected( int ) ),
03864 this, SIGNAL( changed() ) );
03865 connect( extensionsList, SIGNAL( selected( int ) ),
03866 this, SIGNAL( changed() ) );
03867 }
03868
03869 KApplicationPropsPlugin::~KApplicationPropsPlugin()
03870 {
03871 delete d;
03872 }
03873
03874
03875
03876
03877
03878
03879 void KApplicationPropsPlugin::updateButton()
03880 {
03881 addExtensionButton->setEnabled(availableExtensionsList->currentItem()>-1);
03882 delExtensionButton->setEnabled(extensionsList->currentItem()>-1);
03883 }
03884
03885 void KApplicationPropsPlugin::addMimeType( const QString & name )
03886 {
03887
03888
03889 bool insert = true;
03890
03891 for ( uint i = 0; i < extensionsList->count(); i++ )
03892 if ( extensionsList->text( i ) == name )
03893 insert = false;
03894
03895 if ( insert )
03896 {
03897 availableExtensionsList->insertItem( name );
03898 availableExtensionsList->sort();
03899 }
03900 }
03901
03902 bool KApplicationPropsPlugin::supports( KFileItemList _items )
03903 {
03904
03905 return KExecPropsPlugin::supports( _items );
03906 }
03907
03908 void KApplicationPropsPlugin::applyChanges()
03909 {
03910 QString path = properties->kurl().path();
03911
03912 QFile f( path );
03913
03914 if ( !f.open( IO_ReadWrite ) ) {
03915 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not "
03916 "have sufficient access to write to <b>%1</b>.</qt>").arg(path));
03917 return;
03918 }
03919 f.close();
03920
03921 KSimpleConfig config( path );
03922 config.setDesktopGroup();
03923 config.writeEntry( "Type", QString::fromLatin1("Application"));
03924 config.writeEntry( "Comment", commentEdit->text() );
03925 config.writeEntry( "Comment", commentEdit->text(), true, false, true );
03926 config.writeEntry( "GenericName", genNameEdit->text() );
03927 config.writeEntry( "GenericName", genNameEdit->text(), true, false, true );
03928
03929 QStringList selectedTypes;
03930 for ( uint i = 0; i < extensionsList->count(); i++ )
03931 selectedTypes.append( extensionsList->text( i ) );
03932
03933 config.writeEntry( "MimeType", selectedTypes, ';' );
03934 config.writeEntry( "ServiceTypes", "" );
03935
03936
03937 QString nameStr = nameEdit ? nameEdit->text() : QString::null;
03938 if ( nameStr.isEmpty() )
03939 nameStr = nameFromFileName(properties->kurl().fileName());
03940
03941 config.writeEntry( "Name", nameStr );
03942 config.writeEntry( "Name", nameStr, true, false, true );
03943
03944 config.sync();
03945 }
03946
03947 void KApplicationPropsPlugin::slotAddExtension()
03948 {
03949 QListBoxItem *item = availableExtensionsList->firstItem();
03950 QListBoxItem *nextItem;
03951
03952 while ( item )
03953 {
03954 nextItem = item->next();
03955
03956 if ( item->isSelected() )
03957 {
03958 extensionsList->insertItem( item->text() );
03959 availableExtensionsList->removeItem( availableExtensionsList->index( item ) );
03960 }
03961
03962 item = nextItem;
03963 }
03964
03965 extensionsList->sort();
03966 updateButton();
03967 }
03968
03969 void KApplicationPropsPlugin::slotDelExtension()
03970 {
03971 QListBoxItem *item = extensionsList->firstItem();
03972 QListBoxItem *nextItem;
03973
03974 while ( item )
03975 {
03976 nextItem = item->next();
03977
03978 if ( item->isSelected() )
03979 {
03980 availableExtensionsList->insertItem( item->text() );
03981 extensionsList->removeItem( extensionsList->index( item ) );
03982 }
03983
03984 item = nextItem;
03985 }
03986
03987 availableExtensionsList->sort();
03988 updateButton();
03989 }
03990
03991
03992
03993 #include "kpropertiesdialog.moc"