00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "kacleditwidget.h"
00023 #include "kacleditwidget_p.h"
00024
00025 #ifdef USE_POSIX_ACL
00026
00027 #include <qpainter.h>
00028 #include <qptrlist.h>
00029 #include <qvbox.h>
00030 #include <qhbox.h>
00031 #include <qpushbutton.h>
00032 #include <qvbuttongroup.h>
00033 #include <qradiobutton.h>
00034 #include <qcombobox.h>
00035 #include <qlabel.h>
00036 #include <qcheckbox.h>
00037 #include <qlayout.h>
00038 #include <qwidgetstack.h>
00039 #include <qheader.h>
00040
00041 #include <klocale.h>
00042 #include <kfileitem.h>
00043 #include <kdebug.h>
00044 #include <kdialog.h>
00045 #include <kdialogbase.h>
00046
00047 #ifdef HAVE_ACL_LIBACL_H
00048 # include <acl/libacl.h>
00049 #endif
00050 extern "C" {
00051 #include <pwd.h>
00052 #include <grp.h>
00053 }
00054 #include <assert.h>
00055
00056 #include "images.h"
00057
00058 static struct {
00059 const char* label;
00060 const char* pixmapName;
00061 QPixmap* pixmap;
00062 } s_itemAttributes[] = {
00063 { I18N_NOOP( "Owner" ), "user-grey", 0 },
00064 { I18N_NOOP( "Owning Group" ), "group-grey", 0 },
00065 { I18N_NOOP( "Others" ), "others-grey", 0 },
00066 { I18N_NOOP( "Mask" ), "mask", 0 },
00067 { I18N_NOOP( "Named User" ), "user", 0 },
00068 { I18N_NOOP( "Named Group" ), "group", 0 },
00069 };
00070
00071 KACLEditWidget::KACLEditWidget( QWidget *parent, const char *name )
00072 :QWidget( parent, name )
00073 {
00074 QHBox *hbox = new QHBox( parent );
00075 hbox->setSpacing( KDialog::spacingHint() );
00076 m_listView = new KACLListView( hbox, "acl_listview" );
00077 connect( m_listView, SIGNAL( selectionChanged() ),
00078 this, SLOT( slotUpdateButtons() ) );
00079 QVBox *vbox = new QVBox( hbox );
00080 vbox->setSpacing( KDialog::spacingHint() );
00081 m_AddBtn = new QPushButton( i18n( "Add Entry..." ), vbox, "add_entry_button" );
00082 connect( m_AddBtn, SIGNAL( clicked() ), m_listView, SLOT( slotAddEntry() ) );
00083 m_EditBtn = new QPushButton( i18n( "Edit Entry..." ), vbox, "edit_entry_button" );
00084 connect( m_EditBtn, SIGNAL( clicked() ), m_listView, SLOT( slotEditEntry() ) );
00085 m_DelBtn = new QPushButton( i18n( "Delete Entry" ), vbox, "delete_entry_button" );
00086 connect( m_DelBtn, SIGNAL( clicked() ), m_listView, SLOT( slotRemoveEntry() ) );
00087 QWidget *spacer = new QWidget( vbox );
00088 spacer->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding );
00089 slotUpdateButtons();
00090 }
00091
00092 void KACLEditWidget::slotUpdateButtons()
00093 {
00094 bool atLeastOneIsNotDeletable = false;
00095 bool atLeastOneIsNotAllowedToChangeType = false;
00096 int selectedCount = 0;
00097 QListViewItemIterator it( m_listView, QListViewItemIterator::Selected );
00098 while ( KACLListViewItem *item = dynamic_cast<KACLListViewItem*>( it.current() ) ) {
00099 ++it; ++selectedCount;
00100 if ( !item->isDeletable() )
00101 atLeastOneIsNotDeletable = true;
00102 if ( !item->isAllowedToChangeType() )
00103 atLeastOneIsNotAllowedToChangeType = true;
00104 }
00105 m_EditBtn->setEnabled( selectedCount && !atLeastOneIsNotAllowedToChangeType );
00106 m_DelBtn->setEnabled( selectedCount && !atLeastOneIsNotDeletable );
00107 }
00108
00109 KACL KACLEditWidget::getACL() const
00110 {
00111 return m_listView->getACL();
00112 }
00113
00114 KACL KACLEditWidget::getDefaultACL() const
00115 {
00116 return m_listView->getDefaultACL();
00117 }
00118
00119 void KACLEditWidget::setACL( const KACL &acl )
00120 {
00121 return m_listView->setACL( acl );
00122 }
00123
00124 void KACLEditWidget::setDefaultACL( const KACL &acl )
00125 {
00126 return m_listView->setDefaultACL( acl );
00127 }
00128
00129 void KACLEditWidget::setAllowDefaults( bool value )
00130 {
00131 m_listView->setAllowDefaults( value );
00132 }
00133
00134 void KACLEditWidget::setReadOnly( bool on )
00135 {
00136 m_listView->setEnabled( !on );
00137 m_AddBtn->setEnabled( !on );
00138 if ( !on )
00139 slotUpdateButtons();
00140 }
00141
00142 KACLListViewItem::KACLListViewItem( QListView* parent,
00143 KACLListView::EntryType _type,
00144 unsigned short _value, bool defaults,
00145 const QString& _qualifier )
00146 : KListViewItem( parent, parent->lastItem() ),
00147 type( _type ), value( _value ), isDefault( defaults ),
00148 qualifier( _qualifier ), isPartial( false )
00149 {
00150 m_pACLListView = dynamic_cast<KACLListView*>( parent );
00151 repaint();
00152 }
00153
00154
00155 KACLListViewItem::~ KACLListViewItem()
00156 {
00157
00158 }
00159
00160 QString KACLListViewItem::key( int, bool ) const
00161 {
00162 QString key;
00163 if ( !isDefault )
00164 key = "A";
00165 else
00166 key = "B";
00167 switch ( type )
00168 {
00169 case KACLListView::User:
00170 key += "A";
00171 break;
00172 case KACLListView::Group:
00173 key += "B";
00174 break;
00175 case KACLListView::Others:
00176 key += "C";
00177 break;
00178 case KACLListView::Mask:
00179 key += "D";
00180 break;
00181 case KACLListView::NamedUser:
00182 key += "E" + text( 1 );
00183 break;
00184 case KACLListView::NamedGroup:
00185 key += "F" + text( 1 );
00186 break;
00187 default:
00188 key += text( 0 );
00189 break;
00190 }
00191 return key;
00192 }
00193
00194 void KACLListViewItem::paintCell( QPainter* p, const QColorGroup &cg,
00195 int column, int width, int alignment )
00196 {
00197 QColorGroup mycg = cg;
00198 if ( isDefault ) {
00199 mycg.setColor( QColorGroup::Text, QColor( 0, 0, 255 ) );
00200 }
00201 if ( isPartial ) {
00202 QFont font = p->font();
00203 font.setItalic( true );
00204 mycg.setColor( QColorGroup::Text, QColor( 100, 100, 100 ) );
00205 p->setFont( font );
00206 }
00207 KListViewItem::paintCell( p, mycg, column, width, alignment );
00208
00209 KACLListViewItem *below =0;
00210 if ( itemBelow() )
00211 below = static_cast<KACLListViewItem*>( itemBelow() );
00212 const bool lastUser = type == KACLListView::NamedUser && below && below->type == KACLListView::NamedGroup;
00213 const bool lastNonDefault = !isDefault && below && below->isDefault;
00214 if ( type == KACLListView::Mask || lastUser || lastNonDefault )
00215 {
00216 p->setPen( QPen( Qt::gray, 0, QPen::DotLine ) );
00217 if ( type == KACLListView::Mask )
00218 p->drawLine( 0, 0, width - 1, 0 );
00219 p->drawLine( 0, height() - 1, width - 1, height() - 1 );
00220 }
00221 }
00222
00223
00224 void KACLListViewItem::updatePermPixmaps()
00225 {
00226 unsigned int partialPerms = value;
00227
00228 if ( value & ACL_READ )
00229 setPixmap( 2, m_pACLListView->getYesPixmap() );
00230 else if ( partialPerms & ACL_READ )
00231 setPixmap( 2, m_pACLListView->getYesPartialPixmap() );
00232 else
00233 setPixmap( 2, QPixmap() );
00234
00235 if ( value & ACL_WRITE )
00236 setPixmap( 3, m_pACLListView->getYesPixmap() );
00237 else if ( partialPerms & ACL_WRITE )
00238 setPixmap( 3, m_pACLListView->getYesPartialPixmap() );
00239 else
00240 setPixmap( 3, QPixmap() );
00241
00242 if ( value & ACL_EXECUTE )
00243 setPixmap( 4, m_pACLListView->getYesPixmap() );
00244 else if ( partialPerms & ACL_EXECUTE )
00245 setPixmap( 4, m_pACLListView->getYesPartialPixmap() );
00246 else
00247 setPixmap( 4, QPixmap() );
00248 }
00249
00250 void KACLListViewItem::repaint()
00251 {
00252 int idx = 0;
00253 switch ( type )
00254 {
00255 case KACLListView::User:
00256 idx = KACLListView::OWNER_IDX;
00257 break;
00258 case KACLListView::Group:
00259 idx = KACLListView::GROUP_IDX;
00260 break;
00261 case KACLListView::Others:
00262 idx = KACLListView::OTHERS_IDX;
00263 break;
00264 case KACLListView::Mask:
00265 idx = KACLListView::MASK_IDX;
00266 break;
00267 case KACLListView::NamedUser:
00268 idx = KACLListView::NAMED_USER_IDX;
00269 break;
00270 case KACLListView::NamedGroup:
00271 idx = KACLListView::NAMED_GROUP_IDX;
00272 break;
00273 default:
00274 idx = KACLListView::OWNER_IDX;
00275 break;
00276 }
00277 setText( 0, i18n(s_itemAttributes[idx].label) );
00278 setPixmap( 0, *s_itemAttributes[idx].pixmap );
00279 if ( isDefault )
00280 setText( 0, text( 0 ) + i18n( " (Default)" ) );
00281 setText( 1, qualifier );
00282
00283 updatePermPixmaps();
00284 }
00285
00286 void KACLListViewItem::calcEffectiveRights()
00287 {
00288 QString strEffective = QString( "---" );
00289
00290
00291
00292 if ( m_pACLListView->hasMaskEntry()
00293 && ( type == KACLListView::NamedUser
00294 || type == KACLListView::Group
00295 || type == KACLListView::NamedGroup )
00296 && !isDefault )
00297 {
00298
00299 strEffective[0] = ( m_pACLListView->maskPermissions() & value & ACL_READ ) ? 'r' : '-';
00300 strEffective[1] = ( m_pACLListView->maskPermissions() & value & ACL_WRITE ) ? 'w' : '-';
00301 strEffective[2] = ( m_pACLListView->maskPermissions() & value & ACL_EXECUTE ) ? 'x' : '-';
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 }
00318 else
00319 {
00320
00321 strEffective[0] = ( value & ACL_READ ) ? 'r' : '-';
00322 strEffective[1] = ( value & ACL_WRITE ) ? 'w' : '-';
00323 strEffective[2] = ( value & ACL_EXECUTE ) ? 'x' : '-';
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 }
00335 setText( 5, strEffective );
00336 }
00337
00338 bool KACLListViewItem::isDeletable() const
00339 {
00340 bool isMaskAndDeletable = false;
00341 if (type == KACLListView::Mask ) {
00342 if ( !isDefault && m_pACLListView->maskCanBeDeleted() )
00343 isMaskAndDeletable = true;
00344 else if ( isDefault && m_pACLListView->defaultMaskCanBeDeleted() )
00345 isMaskAndDeletable = true;
00346 }
00347 return type != KACLListView::User &&
00348 type != KACLListView::Group &&
00349 type != KACLListView::Others &&
00350 ( type != KACLListView::Mask || isMaskAndDeletable );
00351 }
00352
00353 bool KACLListViewItem::isAllowedToChangeType() const
00354 {
00355 return type != KACLListView::User &&
00356 type != KACLListView::Group &&
00357 type != KACLListView::Others &&
00358 type != KACLListView::Mask;
00359 }
00360
00361 void KACLListViewItem::togglePerm( acl_perm_t perm )
00362 {
00363 value ^= perm;
00364 if ( type == KACLListView::Mask && !isDefault ) {
00365 m_pACLListView->setMaskPermissions( value );
00366 }
00367 calcEffectiveRights();
00368 updatePermPixmaps();
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 }
00386
00387
00388
00389 EditACLEntryDialog::EditACLEntryDialog( KACLListView *listView, KACLListViewItem *item,
00390 const QStringList &users,
00391 const QStringList &groups,
00392 const QStringList &defaultUsers,
00393 const QStringList &defaultGroups,
00394 int allowedTypes, int allowedDefaultTypes,
00395 bool allowDefaults )
00396 : KDialogBase( listView, "edit_entry_dialog", true,
00397 i18n( "Edit ACL Entry" ), KDialogBase::Ok|KDialogBase::Cancel,
00398 KDialogBase::Ok, false ),
00399 m_listView( listView ), m_item( item ), m_users( users ), m_groups( groups ),
00400 m_defaultUsers( defaultUsers ), m_defaultGroups( defaultGroups ),
00401 m_allowedTypes( allowedTypes ), m_allowedDefaultTypes( allowedDefaultTypes ),
00402 m_defaultCB( 0 )
00403 {
00404 QWidget *page = new QWidget( this );
00405 setMainWidget( page );
00406 QVBoxLayout *mainLayout = new QVBoxLayout( page, 0, spacingHint(), "mainLayout" );
00407 m_buttonGroup = new QVButtonGroup( i18n("Entry Type"), page, "bg" );
00408
00409 if ( allowDefaults ) {
00410 m_defaultCB = new QCheckBox( i18n("Default for new files in this folder"), page, "defaultCB" );
00411 mainLayout->addWidget( m_defaultCB );
00412 connect( m_defaultCB, SIGNAL( toggled( bool ) ),
00413 this, SLOT( slotUpdateAllowedUsersAndGroups() ) );
00414 connect( m_defaultCB, SIGNAL( toggled( bool ) ),
00415 this, SLOT( slotUpdateAllowedTypes() ) );
00416
00417 }
00418
00419 mainLayout->addWidget( m_buttonGroup );
00420
00421 QRadioButton *ownerType = new QRadioButton( i18n("Owner"), m_buttonGroup, "ownerType" );
00422 m_buttonGroup->insert( ownerType, KACLListView::User );
00423 QRadioButton *owningGroupType = new QRadioButton( i18n("Owning Group"), m_buttonGroup, "owningGroupType" );
00424 m_buttonGroup->insert( owningGroupType, KACLListView::Group );
00425 QRadioButton *othersType = new QRadioButton( i18n("Others"), m_buttonGroup, "othersType" );
00426 m_buttonGroup->insert( othersType, KACLListView::Others );
00427 QRadioButton *maskType = new QRadioButton( i18n("Mask"), m_buttonGroup, "maskType" );
00428 m_buttonGroup->insert( maskType, KACLListView::Mask );
00429 QRadioButton *namedUserType = new QRadioButton( i18n("Named User"), m_buttonGroup, "namesUserType" );
00430 m_buttonGroup->insert( namedUserType, KACLListView::NamedUser );
00431 QRadioButton *namedGroupType = new QRadioButton( i18n("Named Group"), m_buttonGroup, "namedGroupType" );
00432 m_buttonGroup->insert( namedGroupType, KACLListView::NamedGroup );
00433
00434 connect( m_buttonGroup, SIGNAL( clicked( int ) ),
00435 this, SLOT( slotSelectionChanged( int ) ) );
00436
00437 m_widgetStack = new QWidgetStack( page );
00438 mainLayout->addWidget( m_widgetStack );
00439
00440 QHBox *usersBox = new QHBox( m_widgetStack );
00441 m_widgetStack->addWidget( usersBox, KACLListView::NamedUser );
00442
00443 QHBox *groupsBox = new QHBox( m_widgetStack );
00444 m_widgetStack->addWidget( groupsBox, KACLListView::NamedGroup );
00445
00446 QLabel *usersLabel = new QLabel( i18n( "User: " ), usersBox );
00447 m_usersCombo = new QComboBox( false, usersBox, "users" );
00448 usersLabel->setBuddy( m_usersCombo );
00449
00450 QLabel *groupsLabel = new QLabel( i18n( "Group: " ), groupsBox );
00451 m_groupsCombo = new QComboBox( false, groupsBox, "groups" );
00452 groupsLabel->setBuddy( m_groupsCombo );
00453
00454 if ( m_item ) {
00455 m_buttonGroup->setButton( m_item->type );
00456 if ( m_defaultCB )
00457 m_defaultCB->setChecked( m_item->isDefault );
00458 slotUpdateAllowedTypes();
00459 slotSelectionChanged( m_item->type );
00460 slotUpdateAllowedUsersAndGroups();
00461 if ( m_item->type == KACLListView::NamedUser ) {
00462 m_usersCombo->setCurrentText( m_item->qualifier );
00463 } else if ( m_item->type == KACLListView::NamedGroup ) {
00464 m_groupsCombo->setCurrentText( m_item->qualifier );
00465 }
00466 } else {
00467
00468 m_buttonGroup->setButton( KACLListView::NamedUser );
00469 slotUpdateAllowedTypes();
00470 slotSelectionChanged( KACLListView::NamedUser );
00471 slotUpdateAllowedUsersAndGroups();
00472 }
00473 incInitialSize( QSize( 100, 0 ) );
00474 }
00475
00476 void EditACLEntryDialog::slotUpdateAllowedTypes()
00477 {
00478 int allowedTypes = m_allowedTypes;
00479 if ( m_defaultCB && m_defaultCB->isChecked() ) {
00480 allowedTypes = m_allowedDefaultTypes;
00481 }
00482 for ( int i=1; i < KACLListView::AllTypes; i=i*2 ) {
00483 if ( allowedTypes & i )
00484 m_buttonGroup->find( i )->show();
00485 else
00486 m_buttonGroup->find( i )->hide();
00487 }
00488 }
00489
00490 void EditACLEntryDialog::slotUpdateAllowedUsersAndGroups()
00491 {
00492 const QString oldUser = m_usersCombo->currentText();
00493 const QString oldGroup = m_groupsCombo->currentText();
00494 m_usersCombo->clear();
00495 m_groupsCombo->clear();
00496 if ( m_defaultCB && m_defaultCB->isChecked() ) {
00497 m_usersCombo->insertStringList( m_defaultUsers );
00498 if ( m_defaultUsers.find( oldUser ) != m_defaultUsers.end() )
00499 m_usersCombo->setCurrentText( oldUser );
00500 m_groupsCombo->insertStringList( m_defaultGroups );
00501 if ( m_defaultGroups.find( oldGroup ) != m_defaultGroups.end() )
00502 m_groupsCombo->setCurrentText( oldGroup );
00503 } else {
00504 m_usersCombo->insertStringList( m_users );
00505 if ( m_users.find( oldUser ) != m_users.end() )
00506 m_usersCombo->setCurrentText( oldUser );
00507 m_groupsCombo->insertStringList( m_groups );
00508 if ( m_groups.find( oldGroup ) != m_groups.end() )
00509 m_groupsCombo->setCurrentText( oldGroup );
00510 }
00511 }
00512 void EditACLEntryDialog::slotOk()
00513 {
00514 KACLListView::EntryType type = static_cast<KACLListView::EntryType>( m_buttonGroup->selectedId() );
00515
00516 QString qualifier;
00517 if ( type == KACLListView::NamedUser )
00518 qualifier = m_usersCombo->currentText();
00519 if ( type == KACLListView::NamedGroup )
00520 qualifier = m_groupsCombo->currentText();
00521
00522 if ( !m_item ) {
00523 m_item = new KACLListViewItem( m_listView, type, ACL_READ | ACL_WRITE | ACL_EXECUTE, false, qualifier );
00524 } else {
00525 m_item->type = type;
00526 m_item->qualifier = qualifier;
00527 }
00528 if ( m_defaultCB )
00529 m_item->isDefault = m_defaultCB->isChecked();
00530 m_item->repaint();
00531
00532 KDialogBase::slotOk();
00533 }
00534
00535 void EditACLEntryDialog::slotSelectionChanged( int id )
00536 {
00537 switch ( id ) {
00538 case KACLListView::User:
00539 case KACLListView::Group:
00540 case KACLListView::Others:
00541 case KACLListView::Mask:
00542 m_widgetStack->setEnabled( false );
00543 break;
00544 case KACLListView::NamedUser:
00545 m_widgetStack->setEnabled( true );
00546 m_widgetStack->raiseWidget( KACLListView::NamedUser );
00547 break;
00548 case KACLListView::NamedGroup:
00549 m_widgetStack->setEnabled( true );
00550 m_widgetStack->raiseWidget( KACLListView::NamedGroup );
00551 break;
00552 default:
00553 break;
00554 }
00555 }
00556
00557
00558 KACLListView::KACLListView( QWidget* parent, const char* name )
00559 : KListView( parent, name ),
00560 m_hasMask( false ), m_allowDefaults( false )
00561 {
00562
00563 addColumn( i18n( "Type" ) );
00564 addColumn( i18n( "Name" ) );
00565 addColumn( i18n( "read permission", "r" ) );
00566 addColumn( i18n( "write permission", "w" ) );
00567 addColumn( i18n( "execute permission", "x" ) );
00568 addColumn( i18n( "Effective" ) );
00569
00570 header()->setClickEnabled( false );
00571
00572
00573 for ( int i=0; i < LAST_IDX; ++i ) {
00574 s_itemAttributes[i].pixmap = new QPixmap( qembed_findImage( s_itemAttributes[i].pixmapName ) );
00575 }
00576 m_yesPixmap = new QPixmap( qembed_findImage( "yes" ) );
00577 m_yesPartialPixmap = new QPixmap( qembed_findImage( "yespartial" ) );
00578
00579 setSelectionMode( QListView::Extended );
00580
00581
00582 struct passwd *user = 0;
00583 setpwent();
00584 while ( ( user = getpwent() ) != 0 ) {
00585 m_allUsers << QString::fromLatin1( user->pw_name );
00586 }
00587 endpwent();
00588
00589 struct group *gr = 0;
00590 setgrent();
00591 while ( ( gr = getgrent() ) != 0 ) {
00592 m_allGroups << QString::fromLatin1( gr->gr_name );
00593 }
00594 endgrent();
00595 m_allUsers.sort();
00596 m_allGroups.sort();
00597 }
00598
00599
00600 KACLListView::~KACLListView()
00601 {
00602 for ( int i=0; i < LAST_IDX; ++i ) {
00603 delete s_itemAttributes[i].pixmap;
00604 }
00605 delete m_yesPixmap;
00606 delete m_yesPartialPixmap;
00607 }
00608
00609 QStringList KACLListView::allowedUsers( bool defaults, KACLListViewItem *allowedItem )
00610 {
00611 QStringList allowedUsers = m_allUsers;
00612 QListViewItemIterator it( this );
00613 while ( it.current() ) {
00614 const KACLListViewItem *item = static_cast<const KACLListViewItem*>( *it );
00615 ++it;
00616 if ( !item->type == NamedUser || item->isDefault != defaults ) continue;
00617 if ( allowedItem && item == allowedItem && allowedItem->isDefault == defaults ) continue;
00618 allowedUsers.remove( item->qualifier );
00619 }
00620 return allowedUsers;
00621 }
00622
00623 QStringList KACLListView::allowedGroups( bool defaults, KACLListViewItem *allowedItem )
00624 {
00625 QStringList allowedGroups = m_allGroups;
00626 QListViewItemIterator it( this );
00627 while ( it.current() ) {
00628 const KACLListViewItem *item = static_cast<const KACLListViewItem*>( *it );
00629 ++it;
00630 if ( !item->type == NamedGroup || item->isDefault != defaults ) continue;
00631 if ( allowedItem && item == allowedItem && allowedItem->isDefault == defaults ) continue;
00632 allowedGroups.remove( item->qualifier );
00633 }
00634 return allowedGroups;
00635 }
00636
00637 void KACLListView::fillItemsFromACL( const KACL &pACL, bool defaults )
00638 {
00639
00640 QListViewItemIterator it( this );
00641 while ( KACLListViewItem *item = static_cast<KACLListViewItem*>( it.current() ) ) {
00642 ++it;
00643 if ( item->isDefault == defaults )
00644 delete item;
00645 }
00646 KACLListViewItem *item =
00647 new KACLListViewItem( this, User, pACL.ownerPermissions(), defaults );
00648
00649 item = new KACLListViewItem( this, Group, pACL.owningGroupPermissions(), defaults );
00650
00651 item = new KACLListViewItem( this, Others, pACL.othersPermissions(), defaults );
00652
00653 bool hasMask = false;
00654 unsigned short mask = pACL.maskPermissions( hasMask );
00655 if ( hasMask ) {
00656 item = new KACLListViewItem( this, Mask, mask, defaults );
00657 }
00658
00659
00660 const ACLUserPermissionsList &userList = pACL.allUserPermissions();
00661 ACLUserPermissionsConstIterator itu = userList.begin();
00662 while ( itu != userList.end() ) {
00663 new KACLListViewItem( this, NamedUser, (*itu).second, defaults, (*itu).first );
00664 ++itu;
00665 }
00666
00667
00668 const ACLUserPermissionsList &groupList = pACL.allGroupPermissions();
00669 ACLUserPermissionsConstIterator itg = groupList.begin();
00670 while ( itg != groupList.end() ) {
00671 new KACLListViewItem( this, NamedGroup, (*itg).second, defaults, (*itg).first );
00672 ++itg;
00673 }
00674 }
00675
00676 void KACLListView::setACL( const KACL &acl )
00677 {
00678 if ( !acl.isValid() ) return;
00679
00680 m_ACL = acl;
00681 fillItemsFromACL( m_ACL );
00682
00683 m_mask = acl.maskPermissions( m_hasMask );
00684 calculateEffectiveRights();
00685 }
00686
00687 void KACLListView::setDefaultACL( const KACL &acl )
00688 {
00689 if ( !acl.isValid() ) return;
00690 m_defaultACL = acl;
00691 fillItemsFromACL( m_defaultACL, true );
00692 calculateEffectiveRights();
00693 }
00694
00695 KACL KACLListView::itemsToACL( bool defaults ) const
00696 {
00697 KACL newACL( 0 );
00698 bool atLeastOneEntry = false;
00699 ACLUserPermissionsList users;
00700 ACLGroupPermissionsList groups;
00701 QListViewItemIterator it( const_cast<KACLListView*>( this ) );
00702 while ( QListViewItem* qlvi = it.current() ) {
00703 ++it;
00704 const KACLListViewItem* item = static_cast<KACLListViewItem*>( qlvi );
00705 if ( item->isDefault != defaults ) continue;
00706 atLeastOneEntry = true;
00707 switch ( item->type ) {
00708 case User:
00709 newACL.setOwnerPermissions( item->value );
00710 break;
00711 case Group:
00712 newACL.setOwningGroupPermissions( item->value );
00713 break;
00714 case Others:
00715 newACL.setOthersPermissions( item->value );
00716 break;
00717 case Mask:
00718 newACL.setMaskPermissions( item->value );
00719 break;
00720 case NamedUser:
00721 users.append( qMakePair( item->text( 1 ), item->value ) );
00722 break;
00723 case NamedGroup:
00724 groups.append( qMakePair( item->text( 1 ), item->value ) );
00725 break;
00726 default:
00727 break;
00728 }
00729 }
00730 if ( atLeastOneEntry ) {
00731 newACL.setAllUserPermissions( users );
00732 newACL.setAllGroupPermissions( groups );
00733 if ( newACL.isValid() )
00734 return newACL;
00735 }
00736 return KACL();
00737 }
00738
00739 KACL KACLListView::getACL()
00740 {
00741 return itemsToACL( false );
00742 }
00743
00744
00745 KACL KACLListView::getDefaultACL()
00746 {
00747 return itemsToACL( true );
00748 }
00749
00750 void KACLListView::contentsMousePressEvent( QMouseEvent * e )
00751 {
00752 QListViewItem *clickedItem = itemAt( contentsToViewport( e->pos() ) );
00753 if ( !clickedItem ) return;
00754
00755 if ( !clickedItem->isSelected() )
00756 KListView::contentsMousePressEvent( e );
00757
00758 if ( !currentItem() ) return;
00759 int column = header()->sectionAt( e->x() );
00760 acl_perm_t perm;
00761 switch ( column )
00762 {
00763 case 2:
00764 perm = ACL_READ;
00765 break;
00766 case 3:
00767 perm = ACL_WRITE;
00768 break;
00769 case 4:
00770 perm = ACL_EXECUTE;
00771 break;
00772 default:
00773 return KListView::contentsMousePressEvent( e );
00774 }
00775 KACLListViewItem* referenceItem = static_cast<KACLListViewItem*>( clickedItem );
00776 unsigned short referenceHadItSet = referenceItem->value & perm;
00777 QListViewItemIterator it( this );
00778 while ( KACLListViewItem* item = static_cast<KACLListViewItem*>( it.current() ) ) {
00779 ++it;
00780 if ( !item->isSelected() ) continue;
00781
00782 if ( referenceHadItSet == ( item->value & perm ) )
00783 item->togglePerm( perm );
00784 }
00785 }
00786
00787 void KACLListView::entryClicked( QListViewItem* pItem, const QPoint& , int col )
00788 {
00789 if ( !pItem ) return;
00790
00791 QListViewItemIterator it( this );
00792 while ( KACLListViewItem* item = static_cast<KACLListViewItem*>( it.current() ) ) {
00793 ++it;
00794 if ( !item->isSelected() ) continue;
00795 switch ( col )
00796 {
00797 case 2:
00798 item->togglePerm( ACL_READ );
00799 break;
00800 case 3:
00801 item->togglePerm( ACL_WRITE );
00802 break;
00803 case 4:
00804 item->togglePerm( ACL_EXECUTE );
00805 break;
00806
00807 default:
00808 ;
00809 }
00810 }
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833 }
00834
00835
00836 void KACLListView::calculateEffectiveRights()
00837 {
00838 QListViewItemIterator it( this );
00839 KACLListViewItem* pItem;
00840 while ( ( pItem = dynamic_cast<KACLListViewItem*>( it.current() ) ) != 0 )
00841 {
00842 ++it;
00843 pItem->calcEffectiveRights();
00844 }
00845 }
00846
00847
00848 unsigned short KACLListView::maskPermissions() const
00849 {
00850 return m_mask;
00851 }
00852
00853
00854 void KACLListView::setMaskPermissions( unsigned short maskPerms )
00855 {
00856 m_mask = maskPerms;
00857 calculateEffectiveRights();
00858 }
00859
00860
00861 acl_perm_t KACLListView::maskPartialPermissions() const
00862 {
00863
00864 return 0;
00865 }
00866
00867
00868 void KACLListView::setMaskPartialPermissions( acl_perm_t )
00869 {
00870
00871 calculateEffectiveRights();
00872 }
00873
00874 bool KACLListView::hasDefaultEntries() const
00875 {
00876 QListViewItemIterator it( const_cast<KACLListView*>( this ) );
00877 while ( it.current() ) {
00878 const KACLListViewItem *item = static_cast<const KACLListViewItem*>( it.current() );
00879 ++it;
00880 if ( item->isDefault ) return true;
00881 }
00882 return false;
00883 }
00884
00885 const KACLListViewItem* KACLListView::findDefaultItemByType( EntryType type ) const
00886 {
00887 return findItemByType( type, true );
00888 }
00889
00890 const KACLListViewItem* KACLListView::findItemByType( EntryType type, bool defaults ) const
00891 {
00892 QListViewItemIterator it( const_cast<KACLListView*>( this ) );
00893 while ( it.current() ) {
00894 const KACLListViewItem *item = static_cast<const KACLListViewItem*>( it.current() );
00895 ++it;
00896 if ( item->isDefault == defaults && item->type == type ) {
00897 return item;
00898 }
00899 }
00900 return 0;
00901 }
00902
00903
00904 unsigned short KACLListView::calculateMaskValue( bool defaults ) const
00905 {
00906
00907 bool dummy;
00908 return itemsToACL( defaults ).maskPermissions( dummy );
00909 }
00910
00911 void KACLListView::slotAddEntry()
00912 {
00913 int allowedTypes = NamedUser | NamedGroup;
00914 if ( !m_hasMask )
00915 allowedTypes |= Mask;
00916 int allowedDefaultTypes = NamedUser | NamedGroup;
00917 if ( !findDefaultItemByType( Mask ) )
00918 allowedDefaultTypes |= Mask;
00919 if ( !hasDefaultEntries() )
00920 allowedDefaultTypes |= User | Group;
00921 EditACLEntryDialog dlg( this, 0,
00922 allowedUsers( false ), allowedGroups( false ),
00923 allowedUsers( true ), allowedGroups( true ),
00924 allowedTypes, allowedDefaultTypes, m_allowDefaults );
00925 dlg.exec();
00926 KACLListViewItem *item = dlg.item();
00927 if ( !item ) return;
00928 if ( item->type == Mask && !item->isDefault ) {
00929 m_hasMask = true;
00930 m_mask = item->value;
00931 }
00932 if ( item->isDefault && !hasDefaultEntries() ) {
00933
00934 if ( item->type != User ) {
00935 unsigned short v = findDefaultItemByType( User )->value;
00936 new KACLListViewItem( this, User, v, true );
00937 }
00938 if ( item->type != Group ) {
00939 unsigned short v = findDefaultItemByType( Group )->value;
00940 new KACLListViewItem( this, Group, v, true );
00941 }
00942 if ( item->type != Others ) {
00943 unsigned short v = findDefaultItemByType( Others )->value;
00944 new KACLListViewItem( this, Others, v, true );
00945 }
00946 }
00947 const KACLListViewItem *defaultMaskItem = findDefaultItemByType( Mask );
00948 if ( item->isDefault && !defaultMaskItem ) {
00949 unsigned short v = calculateMaskValue( true );
00950 new KACLListViewItem( this, Mask, v, true );
00951 }
00952 if ( !item->isDefault && !m_hasMask &&
00953 ( item->type == Group
00954 || item->type == NamedUser
00955 || item->type == NamedGroup ) ) {
00956
00957 unsigned short v = calculateMaskValue( false );
00958 new KACLListViewItem( this, Mask, v, false );
00959 m_hasMask = true;
00960 m_mask = v;
00961 }
00962 calculateEffectiveRights();
00963 sort();
00964 setCurrentItem( item );
00965
00966
00967 if ( childCount() == 1 )
00968 emit currentChanged( item );
00969 }
00970
00971 void KACLListView::slotEditEntry()
00972 {
00973 QListViewItem * current = currentItem();
00974 if ( !current ) return;
00975 KACLListViewItem *item = static_cast<KACLListViewItem*>( current );
00976 int allowedTypes = item->type | NamedUser | NamedGroup;
00977 bool itemWasMask = item->type == Mask;
00978 if ( !m_hasMask || itemWasMask )
00979 allowedTypes |= Mask;
00980 int allowedDefaultTypes = item->type | NamedUser | NamedGroup;
00981 if ( !findDefaultItemByType( Mask ) )
00982 allowedDefaultTypes |= Mask;
00983 if ( !hasDefaultEntries() )
00984 allowedDefaultTypes |= User | Group;
00985
00986 EditACLEntryDialog dlg( this, item,
00987 allowedUsers( false, item ), allowedGroups( false, item ),
00988 allowedUsers( true, item ), allowedGroups( true, item ),
00989 allowedTypes, allowedDefaultTypes, m_allowDefaults );
00990 dlg.exec();
00991 if ( itemWasMask && item->type != Mask ) {
00992 m_hasMask = false;
00993 m_mask = 0;
00994 }
00995 if ( !itemWasMask && item->type == Mask ) {
00996 m_mask = item->value;
00997 m_hasMask = true;
00998 }
00999 calculateEffectiveRights();
01000 sort();
01001 }
01002
01003 void KACLListView::slotRemoveEntry()
01004 {
01005 QListViewItemIterator it( this, QListViewItemIterator::Selected );
01006 while ( it.current() ) {
01007 KACLListViewItem *item = static_cast<KACLListViewItem*>( it.current() );
01008 ++it;
01009
01010
01011
01012 if ( item->type == Mask ) {
01013 bool itemWasDefault = item->isDefault;
01014 if ( !itemWasDefault && maskCanBeDeleted() ) {
01015 m_hasMask= false;
01016 m_mask = 0;
01017 delete item;
01018 } else if ( itemWasDefault && defaultMaskCanBeDeleted() ) {
01019 delete item;
01020 } else {
01021 item->value = 0;
01022 item->repaint();
01023 }
01024 if ( !itemWasDefault )
01025 calculateEffectiveRights();
01026 } else {
01027
01028 if ( !item->isDefault &&
01029 ( item->type == User
01030 || item->type == Group
01031 || item->type == Others ) ) {
01032 item->value = 0;
01033 item->repaint();
01034 } else {
01035 delete item;
01036 }
01037 }
01038 }
01039 }
01040
01041 bool KACLListView::maskCanBeDeleted() const
01042 {
01043 return !findItemByType( NamedUser ) && !findItemByType( NamedGroup );
01044 }
01045
01046 bool KACLListView::defaultMaskCanBeDeleted() const
01047 {
01048 return !findDefaultItemByType( NamedUser ) && !findDefaultItemByType( NamedGroup );
01049 }
01050
01051 #include "kacleditwidget.moc"
01052 #include "kacleditwidget_p.moc"
01053 #endif
01054