class UserEditDialog(KPageDialog): def __init__(self,parent,admincontext): KPageDialog.__init__( self, parent ) self.setFaceType(KPageDialog.Tabbed) self.setCaption(i18n("User Account")) self.setModal(True) self.details_tab = uic.loadUi(pj(UI_DIR, 'userproperties-details.ui')) self.addPage(self.details_tab, i18n("Details")) self.privgroups_tab = uic.loadUi(pj(UI_DIR, 'userproperties-privgroups.ui')) self.addPage(self.privgroups_tab, i18n("Privileges and Groups")) self.pwsec_tab = uic.loadUi(pj(UI_DIR, 'userproperties-pwsec.ui')) self.addPage(self.pwsec_tab, i18n("Password/Security")) self.admincontext = admincontext self.userobj = None self.updatingGUI = True self.groups_model = GroupListModel(None, self.admincontext.getGroups(), self.userobj) ####################################################################### # Set up the user details tab self.details_tab.enabledradio.setIcon(KIcon("user-identity")) self.details_tab.disabledradio.setIcon(KIcon("object-locked")) self.details_tab.enabledradiogroup = QButtonGroup() self.details_tab.enabledradiogroup.addButton( self.details_tab.enabledradio, 0) self.details_tab.enabledradiogroup.addButton( self.details_tab.disabledradio, 1) self.details_tab.loginnameedit.setValidator( LoginNameValidator(self.details_tab.loginnameedit)) self.connect(self.details_tab.loginnameedit, SIGNAL("textChanged(const QString &)"), self.slotLoginChanged) self.details_tab.realnameedit.setValidator( RealUserNameValidator(self.details_tab.realnameedit)) self.details_tab.uidedit.setValidator( QIntValidator(0, 65535, self.details_tab.uidedit)) self.details_tab.primarygroupedit.setValidator( LoginNameValidator(self.details_tab.primarygroupedit)) self.details_tab.primarygroupedit.setInsertPolicy( QComboBox.NoInsert) self.simple_groups_model = SimpleGroupListProxyModel(None) self.simple_groups_model.setSourceModel(self.groups_model) self.details_tab.primarygroupedit.setModel(self.simple_groups_model) self.connect(self.details_tab.primarygroupedit, SIGNAL("editTextChanged(const QString&)"), self.slotPrimaryGroupChanged) self.connect(self.details_tab.homediredit, SIGNAL("textChanged(const QString &)"), self.slotHomeDirChanged) self.connect(self.details_tab.homedirbutton, SIGNAL("clicked()"), self.slotBrowseHomeDirClicked) for shell in self.admincontext.getUserShells(): self.details_tab.shelledit.addItem(shell) ####################################################################### # Set up the privileges and groups tab self.privgroups_tab.groupslistview.setModel(self.groups_model) self.privileges_model = PrivilegeListProxyModel(None) self.privileges_model.setSourceModel(self.groups_model) self.privgroups_tab.privilegeslistview.setModel(self.privileges_model) ####################################################################### # Set up the password/security tab #FIXME Doesn't work #self.up.passwordLabel.setPixmap(UserIcon("hi32-password")) self.pwsec_tab.validradiogroup = QButtonGroup() self.pwsec_tab.validradiogroup.addButton( self.pwsec_tab.validalwaysradio, 0) self.pwsec_tab.validradiogroup.addButton( self.pwsec_tab.expireradio, 1) self.connect(self.pwsec_tab.expireradio, SIGNAL("toggled(bool)"), self.slotValidUntilToggled) # Password Aging & Expiration. # [*] Require new password after: [_____5 days] self.connect(self.pwsec_tab.forcepasswordchangecheckbox, SIGNAL("toggled(bool)"), self.slotForcePasswordChangeToggled) self.pwsec_tab.warningedit.setSpecialValueText(i18n("Never")) self.pwsec_tab.disableexpireedit.setSpecialValueText(i18n("Never")) self.connect(self.pwsec_tab.enforcepasswordminagecheckbox, SIGNAL("toggled(bool)"), self.slotEnforePasswordAgeToggled) self.homedirdialog = KDirSelectDialog(KUrl.fromPath("/"),True,self) self.createhomedirectorydialog = OverwriteHomeDirectoryDialog(None) # Data changed signals # Details tab self.connect(self.details_tab.enabledradio, SIGNAL("toggled(bool)"), self.slotDataChanged) self.connect(self.details_tab.loginnameedit, SIGNAL("textEdited(const QString&)"), self.slotDataChanged) self.connect(self.details_tab.realnameedit, SIGNAL("textEdited(const QString&)"), self.slotDataChanged) self.connect(self.details_tab.primarygroupedit, SIGNAL("editTextChanged(const QString&)"), self.slotDataChanged) self.connect(self.details_tab.homediredit, SIGNAL("textEdited(const QString&)"), self.slotDataChanged) self.connect(self.details_tab.shelledit, SIGNAL("editTextChanged(const QString&)"), self.slotDataChanged) # Groups tab self.connect(self.groups_model, SIGNAL("modelReset()"), self.slotDataChanged) # Password/security tab self.connect(self.pwsec_tab.passwordedit, SIGNAL("textEdited(const QString&)"), self.slotDataChanged) self.connect(self.pwsec_tab.expireradio, SIGNAL("toggled(bool)"), self.slotDataChanged) self.connect(self.pwsec_tab.expiredate, SIGNAL("changed(const QDate&)"), self.slotDataChanged) self.connect(self.pwsec_tab.forcepasswordchangecheckbox, SIGNAL("toggled(bool)"), self.slotDataChanged) self.connect(self.pwsec_tab.maximumpasswordedit, SIGNAL("valueChanged(int)"), self.slotDataChanged) self.connect(self.pwsec_tab.warningedit, SIGNAL("valueChanged(int)"), self.slotDataChanged) self.connect(self.pwsec_tab.disableexpireedit, SIGNAL("valueChanged(int)"), self.slotDataChanged) self.connect(self.pwsec_tab.enforcepasswordminagecheckbox, SIGNAL("toggled(bool)"), self.slotDataChanged) self.connect(self.pwsec_tab.minimumpasswordedit, SIGNAL("valueChanged(int)"), self.slotDataChanged) self.updatingGUI = False ######################################################################## def showEditUser(self, userid): """ Sets up the dialog to modify an existing user. Returns the UID of the user if successful, None otherwise. """ self.updatingGUI = True self.newusermode = False self.userobj = self.admincontext.lookupUID(userid) self.setCaption(i18n("Modifying User Account %1")\ .arg(self.userobj.getUsername())) # Set up buttons self.setButtons(KDialog.ButtonCode(KDialog.Cancel | KDialog.Ok | KDialog.Apply)) self.connect(self, SIGNAL("applyClicked()"), self.applyChanges) self.pwsec_tab.passwordedit.clear() # Save the groups so they can be restored, and for isChanged() self.originalgroups = [g for g in self.userobj.getGroups() if g is not self.userobj.getPrimaryGroup()] self.originalprimarygroup = self.userobj.getPrimaryGroup() # Set the user on the model. This should update all views and select # groups. self.groups_model.setUser(self.userobj) # Puts most of the user data into the GUI self.__syncGUI() self.details_tab.uidedit.setReadOnly(True) self.updatingGUI = False self.homedirectoryislinked = False self.primarygroupislinked = False if self.exec_() == QDialog.Accepted: result = self.applyChanges() self.pwsec_tab.passwordedit.clear() if result: return self.userobj.getUID() else: self.revertChanges() return None else: # Dialog rejected self.revertChanges() return None ######################################################################## def showNewUser(self): """ Sets up the dialog to create a new user. Returns the UID of the new user if successful, None otherwise. """ self.updatingGUI = True self.newusermode = True self.userobj = self.admincontext.newUser(True) self.setCaption(i18n("New User Account")) # Set up buttons self.setButtons(KDialog.ButtonCode(KDialog.Cancel | KDialog.Ok)) self.newgroup = self.admincontext.newGroup(True) self.newgroup.setGroupname(self.__fudgeNewGroupName( self.userobj.getUsername())) self.userobj.setPrimaryGroup(self.newgroup) # Add the new user to a default set of groups # TODO: move this list somewhere more general? self.selectedgroups = [ u'dialout',u'cdrom',u'floppy',u'sambashare', u'plugdev',u'lpadmin',u'scanner'] for groupname in self.selectedgroups: groupobj = self.admincontext.lookupGroupname(groupname) if groupobj: self.userobj.addToGroup(groupobj) # TODO consider adding a drop down that will select the appropriate # profile Limited User, Advanced User or Administrator (and see if # there is a config file where these profiles can be read). # Set the user on the model. This should update all views and select # groups. self.groups_model.setUser(self.userobj) homedir = self.__fudgeNewHomeDirectory(self.userobj.getUsername()) self.userobj.setHomeDirectory(homedir) shells = self.admincontext.getUserShells() dshell = self.admincontext.dshell if dshell and (dshell in shells): self.userobj.setLoginShell(dshell) elif '/bin/bash' in shells: self.userobj.setLoginShell('/bin/bash') elif '/bin/sh' in shells: self.userobj.setLoginShell('/bin/sh') elif len(shells) != 0: self.userobj.setLoginShell(shells[0]) # Puts most of the user data into the GUI self.__syncGUI() self.details_tab.uidedit.setReadOnly(False) self.pwsec_tab.passwordedit.clear() self.updatingGUI = False self.homedirectoryislinked = True self.primarygroupislinked = True self.details_tab.loginnameedit.setFocus(Qt.OtherFocusReason) if self.exec_() == QDialog.Accepted: result = self.applyChanges() self.pwsec_tab.passwordedit.clear() if result: return self.userobj.getUID() else: return None else: # Dialog rejected self.pwsec_tab.passwordedit.clear() return None ######################################################################## def sanityCheck(self): """ Do some sanity checks. Returns True if data is ok or has been fixed up, otherwise pops up a message and returns False """ # Check that the username doesn't clash # TODO: do this in the UI instead of canceling the operation newusername = unicode(self.details_tab.loginnameedit.text()) existinguser = self.admincontext.lookupUsername(newusername) if existinguser is not None and existinguser is not self.userobj: KMessageBox.sorry(self, i18n("Sorry, you must choose a different " + "user name.\n" + "'%1' is already being used.")\ .arg(newusername)) return False # Check that the UID doesn't clash (can't change UID of existing user) # TODO: do this in the UI instead of canceling the operation if self.newusermode: newuid = int(unicode(self.details_tab.uidedit.text())) originaluid = self.userobj.getUID() if self.admincontext.lookupUID(newuid) is not None: rc = KMessageBox.questionYesNo(self, i18n("Sorry, the UID %1 is already in use. Should %2" + " be used instead?").arg(newuid).arg(originaluid), i18n("User ID in use")) if rc == KMessageBox.Yes: self.details_tab.uidedit.setValue(unicode(originaluid)) else: return False return True ######################################################################## def applyChanges(self): if not self.newusermode and not self.isChanged(): return False if not self.sanityCheck(): return False # Put in most of the data self.__updateObjectFromGUI(self.userobj) if self.newusermode: # Decide what to do about the home directory makehomedir = True deleteoldhomedir = False if os.path.exists(self.userobj.getHomeDirectory()): rc = self.createhomedirectorydialog.do(self.userobj) if rc == OverwriteHomeDirectoryDialog.CANCEL: return False if rc == OverwriteHomeDirectoryDialog.OK_KEEP: makehomedir = False elif rc == OverwriteHomeDirectoryDialog.OK_REPLACE: deleteoldhomedir = True # Add the user to the admin context. Before this the userobj # exists on its own. self.admincontext.addUser(self.userobj) # Secondary groups are updated within the model, nothing to do here # Set the password. if self.pwsec_tab.passwordedit.text() != "": self.userobj.setPassword(str(self.pwsec_tab.passwordedit.text())) # Enable/Disable the account self.userobj.setLocked( self.details_tab.enabledradiogroup.checkedId() != 0) # Save everything self.admincontext.save() # Create the home directory if needed if deleteoldhomedir: if os.path.exists(self.userobj.getHomeDirectory()): shutil.rmtree(self.userobj.getHomeDirectory()) if makehomedir: self.admincontext.createHomeDirectory(self.userobj) # The rest applies to both new users and existing users # Set the password. # TODO: password should need to be typed twice if self.pwsec_tab.passwordedit.text() != "": self.userobj.setPassword(str(self.pwsec_tab.passwordedit.text())) # Secondary groups are updated within the model, nothing to do here # if dialog accepted, need to revert if rejected. # __updateObjectFromGUI tries to set the primary group, but won't # set it if the group doesn't exist yet if self.admincontext.lookupGroupname(self.primarygroupname) is None: # Create a new group if not self.newusermode: if KMessageBox.questionYesNo(self, i18n("You selected %1 as the new primary group. This " + "group does not exist. Would you like to create " + "it?").arg(self.primarygroupname), i18n("Create group")) != KMessageBox.Yes: return False newgroup = self.admincontext.newGroup(True) newgroup.setGroupname(self.primarygroupname) self.admincontext.addGroup(newgroup) origprimarygroup = self.userobj.getPrimaryGroup() self.userobj.setPrimaryGroup(newgroup) self.userobj.removeFromGroup(origprimarygroup) # For Apply button, make sure views get updated self.groups_model.setItems(self.admincontext.getGroups()) # Enable/Disable the account self.userobj.setLocked( self.details_tab.enabledradiogroup.checkedId() != 0) # Save everything self.admincontext.save() # For Apply button if not self.newusermode: # Save the groups so they can be restored, and for isChanged() self.originalgroups = [g for g in self.userobj.getGroups() if g is not self.userobj.getPrimaryGroup()] self.originalprimarygroup = self.userobj.getPrimaryGroup() self.slotDataChanged() return True ######################################################################## def revertChanges(self): # Revert secondary groups, since those are being stored in the user # by the model currentgroups = [g for g in self.userobj.getGroups() if g not in (self.userobj.getPrimaryGroup(), self.originalprimarygroup)] addedgroups = [g for g in currentgroups if g not in self.originalgroups] removedgroups = [g for g in self.originalgroups if g not in currentgroups] for group in removedgroups: self.userobj.addToGroup(group) for group in addedgroups: self.userobj.removeFromGroup(group) # Revert the primary group self.userobj.setPrimaryGroup(self.originalprimarygroup) self.pwsec_tab.passwordedit.clear() ######################################################################## def slotLoginChanged(self, text): newtext = unicode(text) if not self.updatingGUI: if self.newusermode: self.updatingGUI = True if self.primarygroupislinked: newprimarygroupname = self.__fudgeNewGroupName(newtext) self.details_tab.primarygroupedit.setEditText( newprimarygroupname) if self.homedirectoryislinked: homedir = self.__fudgeNewHomeDirectory(newtext) self.details_tab.homediredit.setText(homedir) self.updatingGUI = False ######################################################################## def slotPrimaryGroupChanged(self, text): newtext = unicode(text) if not self.updatingGUI: self.updatingGUI = True self.primarygroupislinked = False if not newtext: self.__selectPrimaryGroup() else: groupobj = self.admincontext.lookupGroupname(text) origprimarygroup = self.userobj.getPrimaryGroup() if groupobj is not None: if groupobj is origprimarygroup: self.__selectPrimaryGroup() else: self.userobj.setPrimaryGroup(groupobj) self.userobj.removeFromGroup(origprimarygroup) else: # FIXME: Can't remove the group here because unixauthdb # will asign a random one pass self.updatingGUI = False ######################################################################## def __selectPrimaryGroup(self): idx = self.details_tab.primarygroupedit.findText( self.userobj.getPrimaryGroup().getGroupname()) self.details_tab.primarygroupedit.setCurrentIndex(idx) ######################################################################## def slotHomeDirChanged(self, newdir): if not self.updatingGUI: self.homedirectoryislinked = False ######################################################################## def __syncGUI(self): if self.userobj.isLocked(): self.details_tab.enabledradiogroup.button(1).setChecked(True) else: self.details_tab.enabledradiogroup.button(0).setChecked(True) self.details_tab.loginnameedit.setText(self.userobj.getUsername()) self.details_tab.realnameedit.setText(self.userobj.getRealName()) self.details_tab.uidedit.setText(unicode(self.userobj.getUID())) self.details_tab.homediredit.setText(self.userobj.getHomeDirectory()) self.details_tab.shelledit.setEditText(self.userobj.getLoginShell()) # Primary Group if self.newusermode: # New user mode newprimarygroupname = \ self.__fudgeNewGroupName(unicode(self.userobj.getUsername())) self.details_tab.primarygroupedit.setEditText(newprimarygroupname) else: # Existing user mode primarygroupname = self.userobj.getPrimaryGroup().getGroupname() self.__selectPrimaryGroup() # If ShadowExpire is turn off then we change the radio box. if self.userobj.getExpirationDate() is None: self.pwsec_tab.validradiogroup.button(0).setChecked(True) self.pwsec_tab.expiredate.setDisabled(True) self.pwsec_tab.expiredate.setDate(SptimeToQDate(99999L)) else: self.pwsec_tab.validradiogroup.button(1).setChecked(True) self.pwsec_tab.expiredate.setDisabled(False) self.pwsec_tab.expiredate.setDate( SptimeToQDate(self.userobj.getExpirationDate())) if self.userobj.getMaximumPasswordAge() is None: # Password aging is turn off self.pwsec_tab.forcepasswordchangecheckbox.setChecked(False) d = True else: # Password aging is turn on self.pwsec_tab.forcepasswordchangecheckbox.setChecked(True) d = False self.pwsec_tab.warningedit.setDisabled(d) self.pwsec_tab.maximumpasswordedit.setDisabled(d) self.pwsec_tab.disableexpireedit.setDisabled(d) if self.userobj.getPasswordExpireWarning() is None: self.pwsec_tab.warningedit.setValue(0) else: self.pwsec_tab.warningedit.setValue(self.userobj.getPasswordExpireWarning()) if self.userobj.getMaximumPasswordAge() is None: self.pwsec_tab.maximumpasswordedit.setValue(30) else: self.pwsec_tab.maximumpasswordedit.setValue( self.userobj.getMaximumPasswordAge()) if self.userobj.getPasswordDisableAfterExpire() is None: self.pwsec_tab.disableexpireedit.setValue(0) else: self.pwsec_tab.disableexpireedit.setValue( self.userobj.getPasswordDisableAfterExpire()) minage = self.userobj.getMinimumPasswordAgeBeforeChange() self.pwsec_tab.enforcepasswordminagecheckbox.setChecked(minage > 0) self.pwsec_tab.minimumpasswordedit.setDisabled(minage <= 0) if minage <= 0: minage = 1 self.pwsec_tab.minimumpasswordedit.setValue(minage) if self.userobj.getLastPasswordChange() in (None, 0): self.pwsec_tab.lastchangelabel.setText('-'); else: self.pwsec_tab.lastchangelabel.setText( KGlobal.locale().formatDate(SptimeToQDate( int(self.userobj.getLastPasswordChange())))) self.slotDataChanged() ######################################################################## def __updateObjectFromGUI(self, userobj): username = unicode(self.details_tab.loginnameedit.text()) userobj.setUsername(username) userobj.setRealName(unicode(self.details_tab.realnameedit.text())) userobj.setHomeDirectory(unicode(self.details_tab.homediredit.text())) userobj.setLoginShell(unicode(self.details_tab.shelledit.currentText())) self.primarygroupname = \ unicode(self.details_tab.primarygroupedit.currentText()) groupobj = self.admincontext.lookupGroupname(self.primarygroupname) if groupobj is not None: userobj.setPrimaryGroup(groupobj) # Password expiration. if self.pwsec_tab.validradiogroup.checkedId() == 0: # Password is always valid. userobj.setExpirationDate(None) else: # Password will expire at... userobj.setExpirationDate(QDateToSptime(self.pwsec_tab.expiredate.date())) if self.pwsec_tab.forcepasswordchangecheckbox.isChecked(): userobj.setMaximumPasswordAge(self.pwsec_tab.maximumpasswordedit.value()) else: userobj.setMaximumPasswordAge(None) if self.pwsec_tab.disableexpireedit.value() == 0: userobj.setPasswordDisableAfterExpire(None) else: userobj.setPasswordDisableAfterExpire(self.pwsec_tab.disableexpireedit.value()) if self.pwsec_tab.enforcepasswordminagecheckbox.isChecked(): userobj.setMinimumPasswordAgeBeforeChange(self.pwsec_tab.minimumpasswordedit.value()) else: userobj.setMinimumPasswordAgeBeforeChange(0) userobj.setPasswordExpireWarning(self.pwsec_tab.warningedit.value()) ######################################################################## def slotBrowseHomeDirClicked(self): fileurl = KUrl() fileurl.setPath(self.details_tab.homediredit.text()) self.homedirdialog.setCurrentUrl(fileurl) if self.homedirdialog.exec_()==QDialog.Accepted: self.details_tab.homediredit.setText(self.homedirdialog.url().path()) self.homedirectoryislinked = False ######################################################################## def slotValidUntilToggled(self, expire_on): if expire_on: self.pwsec_tab.expiredate.setEnabled(True) else: self.pwsec_tab.expiredate.setEnabled(False) ######################################################################## def slotForcePasswordChangeToggled(self,on): on = not on self.pwsec_tab.warningedit.setDisabled(on) self.pwsec_tab.maximumpasswordedit.setDisabled(on) self.pwsec_tab.disableexpireedit.setDisabled(on) ######################################################################## def slotEnforePasswordAgeToggled(self,on): self.pwsec_tab.minimumpasswordedit.setDisabled(not on) ######################################################################## def slotDataChanged(self): changed = self.isChanged() if not self.newusermode: self.enableButtonOk(changed) self.enableButtonApply(changed) self.setCaption(i18n("Modifying User Account %1")\ .arg(self.userobj.getUsername()), changed) ######################################################################## def isChanged(self): if not self.newusermode: # Kind of ugly. Hopefully short-circuit evaluation makes it not # too much work. # UID not included, it can't be modified changed = ( self.details_tab.enabledradio.isChecked() == self.userobj.isLocked() or self.details_tab.loginnameedit.text() != self.userobj.getUsername()\ or self.details_tab.realnameedit.text() != self.userobj.getRealName() or self.details_tab.primarygroupedit.currentText() != self.originalprimarygroup.getGroupname() or self.details_tab.homediredit.text() != self.userobj.getHomeDirectory() or self.details_tab.shelledit.currentText() != self.userobj.getLoginShell() or [g for g in self.userobj.getGroups() if g is not self.userobj.getPrimaryGroup()] != self.originalgroups or self.pwsec_tab.passwordedit.text() != "" or (self.pwsec_tab.validalwaysradio.isChecked() and self.userobj.getExpirationDate() is not None) or (self.pwsec_tab.expireradio.isChecked() and (self.userobj.getExpirationDate() != QDateToSptime(self.pwsec_tab.expiredate.date()))) or (not self.pwsec_tab.forcepasswordchangecheckbox.isChecked() and self.userobj.getMaximumPasswordAge() is not None) or (self.pwsec_tab.forcepasswordchangecheckbox.isChecked() and (self.userobj.getMaximumPasswordAge() != self.pwsec_tab.maximumpasswordedit.value() or self.userobj.getPasswordExpireWarning() != self.pwsec_tab.warningedit.value() or (self.userobj.getPasswordDisableAfterExpire() is not None and self.userobj.getPasswordDisableAfterExpire() != self.pwsec_tab.disableexpireedit.value()) or (self.userobj.getPasswordDisableAfterExpire() is None and self.pwsec_tab.disableexpireedit.value() != 0) )) or (not self.pwsec_tab.enforcepasswordminagecheckbox.isChecked() and self.userobj.getMinimumPasswordAgeBeforeChange() > 0) or (self.pwsec_tab.enforcepasswordminagecheckbox.isChecked() and (self.userobj.getMinimumPasswordAgeBeforeChange() != self.pwsec_tab.minimumpasswordedit.value())) ) return changed else: return False ####################################################################### def __fudgeNewGroupName(self,basename): if self.admincontext.lookupGroupname(basename) is None: return basename x = 1 while self.admincontext.lookupGroupname(basename + u'_' + unicode(x)) is not None: x += 1 return basename + u'_' + unicode(x) ####################################################################### def __fudgeNewHomeDirectory(self,origbasename): basename = origbasename.replace("/","") if basename=="": basename = u"user" dhome = self.admincontext.dhome if not os.path.isdir(dhome): raise OSError, dhome+" does not exist, is it correctly set in "+ \ self.admincontext.adduserconf+" ?" else: # Make sure there's a trailing / if dhome[-1] is not '/': dhome = dhome+'/' if os.path.exists(dhome+basename)==False: return dhome+basename else: x = 1 while os.path.exists(dhome+basename + u'_' + unicode(x)): x += 1 return dhome+basename
def __init__(self,parent,admincontext): KPageDialog.__init__( self, parent ) self.setFaceType(KPageDialog.Tabbed) self.setCaption(i18n("User Account")) self.setModal(True) self.details_tab = uic.loadUi(pj(UI_DIR, 'userproperties-details.ui')) self.addPage(self.details_tab, i18n("Details")) self.privgroups_tab = uic.loadUi(pj(UI_DIR, 'userproperties-privgroups.ui')) self.addPage(self.privgroups_tab, i18n("Privileges and Groups")) self.pwsec_tab = uic.loadUi(pj(UI_DIR, 'userproperties-pwsec.ui')) self.addPage(self.pwsec_tab, i18n("Password/Security")) self.admincontext = admincontext self.userobj = None self.updatingGUI = True self.groups_model = GroupListModel(None, self.admincontext.getGroups(), self.userobj) ####################################################################### # Set up the user details tab self.details_tab.enabledradio.setIcon(KIcon("user-identity")) self.details_tab.disabledradio.setIcon(KIcon("object-locked")) self.details_tab.enabledradiogroup = QButtonGroup() self.details_tab.enabledradiogroup.addButton( self.details_tab.enabledradio, 0) self.details_tab.enabledradiogroup.addButton( self.details_tab.disabledradio, 1) self.details_tab.loginnameedit.setValidator( LoginNameValidator(self.details_tab.loginnameedit)) self.connect(self.details_tab.loginnameedit, SIGNAL("textChanged(const QString &)"), self.slotLoginChanged) self.details_tab.realnameedit.setValidator( RealUserNameValidator(self.details_tab.realnameedit)) self.details_tab.uidedit.setValidator( QIntValidator(0, 65535, self.details_tab.uidedit)) self.details_tab.primarygroupedit.setValidator( LoginNameValidator(self.details_tab.primarygroupedit)) self.details_tab.primarygroupedit.setInsertPolicy( QComboBox.NoInsert) self.simple_groups_model = SimpleGroupListProxyModel(None) self.simple_groups_model.setSourceModel(self.groups_model) self.details_tab.primarygroupedit.setModel(self.simple_groups_model) self.connect(self.details_tab.primarygroupedit, SIGNAL("editTextChanged(const QString&)"), self.slotPrimaryGroupChanged) self.connect(self.details_tab.homediredit, SIGNAL("textChanged(const QString &)"), self.slotHomeDirChanged) self.connect(self.details_tab.homedirbutton, SIGNAL("clicked()"), self.slotBrowseHomeDirClicked) for shell in self.admincontext.getUserShells(): self.details_tab.shelledit.addItem(shell) ####################################################################### # Set up the privileges and groups tab self.privgroups_tab.groupslistview.setModel(self.groups_model) self.privileges_model = PrivilegeListProxyModel(None) self.privileges_model.setSourceModel(self.groups_model) self.privgroups_tab.privilegeslistview.setModel(self.privileges_model) ####################################################################### # Set up the password/security tab #FIXME Doesn't work #self.up.passwordLabel.setPixmap(UserIcon("hi32-password")) self.pwsec_tab.validradiogroup = QButtonGroup() self.pwsec_tab.validradiogroup.addButton( self.pwsec_tab.validalwaysradio, 0) self.pwsec_tab.validradiogroup.addButton( self.pwsec_tab.expireradio, 1) self.connect(self.pwsec_tab.expireradio, SIGNAL("toggled(bool)"), self.slotValidUntilToggled) # Password Aging & Expiration. # [*] Require new password after: [_____5 days] self.connect(self.pwsec_tab.forcepasswordchangecheckbox, SIGNAL("toggled(bool)"), self.slotForcePasswordChangeToggled) self.pwsec_tab.warningedit.setSpecialValueText(i18n("Never")) self.pwsec_tab.disableexpireedit.setSpecialValueText(i18n("Never")) self.connect(self.pwsec_tab.enforcepasswordminagecheckbox, SIGNAL("toggled(bool)"), self.slotEnforePasswordAgeToggled) self.homedirdialog = KDirSelectDialog(KUrl.fromPath("/"),True,self) self.createhomedirectorydialog = OverwriteHomeDirectoryDialog(None) # Data changed signals # Details tab self.connect(self.details_tab.enabledradio, SIGNAL("toggled(bool)"), self.slotDataChanged) self.connect(self.details_tab.loginnameedit, SIGNAL("textEdited(const QString&)"), self.slotDataChanged) self.connect(self.details_tab.realnameedit, SIGNAL("textEdited(const QString&)"), self.slotDataChanged) self.connect(self.details_tab.primarygroupedit, SIGNAL("editTextChanged(const QString&)"), self.slotDataChanged) self.connect(self.details_tab.homediredit, SIGNAL("textEdited(const QString&)"), self.slotDataChanged) self.connect(self.details_tab.shelledit, SIGNAL("editTextChanged(const QString&)"), self.slotDataChanged) # Groups tab self.connect(self.groups_model, SIGNAL("modelReset()"), self.slotDataChanged) # Password/security tab self.connect(self.pwsec_tab.passwordedit, SIGNAL("textEdited(const QString&)"), self.slotDataChanged) self.connect(self.pwsec_tab.expireradio, SIGNAL("toggled(bool)"), self.slotDataChanged) self.connect(self.pwsec_tab.expiredate, SIGNAL("changed(const QDate&)"), self.slotDataChanged) self.connect(self.pwsec_tab.forcepasswordchangecheckbox, SIGNAL("toggled(bool)"), self.slotDataChanged) self.connect(self.pwsec_tab.maximumpasswordedit, SIGNAL("valueChanged(int)"), self.slotDataChanged) self.connect(self.pwsec_tab.warningedit, SIGNAL("valueChanged(int)"), self.slotDataChanged) self.connect(self.pwsec_tab.disableexpireedit, SIGNAL("valueChanged(int)"), self.slotDataChanged) self.connect(self.pwsec_tab.enforcepasswordminagecheckbox, SIGNAL("toggled(bool)"), self.slotDataChanged) self.connect(self.pwsec_tab.minimumpasswordedit, SIGNAL("valueChanged(int)"), self.slotDataChanged) self.updatingGUI = False
def __init__(self, component_data=None, parent=None): global standalone, isroot KGlobal.locale().insertCatalog("userconfig") self.aboutdata = MakeAboutData() if standalone: KPageDialog.__init__(self) self.setFaceType(KPageDialog.Tabbed) # Set up buttons self.setButtons(KDialog.ButtonCode(KDialog.Close | KDialog.User1)) self.setButtonText(KDialog.ButtonCode(KDialog.User1), i18n("About")) self.setButtonIcon(KDialog.User1, KIcon('help-about')) self.connect(self, SIGNAL("user1Clicked()"), self.slotUser1) self.aboutus = KAboutApplicationDialog(self.aboutdata, self) # Make UI set up code the same for standalone tabcontrol = self else: KCModule.__init__(self, component_data, parent) self.setAboutData(self.aboutdata) self.setButtons(KCModule.Help) self.setUseRootOnlyMessage(True) # Create layout and tabs otherwise taken care of by KPageDialog toplayout = QVBoxLayout() self.setLayout(toplayout) tabcontrol = KPageWidget(self) tabcontrol.setFaceType(KPageWidget.Tabbed) toplayout.addWidget(tabcontrol) # Load UI self.userstab = uic.loadUi(pj(UI_DIR, 'users.ui')) userstab_pwi = tabcontrol.addPage(self.userstab, i18n("User Accounts") ) self.groupstab = uic.loadUi(pj(UI_DIR, 'groups.ui')) groupstab_pwi = tabcontrol.addPage(self.groupstab, i18n("Groups") ) # Create a configuration object. self.config = KConfig("userconfigrc") self.generalconfiggroup = KConfigGroup(self.config, "General") self.optionsconfiggroup = KConfigGroup(self.config, "Options") KIconLoader.global_().addAppDir("guidance") self.admincontext = getContext(isroot) self.selecteduserid = None self.selectedgroupid = None self.updatingGUI = True ####################################################################### # Set up the users tab userstab_pwi.setIcon(KIcon('user-identity')) self.userlistmodel = UserModel(None, self.admincontext.getUsers()) self.userstab.userlistview.setModel(self.userlistmodel) self.userlist_nosys_model = FilterSystemAcctsProxyModel(None) self.userlist_nosys_model.setSourceModel(self.userlistmodel) # Last column is really big without this #fix_treeview(self.userstab.userlistview) self.userstab.userlistview.setColumnWidth(2, 20) self.connect( self.userstab.userlistview.selectionModel(), SIGNAL("currentChanged(const QModelIndex&,const QModelIndex&)"), self.slotUserSelected ) self.secondary_groups_model = GroupListModel(None, [], None) simple_sec_groups_model = SimpleGroupListProxyModel(None) simple_sec_groups_model.setSourceModel(self.secondary_groups_model) self.userstab.secondarygroupslist.setModel(simple_sec_groups_model) if isroot: self.connect( self.userstab.userlistview, SIGNAL("doubleClicked(const QModelIndex&)"), self.slotModifyClicked ) # TODO: context menu #self.connect(self.userstab.userlistview, SIGNAL("contextMenu(KListView*,QListViewItem*,const QPoint&)"), self.slotUserContext) self.connect( self.userstab.show_sysusers_checkbox, SIGNAL("toggled(bool)"), self.slotShowSystemUsers ) # Buttons self.connect( self.userstab.modifybutton, SIGNAL("clicked()"), self.slotModifyClicked ) self.userstab.modifybutton.setIcon( SmallIconSet('user-properties') ) self.connect( self.userstab.newbutton, SIGNAL("clicked()"), self.slotNewClicked ) self.userstab.newbutton.setIcon( SmallIconSet('list-add-user') ) self.connect( self.userstab.deletebutton, SIGNAL("clicked()"), self.slotDeleteClicked) self.userstab.deletebutton.setIcon( SmallIconSet('list-remove-user') ) self.userstab.statusiconlabel.setPixmap( KIconLoader.global_().loadIcon('object-locked', KIconLoader.Small)) self.__selectUser(None) ####################################################################### # Set up the groups tab #FIXME: Need to find Oxygen group icon groupstab_pwi.setIcon(KIcon('user-group-properties')) self.grouplistmodel = GroupModel(None, self.admincontext.getGroups()) self.groupstab.grouplistview.setModel(self.grouplistmodel) self.grouplist_nosys_model = FilterSystemAcctsProxyModel(None) self.grouplist_nosys_model.setSourceModel(self.grouplistmodel) # Last column is really big without this fix_treeview(self.groupstab.grouplistview) self.groupmemberslistmodel = UserModel(None, []) self.groupstab.groupmemberlistview.setModel( self.groupmemberslistmodel ) # Last column is really big without this fix_treeview(self.groupstab.groupmemberlistview) self.connect( self.groupstab.grouplistview.selectionModel(), SIGNAL("currentChanged(const QModelIndex&,const QModelIndex&)"), self.slotGroupSelected ) if isroot: self.connect( self.groupstab.grouplistview, SIGNAL("doubleClicked(const QModelIndex&)"), self.slotModifyGroupClicked ) # TODO: group context menu #self.connect(self.grouplist, SIGNAL("contextMenu(KListView*,QListViewItem*,const QPoint&)"), #self.slotGroupContext) self.connect( self.groupstab.show_sysgroups_checkbox, SIGNAL("toggled(bool)"), self.slotShowSystemGroups ) # Buttons self.connect( self.groupstab.modifygroupbutton, SIGNAL("clicked()"), self.slotModifyGroupClicked ) self.groupstab.modifygroupbutton.setIcon( SmallIconSet('user-group-properties') ) self.connect( self.groupstab.newgroupbutton, SIGNAL("clicked()"), self.slotNewGroupClicked ) self.groupstab.newgroupbutton.setIcon( SmallIconSet('user-group-new') ) self.connect( self.groupstab.deletegroupbutton, SIGNAL("clicked()"), self.slotDeleteGroupClicked ) self.groupstab.deletegroupbutton.setIcon( SmallIconSet('user-group-delete') ) # Disable some buttons. Disable all if not root. disablebuttons = [ self.userstab.modifybutton, self.groupstab.modifygroupbutton, self.userstab.deletebutton, self.groupstab.deletegroupbutton, ] if not isroot: disablebuttons += ( self.userstab.newbutton, self.groupstab.newgroupbutton ) for widget in disablebuttons: widget.setDisabled(True) self.usereditdialog = UserEditDialog(None,self.admincontext) self.userdeletedialog = UserDeleteDialog(None,self.admincontext) self.groupeditdialog = GroupEditDialog(None,self.admincontext) # exec_ doesn't get called for a KCM if not standalone: self.__loadOptions()