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