source: src-qt4/PCDM/src/loginWidget.cpp @ ae41693

releng/10.0.1releng/10.0.2releng/10.0.3
Last change on this file since ae41693 was ae41693, checked in by Ken Moore <ken@…>, 8 months ago

Couple new features for PCDM
1) Add option to require that the user type in the username instead of just selecting one from a list (does not recognize "root" or "toor", I made sure of that)
2) Move the backend system user detection to using "getent" after conversation with john @ ixsystems. That should properly pick up LDAP/ActiveDirectory users as well, whereas "pw" might not.

  • Property mode set to 100644
File size: 12.6 KB
Line 
1/* PCDM Login Manager:
2*  Written by Ken Moore (ken@pcbsd.org) 2012/2013
3*  Copyright(c) 2013 by the PC-BSD Project
4*  Available under the 3-clause BSD license
5*/
6
7/*
8Sub-classed widget for inputting login information
9*/
10
11#include "loginWidget.h"
12
13LoginWidget::LoginWidget(QWidget* parent) : QGroupBox(parent)
14{
15  //Set the default values for the current item
16  idL.clear(); //Clear the login names available
17  userSelected = FALSE; //focus on the username first
18  pwVisible = FALSE; //Have the password box hide the input behind dots
19  allowPWVisible = TRUE; //Allow the password button to show the password text
20  showUsers = true; //Display the available users on the system
21       
22  //Create the Grid layout
23  QHBoxLayout* hlayout1 = new QHBoxLayout();
24  QHBoxLayout* hlayout2 = new QHBoxLayout();
25  QHBoxLayout* hlayout3 = new QHBoxLayout();
26  QVBoxLayout* vlayout = new QVBoxLayout();
27  QFormLayout* flayout = new QFormLayout();
28  //Create the items
29  userIcon = new QToolButton;
30        QAction* tmp = new QAction(this);
31        userIcon->setDefaultAction( tmp );
32        userIcon->setFocusPolicy(Qt::NoFocus);
33  listUserBig = new QListWidget;
34        listUserBig->setFocusPolicy(Qt::StrongFocus);
35        listUserBig->setSelectionMode(QAbstractItemView::SingleSelection);
36  listUsers = new QComboBox;
37        listUsers->setFocusPolicy(Qt::NoFocus); //big one gets keyboard focus instead
38  linePassword = new QLineEdit;
39        linePassword->setFocusPolicy(Qt::StrongFocus);
40  lineUsername = new QLineEdit;
41        lineUsername->setFocusPolicy(Qt::StrongFocus);
42  pushLogin = new QToolButton;
43        QAction* tmp1 = new QAction(this);
44        pushLogin->setDefaultAction( tmp1 );
45        pushLogin->setFocusPolicy(Qt::StrongFocus);
46  pushViewPassword = new QToolButton;
47        QAction* tmp2 = new QAction(this);
48        pushViewPassword->setDefaultAction( tmp2 );
49        pushViewPassword->setFocusPolicy(Qt::NoFocus);
50  pushUserIcon = new QToolButton;
51        QAction* tmp3 = new QAction(this);
52        pushUserIcon->setDefaultAction( tmp3 );
53        pushUserIcon->setFocusPolicy(Qt::NoFocus);
54  listDE = new QComboBox;
55  deIcon = new QLabel;
56       
57  //Add the items to the grid
58    //user not yet selected widgets
59      hlayout1->addWidget(userIcon);
60    vlayout->addLayout(hlayout1);
61    vlayout->addWidget(listUserBig);
62    //User selected widgets
63        hlayout3->addWidget(listUsers);
64        hlayout3->addWidget(lineUsername);
65      flayout->addRow(pushUserIcon, hlayout3);
66      flayout->addRow(pushViewPassword, linePassword);
67      flayout->addRow(deIcon,listDE);
68    vlayout->addSpacing(15);
69    vlayout->addLayout(flayout);
70    vlayout->addSpacing(20);
71      hlayout2->addWidget(pushLogin);
72    vlayout->addLayout(hlayout2);
73   
74  //Setup the Signals/Slots
75  connect(pushLogin,SIGNAL(clicked()),this,SLOT(slotTryLogin()));
76  connect(pushUserIcon,SIGNAL(triggered(QAction*)), this, SLOT(slotUserActivated()));
77  connect(userIcon,SIGNAL(triggered(QAction*)), this, SLOT(slotUserActivated()));
78  connect(listUsers,SIGNAL(activated(int)),this,SLOT(slotChooseUser(int)));
79  connect(listUserBig,SIGNAL(itemClicked(QListWidgetItem*)),this,SLOT(slotUserSelected()) );
80  connect(listUserBig,SIGNAL(currentRowChanged(int)),this,SLOT(slotUserHighlighted(int)) );
81  connect(listDE,SIGNAL(currentIndexChanged(int)),this,SLOT(slotDesktopChanged(int)) );
82  allowPasswordView(allowPWVisible); //setup signal/slots for pushViewPassword
83  //Set this layout for the loginWidget
84  this->setLayout(vlayout);
85 
86  //Run the display setup to ensure appropriate visiblility/usage
87  updateWidget();
88 
89}
90
91LoginWidget::~LoginWidget(){
92}
93
94void LoginWidget::updateWidget(){
95  //Setup the visibility/sizes
96  if(userSelected && showUsers){
97    userIcon->setVisible(FALSE);
98    listUserBig->setVisible(FALSE);
99    pushUserIcon->setVisible(TRUE);
100    listUsers->setVisible(TRUE);
101    lineUsername->setVisible(false);
102    linePassword->setVisible(TRUE);
103    pushLogin->setVisible(TRUE);
104    pushViewPassword->setVisible(TRUE);
105    if( listDE->count() < 1 ){ listDE->setVisible(FALSE); deIcon->setVisible(FALSE); }
106    else{ listDE->setVisible(TRUE); deIcon->setVisible(TRUE); }
107  }else if(!showUsers){
108    //Do not show either of the user selection widgets
109    userIcon->setVisible(FALSE);
110    listUserBig->setVisible(FALSE);
111    pushUserIcon->setVisible(TRUE);
112    listUsers->setVisible(false);
113    lineUsername->setVisible(true);
114    linePassword->setVisible(TRUE);
115    pushLogin->setVisible(TRUE);
116    pushViewPassword->setVisible(TRUE);
117    if( listDE->count() < 1 ){ listDE->setVisible(FALSE); deIcon->setVisible(FALSE); }
118    else{ listDE->setVisible(TRUE); deIcon->setVisible(TRUE); }
119  }else{
120    //ShowUsers and none selected
121    userIcon->setVisible(TRUE);
122    listUserBig->setVisible(TRUE);
123    pushUserIcon->setVisible(FALSE);
124    listUsers->setVisible(FALSE);
125    linePassword->setVisible(FALSE);
126    pushLogin->setVisible(FALSE);
127    pushViewPassword->setVisible(FALSE); 
128    listDE->setVisible(FALSE);
129    deIcon->setVisible(FALSE);
130  }
131  if(pwVisible){
132    linePassword->setEchoMode(QLineEdit::Normal);         
133  }else{
134    linePassword->setEchoMode(QLineEdit::Password);       
135  }
136  retranslateUi();
137}
138
139void LoginWidget::keyPressEvent(QKeyEvent *e){
140  if( (e->key()==Qt::Key_Enter) || (e->key()==Qt::Key_Return) ){
141    if(userSelected){
142      slotTryLogin();
143    }else{
144      slotUserSelected();     
145    }
146  }else if(e->key() == Qt::Key_Escape){
147    if(userSelected){
148      slotUserUnselected();
149    }else{
150      emit escapePressed();
151    }
152  }
153}
154
155//-------------------------------------
156//    PRIVATE SLOTS
157//-------------------------------------
158void LoginWidget::slotUserActivated(){
159    //Toggle the user box as to what is visible
160    if(!userSelected){ 
161        slotUserSelected(); 
162    }else{
163        slotUserUnselected();
164    }
165}
166
167/*void LoginWidget::slotUserClicked(QListWidgetItem* item){
168  slotUserSelected();   
169}*/
170
171void LoginWidget::slotUserHighlighted(int row){
172  emit UserChanged(idL[row]);   
173}
174
175void LoginWidget::slotTryLogin(){
176  QString user;
177  if(showUsers){
178    user = listUsers->currentText();
179  }else{
180    user = lineUsername->text();
181  }
182  QString pw = linePassword->text();
183  emit loginRequested(user,pw);
184  linePassword->setText(""); //always clear the box after a login attempt
185}
186
187void LoginWidget::slotChooseUser(int i){
188  if(i!=-1){ slotUserSelected(); }     
189}
190
191void LoginWidget::slotUserSelected(){
192  if(userSelected){ //make sure the big user widget is updated as well
193    listUserBig->setCurrentRow( listUsers->currentIndex() );
194  }else{ //make sure the small user widget is updated as well
195    listUsers->setCurrentIndex( listUserBig->currentRow() );
196  }
197  userSelected = TRUE;
198  pwVisible = FALSE;
199  linePassword->clear(); //make sure the password is cleared if the user is changed
200  updateWidget();
201  linePassword->setFocus();
202  emit UserSelected(listUsers->currentText());
203}
204
205void LoginWidget::slotUserUnselected(){
206  userSelected = FALSE;
207  pwVisible = FALSE;
208  linePassword->clear(); //make sure the password is cleared if the user is changed
209  updateWidget();
210  listUserBig->setFocus();
211  emit UserSelected("");
212}
213
214void LoginWidget::slotChangePWView(){
215  if(pwVisible){
216    pwVisible = FALSE;
217  }else{
218    pwVisible = TRUE;
219  }
220  updateWidget();
221}
222
223void LoginWidget::slotDesktopChanged(int index){
224  if(index == -1){
225    deIcon->setPixmap(QPixmap(""));
226    deIcon->setToolTip("");
227  }else{
228    deIcon->setPixmap( QPixmap(desktopIcons[index]).scaled(desktopIconSize) );
229    deIcon->setToolTip(desktopInfo[index]);
230  }
231}
232
233//-----------------------------
234//     PUBLIC FUNCTIONS
235//-----------------------------
236QString LoginWidget::currentUsername(){
237  QString id = listUsers->currentText();
238  return id;
239}
240
241QString LoginWidget::currentPassword(){
242  QString pw = linePassword->text();
243  return pw;
244}
245
246QString LoginWidget::currentDE(){
247  QString de = listDE->currentText();
248  return de;
249}
250
251void LoginWidget::setCurrentUser(QString id){
252  int index = idL.indexOf(id);
253  if(index == -1){
254    qDebug() << "LoginWidget: Item does not exist -" << id;
255  }else{
256    listUsers->setCurrentIndex(index);
257    listUserBig->setCurrentRow(index);
258    emit UserChanged(id);
259  }
260}
261
262void LoginWidget::setCurrentDE(QString de){
263  for(int i=0; i<listDE->count(); i++){
264    if( listDE->itemText(i) == de ){
265      listDE->setCurrentIndex(i);
266      break;
267    }
268  }
269  updateWidget();
270}
271
272void LoginWidget::setUsernames(QStringList uList){
273  if(uList.isEmpty()){ return; }
274  //Make sure that the two user widgets are identical
275  listUsers->clear();
276  listUsers->addItems(uList);
277  listUserBig->clear();
278  listUserBig->addItems(uList);
279  idL.clear();
280  idL = uList; //save for later
281  listUsers->setCurrentIndex(0);
282  listUserBig->setCurrentRow(0);
283  //Automatically select the user if there is only one
284  if(uList.length() == 1){
285    qDebug() << "Single User System Detected";
286    slotUserSelected(); 
287  }
288}
289
290void LoginWidget::setDesktops(QStringList text, QStringList icon, QStringList info){
291  if((text.length() != icon.length()) && (text.length() != info.length()) ){ qDebug() << "LoginWidget: Unequal text/icon desktop lists"; return; }
292  listDE->clear();
293  desktopIcons.clear(); desktopInfo.clear();
294  desktopIcons = icon; //save for later
295  desktopInfo = info; //save for later
296  for(int i=0; i<text.length(); i++){
297    listDE->addItem(text[i]);
298  }
299}
300
301void LoginWidget::displayHostName(QString name){
302  hostName = name;
303}
304
305void LoginWidget::changeButtonIcon(QString button, QString iconFile, QSize iconSize){
306  if(!QFile::exists(iconFile)){ qDebug() << "LoginWidget: invalid image file"<<iconFile; return; }
307  if(button.toLower() == "display"){ 
308    pushUserIcon->setIcon(QIcon(iconFile));
309    pushUserIcon->setIconSize(iconSize);
310    userIcon->setIcon(QIcon(iconFile));
311    userIcon->setIconSize(iconSize);
312  }else if(button.toLower() == "login"){ 
313    pushLogin->setIcon(QIcon(iconFile));
314    pushLogin->setIconSize(iconSize);
315  }else if(button.toLower() == "pwview"){ 
316    pushViewPassword->setIcon(QIcon(iconFile));
317    pushViewPassword->setIconSize(iconSize);
318  }else{ 
319    qDebug() << "LoginWidget: Cannot change the icon for button" << button << " - valid buttons are \"display\", \"login\", and \"pwview\""; 
320  }
321}
322
323void LoginWidget::setDesktopIconSize(QSize iconsize){
324  desktopIconSize = iconsize;
325}
326
327void LoginWidget::changeStyleSheet(QString item, QString style){
328  //Propagate the style sheet to both the buttons and the iconViewer
329  if(item.toLower()=="login"){ pushLogin->setStyleSheet(style); }
330  else if(item.toLower()=="pwview"){ pushViewPassword->setStyleSheet(style); }
331  else if(item.toLower()=="user"){ listUsers->setStyleSheet(style); }
332  else if(item.toLower()=="password"){ linePassword->setStyleSheet(style); }
333  else{ 
334    qDebug() << "LoginWidget: Invalid item to change style" << item << " - valid items are \"login\", \"pwview\", \"user\", and \"password\""; 
335  }
336}
337
338void LoginWidget::retranslateUi(){
339  //Set all the text for the widget (to easily allow changing the locale)
340  pushUserIcon->setText(tr("Select")); 
341  pushUserIcon->setToolTip(tr("Select an alternate user and clear the password field"));
342  userIcon->setText(tr("Select"));
343  userIcon->setToolTip(tr("Select this user"));
344 
345  pushLogin->setText(tr("Login"));
346  pushLogin->setToolTip(tr("Login to the system with the current user and password"));
347  pushViewPassword->setText(tr("Password"));
348  if(allowPWVisible){
349    pushViewPassword->setToolTip(tr("Hold to view the currently entered password"));
350  }else{
351    pushViewPassword->setToolTip(tr("Login password for the selected user"));     
352  }
353  listUsers->setToolTip(tr("Available users"));
354  listUserBig->setToolTip(tr("Available users"));
355  linePassword->setToolTip(tr("Login password for the selected user"));
356  listDE->setToolTip(tr("Available desktop environments"));
357  //Setup the computer/host name display
358  if( hostName.isEmpty() ){
359    this->setTitle("");
360  }else{
361    this->setTitle( QString(tr("Login to %1")).arg(hostName) );
362  }
363}
364
365void LoginWidget::resetFocus(QString item){
366  //Check for appropriate action if not specified
367  if(item.isEmpty() && userSelected ){ item="password"; }
368  else if(item.isEmpty() && !userSelected ){ item="userlist"; }   
369  //Set the proper keyboard focus
370  if(item == "userlist"){
371    if(userSelected){ listUsers->setFocus(); }
372    else{ listUserBig->setFocus(); }
373  }else if(item == "password"){
374    linePassword->setFocus();
375  }else{
376    //By default, de-select the user and set focus on the user selection
377    slotUserUnselected();   
378    listUserBig->setFocus();
379  }
380}
381
382void LoginWidget::allowPasswordView(bool allow){
383  //Enable/disable the password view button as desired
384  allowPWVisible = allow;
385  pushViewPassword->disconnect(); //disconnect the signal/slot (keep nice appearance)
386  if(allow){
387    connect(pushViewPassword,SIGNAL(pressed()),this,SLOT(slotChangePWView()));
388    connect(pushViewPassword,SIGNAL(released()),this,SLOT(slotChangePWView()));   
389  }
390}
391
392void LoginWidget::allowUserSelection(bool allow){
393  showUsers = allow;
394  updateWidget();
395}
Note: See TracBrowser for help on using the repository browser.