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