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