• 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
50extern "C" {
51#include <pwd.h>
52#include <grp.h>
53}
54#include <assert.h>
55
56#include "images.h"
57
58static 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
71KACLEditWidget::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
92void 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
109KACL KACLEditWidget::getACL() const
110{
111 return m_listView->getACL();
112}
113
114KACL KACLEditWidget::getDefaultACL() const
115{
116 return m_listView->getDefaultACL();
117}
118
119void KACLEditWidget::setACL( const KACL &acl )
120{
121 return m_listView->setACL( acl );
122}
123
124void KACLEditWidget::setDefaultACL( const KACL &acl )
125{
126 return m_listView->setDefaultACL( acl );
127}
128
129void KACLEditWidget::setAllowDefaults( bool value )
130{
131 m_listView->setAllowDefaults( value );
132}
133
134void KACLEditWidget::setReadOnly( bool on )
135{
136 m_listView->setEnabled( !on );
137 m_AddBtn->setEnabled( !on );
138 if ( !on )
139 slotUpdateButtons();
140}
141
142KACLListViewItem::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
155KACLListViewItem::~ KACLListViewItem()
156{
157
158}
159
160TQString 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
194void 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
224void 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
250void 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
286void 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
338bool 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
353bool KACLListViewItem::isAllowedToChangeType() const
354{
355 return type != KACLListView::User &&
356 type != KACLListView::Group &&
357 type != KACLListView::Others &&
358 type != KACLListView::Mask;
359}
360
361void 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
389EditACLEntryDialog::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
476void 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
490void 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}
512void 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
535void 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
558KACLListView::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
600KACLListView::~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
609TQStringList 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
623TQStringList 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
637void 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
676void 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
687void KACLListView::setDefaultACL( const KACL &acl )
688{
689 if ( !acl.isValid() ) return;
690 m_defaultACL = acl;
691 fillItemsFromACL( m_defaultACL, true );
692 calculateEffectiveRights();
693}
694
695KACL 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
739KACL KACLListView::getACL()
740{
741 return itemsToACL( false );
742}
743
744
745KACL KACLListView::getDefaultACL()
746{
747 return itemsToACL( true );
748}
749
750void 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
787void 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
836void 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
848unsigned short KACLListView::maskPermissions() const
849{
850 return m_mask;
851}
852
853
854void KACLListView::setMaskPermissions( unsigned short maskPerms )
855{
856 m_mask = maskPerms;
857 calculateEffectiveRights();
858}
859
860
861acl_perm_t KACLListView::maskPartialPermissions() const
862{
863 // return m_pMaskEntry->m_partialPerms;
864 return 0;
865}
866
867
868void KACLListView::setMaskPartialPermissions( acl_perm_t /*maskPartialPerms*/ )
869{
870 //m_pMaskEntry->m_partialPerms = maskPartialPerms;
871 calculateEffectiveRights();
872}
873
874bool 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
885const KACLListViewItem* KACLListView::findDefaultItemByType( EntryType type ) const
886{
887 return findItemByType( type, true );
888}
889
890const 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
904unsigned 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
911void 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
971void 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
1003void 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
1041bool KACLListView::maskCanBeDeleted() const
1042{
1043 return !findItemByType( NamedUser ) && !findItemByType( NamedGroup );
1044}
1045
1046bool 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.4
This website is maintained by Timothy Pearson.