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