• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeio/tdefile
 

tdeio/tdefile

  • tdeio
  • tdefile
kacleditwidget.cpp
1 /***************************************************************************
2  * Copyright (C) 2005 by Sean Harmer <sh@rama.homelinux.org> *
3  * Till Adam <adam@kde.org> *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU Library General Public License as *
7  * published by the Free Software Foundation; either version 2 of the *
8  * License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19  ***************************************************************************/
20 
21 
22 #include "kacleditwidget.h"
23 #include "kacleditwidget_p.h"
24 
25 #ifdef USE_POSIX_ACL
26 
27 #include <tqpainter.h>
28 #include <tqptrlist.h>
29 #include <tqvbox.h>
30 #include <tqhbox.h>
31 #include <tqpushbutton.h>
32 #include <tqvbuttongroup.h>
33 #include <tqradiobutton.h>
34 #include <tqcombobox.h>
35 #include <tqlabel.h>
36 #include <tqcheckbox.h>
37 #include <tqlayout.h>
38 #include <tqwidgetstack.h>
39 #include <tqheader.h>
40 
41 #include <tdelocale.h>
42 #include <tdefileitem.h>
43 #include <kdebug.h>
44 #include <kdialog.h>
45 #include <kdialogbase.h>
46 
47 #ifdef HAVE_ACL_LIBACL_H
48 # include <acl/libacl.h>
49 #endif
50 extern "C" {
51 #include <pwd.h>
52 #include <grp.h>
53 }
54 #include <assert.h>
55 
56 #include "images.h"
57 
58 static struct {
59  const char* label;
60  const char* pixmapName;
61  TQPixmap* pixmap;
62 } s_itemAttributes[] = {
63  { I18N_NOOP( "Owner" ), "user-grey", 0 },
64  { I18N_NOOP( "Owning Group" ), "group-grey", 0 },
65  { I18N_NOOP( "Others" ), "others-grey", 0 },
66  { I18N_NOOP( "Mask" ), "mask", 0 },
67  { I18N_NOOP( "Named User" ), "user", 0 },
68  { I18N_NOOP( "Named Group" ), "group", 0 },
69 };
70 
71 KACLEditWidget::KACLEditWidget( TQWidget *parent, const char *name )
72  :TQWidget( parent, name )
73 {
74  TQHBox *hbox = new TQHBox( parent );
75  hbox->setSpacing( KDialog::spacingHint() );
76  m_listView = new KACLListView( hbox, "acl_listview" );
77  connect( m_listView, TQ_SIGNAL( selectionChanged() ),
78  this, TQ_SLOT( slotUpdateButtons() ) );
79  TQVBox *vbox = new TQVBox( hbox );
80  vbox->setSpacing( KDialog::spacingHint() );
81  m_AddBtn = new TQPushButton( i18n( "Add Entry..." ), vbox, "add_entry_button" );
82  connect( m_AddBtn, TQ_SIGNAL( clicked() ), m_listView, TQ_SLOT( slotAddEntry() ) );
83  m_EditBtn = new TQPushButton( i18n( "Edit Entry..." ), vbox, "edit_entry_button" );
84  connect( m_EditBtn, TQ_SIGNAL( clicked() ), m_listView, TQ_SLOT( slotEditEntry() ) );
85  m_DelBtn = new TQPushButton( i18n( "Delete Entry" ), vbox, "delete_entry_button" );
86  connect( m_DelBtn, TQ_SIGNAL( clicked() ), m_listView, TQ_SLOT( slotRemoveEntry() ) );
87  TQWidget *spacer = new TQWidget( vbox );
88  spacer->setSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Expanding );
89  slotUpdateButtons();
90 }
91 
92 void KACLEditWidget::slotUpdateButtons()
93 {
94  bool atLeastOneIsNotDeletable = false;
95  bool atLeastOneIsNotAllowedToChangeType = false;
96  int selectedCount = 0;
97  TQListViewItemIterator it( m_listView, TQListViewItemIterator::Selected );
98  while ( KACLListViewItem *item = dynamic_cast<KACLListViewItem*>( it.current() ) ) {
99  ++it; ++selectedCount;
100  if ( !item->isDeletable() )
101  atLeastOneIsNotDeletable = true;
102  if ( !item->isAllowedToChangeType() )
103  atLeastOneIsNotAllowedToChangeType = true;
104  }
105  m_EditBtn->setEnabled( selectedCount && !atLeastOneIsNotAllowedToChangeType );
106  m_DelBtn->setEnabled( selectedCount && !atLeastOneIsNotDeletable );
107 }
108 
109 KACL KACLEditWidget::getACL() const
110 {
111  return m_listView->getACL();
112 }
113 
114 KACL KACLEditWidget::getDefaultACL() const
115 {
116  return m_listView->getDefaultACL();
117 }
118 
119 void KACLEditWidget::setACL( const KACL &acl )
120 {
121  return m_listView->setACL( acl );
122 }
123 
124 void KACLEditWidget::setDefaultACL( const KACL &acl )
125 {
126  return m_listView->setDefaultACL( acl );
127 }
128 
129 void KACLEditWidget::setAllowDefaults( bool value )
130 {
131  m_listView->setAllowDefaults( value );
132 }
133 
134 void KACLEditWidget::setReadOnly( bool on )
135 {
136  m_listView->setEnabled( !on );
137  m_AddBtn->setEnabled( !on );
138  if ( !on )
139  slotUpdateButtons();
140 }
141 
142 KACLListViewItem::KACLListViewItem( TQListView* parent,
143  KACLListView::EntryType _type,
144  unsigned short _value, bool defaults,
145  const TQString& _qualifier )
146  : TDEListViewItem( parent, parent->lastItem() ), // we want to append
147  type( _type ), value( _value ), isDefault( defaults ),
148  qualifier( _qualifier ), isPartial( false )
149 {
150  m_pACLListView = dynamic_cast<KACLListView*>( parent );
151  repaint();
152 }
153 
154 
155 KACLListViewItem::~ KACLListViewItem()
156 {
157 
158 }
159 
160 TQString KACLListViewItem::key( int, bool ) const
161 {
162  TQString key;
163  if ( !isDefault )
164  key = "A";
165  else
166  key = "B";
167  switch ( type )
168  {
169  case KACLListView::User:
170  key += "A";
171  break;
172  case KACLListView::Group:
173  key += "B";
174  break;
175  case KACLListView::Others:
176  key += "C";
177  break;
178  case KACLListView::Mask:
179  key += "D";
180  break;
181  case KACLListView::NamedUser:
182  key += "E" + text( 1 );
183  break;
184  case KACLListView::NamedGroup:
185  key += "F" + text( 1 );
186  break;
187  default:
188  key += text( 0 );
189  break;
190  }
191  return key;
192 }
193 
194 void KACLListViewItem::paintCell( TQPainter* p, const TQColorGroup &cg,
195  int column, int width, int alignment )
196 {
197  TQColorGroup mycg = cg;
198  if ( isDefault ) {
199  mycg.setColor( TQColorGroup::Text, TQColor( 0, 0, 255 ) );
200  }
201  if ( isPartial ) {
202  TQFont font = p->font();
203  font.setItalic( true );
204  mycg.setColor( TQColorGroup::Text, TQColor( 100, 100, 100 ) );
205  p->setFont( font );
206  }
207  TDEListViewItem::paintCell( p, mycg, column, width, alignment );
208 
209  KACLListViewItem *below =0;
210  if ( itemBelow() )
211  below = static_cast<KACLListViewItem*>( itemBelow() );
212  const bool lastUser = type == KACLListView::NamedUser && below && below->type == KACLListView::NamedGroup;
213  const bool lastNonDefault = !isDefault && below && below->isDefault;
214  if ( type == KACLListView::Mask || lastUser || lastNonDefault )
215  {
216  p->setPen( TQPen( TQt::gray, 0, TQPen::DotLine ) );
217  if ( type == KACLListView::Mask )
218  p->drawLine( 0, 0, width - 1, 0 );
219  p->drawLine( 0, height() - 1, width - 1, height() - 1 );
220  }
221 }
222 
223 
224 void KACLListViewItem::updatePermPixmaps()
225 {
226  unsigned int partialPerms = value;
227 
228  if ( value & ACL_READ )
229  setPixmap( 2, m_pACLListView->getYesPixmap() );
230  else if ( partialPerms & ACL_READ )
231  setPixmap( 2, m_pACLListView->getYesPartialPixmap() );
232  else
233  setPixmap( 2, TQPixmap() );
234 
235  if ( value & ACL_WRITE )
236  setPixmap( 3, m_pACLListView->getYesPixmap() );
237  else if ( partialPerms & ACL_WRITE )
238  setPixmap( 3, m_pACLListView->getYesPartialPixmap() );
239  else
240  setPixmap( 3, TQPixmap() );
241 
242  if ( value & ACL_EXECUTE )
243  setPixmap( 4, m_pACLListView->getYesPixmap() );
244  else if ( partialPerms & ACL_EXECUTE )
245  setPixmap( 4, m_pACLListView->getYesPartialPixmap() );
246  else
247  setPixmap( 4, TQPixmap() );
248 }
249 
250 void KACLListViewItem::repaint()
251 {
252  int idx = 0;
253  switch ( type )
254  {
255  case KACLListView::User:
256  idx = KACLListView::OWNER_IDX;
257  break;
258  case KACLListView::Group:
259  idx = KACLListView::GROUP_IDX;
260  break;
261  case KACLListView::Others:
262  idx = KACLListView::OTHERS_IDX;
263  break;
264  case KACLListView::Mask:
265  idx = KACLListView::MASK_IDX;
266  break;
267  case KACLListView::NamedUser:
268  idx = KACLListView::NAMED_USER_IDX;
269  break;
270  case KACLListView::NamedGroup:
271  idx = KACLListView::NAMED_GROUP_IDX;
272  break;
273  default:
274  idx = KACLListView::OWNER_IDX;
275  break;
276  }
277  setText( 0, i18n(s_itemAttributes[idx].label) );
278  setPixmap( 0, *s_itemAttributes[idx].pixmap );
279  if ( isDefault )
280  setText( 0, text( 0 ) + i18n( " (Default)" ) );
281  setText( 1, qualifier );
282  // Set the pixmaps for which of the perms are set
283  updatePermPixmaps();
284 }
285 
286 void KACLListViewItem::calcEffectiveRights()
287 {
288  TQString strEffective = TQString( "---" );
289 
290  // Do we need to worry about the mask entry? It applies to named users,
291  // owning group, and named groups
292  if ( m_pACLListView->hasMaskEntry()
293  && ( type == KACLListView::NamedUser
294  || type == KACLListView::Group
295  || type == KACLListView::NamedGroup )
296  && !isDefault )
297  {
298 
299  strEffective[0] = ( m_pACLListView->maskPermissions() & value & ACL_READ ) ? 'r' : '-';
300  strEffective[1] = ( m_pACLListView->maskPermissions() & value & ACL_WRITE ) ? 'w' : '-';
301  strEffective[2] = ( m_pACLListView->maskPermissions() & value & ACL_EXECUTE ) ? 'x' : '-';
302 /*
303  // What about any partial perms?
304  if ( maskPerms & partialPerms & ACL_READ || // Partial perms on entry
305  maskPartialPerms & perms & ACL_READ || // Partial perms on mask
306  maskPartialPerms & partialPerms & ACL_READ ) // Partial perms on mask and entry
307  strEffective[0] = 'R';
308  if ( maskPerms & partialPerms & ACL_WRITE || // Partial perms on entry
309  maskPartialPerms & perms & ACL_WRITE || // Partial perms on mask
310  maskPartialPerms & partialPerms & ACL_WRITE ) // Partial perms on mask and entry
311  strEffective[1] = 'W';
312  if ( maskPerms & partialPerms & ACL_EXECUTE || // Partial perms on entry
313  maskPartialPerms & perms & ACL_EXECUTE || // Partial perms on mask
314  maskPartialPerms & partialPerms & ACL_EXECUTE ) // Partial perms on mask and entry
315  strEffective[2] = 'X';
316 */
317  }
318  else
319  {
320  // No, the effective value are just the value in this entry
321  strEffective[0] = ( value & ACL_READ ) ? 'r' : '-';
322  strEffective[1] = ( value & ACL_WRITE ) ? 'w' : '-';
323  strEffective[2] = ( value & ACL_EXECUTE ) ? 'x' : '-';
324 
325  /*
326  // What about any partial perms?
327  if ( partialPerms & ACL_READ )
328  strEffective[0] = 'R';
329  if ( partialPerms & ACL_WRITE )
330  strEffective[1] = 'W';
331  if ( partialPerms & ACL_EXECUTE )
332  strEffective[2] = 'X';
333  */
334  }
335  setText( 5, strEffective );
336 }
337 
338 bool KACLListViewItem::isDeletable() const
339 {
340  bool isMaskAndDeletable = false;
341  if (type == KACLListView::Mask ) {
342  if ( !isDefault && m_pACLListView->maskCanBeDeleted() )
343  isMaskAndDeletable = true;
344  else if ( isDefault && m_pACLListView->defaultMaskCanBeDeleted() )
345  isMaskAndDeletable = true;
346  }
347  return type != KACLListView::User &&
348  type != KACLListView::Group &&
349  type != KACLListView::Others &&
350  ( type != KACLListView::Mask || isMaskAndDeletable );
351 }
352 
353 bool KACLListViewItem::isAllowedToChangeType() const
354 {
355  return type != KACLListView::User &&
356  type != KACLListView::Group &&
357  type != KACLListView::Others &&
358  type != KACLListView::Mask;
359 }
360 
361 void KACLListViewItem::togglePerm( acl_perm_t perm )
362 {
363  value ^= perm; // Toggle the perm
364  if ( type == KACLListView::Mask && !isDefault ) {
365  m_pACLListView->setMaskPermissions( value );
366  }
367  calcEffectiveRights();
368  updatePermPixmaps();
369 /*
370  // If the perm is in the partial perms then remove it. i.e. Once
371  // a user changes a partial perm it then applies to all selected files.
372  if ( m_pEntry->m_partialPerms & perm )
373  m_pEntry->m_partialPerms ^= perm;
374 
375  m_pEntry->setPartialEntry( false );
376  // Make sure that all entries have their effective rights calculated if
377  // we are changing the ACL_MASK entry.
378  if ( type == Mask )
379  {
380  m_pACLListView->setMaskPartialPermissions( m_pEntry->m_partialPerms );
381  m_pACLListView->setMaskPermissions( value );
382  m_pACLListView->calculateEffectiveRights();
383  }
384 */
385 }
386 
387 
388 
389 EditACLEntryDialog::EditACLEntryDialog( KACLListView *listView, KACLListViewItem *item,
390  const TQStringList &users,
391  const TQStringList &groups,
392  const TQStringList &defaultUsers,
393  const TQStringList &defaultGroups,
394  int allowedTypes, int allowedDefaultTypes,
395  bool allowDefaults )
396  : KDialogBase( listView, "edit_entry_dialog", true,
397  i18n( "Edit ACL Entry" ), KDialogBase::Ok|KDialogBase::Cancel,
398  KDialogBase::Ok, false ),
399  m_listView( listView ), m_item( item ), m_users( users ), m_groups( groups ),
400  m_defaultUsers( defaultUsers ), m_defaultGroups( defaultGroups ),
401  m_allowedTypes( allowedTypes ), m_allowedDefaultTypes( allowedDefaultTypes ),
402  m_defaultCB( 0 )
403 {
404  TQWidget *page = new TQWidget( this );
405  setMainWidget( page );
406  TQVBoxLayout *mainLayout = new TQVBoxLayout( page, 0, spacingHint(), "mainLayout" );
407  m_buttonGroup = new TQVButtonGroup( i18n("Entry Type"), page, "bg" );
408 
409  if ( allowDefaults ) {
410  m_defaultCB = new TQCheckBox( i18n("Default for new files in this folder"), page, "defaultCB" );
411  mainLayout->addWidget( m_defaultCB );
412  connect( m_defaultCB, TQ_SIGNAL( toggled( bool ) ),
413  this, TQ_SLOT( slotUpdateAllowedUsersAndGroups() ) );
414  connect( m_defaultCB, TQ_SIGNAL( toggled( bool ) ),
415  this, TQ_SLOT( slotUpdateAllowedTypes() ) );
416 
417  }
418 
419  mainLayout->addWidget( m_buttonGroup );
420 
421  TQRadioButton *ownerType = new TQRadioButton( i18n("Owner"), m_buttonGroup, "ownerType" );
422  m_buttonGroup->insert( ownerType, KACLListView::User );
423  TQRadioButton *owningGroupType = new TQRadioButton( i18n("Owning Group"), m_buttonGroup, "owningGroupType" );
424  m_buttonGroup->insert( owningGroupType, KACLListView::Group );
425  TQRadioButton *othersType = new TQRadioButton( i18n("Others"), m_buttonGroup, "othersType" );
426  m_buttonGroup->insert( othersType, KACLListView::Others );
427  TQRadioButton *maskType = new TQRadioButton( i18n("Mask"), m_buttonGroup, "maskType" );
428  m_buttonGroup->insert( maskType, KACLListView::Mask );
429  TQRadioButton *namedUserType = new TQRadioButton( i18n("Named User"), m_buttonGroup, "namesUserType" );
430  m_buttonGroup->insert( namedUserType, KACLListView::NamedUser );
431  TQRadioButton *namedGroupType = new TQRadioButton( i18n("Named Group"), m_buttonGroup, "namedGroupType" );
432  m_buttonGroup->insert( namedGroupType, KACLListView::NamedGroup );
433 
434  connect( m_buttonGroup, TQ_SIGNAL( clicked( int ) ),
435  this, TQ_SLOT( slotSelectionChanged( int ) ) );
436 
437  m_widgetStack = new TQWidgetStack( page );
438  mainLayout->addWidget( m_widgetStack );
439 
440  TQHBox *usersBox = new TQHBox( m_widgetStack );
441  m_widgetStack->addWidget( usersBox, KACLListView::NamedUser );
442 
443  TQHBox *groupsBox = new TQHBox( m_widgetStack );
444  m_widgetStack->addWidget( groupsBox, KACLListView::NamedGroup );
445 
446  TQLabel *usersLabel = new TQLabel( i18n( "User: " ), usersBox );
447  m_usersCombo = new TQComboBox( false, usersBox, "users" );
448  usersLabel->setBuddy( m_usersCombo );
449 
450  TQLabel *groupsLabel = new TQLabel( i18n( "Group: " ), groupsBox );
451  m_groupsCombo = new TQComboBox( false, groupsBox, "groups" );
452  groupsLabel->setBuddy( m_groupsCombo );
453 
454  if ( m_item ) {
455  m_buttonGroup->setButton( m_item->type );
456  if ( m_defaultCB )
457  m_defaultCB->setChecked( m_item->isDefault );
458  slotUpdateAllowedTypes();
459  slotSelectionChanged( m_item->type );
460  slotUpdateAllowedUsersAndGroups();
461  if ( m_item->type == KACLListView::NamedUser ) {
462  m_usersCombo->setCurrentText( m_item->qualifier );
463  } else if ( m_item->type == KACLListView::NamedGroup ) {
464  m_groupsCombo->setCurrentText( m_item->qualifier );
465  }
466  } else {
467  // new entry, preselect "named user", arguably the most common one
468  m_buttonGroup->setButton( KACLListView::NamedUser );
469  slotUpdateAllowedTypes();
470  slotSelectionChanged( KACLListView::NamedUser );
471  slotUpdateAllowedUsersAndGroups();
472  }
473  incInitialSize( TQSize( 100, 0 ) );
474 }
475 
476 void EditACLEntryDialog::slotUpdateAllowedTypes()
477 {
478  int allowedTypes = m_allowedTypes;
479  if ( m_defaultCB && m_defaultCB->isChecked() ) {
480  allowedTypes = m_allowedDefaultTypes;
481  }
482  for ( int i=1; i < KACLListView::AllTypes; i=i*2 ) {
483  if ( allowedTypes & i )
484  m_buttonGroup->find( i )->show();
485  else
486  m_buttonGroup->find( i )->hide();
487  }
488 }
489 
490 void EditACLEntryDialog::slotUpdateAllowedUsersAndGroups()
491 {
492  const TQString oldUser = m_usersCombo->currentText();
493  const TQString oldGroup = m_groupsCombo->currentText();
494  m_usersCombo->clear();
495  m_groupsCombo->clear();
496  if ( m_defaultCB && m_defaultCB->isChecked() ) {
497  m_usersCombo->insertStringList( m_defaultUsers );
498  if ( m_defaultUsers.find( oldUser ) != m_defaultUsers.end() )
499  m_usersCombo->setCurrentText( oldUser );
500  m_groupsCombo->insertStringList( m_defaultGroups );
501  if ( m_defaultGroups.find( oldGroup ) != m_defaultGroups.end() )
502  m_groupsCombo->setCurrentText( oldGroup );
503  } else {
504  m_usersCombo->insertStringList( m_users );
505  if ( m_users.find( oldUser ) != m_users.end() )
506  m_usersCombo->setCurrentText( oldUser );
507  m_groupsCombo->insertStringList( m_groups );
508  if ( m_groups.find( oldGroup ) != m_groups.end() )
509  m_groupsCombo->setCurrentText( oldGroup );
510  }
511 }
512 void EditACLEntryDialog::slotOk()
513 {
514  KACLListView::EntryType type = static_cast<KACLListView::EntryType>( m_buttonGroup->selectedId() );
515 
516  TQString qualifier;
517  if ( type == KACLListView::NamedUser )
518  qualifier = m_usersCombo->currentText();
519  if ( type == KACLListView::NamedGroup )
520  qualifier = m_groupsCombo->currentText();
521 
522  if ( !m_item ) {
523  m_item = new KACLListViewItem( m_listView, type, ACL_READ | ACL_WRITE | ACL_EXECUTE, false, qualifier );
524  } else {
525  m_item->type = type;
526  m_item->qualifier = qualifier;
527  }
528  if ( m_defaultCB )
529  m_item->isDefault = m_defaultCB->isChecked();
530  m_item->repaint();
531 
532  KDialogBase::slotOk();
533 }
534 
535 void EditACLEntryDialog::slotSelectionChanged( int id )
536 {
537  switch ( id ) {
538  case KACLListView::User:
539  case KACLListView::Group:
540  case KACLListView::Others:
541  case KACLListView::Mask:
542  m_widgetStack->setEnabled( false );
543  break;
544  case KACLListView::NamedUser:
545  m_widgetStack->setEnabled( true );
546  m_widgetStack->raiseWidget( KACLListView::NamedUser );
547  break;
548  case KACLListView::NamedGroup:
549  m_widgetStack->setEnabled( true );
550  m_widgetStack->raiseWidget( KACLListView::NamedGroup );
551  break;
552  default:
553  break;
554  }
555 }
556 
557 
558 KACLListView::KACLListView( TQWidget* parent, const char* name )
559  : TDEListView( parent, name ),
560  m_hasMask( false ), m_allowDefaults( false )
561 {
562  // Add the columns
563  addColumn( i18n( "Type" ) );
564  addColumn( i18n( "Name" ) );
565  addColumn( i18n( "read permission", "r" ) );
566  addColumn( i18n( "write permission", "w" ) );
567  addColumn( i18n( "execute permission", "x" ) );
568  addColumn( i18n( "Effective" ) );
569 
570  header()->setClickEnabled( false );
571 
572  // Load the avatars
573  for ( int i=0; i < LAST_IDX; ++i ) {
574  s_itemAttributes[i].pixmap = new TQPixmap( qembed_findImage( s_itemAttributes[i].pixmapName ) );
575  }
576  m_yesPixmap = new TQPixmap( qembed_findImage( "yes" ) );
577  m_yesPartialPixmap = new TQPixmap( qembed_findImage( "yespartial" ) );
578 
579  setSelectionMode( TQListView::Extended );
580 
581  // fill the lists of all legal users and groups
582  struct passwd *user = 0;
583  setpwent();
584  while ( ( user = getpwent() ) != 0 ) {
585  m_allUsers << TQString::fromLatin1( user->pw_name );
586  }
587  endpwent();
588 
589  struct group *gr = 0;
590  setgrent();
591  while ( ( gr = getgrent() ) != 0 ) {
592  m_allGroups << TQString::fromLatin1( gr->gr_name );
593  }
594  endgrent();
595  m_allUsers.sort();
596  m_allGroups.sort();
597 }
598 
599 
600 KACLListView::~KACLListView()
601 {
602  for ( int i=0; i < LAST_IDX; ++i ) {
603  delete s_itemAttributes[i].pixmap;
604  }
605  delete m_yesPixmap;
606  delete m_yesPartialPixmap;
607 }
608 
609 TQStringList KACLListView::allowedUsers( bool defaults, KACLListViewItem *allowedItem )
610 {
611  TQStringList allowedUsers = m_allUsers;
612  TQListViewItemIterator it( this );
613  while ( it.current() ) {
614  const KACLListViewItem *item = static_cast<const KACLListViewItem*>( *it );
615  ++it;
616  if ( !item->type == NamedUser || item->isDefault != defaults ) continue;
617  if ( allowedItem && item == allowedItem && allowedItem->isDefault == defaults ) continue;
618  allowedUsers.remove( item->qualifier );
619  }
620  return allowedUsers;
621 }
622 
623 TQStringList KACLListView::allowedGroups( bool defaults, KACLListViewItem *allowedItem )
624 {
625  TQStringList allowedGroups = m_allGroups;
626  TQListViewItemIterator it( this );
627  while ( it.current() ) {
628  const KACLListViewItem *item = static_cast<const KACLListViewItem*>( *it );
629  ++it;
630  if ( !item->type == NamedGroup || item->isDefault != defaults ) continue;
631  if ( allowedItem && item == allowedItem && allowedItem->isDefault == defaults ) continue;
632  allowedGroups.remove( item->qualifier );
633  }
634  return allowedGroups;
635 }
636 
637 void KACLListView::fillItemsFromACL( const KACL &pACL, bool defaults )
638 {
639  // clear out old entries of that ilk
640  TQListViewItemIterator it( this );
641  while ( KACLListViewItem *item = static_cast<KACLListViewItem*>( it.current() ) ) {
642  ++it;
643  if ( item->isDefault == defaults )
644  delete item;
645  }
646  KACLListViewItem *item =
647  new KACLListViewItem( this, User, pACL.ownerPermissions(), defaults );
648 
649  item = new KACLListViewItem( this, Group, pACL.owningGroupPermissions(), defaults );
650 
651  item = new KACLListViewItem( this, Others, pACL.othersPermissions(), defaults );
652 
653  bool hasMask = false;
654  unsigned short mask = pACL.maskPermissions( hasMask );
655  if ( hasMask ) {
656  item = new KACLListViewItem( this, Mask, mask, defaults );
657  }
658 
659  // read all named user entries
660  const ACLUserPermissionsList &userList = pACL.allUserPermissions();
661  ACLUserPermissionsConstIterator itu = userList.begin();
662  while ( itu != userList.end() ) {
663  new KACLListViewItem( this, NamedUser, (*itu).second, defaults, (*itu).first );
664  ++itu;
665  }
666 
667  // and now all named groups
668  const ACLUserPermissionsList &groupList = pACL.allGroupPermissions();
669  ACLUserPermissionsConstIterator itg = groupList.begin();
670  while ( itg != groupList.end() ) {
671  new KACLListViewItem( this, NamedGroup, (*itg).second, defaults, (*itg).first );
672  ++itg;
673  }
674 }
675 
676 void KACLListView::setACL( const KACL &acl )
677 {
678  if ( !acl.isValid() ) return;
679  // Remove any entries left over from displaying a previous ACL
680  m_ACL = acl;
681  fillItemsFromACL( m_ACL );
682 
683  m_mask = acl.maskPermissions( m_hasMask );
684  calculateEffectiveRights();
685 }
686 
687 void KACLListView::setDefaultACL( const KACL &acl )
688 {
689  if ( !acl.isValid() ) return;
690  m_defaultACL = acl;
691  fillItemsFromACL( m_defaultACL, true );
692  calculateEffectiveRights();
693 }
694 
695 KACL KACLListView::itemsToACL( bool defaults ) const
696 {
697  KACL newACL( 0 );
698  bool atLeastOneEntry = false;
699  ACLUserPermissionsList users;
700  ACLGroupPermissionsList groups;
701  TQListViewItemIterator it( const_cast<KACLListView*>( this ) );
702  while ( TQListViewItem* qlvi = it.current() ) {
703  ++it;
704  const KACLListViewItem* item = static_cast<KACLListViewItem*>( qlvi );
705  if ( item->isDefault != defaults ) continue;
706  atLeastOneEntry = true;
707  switch ( item->type ) {
708  case User:
709  newACL.setOwnerPermissions( item->value );
710  break;
711  case Group:
712  newACL.setOwningGroupPermissions( item->value );
713  break;
714  case Others:
715  newACL.setOthersPermissions( item->value );
716  break;
717  case Mask:
718  newACL.setMaskPermissions( item->value );
719  break;
720  case NamedUser:
721  users.append( qMakePair( item->text( 1 ), item->value ) );
722  break;
723  case NamedGroup:
724  groups.append( qMakePair( item->text( 1 ), item->value ) );
725  break;
726  default:
727  break;
728  }
729  }
730  if ( atLeastOneEntry ) {
731  newACL.setAllUserPermissions( users );
732  newACL.setAllGroupPermissions( groups );
733  if ( newACL.isValid() )
734  return newACL;
735  }
736  return KACL();
737 }
738 
739 KACL KACLListView::getACL()
740 {
741  return itemsToACL( false );
742 }
743 
744 
745 KACL KACLListView::getDefaultACL()
746 {
747  return itemsToACL( true );
748 }
749 
750 void KACLListView::contentsMousePressEvent( TQMouseEvent * e )
751 {
752  TQListViewItem *clickedItem = itemAt( contentsToViewport( e->pos() ) );
753  if ( !clickedItem ) return;
754  // if the click is on an as yet unselected item, select it first
755  if ( !clickedItem->isSelected() )
756  TDEListView::contentsMousePressEvent( e );
757 
758  if ( !currentItem() ) return;
759  int column = header()->sectionAt( e->x() );
760  acl_perm_t perm;
761  switch ( column )
762  {
763  case 2:
764  perm = ACL_READ;
765  break;
766  case 3:
767  perm = ACL_WRITE;
768  break;
769  case 4:
770  perm = ACL_EXECUTE;
771  break;
772  default:
773  return TDEListView::contentsMousePressEvent( e );
774  }
775  KACLListViewItem* referenceItem = static_cast<KACLListViewItem*>( clickedItem );
776  unsigned short referenceHadItSet = referenceItem->value & perm;
777  TQListViewItemIterator it( this );
778  while ( KACLListViewItem* item = static_cast<KACLListViewItem*>( it.current() ) ) {
779  ++it;
780  if ( !item->isSelected() ) continue;
781  // toggle those with the same value as the clicked item, leave the others
782  if ( referenceHadItSet == ( item->value & perm ) )
783  item->togglePerm( perm );
784  }
785 }
786 
787 void KACLListView::entryClicked( TQListViewItem* pItem, const TQPoint& /*pt*/, int col )
788 {
789  if ( !pItem ) return;
790 
791  TQListViewItemIterator it( this );
792  while ( KACLListViewItem* item = static_cast<KACLListViewItem*>( it.current() ) ) {
793  ++it;
794  if ( !item->isSelected() ) continue;
795  switch ( col )
796  {
797  case 2:
798  item->togglePerm( ACL_READ );
799  break;
800  case 3:
801  item->togglePerm( ACL_WRITE );
802  break;
803  case 4:
804  item->togglePerm( ACL_EXECUTE );
805  break;
806 
807  default:
808  ; // Do nothing
809  }
810  }
811  /*
812  // Has the user changed one of the required entries in a default ACL?
813  if ( m_pACL->aclType() == ACL_TYPE_DEFAULT &&
814  ( col == 2 || col == 3 || col == 4 ) &&
815  ( pACLItem->entryType() == ACL_USER_OBJ ||
816  pACLItem->entryType() == ACL_GROUP_OBJ ||
817  pACLItem->entryType() == ACL_OTHER ) )
818  {
819  // Mark the required entries as no longer being partial entries.
820  // That is, they will get applied to all selected directories.
821  KACLListViewItem* pUserObj = findACLEntryByType( this, ACL_USER_OBJ );
822  pUserObj->entry()->setPartialEntry( false );
823 
824  KACLListViewItem* pGroupObj = findACLEntryByType( this, ACL_GROUP_OBJ );
825  pGroupObj->entry()->setPartialEntry( false );
826 
827  KACLListViewItem* pOther = findACLEntryByType( this, ACL_OTHER );
828  pOther->entry()->setPartialEntry( false );
829 
830  update();
831  }
832  */
833 }
834 
835 
836 void KACLListView::calculateEffectiveRights()
837 {
838  TQListViewItemIterator it( this );
839  KACLListViewItem* pItem;
840  while ( ( pItem = dynamic_cast<KACLListViewItem*>( it.current() ) ) != 0 )
841  {
842  ++it;
843  pItem->calcEffectiveRights();
844  }
845 }
846 
847 
848 unsigned short KACLListView::maskPermissions() const
849 {
850  return m_mask;
851 }
852 
853 
854 void KACLListView::setMaskPermissions( unsigned short maskPerms )
855 {
856  m_mask = maskPerms;
857  calculateEffectiveRights();
858 }
859 
860 
861 acl_perm_t KACLListView::maskPartialPermissions() const
862 {
863  // return m_pMaskEntry->m_partialPerms;
864  return 0;
865 }
866 
867 
868 void KACLListView::setMaskPartialPermissions( acl_perm_t /*maskPartialPerms*/ )
869 {
870  //m_pMaskEntry->m_partialPerms = maskPartialPerms;
871  calculateEffectiveRights();
872 }
873 
874 bool KACLListView::hasDefaultEntries() const
875 {
876  TQListViewItemIterator it( const_cast<KACLListView*>( this ) );
877  while ( it.current() ) {
878  const KACLListViewItem *item = static_cast<const KACLListViewItem*>( it.current() );
879  ++it;
880  if ( item->isDefault ) return true;
881  }
882  return false;
883 }
884 
885 const KACLListViewItem* KACLListView::findDefaultItemByType( EntryType type ) const
886 {
887  return findItemByType( type, true );
888 }
889 
890 const KACLListViewItem* KACLListView::findItemByType( EntryType type, bool defaults ) const
891 {
892  TQListViewItemIterator it( const_cast<KACLListView*>( this ) );
893  while ( it.current() ) {
894  const KACLListViewItem *item = static_cast<const KACLListViewItem*>( it.current() );
895  ++it;
896  if ( item->isDefault == defaults && item->type == type ) {
897  return item;
898  }
899  }
900  return 0;
901 }
902 
903 
904 unsigned short KACLListView::calculateMaskValue( bool defaults ) const
905 {
906  // KACL auto-adds the relevant maks entries, so we can simply query
907  bool dummy;
908  return itemsToACL( defaults ).maskPermissions( dummy );
909 }
910 
911 void KACLListView::slotAddEntry()
912 {
913  int allowedTypes = NamedUser | NamedGroup;
914  if ( !m_hasMask )
915  allowedTypes |= Mask;
916  int allowedDefaultTypes = NamedUser | NamedGroup;
917  if ( !findDefaultItemByType( Mask ) )
918  allowedDefaultTypes |= Mask;
919  if ( !hasDefaultEntries() )
920  allowedDefaultTypes |= User | Group;
921  EditACLEntryDialog dlg( this, 0,
922  allowedUsers( false ), allowedGroups( false ),
923  allowedUsers( true ), allowedGroups( true ),
924  allowedTypes, allowedDefaultTypes, m_allowDefaults );
925  dlg.exec();
926  KACLListViewItem *item = dlg.item();
927  if ( !item ) return; // canceled
928  if ( item->type == Mask && !item->isDefault ) {
929  m_hasMask = true;
930  m_mask = item->value;
931  }
932  if ( item->isDefault && !hasDefaultEntries() ) {
933  // first default entry, fill in what is needed
934  if ( item->type != User ) {
935  unsigned short v = findDefaultItemByType( User )->value;
936  new KACLListViewItem( this, User, v, true );
937  }
938  if ( item->type != Group ) {
939  unsigned short v = findDefaultItemByType( Group )->value;
940  new KACLListViewItem( this, Group, v, true );
941  }
942  if ( item->type != Others ) {
943  unsigned short v = findDefaultItemByType( Others )->value;
944  new KACLListViewItem( this, Others, v, true );
945  }
946  }
947  const KACLListViewItem *defaultMaskItem = findDefaultItemByType( Mask );
948  if ( item->isDefault && !defaultMaskItem ) {
949  unsigned short v = calculateMaskValue( true );
950  new KACLListViewItem( this, Mask, v, true );
951  }
952  if ( !item->isDefault && !m_hasMask &&
953  ( item->type == Group
954  || item->type == NamedUser
955  || item->type == NamedGroup ) ) {
956  // auto-add a mask entry
957  unsigned short v = calculateMaskValue( false );
958  new KACLListViewItem( this, Mask, v, false );
959  m_hasMask = true;
960  m_mask = v;
961  }
962  calculateEffectiveRights();
963  sort();
964  setCurrentItem( item );
965  // TQListView doesn't seem to emit, in this case, and we need to update
966  // the buttons...
967  if ( childCount() == 1 )
968  emit currentChanged( item );
969 }
970 
971 void KACLListView::slotEditEntry()
972 {
973  TQListViewItem * current = currentItem();
974  if ( !current ) return;
975  KACLListViewItem *item = static_cast<KACLListViewItem*>( current );
976  int allowedTypes = item->type | NamedUser | NamedGroup;
977  bool itemWasMask = item->type == Mask;
978  if ( !m_hasMask || itemWasMask )
979  allowedTypes |= Mask;
980  int allowedDefaultTypes = item->type | NamedUser | NamedGroup;
981  if ( !findDefaultItemByType( Mask ) )
982  allowedDefaultTypes |= Mask;
983  if ( !hasDefaultEntries() )
984  allowedDefaultTypes |= User | Group;
985 
986  EditACLEntryDialog dlg( this, item,
987  allowedUsers( false, item ), allowedGroups( false, item ),
988  allowedUsers( true, item ), allowedGroups( true, item ),
989  allowedTypes, allowedDefaultTypes, m_allowDefaults );
990  dlg.exec();
991  if ( itemWasMask && item->type != Mask ) {
992  m_hasMask = false;
993  m_mask = 0;
994  }
995  if ( !itemWasMask && item->type == Mask ) {
996  m_mask = item->value;
997  m_hasMask = true;
998  }
999  calculateEffectiveRights();
1000  sort();
1001 }
1002 
1003 void KACLListView::slotRemoveEntry()
1004 {
1005  TQListViewItemIterator it( this, TQListViewItemIterator::Selected );
1006  while ( it.current() ) {
1007  KACLListViewItem *item = static_cast<KACLListViewItem*>( it.current() );
1008  ++it;
1009  /* First check if it's a mask entry and if so, make sure that there is
1010  * either no name user or group entry, which means the mask can be
1011  * removed, or don't remove it, but reset it. That is allowed. */
1012  if ( item->type == Mask ) {
1013  bool itemWasDefault = item->isDefault;
1014  if ( !itemWasDefault && maskCanBeDeleted() ) {
1015  m_hasMask= false;
1016  m_mask = 0;
1017  delete item;
1018  } else if ( itemWasDefault && defaultMaskCanBeDeleted() ) {
1019  delete item;
1020  } else {
1021  item->value = 0;
1022  item->repaint();
1023  }
1024  if ( !itemWasDefault )
1025  calculateEffectiveRights();
1026  } else {
1027  // for the base permissions, disable them, which is what libacl does
1028  if ( !item->isDefault &&
1029  ( item->type == User
1030  || item->type == Group
1031  || item->type == Others ) ) {
1032  item->value = 0;
1033  item->repaint();
1034  } else {
1035  delete item;
1036  }
1037  }
1038  }
1039 }
1040 
1041 bool KACLListView::maskCanBeDeleted() const
1042 {
1043  return !findItemByType( NamedUser ) && !findItemByType( NamedGroup );
1044 }
1045 
1046 bool KACLListView::defaultMaskCanBeDeleted() const
1047 {
1048  return !findDefaultItemByType( NamedUser ) && !findDefaultItemByType( NamedGroup );
1049 }
1050 
1051 #include "kacleditwidget.moc"
1052 #include "kacleditwidget_p.moc"
1053 #endif

tdeio/tdefile

Skip menu "tdeio/tdefile"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

tdeio/tdefile

Skip menu "tdeio/tdefile"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeio/tdefile by doxygen 1.9.1
This website is maintained by Timothy Pearson.