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