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 #include <config.h>
00043 extern "C" {
00044 #include <pwd.h>
00045 #include <grp.h>
00046 #include <time.h>
00047 }
00048 #include <unistd.h>
00049 #include <errno.h>
00050 #include <assert.h>
00051
00052 #ifdef HAVE_MNTENT_H
00053 #include <mntent.h>
00054 #endif
00055
00056 #include <qfile.h>
00057 #include <qdir.h>
00058 #include <qlabel.h>
00059 #include <qpushbutton.h>
00060 #include <qcheckbox.h>
00061 #include <qstrlist.h>
00062 #include <qstringlist.h>
00063 #include <qtextstream.h>
00064 #include <qpainter.h>
00065 #include <qlayout.h>
00066 #include <qcombobox.h>
00067 #include <qgroupbox.h>
00068
00069 #include <kapplication.h>
00070 #include <kdialog.h>
00071 #include <kdirsize.h>
00072 #include <kdirwatch.h>
00073 #include <kdirnotify_stub.h>
00074 #include <kdiskfreesp.h>
00075 #include <kdebug.h>
00076 #include <kdesktopfile.h>
00077 #include <kicondialog.h>
00078 #include <kurl.h>
00079 #include <kurlrequester.h>
00080 #include <klocale.h>
00081 #include <kglobal.h>
00082 #include <kglobalsettings.h>
00083 #include <kstandarddirs.h>
00084 #include <kio/job.h>
00085 #include <kio/chmodjob.h>
00086 #include <kio/renamedlg.h>
00087 #include <kfiledialog.h>
00088 #include <kmimetype.h>
00089 #include <kiconloader.h>
00090 #include <kmessagebox.h>
00091 #include <kservice.h>
00092 #include <kcompletion.h>
00093 #include <klineedit.h>
00094 #include <kseparator.h>
00095 #include <ksqueezedtextlabel.h>
00096 #include <klibloader.h>
00097 #include <ktrader.h>
00098 #include <kparts/componentfactory.h>
00099 #include <kmetaprops.h>
00100 #include <krun.h>
00101 #include "kfilesharedlg.h"
00102
00103 #include "kpropertiesdialog.h"
00104
00105 #ifdef Q_WS_X11
00106 extern "C" {
00107 #include <X11/Xlib.h>
00108 }
00109 #endif
00110
00111 mode_t KFilePermissionsPropsPlugin::fperm[3][4] = {
00112 {S_IRUSR, S_IWUSR, S_IXUSR, S_ISUID},
00113 {S_IRGRP, S_IWGRP, S_IXGRP, S_ISGID},
00114 {S_IROTH, S_IWOTH, S_IXOTH, S_ISVTX}
00115 };
00116
00117 class KPropertiesDialog::KPropertiesDialogPrivate
00118 {
00119 public:
00120 KPropertiesDialogPrivate()
00121 {
00122 m_aborted = false;
00123 }
00124 ~KPropertiesDialogPrivate()
00125 {
00126 }
00127 bool m_aborted:1;
00128 bool modal:1;
00129 bool autoShow:1;
00130 };
00131
00132 KPropertiesDialog::KPropertiesDialog (KFileItem* item,
00133 QWidget* parent, const char* name,
00134 bool modal, bool autoShow)
00135 : KDialogBase (KDialogBase::Tabbed, i18n( "Properties for %1" ).arg(KIO::decodeFileName(item->url().fileName())),
00136 KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok,
00137 parent, name, modal)
00138 {
00139 d = new KPropertiesDialogPrivate;
00140 assert( item );
00141 m_items.append( new KFileItem(*item) );
00142
00143 m_singleUrl = item->url();
00144 assert(!m_singleUrl.isEmpty());
00145
00146 init (modal, autoShow);
00147 }
00148
00149 KPropertiesDialog::KPropertiesDialog (const QString& title,
00150 QWidget* parent, const char* name, bool modal)
00151 : KDialogBase (KDialogBase::Tabbed, i18n ("Properties for %1").arg(title),
00152 KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok,
00153 parent, name, modal)
00154 {
00155 d = new KPropertiesDialogPrivate;
00156
00157 init (modal, false);
00158 }
00159
00160 KPropertiesDialog::KPropertiesDialog (KFileItemList _items,
00161 QWidget* parent, const char* name,
00162 bool modal, bool autoShow)
00163 : KDialogBase (KDialogBase::Tabbed, i18n( "Properties for %1" ).arg(KIO::decodeFileName(_items.first()->url().fileName())),
00164 KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok,
00165 parent, name, modal)
00166 {
00167 d = new KPropertiesDialogPrivate;
00168
00169 assert( !_items.isEmpty() );
00170 m_singleUrl = _items.first()->url();
00171 assert(!m_singleUrl.isEmpty());
00172
00173 KFileItemListIterator it ( _items );
00174
00175 for ( ; it.current(); ++it )
00176 m_items.append( new KFileItem( **it ) );
00177
00178 init (modal, autoShow);
00179 }
00180
00181 #ifndef KDE_NO_COMPAT
00182 KPropertiesDialog::KPropertiesDialog (const KURL& _url, mode_t ,
00183 QWidget* parent, const char* name,
00184 bool modal, bool autoShow)
00185 : KDialogBase (KDialogBase::Tabbed, i18n( "Properties for %1" ).arg(KIO::decodeFileName(_url.fileName())),
00186 KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok,
00187 parent, name, modal),
00188 m_singleUrl( _url )
00189 {
00190 d = new KPropertiesDialogPrivate;
00191 d->modal = modal;
00192 d->autoShow = autoShow;
00193
00194 assert(!_url.isEmpty());
00195
00196 KIO::StatJob * job = KIO::stat( _url );
00197 connect( job, SIGNAL( result( KIO::Job * ) ),
00198 SLOT( slotStatResult( KIO::Job * ) ) );
00199 }
00200 #endif
00201
00202 KPropertiesDialog::KPropertiesDialog (const KURL& _url,
00203 QWidget* parent, const char* name,
00204 bool modal, bool autoShow)
00205 : KDialogBase (KDialogBase::Tabbed, i18n( "Properties for %1" ).arg(KIO::decodeFileName(_url.fileName())),
00206 KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok,
00207 parent, name, modal),
00208 m_singleUrl( _url )
00209 {
00210 d = new KPropertiesDialogPrivate;
00211 d->modal = modal;
00212 d->autoShow = autoShow;
00213
00214 assert(!_url.isEmpty());
00215
00216 KIO::StatJob * job = KIO::stat( _url );
00217 connect( job, SIGNAL( result( KIO::Job * ) ),
00218 SLOT( slotStatResult( KIO::Job * ) ) );
00219 }
00220
00221 KPropertiesDialog::KPropertiesDialog (const KURL& _tempUrl, const KURL& _currentDir,
00222 const QString& _defaultName,
00223 QWidget* parent, const char* name,
00224 bool modal, bool autoShow)
00225 : KDialogBase (KDialogBase::Tabbed, i18n( "Properties for %1" ).arg(KIO::decodeFileName(_tempUrl.fileName())),
00226 KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok,
00227 parent, name, modal),
00228
00229 m_singleUrl( _tempUrl ),
00230 m_defaultName( _defaultName ),
00231 m_currentDir( _currentDir )
00232 {
00233 d = new KPropertiesDialogPrivate;
00234
00235 assert(!m_singleUrl.isEmpty());
00236
00237
00238 m_items.append( new KFileItem( KFileItem::Unknown, KFileItem::Unknown, m_singleUrl ) );
00239 init (modal, autoShow);
00240 }
00241
00242 void KPropertiesDialog::init (bool modal, bool autoShow)
00243 {
00244 m_pageList.setAutoDelete( true );
00245 m_items.setAutoDelete( true );
00246
00247 #ifdef Q_WS_X11 // FIXME(E): Can we do something similar for Qt Embedded?
00248
00249 if (!modal)
00250 XSetTransientForHint(qt_xdisplay(), winId(), winId());
00251 #endif
00252
00253
00254
00255 insertPages();
00256
00257
00258
00259
00260
00261 enableLinkedHelp( true );
00262 enableLinkedHelp( false );
00263 resize(sizeHint());
00264
00265 if (autoShow)
00266 {
00267 if (!modal)
00268 show();
00269 else
00270 exec();
00271 }
00272 }
00273
00274 void KPropertiesDialog::showFileSharingPage()
00275 {
00276 KPropsDlgPlugin *it;
00277
00278 for ( it=m_pageList.first(); it != 0L; it=m_pageList.next() )
00279 {
00280 KFileSharePropsPlugin* plugin = dynamic_cast<KFileSharePropsPlugin*>(it);
00281 if ( plugin )
00282 {
00283 showPage( pageIndex( plugin->page() ) );
00284 break;
00285 }
00286 }
00287 }
00288
00289 void KPropertiesDialog::slotStatResult( KIO::Job * job )
00290 {
00291 if (job->error())
00292 {
00293 job->showErrorDialog( this );
00294 delete this;
00295 }
00296 else
00297 {
00298 KIO::StatJob * statJob = static_cast<KIO::StatJob*>(job);
00299 m_items.append( new KFileItem( statJob->statResult(), statJob->url() ) );
00300 init (d->modal, d->autoShow);
00301 }
00302 }
00303
00304 KPropertiesDialog::~KPropertiesDialog()
00305 {
00306 m_pageList.clear();
00307 delete d;
00308 }
00309
00310 void KPropertiesDialog::insertPlugin (KPropsDlgPlugin* plugin)
00311 {
00312 connect (plugin, SIGNAL (changed ()),
00313 plugin, SLOT (setDirty ()));
00314
00315 m_pageList.append (plugin);
00316 }
00317
00318 bool KPropertiesDialog::canDisplay( KFileItemList _items )
00319 {
00320 return KFilePropsPlugin::supports( _items ) ||
00321 KFilePermissionsPropsPlugin::supports( _items ) ||
00322 KExecPropsPlugin::supports( _items ) ||
00323 KApplicationPropsPlugin::supports( _items ) ||
00324 KBindingPropsPlugin::supports( _items ) ||
00325 KURLPropsPlugin::supports( _items ) ||
00326 KDevicePropsPlugin::supports( _items ) ||
00327 KFileMetaPropsPlugin::supports( _items );
00328 }
00329
00330 void KPropertiesDialog::slotOk()
00331 {
00332 KPropsDlgPlugin *page;
00333 d->m_aborted = false;
00334
00335 KFilePropsPlugin * filePropsPlugin = 0L;
00336 if ( m_pageList.first()->isA("KFilePropsPlugin") )
00337 filePropsPlugin = static_cast<KFilePropsPlugin *>(m_pageList.first());
00338
00339
00340
00341
00342 for ( page = m_pageList.first(); page != 0L; page = m_pageList.next() )
00343 if ( page->isDirty() && filePropsPlugin )
00344 {
00345 filePropsPlugin->setDirty();
00346 break;
00347 }
00348
00349
00350
00351
00352
00353 for ( page = m_pageList.first(); page != 0L && !d->m_aborted; page = m_pageList.next() )
00354 if ( page->isDirty() )
00355 {
00356 kdDebug( 250 ) << "applying changes for " << page->className() << endl;
00357 page->applyChanges();
00358
00359 }
00360 else
00361 kdDebug( 250 ) << "skipping page " << page->className() << endl;
00362
00363 if ( !d->m_aborted && filePropsPlugin )
00364 filePropsPlugin->postApplyChanges();
00365
00366 if ( !d->m_aborted )
00367 {
00368 emit applied();
00369 emit propertiesClosed();
00370 deleteLater();
00371 accept();
00372 }
00373 }
00374
00375 void KPropertiesDialog::slotCancel()
00376 {
00377 emit canceled();
00378 emit propertiesClosed();
00379
00380 deleteLater();
00381 done( Rejected );
00382 }
00383
00384 void KPropertiesDialog::insertPages()
00385 {
00386 if (m_items.isEmpty())
00387 return;
00388
00389 if ( KFilePropsPlugin::supports( m_items ) )
00390 {
00391 KPropsDlgPlugin *p = new KFilePropsPlugin( this );
00392 insertPlugin (p);
00393 }
00394
00395 if ( KFilePermissionsPropsPlugin::supports( m_items ) )
00396 {
00397 KPropsDlgPlugin *p = new KFilePermissionsPropsPlugin( this );
00398 insertPlugin (p);
00399 }
00400
00401 if ( KExecPropsPlugin::supports( m_items ) )
00402 {
00403 KPropsDlgPlugin *p = new KExecPropsPlugin( this );
00404 insertPlugin (p);
00405 }
00406
00407 if ( KApplicationPropsPlugin::supports( m_items ) )
00408 {
00409 KPropsDlgPlugin *p = new KApplicationPropsPlugin( this );
00410 insertPlugin (p);
00411 }
00412
00413 if ( KBindingPropsPlugin::supports( m_items ) )
00414 {
00415 KPropsDlgPlugin *p = new KBindingPropsPlugin( this );
00416 insertPlugin (p);
00417 }
00418
00419 if ( KURLPropsPlugin::supports( m_items ) )
00420 {
00421 KPropsDlgPlugin *p = new KURLPropsPlugin( this );
00422 insertPlugin (p);
00423 }
00424
00425 if ( KDevicePropsPlugin::supports( m_items ) )
00426 {
00427 KPropsDlgPlugin *p = new KDevicePropsPlugin( this );
00428 insertPlugin (p);
00429 }
00430
00431 if ( KFileMetaPropsPlugin::supports( m_items ) )
00432 {
00433 KPropsDlgPlugin *p = new KFileMetaPropsPlugin( this );
00434 insertPlugin (p);
00435 }
00436
00437 if ( KFileSharePropsPlugin::supports( m_items ) )
00438 {
00439 KPropsDlgPlugin *p = new KFileSharePropsPlugin( this );
00440 insertPlugin (p);
00441 }
00442
00443
00444
00445 if ( m_items.count() != 1 )
00446 return;
00447
00448 KFileItem *item = m_items.first();
00449 QString mimetype = item->mimetype();
00450
00451 if ( mimetype.isEmpty() )
00452 return;
00453
00454 QString query = QString::fromLatin1(
00455 "('KPropsDlg/Plugin' in ServiceTypes) and "
00456 "((not exist [X-KDE-Protocol]) or "
00457 " ([X-KDE-Protocol] == '%1' ) )" ).arg(item->url().protocol());
00458
00459 kdDebug( 250 ) << "trader query: " << query << endl;
00460 KTrader::OfferList offers = KTrader::self()->query( mimetype, query );
00461 KTrader::OfferList::ConstIterator it = offers.begin();
00462 KTrader::OfferList::ConstIterator end = offers.end();
00463 for (; it != end; ++it )
00464 {
00465 KPropsDlgPlugin *plugin = KParts::ComponentFactory
00466 ::createInstanceFromLibrary<KPropsDlgPlugin>( (*it)->library().local8Bit().data(),
00467 this,
00468 (*it)->name().latin1() );
00469 if ( !plugin )
00470 continue;
00471
00472 insertPlugin( plugin );
00473 }
00474 }
00475
00476 void KPropertiesDialog::updateUrl( const KURL& _newUrl )
00477 {
00478 Q_ASSERT( m_items.count() == 1 );
00479 kdDebug(250) << "KPropertiesDialog::updateUrl " << _newUrl.url() << endl;
00480 m_singleUrl = _newUrl;
00481 m_items.first()->setURL( _newUrl );
00482 assert(!m_singleUrl.isEmpty());
00483
00484
00485 for ( QPtrListIterator<KPropsDlgPlugin> it(m_pageList); it.current(); ++it )
00486 if ( it.current()->isA("KExecPropsPlugin") || it.current()->isA("KURLPropsPlugin") )
00487 {
00488
00489 it.current()->setDirty();
00490 break;
00491 }
00492 }
00493
00494 void KPropertiesDialog::rename( const QString& _name )
00495 {
00496 Q_ASSERT( m_items.count() == 1 );
00497 kdDebug(250) << "KPropertiesDialog::rename " << _name << endl;
00498 KURL newUrl;
00499
00500 if ( !m_currentDir.isEmpty() )
00501 {
00502 newUrl = m_currentDir;
00503 newUrl.addPath( _name );
00504 }
00505 else
00506 {
00507 QString tmpurl = m_singleUrl.url();
00508 if ( tmpurl.at(tmpurl.length() - 1) == '/')
00509
00510 tmpurl.truncate( tmpurl.length() - 1);
00511 newUrl = tmpurl;
00512 newUrl.setFileName( _name );
00513 }
00514 updateUrl( newUrl );
00515 }
00516
00517 void KPropertiesDialog::abortApplying()
00518 {
00519 d->m_aborted = true;
00520 }
00521
00522 class KPropsDlgPlugin::KPropsDlgPluginPrivate
00523 {
00524 public:
00525 KPropsDlgPluginPrivate()
00526 {
00527 }
00528 ~KPropsDlgPluginPrivate()
00529 {
00530 }
00531
00532 bool m_bDirty;
00533 };
00534
00535 KPropsDlgPlugin::KPropsDlgPlugin( KPropertiesDialog *_props )
00536 : QObject( _props, 0L )
00537 {
00538 d = new KPropsDlgPluginPrivate;
00539 properties = _props;
00540 fontHeight = 2*properties->dialog()->fontMetrics().height();
00541 d->m_bDirty = false;
00542 }
00543
00544 KPropsDlgPlugin::~KPropsDlgPlugin()
00545 {
00546 delete d;
00547 }
00548
00549 bool KPropsDlgPlugin::isDesktopFile( KFileItem * _item )
00550 {
00551
00552 if ( !_item->isLocalFile() )
00553 return false;
00554
00555
00556 if ( !S_ISREG( _item->mode() ) )
00557 return false;
00558
00559 QString t( _item->url().path() );
00560
00561
00562 FILE *f = fopen( QFile::encodeName(t), "r" );
00563 if ( f == 0L )
00564 return false;
00565 fclose(f);
00566
00567
00568 return ( _item->mimetype() == QString::fromLatin1("application/x-desktop") );
00569 }
00570
00571 void KPropsDlgPlugin::setDirty( bool b )
00572 {
00573 d->m_bDirty = b;
00574 }
00575
00576 void KPropsDlgPlugin::setDirty()
00577 {
00578 d->m_bDirty = true;
00579 }
00580
00581 bool KPropsDlgPlugin::isDirty() const
00582 {
00583 return d->m_bDirty;
00584 }
00585
00586 void KPropsDlgPlugin::applyChanges()
00587 {
00588 kdWarning(250) << "applyChanges() not implemented in page !" << endl;
00589 }
00590
00592
00593 class KFilePropsPlugin::KFilePropsPluginPrivate
00594 {
00595 public:
00596 KFilePropsPluginPrivate()
00597 {
00598 dirSizeJob = 0L;
00599 }
00600 ~KFilePropsPluginPrivate()
00601 {
00602 if ( dirSizeJob )
00603 dirSizeJob->kill();
00604 }
00605
00606 KDirSize * dirSizeJob;
00607 QFrame *m_frame;
00608 bool bMultiple;
00609 QLabel *m_freeSpaceLabel;
00610 };
00611
00612 KFilePropsPlugin::KFilePropsPlugin( KPropertiesDialog *_props )
00613 : KPropsDlgPlugin( _props )
00614 {
00615 d = new KFilePropsPluginPrivate;
00616 d->bMultiple = (properties->items().count() > 1);
00617 kdDebug(250) << "KFilePropsPlugin::KFilePropsPlugin bMultiple=" << d->bMultiple << endl;
00618
00619
00620
00621 bool isLocal = properties->kurl().isLocalFile();
00622 KFileItem * item = properties->item();
00623 bool bDesktopFile = isDesktopFile(item);
00624 mode_t mode = item->mode();
00625 bool hasDirs = item->isDir() && !item->isLink();
00626 bool hasRoot = isLocal && properties->kurl().path() == QString::fromLatin1("/");
00627 QString iconStr = KMimeType::iconForURL(properties->kurl(), mode);
00628 QString directory = properties->kurl().directory();
00629 QString protocol = properties->kurl().protocol();
00630 QString mimeComment = item->mimeComment();
00631 KIO::filesize_t totalSize = item->size();
00632 QString magicMimeComment;
00633 if ( isLocal ) {
00634 KMimeType::Ptr magicMimeType = KMimeType::findByFileContent( properties->kurl().path() );
00635 if ( magicMimeType->name() != KMimeType::defaultMimeType() )
00636 magicMimeComment = magicMimeType->comment();
00637 }
00638
00639
00640 QString filename = QString::null;
00641 bool isTrash = false;
00642 m_bFromTemplate = false;
00643
00644
00645 uint iDirCount = S_ISDIR(mode) ? 1 : 0;
00646 uint iFileCount = 1-iDirCount;
00647
00648 d->m_frame = properties->dialog()->addPage (i18n("&General"));
00649
00650 QVBoxLayout *vbl = new QVBoxLayout( d->m_frame, KDialog::marginHint(),
00651 KDialog::spacingHint(), "vbl");
00652 QGridLayout *grid = new QGridLayout(0, 3);
00653 grid->setColStretch(2, 1);
00654 grid->addColSpacing(1, KDialog::spacingHint());
00655 vbl->addLayout(grid);
00656 int curRow = 0;
00657
00658 if ( !d->bMultiple )
00659 {
00660
00661 filename = properties->defaultName();
00662 if ( filename.isEmpty() )
00663 filename = properties->kurl().fileName();
00664 else
00665 {
00666 m_bFromTemplate = true;
00667 setDirty();
00668 }
00669 oldName = filename;
00670
00671
00672 filename = KIO::decodeFileName( filename );
00673
00674 QString path;
00675
00676 if ( !m_bFromTemplate ) {
00677 QString tmp = properties->kurl().path( 1 );
00678
00679 if ( isLocal && tmp == KGlobalSettings::trashPath())
00680 isTrash = true;
00681
00682
00683 if ( isLocal )
00684 path = properties->kurl().path();
00685 else
00686 path = properties->kurl().prettyURL();
00687 } else {
00688 path = properties->currentDir().path(1) + properties->defaultName();
00689 directory = properties->currentDir().prettyURL();
00690 }
00691
00692 if (KExecPropsPlugin::supports(properties->items()) ||
00693 KBindingPropsPlugin::supports(properties->items())) {
00694
00695 determineRelativePath( path );
00696
00697 }
00698
00699 }
00700 else
00701 {
00702
00703 KFileItemList items = properties->items();
00704 KFileItemListIterator it( items );
00705 for ( ++it ; it.current(); ++it )
00706 {
00707 KURL url = (*it)->url();
00708 kdDebug(250) << "KFilePropsPlugin::KFilePropsPlugin " << url.prettyURL() << endl;
00709
00710
00711 if ( url.isLocalFile() != isLocal )
00712 isLocal = false;
00713 if ( bDesktopFile && isDesktopFile(*it) != bDesktopFile )
00714 bDesktopFile = false;
00715 if ( (*it)->mode() != mode )
00716 mode = (mode_t)0;
00717 if ( KMimeType::iconForURL(url, mode) != iconStr )
00718 iconStr = "kmultiple";
00719 if ( url.directory() != directory )
00720 directory = QString::null;
00721 if ( url.protocol() != protocol )
00722 protocol = QString::null;
00723 if ( !mimeComment.isNull() && (*it)->mimeComment() != mimeComment )
00724 mimeComment = QString::null;
00725 if ( isLocal && !magicMimeComment.isNull() ) {
00726 KMimeType::Ptr magicMimeType = KMimeType::findByFileContent( url.path() );
00727 if ( magicMimeType->comment() != magicMimeComment )
00728 magicMimeComment = QString::null;
00729 }
00730
00731 if ( isLocal && url.path() == QString::fromLatin1("/") )
00732 hasRoot = true;
00733 if ( (*it)->isDir() && !(*it)->isLink() )
00734 {
00735 iDirCount++;
00736 hasDirs = true;
00737 }
00738 else
00739 {
00740 iFileCount++;
00741 totalSize += (*it)->size();
00742 }
00743 }
00744 }
00745
00746 if (!isLocal && !protocol.isEmpty())
00747 {
00748 directory += ' ';
00749 directory += '(';
00750 directory += protocol;
00751 directory += ')';
00752 }
00753
00754 if ( (bDesktopFile || S_ISDIR(mode)) && !d->bMultiple )
00755 {
00756 KIconButton *iconButton = new KIconButton( d->m_frame );
00757 iconButton->setFixedSize(70, 70);
00758 iconButton->setStrictIconSize(false);
00759 iconButton->setIconType(KIcon::Desktop, KIcon::Device);
00760
00761
00762 QString iconStr = KMimeType::findByURL( properties->kurl(),
00763 mode )->icon( properties->kurl(),
00764 isLocal );
00765 if ( bDesktopFile && isLocal )
00766 {
00767 KSimpleConfig config( properties->kurl().path() );
00768 config.setDesktopGroup();
00769 iconStr = config.readEntry( QString::fromLatin1("Icon") );
00770 }
00771 iconButton->setIcon(iconStr);
00772 iconArea = iconButton;
00773 connect( iconButton, SIGNAL( iconChanged(QString) ),
00774 this, SIGNAL( changed() ) );
00775 } else {
00776 QLabel *iconLabel = new QLabel( d->m_frame );
00777 iconLabel->setFixedSize(70, 70);
00778 iconLabel->setPixmap( DesktopIcon( iconStr ) );
00779 iconArea = iconLabel;
00780 }
00781 grid->addWidget(iconArea, curRow, 0, AlignLeft);
00782
00783 if (d->bMultiple || isTrash || filename == QString::fromLatin1("/"))
00784 {
00785 QLabel *lab = new QLabel(d->m_frame );
00786 if ( d->bMultiple )
00787 lab->setText( KIO::itemsSummaryString( iFileCount + iDirCount, iFileCount, iDirCount, 0, false ) );
00788 else
00789 lab->setText( filename );
00790 nameArea = lab;
00791 } else
00792 {
00793 KLineEdit *lined = new KLineEdit( d->m_frame );
00794 lined->setText(filename);
00795 nameArea = lined;
00796 lined->setFocus();
00797 connect( lined, SIGNAL( textChanged( const QString & ) ),
00798 this, SLOT( nameFileChanged(const QString & ) ) );
00799 }
00800
00801 grid->addWidget(nameArea, curRow++, 2);
00802
00803 KSeparator* sep = new KSeparator( KSeparator::HLine, d->m_frame);
00804 grid->addMultiCellWidget(sep, curRow, curRow, 0, 2);
00805 ++curRow;
00806
00807 QLabel *l;
00808 if ( !mimeComment.isEmpty() )
00809 {
00810 l = new QLabel(i18n("Type:"), d->m_frame );
00811 grid->addWidget(l, curRow, 0);
00812
00813 l = new QLabel(mimeComment, d->m_frame );
00814 grid->addWidget(l, curRow++, 2);
00815 }
00816
00817 if ( !magicMimeComment.isEmpty() && magicMimeComment != mimeComment )
00818 {
00819 l = new QLabel(i18n("Contents:"), d->m_frame );
00820 grid->addWidget(l, curRow, 0);
00821
00822 l = new QLabel(magicMimeComment, d->m_frame );
00823 grid->addWidget(l, curRow++, 2);
00824 }
00825
00826 if ( !directory.isEmpty() )
00827 {
00828 l = new QLabel( i18n("Location:"), d->m_frame );
00829 grid->addWidget(l, curRow, 0);
00830
00831 l = new KSqueezedTextLabel( d->m_frame );
00832 l->setText( directory );
00833 grid->addWidget(l, curRow++, 2);
00834 }
00835
00836 l = new QLabel(i18n("Size:"), d->m_frame );
00837 grid->addWidget(l, curRow, 0);
00838
00839 m_sizeLabel = new QLabel( d->m_frame );
00840 grid->addWidget( m_sizeLabel, curRow++, 2 );
00841
00842 if ( !hasDirs )
00843 {
00844 m_sizeLabel->setText(QString::fromLatin1("%1 (%2)").arg(KIO::convertSize(totalSize)).arg(KGlobal::locale()->formatNumber(totalSize, 0)));
00845 m_sizeDetermineButton = 0L;
00846 m_sizeStopButton = 0L;
00847 }
00848 else
00849 {
00850 QHBoxLayout * sizelay = new QHBoxLayout(KDialog::spacingHint());
00851 grid->addLayout( sizelay, curRow++, 2 );
00852
00853
00854 m_sizeDetermineButton = new QPushButton( i18n("Calculate"), d->m_frame );
00855 m_sizeStopButton = new QPushButton( i18n("Stop"), d->m_frame );
00856 connect( m_sizeDetermineButton, SIGNAL( clicked() ), this, SLOT( slotSizeDetermine() ) );
00857 connect( m_sizeStopButton, SIGNAL( clicked() ), this, SLOT( slotSizeStop() ) );
00858 sizelay->addWidget(m_sizeDetermineButton, 0);
00859 sizelay->addWidget(m_sizeStopButton, 0);
00860 sizelay->addStretch(10);
00861
00862
00863 if ( isLocal && !hasRoot )
00864 {
00865 m_sizeDetermineButton->setText( i18n("Refresh") );
00866 slotSizeDetermine();
00867 }
00868 else
00869 m_sizeStopButton->setEnabled( false );
00870 }
00871
00872 if ( isLocal )
00873 {
00874 QString mountPoint = KIO::findPathMountPoint( properties->item()->url().path() );
00875
00876 l = new QLabel(i18n("Free space on %1:").arg(mountPoint), d->m_frame );
00877 grid->addWidget(l, curRow, 0);
00878
00879 d->m_freeSpaceLabel = new QLabel( d->m_frame );
00880 grid->addWidget( d->m_freeSpaceLabel, curRow++, 2 );
00881
00882 KDiskFreeSp * job = new KDiskFreeSp;
00883 connect( job, SIGNAL( foundMountPoint( const unsigned long&, const unsigned long&, const unsigned long&, const QString& ) ),
00884 this, SLOT( slotFoundMountPoint( const unsigned long&, const unsigned long&, const unsigned long&, const QString& ) ) );
00885 job->readDF( mountPoint );
00886 }
00887
00888 if (!d->bMultiple && item->isLink()) {
00889 l = new QLabel(i18n("Points to:"), d->m_frame );
00890 grid->addWidget(l, curRow, 0);
00891
00892 l = new QLabel(item->linkDest(), d->m_frame );
00893 grid->addWidget(l, curRow++, 2);
00894 }
00895
00896 if (!d->bMultiple)
00897 {
00898 sep = new KSeparator( KSeparator::HLine, d->m_frame);
00899 grid->addMultiCellWidget(sep, curRow, curRow, 0, 2);
00900 ++curRow;
00901
00902 grid = new QGridLayout(0, 3);
00903 grid->setColStretch(2, 1);
00904 grid->addColSpacing(1, KDialog::spacingHint());
00905 vbl->addLayout(grid);
00906 curRow = 0;
00907
00908 QDateTime dt;
00909 time_t tim = item->time(KIO::UDS_CREATION_TIME);
00910 if ( tim )
00911 {
00912 l = new QLabel(i18n("Created:"), d->m_frame );
00913 grid->addWidget(l, curRow, 0);
00914
00915 dt.setTime_t( tim );
00916 l = new QLabel(KGlobal::locale()->formatDateTime(dt), d->m_frame );
00917 grid->addWidget(l, curRow++, 2);
00918 }
00919
00920 tim = item->time(KIO::UDS_MODIFICATION_TIME);
00921 if ( tim )
00922 {
00923 l = new QLabel(i18n("Modified:"), d->m_frame );
00924 grid->addWidget(l, curRow, 0);
00925
00926 dt.setTime_t( tim );
00927 l = new QLabel(KGlobal::locale()->formatDateTime(dt), d->m_frame );
00928 grid->addWidget(l, curRow++, 2);
00929 }
00930
00931 tim = item->time(KIO::UDS_ACCESS_TIME);
00932 if ( tim )
00933 {
00934 l = new QLabel(i18n("Accessed:"), d->m_frame );
00935 grid->addWidget(l, curRow, 0);
00936
00937 dt.setTime_t( tim );
00938 l = new QLabel(KGlobal::locale()->formatDateTime(dt), d->m_frame );
00939 grid->addWidget(l, curRow++, 2);
00940 }
00941 }
00942
00943 vbl->addStretch(1);
00944 }
00945
00946
00947
00948
00949
00950
00951
00952 void KFilePropsPlugin::nameFileChanged(const QString &text )
00953 {
00954 properties->enableButtonOK(!text.isEmpty());
00955 emit changed();
00956 }
00957 void KFilePropsPlugin::determineRelativePath( const QString & path )
00958 {
00959 m_sRelativePath = "";
00960
00961 QStringList dirs;
00962 if (KBindingPropsPlugin::supports(properties->items()))
00963 dirs = KGlobal::dirs()->resourceDirs("mime");
00964 else
00965 dirs = KGlobal::dirs()->resourceDirs("apps");
00966
00967 QStringList::ConstIterator it = dirs.begin();
00968 for ( ; it != dirs.end() && m_sRelativePath.isEmpty(); ++it ) {
00969
00970 if ( path.find( *it ) == 0 )
00971 m_sRelativePath = path.mid( (*it).length() );
00972 }
00973 if ( m_sRelativePath.isEmpty() )
00974 {
00975 if (KBindingPropsPlugin::supports(properties->items()))
00976 kdWarning(250) << "Warning : editing a mimetype file out of the mimetype dirs!" << endl;
00977
00978 } else
00979 while ( m_sRelativePath.at(0) == '/' ) m_sRelativePath.remove( 0, 1 );
00980 }
00981
00982 void KFilePropsPlugin::slotFoundMountPoint( const QString&, unsigned long kBSize, unsigned long , unsigned long kBAvail )
00983 {
00984 d->m_freeSpaceLabel->setText( i18n("Available space out of total partition size (percent used)", "%1/%2 (%3% used)")
00985 .arg(KIO::convertSizeFromKB(kBAvail))
00986 .arg(KIO::convertSizeFromKB(kBSize))
00987 .arg( 100 - (int)(100.0 * kBAvail / kBSize) ));
00988 }
00989
00990
00991
00992 void KFilePropsPlugin::slotFoundMountPoint( const unsigned long& kBSize, const unsigned long& , const unsigned long& kBAvail, const QString& )
00993 {
00994 d->m_freeSpaceLabel->setText( i18n("Available space out of total partition size (percent used)", "%1/%2 (%3% used)")
00995 .arg(KIO::convertSizeFromKB(kBAvail))
00996 .arg(KIO::convertSizeFromKB(kBSize))
00997 .arg( 100 - (int)(100.0 * kBAvail / kBSize) ));
00998 }
00999
01000 void KFilePropsPlugin::slotDirSizeFinished( KIO::Job * job )
01001 {
01002 if (job->error())
01003 m_sizeLabel->setText( job->errorString() );
01004 else
01005 {
01006 KIO::filesize_t totalSize = static_cast<KDirSize*>(job)->totalSize();
01007 m_sizeLabel->setText( QString::fromLatin1("%1 (%2)").arg(KIO::convertSize(totalSize)).arg(KGlobal::locale()->formatNumber(totalSize, 0)) );
01008 }
01009 m_sizeStopButton->setEnabled(false);
01010
01011 m_sizeDetermineButton->setText( i18n("Refresh") );
01012 m_sizeDetermineButton->setEnabled(true);
01013 d->dirSizeJob = 0L;
01014 }
01015
01016 void KFilePropsPlugin::slotSizeDetermine()
01017 {
01018 m_sizeLabel->setText( i18n("Calculating...") );
01019 kdDebug(250) << " KFilePropsPlugin::slotSizeDetermine() properties->item()=" << properties->item() << endl;
01020 kdDebug(250) << " URL=" << properties->item()->url().url() << endl;
01021 d->dirSizeJob = KDirSize::dirSizeJob( properties->items() );
01022 connect( d->dirSizeJob, SIGNAL( result( KIO::Job * ) ),
01023 SLOT( slotDirSizeFinished( KIO::Job * ) ) );
01024 m_sizeStopButton->setEnabled(true);
01025 m_sizeDetermineButton->setEnabled(false);
01026 }
01027
01028 void KFilePropsPlugin::slotSizeStop()
01029 {
01030 if ( d->dirSizeJob )
01031 {
01032 m_sizeLabel->setText( i18n("Stopped") );
01033 d->dirSizeJob->kill();
01034 d->dirSizeJob = 0;
01035 }
01036 m_sizeStopButton->setEnabled(false);
01037 m_sizeDetermineButton->setEnabled(true);
01038 }
01039
01040 KFilePropsPlugin::~KFilePropsPlugin()
01041 {
01042 delete d;
01043 }
01044
01045 bool KFilePropsPlugin::supports( KFileItemList )
01046 {
01047 return true;
01048 }
01049
01050
01051 void qt_enter_modal( QWidget *widget );
01052 void qt_leave_modal( QWidget *widget );
01053
01054 void KFilePropsPlugin::applyChanges()
01055 {
01056 if ( d->dirSizeJob )
01057 slotSizeStop();
01058
01059 kdDebug(250) << "KFilePropsPlugin::applyChanges" << endl;
01060
01061 if (nameArea->inherits("QLineEdit"))
01062 {
01063 QString n = KIO::encodeFileName(((QLineEdit *) nameArea)->text());
01064
01065 while ( n[n.length()-1].isSpace() )
01066 n.truncate( n.length() - 1 );
01067 if ( n.isEmpty() )
01068 {
01069 KMessageBox::sorry( properties, i18n("The new file name is empty!"));
01070 properties->abortApplying();
01071 return;
01072 }
01073
01074
01075 kdDebug(250) << "oldname = " << oldName << endl;
01076 kdDebug(250) << "newname = " << n << endl;
01077 if ( oldName != n || m_bFromTemplate ) {
01078 KIO::Job * job = 0L;
01079 KURL oldurl = properties->kurl();
01080
01081 properties->rename( n );
01082
01083
01084 if ( !m_sRelativePath.isEmpty() )
01085 determineRelativePath( properties->kurl().path() );
01086
01087 kdDebug(250) << "New URL = " << properties->kurl().url() << endl;
01088 kdDebug(250) << "old = " << oldurl.url() << endl;
01089
01090
01091 if ( !m_bFromTemplate )
01092 job = KIO::move( oldurl, properties->kurl() );
01093 else
01094 job = KIO::copy( oldurl, properties->kurl() );
01095
01096 connect( job, SIGNAL( result( KIO::Job * ) ),
01097 SLOT( slotCopyFinished( KIO::Job * ) ) );
01098 connect( job, SIGNAL( renamed( KIO::Job *, const KURL &, const KURL & ) ),
01099 SLOT( slotFileRenamed( KIO::Job *, const KURL &, const KURL & ) ) );
01100
01101 QWidget dummy(0,0,WType_Dialog|WShowModal);
01102 qt_enter_modal(&dummy);
01103 qApp->enter_loop();
01104 qt_leave_modal(&dummy);
01105 return;
01106 }
01107 }
01108
01109
01110 slotCopyFinished( 0L );
01111 }
01112
01113 void KFilePropsPlugin::slotCopyFinished( KIO::Job * job )
01114 {
01115 kdDebug(250) << "KFilePropsPlugin::slotCopyFinished" << endl;
01116 if (job)
01117 {
01118
01119 qApp->exit_loop();
01120 if ( job->error() )
01121 {
01122 job->showErrorDialog( d->m_frame );
01123
01124 properties->updateUrl( static_cast<KIO::CopyJob*>(job)->srcURLs().first() );
01125 properties->abortApplying();
01126 return;
01127 }
01128 }
01129
01130 assert( properties->item() );
01131 assert( !properties->item()->url().isEmpty() );
01132
01133
01134 if (KBindingPropsPlugin::supports(properties->items()) && !m_sRelativePath.isEmpty())
01135 {
01136 KURL newURL;
01137 newURL.setPath( locateLocal("mime", m_sRelativePath) );
01138 properties->updateUrl( newURL );
01139 }
01140 else if (KExecPropsPlugin::supports(properties->items()) && !m_sRelativePath.isEmpty())
01141 {
01142 kdDebug(250) << "KFilePropsPlugin::slotCopyFinished " << m_sRelativePath << endl;
01143 KURL newURL;
01144 newURL.setPath( locateLocal("apps", m_sRelativePath) );
01145 kdDebug(250) << "KFilePropsPlugin::slotCopyFinished path=" << newURL.path() << endl;
01146 properties->updateUrl( newURL );
01147 }
01148
01149
01150
01151 if (!iconArea->isA("QLabel") && properties->kurl().isLocalFile()) {
01152 KIconButton *iconButton = (KIconButton *) iconArea;
01153 QString path;
01154
01155 if (S_ISDIR(properties->item()->mode()))
01156 {
01157 path = properties->kurl().path(1) + QString::fromLatin1(".directory");
01158
01159
01160 }
01161 else
01162 path = properties->kurl().path();
01163
01164
01165 QString str = KMimeType::findByURL( properties->kurl(),
01166 properties->item()->mode(),
01167 true )->KServiceType::icon();
01168
01169 QString sIcon;
01170 if ( str != iconButton->icon() )
01171 sIcon = iconButton->icon();
01172
01173
01174 kdDebug(250) << "**" << path << "**" << endl;
01175 QFile f( path );
01176
01177
01178 if ( !sIcon.isEmpty() || f.exists() )
01179 {
01180 if ( !f.open( IO_ReadWrite ) ) {
01181 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have sufficient access to write to <b>%1</b>.</qt>").arg(path));
01182 return;
01183 }
01184 f.close();
01185
01186 KDesktopFile cfg(path);
01187 kdDebug(250) << "sIcon = " << (sIcon) << endl;
01188 kdDebug(250) << "str = " << (str) << endl;
01189 cfg.writeEntry( QString::fromLatin1("Icon"), sIcon );
01190 cfg.sync();
01191 }
01192 }
01193 }
01194
01195 void KFilePropsPlugin::slotFileRenamed( KIO::Job *, const KURL &, const KURL & newUrl )
01196 {
01197
01198
01199 properties->updateUrl( newUrl );
01200 }
01201
01202 void KFilePropsPlugin::postApplyChanges()
01203 {
01204 KURL::List lst;
01205 KFileItemList items = properties->items();
01206 for ( KFileItemListIterator it( items ); it.current(); ++it )
01207 lst.append((*it)->url());
01208 KDirNotify_stub allDirNotify("*", "KDirNotify*");
01209 allDirNotify.FilesChanged( lst );
01210 }
01211
01212 class KFilePermissionsPropsPlugin::KFilePermissionsPropsPluginPrivate
01213 {
01214 public:
01215 KFilePermissionsPropsPluginPrivate()
01216 {
01217 }
01218 ~KFilePermissionsPropsPluginPrivate()
01219 {
01220 }
01221
01222 QFrame *m_frame;
01223 QCheckBox *cbRecursive;
01224 mode_t partialPermissions;
01225 };
01226
01227 KFilePermissionsPropsPlugin::KFilePermissionsPropsPlugin( KPropertiesDialog *_props )
01228 : KPropsDlgPlugin( _props )
01229 {
01230 d = new KFilePermissionsPropsPluginPrivate;
01231 d->cbRecursive = 0L;
01232 grpCombo = 0L; grpEdit = 0;
01233 usrEdit = 0L;
01234 QString path = properties->kurl().path(-1);
01235 QString fname = properties->kurl().fileName();
01236 bool isLocal = properties->kurl().isLocalFile();
01237
01238 bool IamRoot = (geteuid() == 0);
01239
01240 KFileItem * item = properties->item();
01241 bool isLink = item->isLink();
01242 bool isDir = item->isDir();
01243 bool hasDir = item->isDir();
01244 permissions = item->permissions();
01245 d->partialPermissions = permissions;
01246 strOwner = item->user();
01247 strGroup = item->group();
01248
01249 if ( properties->items().count() > 1 )
01250 {
01251
01252 KFileItemList items = properties->items();
01253 KFileItemListIterator it( items );
01254 for ( ++it ; it.current(); ++it )
01255 {
01256 if ( (*it)->isLink() != isLink )
01257 isLink = false;
01258 if ( (*it)->isDir() != isDir )
01259 isDir = false;
01260 hasDir |= (*it)->isDir();
01261 if ( (*it)->permissions() != permissions )
01262 {
01263 permissions &= (*it)->permissions();
01264 d->partialPermissions |= (*it)->permissions();
01265 }
01266 if ( (*it)->user() != strOwner )
01267 strOwner = QString::null;
01268 if ( (*it)->group() != strGroup )
01269 strGroup = QString::null;
01270 }
01271 }
01272
01273
01274 d->partialPermissions = d->partialPermissions & ~permissions;
01275
01276 bool isMyFile = false;
01277
01278 if (isLocal && !strOwner.isEmpty()) {
01279 struct passwd *myself = getpwuid( geteuid() );
01280 if ( myself != 0L )
01281 {
01282 isMyFile = (strOwner == QString::fromLocal8Bit(myself->pw_name));
01283 } else
01284 kdWarning() << "I don't exist ?! geteuid=" << geteuid() << endl;
01285 } else {
01286
01287
01288
01289 isMyFile = true;
01290 }
01291
01292 d->m_frame = properties->dialog()->addPage(i18n("&Permissions"));
01293
01294 QBoxLayout *box = new QVBoxLayout( d->m_frame, KDialog::spacingHint() );
01295
01296 QLabel *l, *cl[3];
01297 QGroupBox *gb;
01298 QGridLayout *gl;
01299
01300
01301 gb = new QGroupBox ( i18n("Access Permissions"), d->m_frame );
01302 box->addWidget (gb);
01303
01304 gl = new QGridLayout (gb, 6, 6, 15);
01305 gl->addRowSpacing(0, 10);
01306
01307 l = new QLabel(i18n("Class"), gb);
01308 gl->addWidget(l, 1, 0);
01309
01310 if (isDir)
01311 l = new QLabel( i18n("Show\nEntries"), gb );
01312 else
01313 l = new QLabel( i18n("Read"), gb );
01314 gl->addWidget (l, 1, 1);
01315
01316 if (isDir)
01317 l = new QLabel( i18n("Write\nEntries"), gb );
01318 else
01319 l = new QLabel( i18n("Write"), gb );
01320 gl->addWidget (l, 1, 2);
01321
01322 if (isDir)
01323 l = new QLabel( i18n("Enter directory", "Enter"), gb );
01324 else
01325 l = new QLabel( i18n("Exec"), gb );
01326
01327 QSize size = l->sizeHint();
01328 size.setWidth(size.width() + 15);
01329 l->setFixedSize(size);
01330 gl->addWidget (l, 1, 3);
01331
01332 l = new QLabel( i18n("Special"), gb );
01333 gl->addMultiCellWidget(l, 1, 1, 4, 5);
01334
01335 cl[0] = new QLabel( i18n("User"), gb );
01336 gl->addWidget (cl[0], 2, 0);
01337
01338 cl[1] = new QLabel( i18n("Group"), gb );
01339 gl->addWidget (cl[1], 3, 0);
01340
01341 cl[2] = new QLabel( i18n("Others"), gb );
01342 gl->addWidget (cl[2], 4, 0);
01343
01344 l = new QLabel(i18n("Set UID"), gb);
01345 gl->addWidget(l, 2, 5);
01346
01347 l = new QLabel(i18n("Set GID"), gb);
01348 gl->addWidget(l, 3, 5);
01349
01350 l = new QLabel(i18n("File permission, sets user or group ID on execution", "Sticky"), gb);
01351 gl->addWidget(l, 4, 5);
01352
01353 bool enablePage = (isMyFile || IamRoot) && (!isLink);
01354
01355 for (int row = 0; row < 3 ; ++row) {
01356 for (int col = 0; col < 4; ++col) {
01357 QCheckBox *cb = new QCheckBox(gb);
01358 cb->setChecked(permissions & fperm[row][col]);
01359 if ( d->partialPermissions & fperm[row][col] )
01360 {
01361 cb->setTristate( true );
01362 cb->setNoChange();
01363 }
01364 cb->setEnabled( enablePage );
01365 permBox[row][col] = cb;
01366 gl->addWidget (permBox[row][col], row+2, col+1);
01367 connect( cb, SIGNAL( clicked() ),
01368 this, SIGNAL( changed() ) );
01369 }
01370 }
01371 gl->setColStretch(6, 10);
01372 gb->setEnabled( enablePage );
01373
01374
01375 gb = new QGroupBox ( i18n("Ownership"), d->m_frame );
01376 box->addWidget (gb);
01377
01378 gl = new QGridLayout (gb, 4, 3, 15);
01379 gl->addRowSpacing(0, 10);
01380
01381
01382 l = new QLabel( i18n("User:"), gb );
01383 gl->addWidget (l, 1, 0);
01384
01385
01386
01387
01388
01389
01390 int i, maxEntries = 1000;
01391 struct passwd *user;
01392 struct group *ge;
01393
01394
01395
01396
01397 if (IamRoot && isLocal)
01398 {
01399 usrEdit = new KLineEdit( gb );
01400 KCompletion *kcom = usrEdit->completionObject();
01401 kcom->setOrder(KCompletion::Sorted);
01402 setpwent();
01403 for (i=0; ((user = getpwent()) != 0L) && (i < maxEntries); i++)
01404 kcom->addItem(QString::fromLatin1(user->pw_name));
01405 endpwent();
01406 usrEdit->setCompletionMode((i < maxEntries) ? KGlobalSettings::CompletionAuto :
01407 KGlobalSettings::CompletionNone);
01408 usrEdit->setText(strOwner);
01409 gl->addWidget(usrEdit, 1, 1);
01410 connect( usrEdit, SIGNAL( textChanged( const QString & ) ),
01411 this, SIGNAL( changed() ) );
01412 }
01413 else
01414 {
01415 l = new QLabel(strOwner, gb);
01416 gl->addWidget(l, 1, 1);
01417 }
01418
01419
01420
01421 QStringList groupList;
01422 QCString strUser;
01423 user = getpwuid(geteuid());
01424 if (user != 0L)
01425 strUser = user->pw_name;
01426
01427 setgrent();
01428 for (i=0; ((ge = getgrent()) != 0L) && (i < maxEntries); i++)
01429 {
01430 if (IamRoot)
01431 groupList += QString::fromLatin1(ge->gr_name);
01432 else
01433 {
01434
01435 char ** members = ge->gr_mem;
01436 char * member;
01437 while ((member = *members) != 0L) {
01438 if (strUser == member) {
01439 groupList += QString::fromLocal8Bit(ge->gr_name);
01440 break;
01441 }
01442 ++members;
01443 }
01444 }
01445 }
01446 endgrent();
01447
01448
01449 ge = getgrgid (getegid());
01450 if (ge) {
01451 QString name = QString::fromLatin1(ge->gr_name);
01452 if (name.isEmpty())
01453 name.setNum(ge->gr_gid);
01454 if (groupList.find(name) == groupList.end())
01455 groupList += name;
01456 }
01457
01458 bool isMyGroup = groupList.contains(strGroup);
01459
01460
01461
01462
01463 if (!isMyGroup)
01464 groupList += strGroup;
01465
01466 l = new QLabel( i18n("Group:"), gb );
01467 gl->addWidget (l, 2, 0);
01468
01469
01470
01471
01472
01473
01474
01475 if (IamRoot && isLocal)
01476 {
01477 grpEdit = new KLineEdit(gb);
01478 KCompletion *kcom = new KCompletion;
01479 kcom->setItems(groupList);
01480 grpEdit->setCompletionObject(kcom, true);
01481 grpEdit->setAutoDeleteCompletionObject( true );
01482 grpEdit->setCompletionMode(KGlobalSettings::CompletionAuto);
01483 grpEdit->setText(strGroup);
01484 gl->addWidget(grpEdit, 2, 1);
01485 connect( grpEdit, SIGNAL( textChanged( const QString & ) ),
01486 this, SIGNAL( changed() ) );
01487 }
01488 else if ((groupList.count() > 1) && isMyFile && isLocal)
01489 {
01490 grpCombo = new QComboBox(gb, "combogrouplist");
01491 grpCombo->insertStringList(groupList);
01492 grpCombo->setCurrentItem(groupList.findIndex(strGroup));
01493 gl->addWidget(grpCombo, 2, 1);
01494 connect( grpCombo, SIGNAL( activated( int ) ),
01495 this, SIGNAL( changed() ) );
01496 }
01497 else
01498 {
01499 l = new QLabel(strGroup, gb);
01500 gl->addWidget(l, 2, 1);
01501 }
01502
01503 gl->setColStretch(2, 10);
01504
01505
01506 if ( hasDir )
01507 {
01508 d->cbRecursive = new QCheckBox( i18n("Apply changes to all subdirectories and their contents"), d->m_frame );
01509 box->addWidget( d->cbRecursive );
01510 connect( d->cbRecursive, SIGNAL( clicked() ),
01511 this, SLOT( slotRecursiveClicked() ) );
01512 }
01513
01514 box->addStretch (10);
01515
01516 if (isMyFile)
01517 cl[0]->setText(i18n("<b>User</b>"));
01518 else if (isMyGroup)
01519 cl[1]->setText(i18n("<b>Group</b>"));
01520 else
01521 cl[2]->setText(i18n("<b>Others</b>"));
01522 }
01523
01524
01525
01526
01527
01528
01529 KFilePermissionsPropsPlugin::~KFilePermissionsPropsPlugin()
01530 {
01531 delete d;
01532 }
01533
01534 bool KFilePermissionsPropsPlugin::supports( KFileItemList )
01535 {
01536 return true;
01537 }
01538
01539 void KFilePermissionsPropsPlugin::slotRecursiveClicked()
01540 {
01541
01542
01543
01544
01545
01546 for (int row = 0;row < 3; ++row)
01547 for (int col = 0; col < 4; ++col)
01548 permBox[row][col]->setTristate();
01549 }
01550
01551 void KFilePermissionsPropsPlugin::applyChanges()
01552 {
01553 mode_t newPermission = 0;
01554 mode_t newPartialPermission = 0;
01555 mode_t permissionMask = 0;
01556 for (int row = 0;row < 3; ++row)
01557 for (int col = 0; col < 4; ++col)
01558 {
01559 switch (permBox[row][col]->state())
01560 {
01561 case QCheckBox::On:
01562 newPermission |= fperm[row][col];
01563
01564 case QCheckBox::Off:
01565 permissionMask |= fperm[row][col];
01566 break;
01567 default:
01568 newPartialPermission |= fperm[ row ][ col ];
01569 break;
01570 }
01571 }
01572
01573 QString owner, group;
01574 if (usrEdit)
01575 owner = usrEdit->text();
01576 if (grpEdit)
01577 group = grpEdit->text();
01578 else if (grpCombo)
01579 group = grpCombo->currentText();
01580
01581 if (owner == strOwner)
01582 owner = QString::null;
01583
01584 if (group == strGroup)
01585 group = QString::null;
01586
01587 kdDebug(250) << "old permissions : " << QString::number(permissions,8) << endl;
01588 kdDebug(250) << "new permissions : " << QString::number(newPermission,8) << endl;
01589 kdDebug(250) << "permissions mask : " << QString::number(permissionMask,8) << endl;
01590 kdDebug(250) << "url=" << properties->items().first()->url().url() << endl;
01591
01592 if ( permissions != newPermission || d->partialPermissions != newPartialPermission
01593 || !owner.isEmpty() || !group.isEmpty() )
01594 {
01595 KIO::Job * job = KIO::chmod( properties->items(), newPermission, permissionMask,
01596 owner, group,
01597 d->cbRecursive && d->cbRecursive->isChecked() );
01598 connect( job, SIGNAL( result( KIO::Job * ) ),
01599 SLOT( slotChmodResult( KIO::Job * ) ) );
01600
01601 QWidget dummy(0,0,WType_Dialog|WShowModal);
01602 qt_enter_modal(&dummy);
01603 qApp->enter_loop();
01604 qt_leave_modal(&dummy);
01605 }
01606 }
01607
01608 void KFilePermissionsPropsPlugin::slotChmodResult( KIO::Job * job )
01609 {
01610 kdDebug(250) << "KFilePermissionsPropsPlugin::slotChmodResult" << endl;
01611 if (job->error())
01612 job->showErrorDialog( d->m_frame );
01613
01614 qApp->exit_loop();
01615 }
01616
01617 class KExecPropsPlugin::KExecPropsPluginPrivate
01618 {
01619 public:
01620 KExecPropsPluginPrivate()
01621 {
01622 }
01623 ~KExecPropsPluginPrivate()
01624 {
01625 }
01626
01627 QFrame *m_frame;
01628 };
01629
01630 KExecPropsPlugin::KExecPropsPlugin( KPropertiesDialog *_props )
01631 : KPropsDlgPlugin( _props )
01632 {
01633 d = new KExecPropsPluginPrivate;
01634 d->m_frame = properties->dialog()->addPage(i18n("E&xecute"));
01635 QVBoxLayout * mainlayout = new QVBoxLayout( d->m_frame );
01636 mainlayout->setSpacing( KDialog::spacingHint() );
01637
01638
01639
01640 QLabel* l;
01641 l = new QLabel( i18n( "Comman&d:" ), d->m_frame );
01642 mainlayout->addWidget(l);
01643
01644 QHBoxLayout * hlayout;
01645 hlayout = new QHBoxLayout(KDialog::spacingHint());
01646 mainlayout->addLayout(hlayout);
01647
01648 execEdit = new KLineEdit( d->m_frame );
01649 hlayout->addWidget(execEdit, 1);
01650
01651 l->setBuddy( execEdit );
01652
01653 execBrowse = new QPushButton( d->m_frame );
01654 execBrowse->setText( i18n("&Browse...") );
01655 hlayout->addWidget(execBrowse);
01656
01657
01658 QGroupBox* tmpQGroupBox;
01659 tmpQGroupBox = new QGroupBox( i18n("Panel Embedding"), d->m_frame );
01660 tmpQGroupBox->setColumnLayout( 0, Qt::Horizontal );
01661
01662 mainlayout->addWidget(tmpQGroupBox);
01663
01664 QGridLayout *grid = new QGridLayout(tmpQGroupBox->layout(), 2, 2);
01665 grid->setSpacing( KDialog::spacingHint() );
01666 grid->setColStretch(1, 1);
01667
01668 l = new QLabel( i18n( "&Execute on click:" ), tmpQGroupBox );
01669 grid->addWidget(l, 0, 0);
01670
01671 swallowExecEdit = new KLineEdit( tmpQGroupBox );
01672 grid->addWidget(swallowExecEdit, 0, 1);
01673
01674 l->setBuddy( swallowExecEdit );
01675
01676 l = new QLabel( i18n( "&Window title:" ), tmpQGroupBox );
01677 grid->addWidget(l, 1, 0);
01678
01679 swallowTitleEdit = new KLineEdit( tmpQGroupBox );
01680 grid->addWidget(swallowTitleEdit, 1, 1);
01681
01682 l->setBuddy( swallowTitleEdit );
01683
01684
01685
01686 tmpQGroupBox = new QGroupBox( d->m_frame );
01687 tmpQGroupBox->setColumnLayout( 0, Qt::Horizontal );
01688
01689 mainlayout->addWidget(tmpQGroupBox);
01690
01691 grid = new QGridLayout(tmpQGroupBox->layout(), 2, 2);
01692 grid->setSpacing( KDialog::spacingHint() );
01693 grid->setColStretch(1, 1);
01694
01695 terminalCheck = new QCheckBox( tmpQGroupBox );
01696 terminalCheck->setText( i18n("&Run in terminal") );
01697 grid->addMultiCellWidget(terminalCheck, 0, 0, 0, 1);
01698
01699 terminalLabel = new QLabel( i18n( "&Terminal options:" ), tmpQGroupBox );
01700 grid->addWidget(terminalLabel, 1, 0);
01701
01702 terminalEdit = new KLineEdit( tmpQGroupBox );
01703 grid->addWidget(terminalEdit, 1, 1);
01704
01705 terminalLabel->setBuddy( terminalEdit );
01706
01707
01708
01709 tmpQGroupBox = new QGroupBox( d->m_frame );
01710 tmpQGroupBox->setColumnLayout( 0, Qt::Horizontal );
01711
01712 mainlayout->addWidget(tmpQGroupBox);
01713
01714 grid = new QGridLayout(tmpQGroupBox->layout(), 2, 2);
01715 grid->setSpacing(KDialog::spacingHint());
01716 grid->setColStretch(1, 1);
01717
01718 suidCheck = new QCheckBox(tmpQGroupBox);
01719 suidCheck->setText(i18n("Ru&n as a different user"));
01720 grid->addMultiCellWidget(suidCheck, 0, 0, 0, 1);
01721
01722 suidLabel = new QLabel(i18n( "&Username:" ), tmpQGroupBox);
01723 grid->addWidget(suidLabel, 1, 0);
01724
01725 suidEdit = new KLineEdit(tmpQGroupBox);
01726 grid->addWidget(suidEdit, 1, 1);
01727
01728 suidLabel->setBuddy( suidEdit );
01729
01730 mainlayout->addStretch(1);
01731
01732
01733 QString path = _props->kurl().path();
01734 QFile f( path );
01735 if ( !f.open( IO_ReadOnly ) )
01736 return;
01737 f.close();
01738
01739 KSimpleConfig config( path );
01740 config.setDollarExpansion( false );
01741 config.setDesktopGroup();
01742 execStr = config.readPathEntry( QString::fromLatin1("Exec") );
01743 swallowExecStr = config.readPathEntry( QString::fromLatin1("SwallowExec") );
01744 swallowTitleStr = config.readEntry( QString::fromLatin1("SwallowTitle") );
01745 termBool = config.readBoolEntry( QString::fromLatin1("Terminal") );
01746 termOptionsStr = config.readEntry( QString::fromLatin1("TerminalOptions") );
01747 suidBool = config.readBoolEntry( QString::fromLatin1("X-KDE-SubstituteUID") );
01748 suidUserStr = config.readEntry( QString::fromLatin1("X-KDE-Username") );
01749
01750 if ( !swallowExecStr.isNull() )
01751 swallowExecEdit->setText( swallowExecStr );
01752 if ( !swallowTitleStr.isNull() )
01753 swallowTitleEdit->setText( swallowTitleStr );
01754
01755 if ( !execStr.isNull() )
01756 execEdit->setText( execStr );
01757 if ( !termOptionsStr.isNull() )
01758 terminalEdit->setText( termOptionsStr );
01759
01760 terminalCheck->setChecked( termBool );
01761 enableCheckedEdit();
01762
01763 suidCheck->setChecked( suidBool );
01764 suidEdit->setText( suidUserStr );
01765 enableSuidEdit();
01766
01767
01768 KCompletion *kcom = new KCompletion;
01769 kcom->setOrder(KCompletion::Sorted);
01770 struct passwd *pw;
01771 int i, maxEntries = 1000;
01772 setpwent();
01773 for (i=0; ((pw = getpwent()) != 0L) && (i < maxEntries); i++)
01774 kcom->addItem(QString::fromLatin1(pw->pw_name));
01775 endpwent();
01776 if (i < maxEntries)
01777 {
01778 suidEdit->setCompletionObject(kcom, true);
01779 suidEdit->setAutoDeleteCompletionObject( true );
01780 suidEdit->setCompletionMode(KGlobalSettings::CompletionAuto);
01781 }
01782 else
01783 {
01784 delete kcom;
01785 }
01786
01787 connect( swallowExecEdit, SIGNAL( textChanged( const QString & ) ),
01788 this, SIGNAL( changed() ) );
01789 connect( swallowTitleEdit, SIGNAL( textChanged( const QString & ) ),
01790 this, SIGNAL( changed() ) );
01791 connect( execEdit, SIGNAL( textChanged( const QString & ) ),
01792 this, SIGNAL( changed() ) );
01793 connect( terminalEdit, SIGNAL( textChanged( const QString & ) ),
01794 this, SIGNAL( changed() ) );
01795 connect( terminalCheck, SIGNAL( toggled( bool ) ),
01796 this, SIGNAL( changed() ) );
01797 connect( suidCheck, SIGNAL( toggled( bool ) ),
01798 this, SIGNAL( changed() ) );
01799 connect( suidEdit, SIGNAL( textChanged( const QString & ) ),
01800 this, SIGNAL( changed() ) );
01801
01802 connect( execBrowse, SIGNAL( clicked() ), this, SLOT( slotBrowseExec() ) );
01803 connect( terminalCheck, SIGNAL( clicked() ), this, SLOT( enableCheckedEdit() ) );
01804 connect( suidCheck, SIGNAL( clicked() ), this, SLOT( enableSuidEdit() ) );
01805
01806 }
01807
01808 KExecPropsPlugin::~KExecPropsPlugin()
01809 {
01810 delete d;
01811 }
01812
01813
01814
01815
01816
01817
01818 void KExecPropsPlugin::enableCheckedEdit()
01819 {
01820 bool checked = terminalCheck->isChecked();
01821 terminalLabel->setEnabled( checked );
01822 terminalEdit->setEnabled( checked );
01823 }
01824
01825 void KExecPropsPlugin::enableSuidEdit()
01826 {
01827 bool checked = suidCheck->isChecked();
01828 suidLabel->setEnabled( checked );
01829 suidEdit->setEnabled( checked );
01830 }
01831
01832 bool KExecPropsPlugin::supports( KFileItemList _items )
01833 {
01834 if ( _items.count() != 1 )
01835 return false;
01836 KFileItem * item = _items.first();
01837
01838 if ( !KPropsDlgPlugin::isDesktopFile( item ) )
01839 return false;
01840
01841 KDesktopFile config( item->url().path(), true );
01842 return config.hasApplicationType() && kapp->authorize("run_desktop_files") && kapp->authorize("shell_access");
01843 }
01844
01845 void KExecPropsPlugin::applyChanges()
01846 {
01847 kdDebug(250) << "KExecPropsPlugin::applyChanges" << endl;
01848 QString path = properties->kurl().path();
01849
01850 QFile f( path );
01851
01852 if ( !f.open( IO_ReadWrite ) ) {
01853 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have sufficient access to write to <b>%1</b>.</qt>").arg(path));
01854 return;
01855 }
01856 f.close();
01857
01858 KSimpleConfig config( path );
01859 config.setDesktopGroup();
01860 config.writeEntry( QString::fromLatin1("Type"), QString::fromLatin1("Application"));
01861 config.writeEntry( QString::fromLatin1("Exec"), execEdit->text() );
01862 config.writeEntry( QString::fromLatin1("SwallowExec"), swallowExecEdit->text() );
01863 config.writeEntry( QString::fromLatin1("SwallowTitle"), swallowTitleEdit->text() );
01864 config.writeEntry( QString::fromLatin1("Terminal"), terminalCheck->isChecked() );
01865 config.writeEntry( QString::fromLatin1("TerminalOptions"), terminalEdit->text() );
01866 config.writeEntry( QString::fromLatin1("X-KDE-SubstituteUID"), suidCheck->isChecked() );
01867 config.writeEntry( QString::fromLatin1("X-KDE-Username"), suidEdit->text() );
01868 }
01869
01870
01871 void KExecPropsPlugin::slotBrowseExec()
01872 {
01873 KURL f = KFileDialog::getOpenURL( QString::null,
01874 QString::null, d->m_frame );
01875 if ( f.isEmpty() )
01876 return;
01877
01878 if ( !f.isLocalFile()) {
01879 KMessageBox::sorry(d->m_frame, i18n("Only executables on local file systems are supported."));
01880 return;
01881 }
01882
01883 QString path = f.path();
01884 KRun::shellQuote( path );
01885 execEdit->setText( path );
01886 }
01887
01888 class KURLPropsPlugin::KURLPropsPluginPrivate
01889 {
01890 public:
01891 KURLPropsPluginPrivate()
01892 {
01893 }
01894 ~KURLPropsPluginPrivate()
01895 {
01896 }
01897
01898 QFrame *m_frame;
01899 };
01900
01901 KURLPropsPlugin::KURLPropsPlugin( KPropertiesDialog *_props )
01902 : KPropsDlgPlugin( _props )
01903 {
01904 d = new KURLPropsPluginPrivate;
01905 d->m_frame = properties->dialog()->addPage(i18n("U&RL"));
01906 QVBoxLayout * layout = new QVBoxLayout(d->m_frame, KDialog::spacingHint());
01907
01908 QLabel *l;
01909 l = new QLabel( d->m_frame, "Label_1" );
01910 l->setText( i18n("URL:") );
01911 layout->addWidget(l);
01912
01913 URLEdit = new KURLRequester( d->m_frame, "URL Requester" );
01914 layout->addWidget(URLEdit);
01915
01916 QString path = properties->kurl().path();
01917
01918 QFile f( path );
01919 if ( !f.open( IO_ReadOnly ) )
01920 return;
01921 f.close();
01922
01923 KSimpleConfig config( path );
01924 config.setDesktopGroup();
01925 URLStr = config.readPathEntry( QString::fromLatin1("URL") );
01926
01927 if ( !URLStr.isNull() )
01928 URLEdit->setURL( URLStr );
01929
01930 connect( URLEdit, SIGNAL( textChanged( const QString & ) ),
01931 this, SIGNAL( changed() ) );
01932
01933 layout->addStretch (1);
01934 }
01935
01936 KURLPropsPlugin::~KURLPropsPlugin()
01937 {
01938 delete d;
01939 }
01940
01941
01942
01943
01944
01945
01946 bool KURLPropsPlugin::supports( KFileItemList _items )
01947 {
01948 if ( _items.count() != 1 )
01949 return false;
01950 KFileItem * item = _items.first();
01951
01952 if ( !KPropsDlgPlugin::isDesktopFile( item ) )
01953 return false;
01954
01955
01956 KDesktopFile config( item->url().path(), true );
01957 return config.hasLinkType();
01958 }
01959
01960 void KURLPropsPlugin::applyChanges()
01961 {
01962 QString path = properties->kurl().path();
01963
01964 QFile f( path );
01965 if ( !f.open( IO_ReadWrite ) ) {
01966 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have sufficient access to write to <b>%1</b>.</qt>").arg(path));
01967 return;
01968 }
01969 f.close();
01970
01971 KSimpleConfig config( path );
01972 config.setDesktopGroup();
01973 config.writeEntry( QString::fromLatin1("Type"), QString::fromLatin1("Link"));
01974 config.writeEntry( QString::fromLatin1("URL"), URLEdit->url() );
01975
01976
01977 if ( config.hasKey("Name") )
01978 {
01979
01980 QString nameStr = properties->kurl().fileName();
01981 if ( nameStr.right(8) == QString::fromLatin1(".desktop") )
01982 nameStr.truncate( nameStr.length() - 8 );
01983 if ( nameStr.right(7) == QString::fromLatin1(".kdelnk") )
01984 nameStr.truncate( nameStr.length() - 7 );
01985 config.writeEntry( QString::fromLatin1("Name"), nameStr );
01986 }
01987 }
01988
01989
01990
01991
01992
01993
01994
01995 class KApplicationPropsPlugin::KApplicationPropsPluginPrivate
01996 {
01997 public:
01998 KApplicationPropsPluginPrivate()
01999 {
02000 m_kdesktopMode = QCString(qApp->name()) == "kdesktop";
02001 }
02002 ~KApplicationPropsPluginPrivate()
02003 {
02004 }
02005
02006 QFrame *m_frame;
02007 bool m_kdesktopMode;
02008 };
02009
02010 KApplicationPropsPlugin::KApplicationPropsPlugin( KPropertiesDialog *_props )
02011 : KPropsDlgPlugin( _props )
02012 {
02013 d = new KApplicationPropsPluginPrivate;
02014 d->m_frame = properties->dialog()->addPage(i18n("&Application"));
02015 QVBoxLayout *toplayout = new QVBoxLayout( d->m_frame, KDialog::spacingHint());
02016
02017 QIconSet iconSet;
02018 QPixmap pixMap;
02019
02020 addExtensionButton = new QPushButton( QString::null, d->m_frame );
02021 iconSet = SmallIconSet( "back" );
02022 addExtensionButton->setIconSet( iconSet );
02023 pixMap = iconSet.pixmap( QIconSet::Small, QIconSet::Normal );
02024 addExtensionButton->setFixedSize( pixMap.width()+8, pixMap.height()+8 );
02025 connect( addExtensionButton, SIGNAL( clicked() ),
02026 SLOT( slotAddExtension() ) );
02027
02028 delExtensionButton = new QPushButton( QString::null, d->m_frame );
02029 iconSet = SmallIconSet( "forward" );
02030 delExtensionButton->setIconSet( iconSet );
02031 delExtensionButton->setFixedSize( pixMap.width()+8, pixMap.height()+8 );
02032 connect( delExtensionButton, SIGNAL( clicked() ),
02033 SLOT( slotDelExtension() ) );
02034
02035 QLabel *l;
02036
02037 QGridLayout *grid = new QGridLayout(2, 2);
02038 grid->setColStretch(1, 1);
02039 toplayout->addLayout(grid);
02040
02041 if ( d->m_kdesktopMode )
02042 {
02043
02044 nameEdit = 0L;
02045 }
02046 else
02047 {
02048 l = new QLabel(i18n("Name:"), d->m_frame, "Label_4" );
02049 grid->addWidget(l, 0, 0);
02050
02051 nameEdit = new KLineEdit( d->m_frame, "LineEdit_3" );
02052 grid->addWidget(nameEdit, 0, 1);
02053 }
02054
02055 l = new QLabel(i18n("Description:"), d->m_frame, "Label_5" );
02056 grid->addWidget(l, 1, 0);
02057
02058 genNameEdit = new KLineEdit( d->m_frame, "LineEdit_4" );
02059 grid->addWidget(genNameEdit, 1, 1);
02060
02061 l = new QLabel(i18n("Comment:"), d->m_frame, "Label_3" );
02062 grid->addWidget(l, 2, 0);
02063
02064 commentEdit = new KLineEdit( d->m_frame, "LineEdit_2" );
02065 grid->addWidget(commentEdit, 2, 1);
02066
02067 l = new QLabel(i18n("File types:"), d->m_frame);
02068 toplayout->addWidget(l, 0, AlignLeft);
02069
02070 grid = new QGridLayout(4, 3);
02071 grid->setColStretch(0, 1);
02072 grid->setColStretch(2, 1);
02073 grid->setRowStretch( 0, 1 );
02074 grid->setRowStretch( 3, 1 );
02075 toplayout->addLayout(grid, 2);
02076
02077 extensionsList = new QListBox( d->m_frame );
02078 extensionsList->setSelectionMode( QListBox::Extended );
02079 grid->addMultiCellWidget(extensionsList, 0, 3, 0, 0);
02080
02081 grid->addWidget(addExtensionButton, 1, 1);
02082 grid->addWidget(delExtensionButton, 2, 1);
02083
02084 availableExtensionsList = new QListBox( d->m_frame );
02085 availableExtensionsList->setSelectionMode( QListBox::Extended );
02086 grid->addMultiCellWidget(availableExtensionsList, 0, 3, 2, 2);
02087
02088 QString path = properties->kurl().path() ;
02089 QFile f( path );
02090 if ( !f.open( IO_ReadOnly ) )
02091 return;
02092 f.close();
02093
02094 KSimpleConfig config( path );
02095 config.setDesktopGroup();
02096 QString commentStr = config.readEntry( QString::fromLatin1("Comment") );
02097 QString genNameStr = config.readEntry( QString::fromLatin1("GenericName") );
02098
02099 QStringList selectedTypes = config.readListEntry( "ServiceTypes" );
02100
02101 selectedTypes += config.readListEntry( "MimeType", ';' );
02102
02103 QString nameStr = config.readEntry( QString::fromLatin1("Name") );
02104 if ( nameStr.isEmpty() || d->m_kdesktopMode ) {
02105
02106
02107
02108 setDirty();
02109 }
02110
02111 commentEdit->setText( commentStr );
02112 genNameEdit->setText( genNameStr );
02113 if ( nameEdit )
02114 nameEdit->setText( nameStr );
02115
02116 selectedTypes.sort();
02117 QStringList::Iterator sit = selectedTypes.begin();
02118 for( ; sit != selectedTypes.end(); ++sit ) {
02119 if ( !((*sit).isEmpty()) )
02120 extensionsList->insertItem( *sit );
02121 }
02122
02123 KMimeType::List mimeTypes = KMimeType::allMimeTypes();
02124 QValueListIterator<KMimeType::Ptr> it2 = mimeTypes.begin();
02125 for ( ; it2 != mimeTypes.end(); ++it2 )
02126 addMimeType ( (*it2)->name() );
02127
02128 updateButton();
02129
02130 connect( extensionsList, SIGNAL( highlighted( int ) ),
02131 this, SLOT( updateButton() ) );
02132 connect( availableExtensionsList, SIGNAL( highlighted( int ) ),
02133 this, SLOT( updateButton() ) );
02134
02135 connect( addExtensionButton, SIGNAL( clicked() ),
02136 this, SIGNAL( changed() ) );
02137 connect( delExtensionButton, SIGNAL( clicked() ),
02138 this, SIGNAL( changed() ) );
02139 if ( nameEdit )
02140 connect( nameEdit, SIGNAL( textChanged( const QString & ) ),
02141 this, SIGNAL( changed() ) );
02142 connect( commentEdit, SIGNAL( textChanged( const QString & ) ),
02143 this, SIGNAL( changed() ) );
02144 connect( genNameEdit, SIGNAL( textChanged( const QString & ) ),
02145 this, SIGNAL( changed() ) );
02146 connect( availableExtensionsList, SIGNAL( selected( int ) ),
02147 this, SIGNAL( changed() ) );
02148 connect( extensionsList, SIGNAL( selected( int ) ),
02149 this, SIGNAL( changed() ) );
02150 }
02151
02152 KApplicationPropsPlugin::~KApplicationPropsPlugin()
02153 {
02154 delete d;
02155 }
02156
02157
02158
02159
02160
02161
02162 void KApplicationPropsPlugin::updateButton()
02163 {
02164 addExtensionButton->setEnabled(availableExtensionsList->currentItem()>-1);
02165 delExtensionButton->setEnabled(extensionsList->currentItem()>-1);
02166 }
02167
02168 void KApplicationPropsPlugin::addMimeType( const QString & name )
02169 {
02170
02171
02172 bool insert = true;
02173
02174 for ( uint i = 0; i < extensionsList->count(); i++ )
02175 if ( extensionsList->text( i ) == name )
02176 insert = false;
02177
02178 if ( insert )
02179 {
02180 availableExtensionsList->insertItem( name );
02181 availableExtensionsList->sort();
02182 }
02183 }
02184
02185 bool KApplicationPropsPlugin::supports( KFileItemList _items )
02186 {
02187
02188 return KExecPropsPlugin::supports( _items );
02189 }
02190
02191 void KApplicationPropsPlugin::applyChanges()
02192 {
02193 QString path = properties->kurl().path();
02194
02195 QFile f( path );
02196
02197 if ( !f.open( IO_ReadWrite ) ) {
02198 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have sufficient access to write to <b>%1</b>.</qt>").arg(path));
02199 return;
02200 }
02201 f.close();
02202
02203 KSimpleConfig config( path );
02204 config.setDesktopGroup();
02205 config.writeEntry( QString::fromLatin1("Type"), QString::fromLatin1("Application"));
02206 config.writeEntry( QString::fromLatin1("Comment"), commentEdit->text() );
02207 config.writeEntry( QString::fromLatin1("Comment"), commentEdit->text(), true, false, true );
02208 config.writeEntry( QString::fromLatin1("GenericName"), genNameEdit->text() );
02209 config.writeEntry( QString::fromLatin1("GenericName"), genNameEdit->text(), true, false, true );
02210
02211 QStringList selectedTypes;
02212 for ( uint i = 0; i < extensionsList->count(); i++ )
02213 selectedTypes.append( extensionsList->text( i ) );
02214
02215 config.writeEntry( QString::fromLatin1("MimeType"), selectedTypes, ';' );
02216 config.writeEntry( QString::fromLatin1("ServiceTypes"), "" );
02217
02218
02219 QString nameStr = nameEdit ? nameEdit->text() : QString::null;
02220 if ( nameStr.isEmpty() )
02221 {
02222 nameStr = properties->kurl().fileName();
02223 if ( nameStr.right(8) == QString::fromLatin1(".desktop") )
02224 nameStr.truncate( nameStr.length() - 8 );
02225 if ( nameStr.right(7) == QString::fromLatin1(".kdelnk") )
02226 nameStr.truncate( nameStr.length() - 7 );
02227 }
02228 config.writeEntry( QString::fromLatin1("Name"), nameStr );
02229 config.writeEntry( QString::fromLatin1("Name"), nameStr, true, false, true );
02230
02231 config.sync();
02232 f.close();
02233 }
02234
02235 void KApplicationPropsPlugin::slotAddExtension()
02236 {
02237 QListBoxItem *item = availableExtensionsList->firstItem();
02238 QListBoxItem *nextItem;
02239
02240 while ( item )
02241 {
02242 nextItem = item->next();
02243
02244 if ( item->isSelected() )
02245 {
02246 extensionsList->insertItem( item->text() );
02247 availableExtensionsList->removeItem( availableExtensionsList->index( item ) );
02248 }
02249
02250 item = nextItem;
02251 }
02252
02253 extensionsList->sort();
02254 updateButton();
02255 }
02256
02257 void KApplicationPropsPlugin::slotDelExtension()
02258 {
02259 QListBoxItem *item = extensionsList->firstItem();
02260 QListBoxItem *nextItem;
02261
02262 while ( item )
02263 {
02264 nextItem = item->next();
02265
02266 if ( item->isSelected() )
02267 {
02268 availableExtensionsList->insertItem( item->text() );
02269 extensionsList->removeItem( extensionsList->index( item ) );
02270 }
02271
02272 item = nextItem;
02273 }
02274
02275 availableExtensionsList->sort();
02276 updateButton();
02277 }
02278
02279
02280
02281
02282
02283
02284
02285 class KBindingPropsPlugin::KBindingPropsPluginPrivate
02286 {
02287 public:
02288 KBindingPropsPluginPrivate()
02289 {
02290 }
02291 ~KBindingPropsPluginPrivate()
02292 {
02293 }
02294
02295 QFrame *m_frame;
02296 };
02297
02298 KBindingPropsPlugin::KBindingPropsPlugin( KPropertiesDialog *_props ) : KPropsDlgPlugin( _props )
02299 {
02300 d = new KBindingPropsPluginPrivate;
02301 d->m_frame = properties->dialog()->addPage(i18n("A&ssociation"));
02302 patternEdit = new KLineEdit( d->m_frame, "LineEdit_1" );
02303 commentEdit = new KLineEdit( d->m_frame, "LineEdit_2" );
02304 mimeEdit = new KLineEdit( d->m_frame, "LineEdit_3" );
02305
02306 QBoxLayout * mainlayout = new QVBoxLayout(d->m_frame, KDialog::spacingHint());
02307 QLabel* tmpQLabel;
02308
02309 tmpQLabel = new QLabel( d->m_frame, "Label_1" );
02310 tmpQLabel->setText( i18n("Pattern ( example: *.html;*.htm )") );
02311 tmpQLabel->setMinimumSize(tmpQLabel->sizeHint());
02312 mainlayout->addWidget(tmpQLabel, 1);
02313
02314
02315
02316 patternEdit->setMaxLength( 512 );
02317 patternEdit->setMinimumSize( patternEdit->sizeHint() );
02318 patternEdit->setFixedHeight( fontHeight );
02319 mainlayout->addWidget(patternEdit, 1);
02320
02321 tmpQLabel = new QLabel( d->m_frame, "Label_2" );
02322 tmpQLabel->setText( i18n("Mime Type") );
02323 tmpQLabel->setMinimumSize(tmpQLabel->sizeHint());
02324 mainlayout->addWidget(tmpQLabel, 1);
02325
02326
02327 mimeEdit->setMaxLength( 256 );
02328 mimeEdit->setMinimumSize( mimeEdit->sizeHint() );
02329 mimeEdit->setFixedHeight( fontHeight );
02330 mainlayout->addWidget(mimeEdit, 1);
02331
02332 tmpQLabel = new QLabel( d->m_frame, "Label_3" );
02333 tmpQLabel->setText( i18n("Comment") );
02334 tmpQLabel->setMinimumSize(tmpQLabel->sizeHint());
02335 mainlayout->addWidget(tmpQLabel, 1);
02336
02337
02338 commentEdit->setMaxLength( 256 );
02339 commentEdit->setMinimumSize( commentEdit->sizeHint() );
02340 commentEdit->setFixedHeight( fontHeight );
02341 mainlayout->addWidget(commentEdit, 1);
02342
02343 cbAutoEmbed = new QCheckBox( i18n("Left click previews"), d->m_frame, "cbAutoEmbed" );
02344 mainlayout->addWidget(cbAutoEmbed, 1);
02345
02346 mainlayout->addStretch (10);
02347 mainlayout->activate();
02348
02349 QFile f( _props->kurl().path() );
02350 if ( !f.open( IO_ReadOnly ) )
02351 return;
02352 f.close();
02353
02354 KSimpleConfig config( _props->kurl().path() );
02355 config.setDesktopGroup();
02356 QString patternStr = config.readEntry( QString::fromLatin1("Patterns") );
02357 QString iconStr = config.readEntry( QString::fromLatin1("Icon") );
02358 QString commentStr = config.readEntry( QString::fromLatin1("Comment") );
02359 m_sMimeStr = config.readEntry( QString::fromLatin1("MimeType") );
02360
02361 if ( !patternStr.isEmpty() )
02362 patternEdit->setText( patternStr );
02363 if ( !commentStr.isEmpty() )
02364 commentEdit->setText( commentStr );
02365 if ( !m_sMimeStr.isEmpty() )
02366 mimeEdit->setText( m_sMimeStr );
02367 cbAutoEmbed->setTristate();
02368 if ( config.hasKey( QString::fromLatin1("X-KDE-AutoEmbed") ) )
02369 cbAutoEmbed->setChecked( config.readBoolEntry( QString::fromLatin1("X-KDE-AutoEmbed") ) );
02370 else
02371 cbAutoEmbed->setNoChange();
02372
02373 connect( patternEdit, SIGNAL( textChanged( const QString & ) ),
02374 this, SIGNAL( changed() ) );
02375 connect( commentEdit, SIGNAL( textChanged( const QString & ) ),
02376 this, SIGNAL( changed() ) );
02377 connect( mimeEdit, SIGNAL( textChanged( const QString & ) ),
02378 this, SIGNAL( changed() ) );
02379 connect( cbAutoEmbed, SIGNAL( toggled( bool ) ),
02380 this, SIGNAL( changed() ) );
02381 }
02382
02383 KBindingPropsPlugin::~KBindingPropsPlugin()
02384 {
02385 delete d;
02386 }
02387
02388
02389
02390
02391
02392
02393 bool KBindingPropsPlugin::supports( KFileItemList _items )
02394 {
02395 if ( _items.count() != 1 )
02396 return false;
02397 KFileItem * item = _items.first();
02398
02399 if ( !KPropsDlgPlugin::isDesktopFile( item ) )
02400 return false;
02401
02402
02403 KDesktopFile config( item->url().path(), true );
02404 return config.hasMimeTypeType();
02405 }
02406
02407 void KBindingPropsPlugin::applyChanges()
02408 {
02409 QString path = properties->kurl().path();
02410 QFile f( path );
02411
02412 if ( !f.open( IO_ReadWrite ) )
02413 {
02414 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have sufficient access to write to <b>%1</b>.</qt>").arg(path));
02415 return;
02416 }
02417 f.close();
02418
02419 KSimpleConfig config( path );
02420 config.setDesktopGroup();
02421 config.writeEntry( QString::fromLatin1("Type"), QString::fromLatin1("MimeType") );
02422
02423 config.writeEntry( QString::fromLatin1("Patterns"), patternEdit->text() );
02424 config.writeEntry( QString::fromLatin1("Comment"), commentEdit->text() );
02425 config.writeEntry( QString::fromLatin1("Comment"), commentEdit->text(), true, false, true );
02426 config.writeEntry( QString::fromLatin1("MimeType"), mimeEdit->text() );
02427 if ( cbAutoEmbed->state() == QButton::NoChange )
02428 config.deleteEntry( QString::fromLatin1("X-KDE-AutoEmbed"), false );
02429 else
02430 config.writeEntry( QString::fromLatin1("X-KDE-AutoEmbed"), cbAutoEmbed->isChecked() );
02431 config.sync();
02432 }
02433
02434
02435
02436
02437
02438
02439
02440 class KDevicePropsPlugin::KDevicePropsPluginPrivate
02441 {
02442 public:
02443 KDevicePropsPluginPrivate()
02444 {
02445 }
02446 ~KDevicePropsPluginPrivate()
02447 {
02448 }
02449
02450 QFrame *m_frame;
02451 QStringList mountpointlist;
02452 };
02453
02454 KDevicePropsPlugin::KDevicePropsPlugin( KPropertiesDialog *_props ) : KPropsDlgPlugin( _props )
02455 {
02456 d = new KDevicePropsPluginPrivate;
02457 d->m_frame = properties->dialog()->addPage(i18n("De&vice"));
02458
02459 QStringList devices;
02460 QCString fstabFile;
02461 indexDevice = 0;
02462 indexMountPoint = 1;
02463 if ( QFile::exists(QString::fromLatin1("/etc/fstab")) )
02464 {
02465 fstabFile = "/etc/fstab";
02466 }
02467 else if ( QFile::exists(QString::fromLatin1("/etc/vfstab")) )
02468 {
02469 fstabFile = "/etc/vfstab";
02470 indexMountPoint++;
02471 }
02472
02473
02474 if ( !fstabFile.isEmpty() )
02475 {
02476 #ifdef HAVE_SETMNTENT
02477
02478 #define SETMNTENT setmntent
02479 #define ENDMNTENT endmntent
02480 #define STRUCT_MNTENT struct mntent *
02481 #define STRUCT_SETMNTENT FILE *
02482 #define GETMNTENT(file, var) ((var = getmntent(file)) != 0)
02483 #define MOUNTPOINT(var) var->mnt_dir
02484 #define MOUNTTYPE(var) var->mnt_type
02485 #define MOUNTOPTIONS(var) var->mnt_opts
02486 #define HASMNTOPT(var, opt) hasmntopt(var, opt)
02487 #define FSNAME(var) var->mnt_fsname
02488
02489 STRUCT_SETMNTENT fstab = SETMNTENT(fstabFile, "r");
02490 if (fstab)
02491 {
02492 STRUCT_MNTENT fe;
02493 while (GETMNTENT(fstab, fe))
02494 {
02495 QString mountPoint = QFile::decodeName(MOUNTPOINT(fe));
02496 QString device = QFile::decodeName(FSNAME(fe));
02497 if (device.startsWith("/") && (mountPoint != "-") &&
02498 (mountPoint != "none") && !mountPoint.isEmpty())
02499 {
02500 devices.append( device + QString::fromLatin1(" (")
02501 + mountPoint + QString::fromLatin1(")") );
02502 m_devicelist.append(device);
02503 d->mountpointlist.append(mountPoint);
02504 }
02505 }
02506 }
02507 #else
02508
02509 QFile f( fstabFile );
02510 if ( f.open( IO_ReadOnly ) )
02511 {
02512 QTextStream stream( &f );
02513 while ( !stream.eof() )
02514 {
02515 QString line = stream.readLine();
02516 line = line.simplifyWhiteSpace();
02517 if (!line.isEmpty() && line[0] == '/')
02518 {
02519 QStringList lst = QStringList::split( ' ', line );
02520 if ( lst.count() > 2 && lst[indexDevice] != QString::fromLatin1("/proc")
02521 && lst[indexMountPoint] != QString::fromLatin1("none")
02522 && lst[indexMountPoint] != QString::fromLatin1("-") )
02523 {
02524 devices.append( lst[indexDevice]+QString::fromLatin1(" (")
02525 +lst[indexMountPoint]+QString::fromLatin1(")") );
02526 m_devicelist.append( lst[indexDevice] );
02527 d->mountpointlist.append( lst[indexMountPoint] );
02528 }
02529 }
02530 }
02531 f.close();
02532 }
02533 #endif
02534 }
02535
02536
02537 QGridLayout *layout = new QGridLayout( d->m_frame, 0, 3, KDialog::marginHint(),
02538 KDialog::spacingHint());
02539 layout->setColStretch(1, 1);
02540
02541 QLabel* label;
02542 label = new QLabel( d->m_frame );
02543 label->setText( devices.count() == 0 ?
02544 i18n("Device (/dev/fd0):") :
02545 i18n("Device:") );
02546 layout->addWidget(label, 0, 0);
02547
02548 device = new QComboBox( true, d->m_frame, "ComboBox_device" );
02549 device->insertStringList( devices );
02550 layout->addWidget(device, 0, 1);
02551 connect( device, SIGNAL( activated( int ) ),
02552 this, SLOT( slotActivated( int ) ) );
02553
02554 readonly = new QCheckBox( d->m_frame, "CheckBox_readonly" );
02555 readonly->setText( i18n("Read only") );
02556 layout->addWidget(readonly, 1, 1);
02557
02558 label = new QLabel( d->m_frame );
02559 label->setText( devices.count()==0 ?
02560 i18n("Mount point (/mnt/floppy):") :
02561 i18n("Mount point:"));
02562 layout->addWidget(label, 2, 0);
02563
02564 mountpoint = new QLabel( d->m_frame, "LineEdit_mountpoint" );
02565
02566 layout->addWidget(mountpoint, 2, 1);
02567
02568 KSeparator* sep = new KSeparator( KSeparator::HLine, d->m_frame);
02569 layout->addMultiCellWidget(sep, 4, 4, 0, 2);
02570
02571 unmounted = new KIconButton( d->m_frame );
02572 unmounted->setFixedSize(70, 70);
02573 unmounted->setIconType(KIcon::Desktop, KIcon::Device);
02574 layout->addWidget(unmounted, 5, 0);
02575
02576 label = new QLabel( i18n("Unmounted Icon"), d->m_frame );
02577 layout->addWidget(label, 5, 1);
02578
02579 layout->setRowStretch(6, 1);
02580
02581 QString path( _props->kurl().path() );
02582
02583 QFile f( path );
02584 if ( !f.open( IO_ReadOnly ) )
02585 return;
02586 f.close();
02587
02588 KSimpleConfig config( path );
02589 config.setDesktopGroup();
02590 QString deviceStr = config.readEntry( QString::fromLatin1("Dev") );
02591 QString mountPointStr = config.readEntry( QString::fromLatin1("MountPoint") );
02592 bool ro = config.readBoolEntry( QString::fromLatin1("ReadOnly"), false );
02593 QString unmountedStr = config.readEntry( QString::fromLatin1("UnmountIcon") );
02594
02595 device->setEditText( deviceStr );
02596 if ( !deviceStr.isEmpty() ) {
02597
02598 int index = m_devicelist.findIndex(deviceStr);
02599 if (index != -1)
02600 {
02601
02602 slotActivated( index );
02603 }
02604 }
02605
02606 if ( !mountPointStr.isEmpty() )
02607 mountpoint->setText( mountPointStr );
02608
02609 readonly->setChecked( ro );
02610
02611 if ( unmountedStr.isEmpty() )
02612 unmountedStr = KMimeType::mimeType(QString::fromLatin1("application/octet-stream"))->KServiceType::icon();
02613
02614 unmounted->setIcon( unmountedStr );
02615
02616 connect( device, SIGNAL( activated( int ) ),
02617 this, SIGNAL( changed() ) );
02618 connect( device, SIGNAL( textChanged( const QString & ) ),
02619 this, SIGNAL( changed() ) );
02620 connect( readonly, SIGNAL( toggled( bool ) ),
02621 this, SIGNAL( changed() ) );
02622 connect( unmounted, SIGNAL( iconChanged( QString ) ),
02623 this, SIGNAL( changed() ) );
02624 }
02625
02626 KDevicePropsPlugin::~KDevicePropsPlugin()
02627 {
02628 delete d;
02629 }
02630
02631
02632
02633
02634
02635
02636 void KDevicePropsPlugin::slotActivated( int index )
02637 {
02638 device->setEditText( m_devicelist[index] );
02639 mountpoint->setText( d->mountpointlist[index] );
02640 }
02641
02642 bool KDevicePropsPlugin::supports( KFileItemList _items )
02643 {
02644 if ( _items.count() != 1 )
02645 return false;
02646 KFileItem * item = _items.first();
02647
02648 if ( !KPropsDlgPlugin::isDesktopFile( item ) )
02649 return false;
02650
02651 KDesktopFile config( item->url().path(), true );
02652 return config.hasDeviceType();
02653 }
02654
02655 void KDevicePropsPlugin::applyChanges()
02656 {
02657 QString path = properties->kurl().path();
02658 QFile f( path );
02659 if ( !f.open( IO_ReadWrite ) )
02660 {
02661 KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have sufficient access to write to <b>%1</b>.</qt>").arg(path));
02662 return;
02663 }
02664 f.close();
02665
02666 KSimpleConfig config( path );
02667 config.setDesktopGroup();
02668 config.writeEntry( QString::fromLatin1("Type"), QString::fromLatin1("FSDevice") );
02669
02670 config.writeEntry( QString::fromLatin1("Dev"), device->currentText() );
02671 config.writeEntry( QString::fromLatin1("MountPoint"), mountpoint->text() );
02672
02673 config.writeEntry( QString::fromLatin1("UnmountIcon"), unmounted->icon() );
02674 kdDebug(250) << "unmounted->icon() = " << unmounted->icon() << endl;
02675
02676 config.writeEntry( QString::fromLatin1("ReadOnly"), readonly->isChecked() );
02677
02678 config.sync();
02679 }
02680
02681 void KPropertiesDialog::virtual_hook( int id, void* data )
02682 { KDialogBase::virtual_hook( id, data ); }
02683
02684 void KPropsDlgPlugin::virtual_hook( int, void* )
02685 { }
02686
02687 #include "kpropertiesdialog.moc"