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