2021-01-20 Fred Gleason <fredg@paravelsystems.com>

* Added a 'RDLogIcons::userType()' method.
	* Added a 'RDUser::Type' enumeration.
	* Added a 'RDUser::type()' method.
	* Added a 'RDUserListModel' class.
	* Refactored the 'List Users' dialog in rdadmin(1) to use the
	model-based API.

Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
This commit is contained in:
Fred Gleason 2021-01-20 15:46:42 -05:00
parent 18c9c1bdfc
commit 962abfa7fc
27 changed files with 1053 additions and 406 deletions

View File

@ -20844,3 +20844,10 @@
* Fixed a regression in rdlibrary(1) that broke display of the
'Group' control in the 'Edit Cart' dialog with a user with
no editing privileges.
2021-01-20 Fred Gleason <fredg@paravelsystems.com>
* Added a 'RDLogIcons::userType()' method.
* Added a 'RDUser::Type' enumeration.
* Added a 'RDUser::type()' method.
* Added a 'RDUserListModel' class.
* Refactored the 'List Users' dialog in rdadmin(1) to use the
model-based API.

View File

@ -244,10 +244,11 @@ dist_librd_la_SOURCES = dbversion.h\
rdttydevice.cpp rdttydevice.h\
rdttyout.cpp rdttyout.h\
rdurl.cpp rdurl.h\
rduser.cpp rduser.h\
rdupload.cpp rdupload.h\
rdunixserver.cpp rdunixserver.h\
rdunixsocket.cpp rdunixsocket.h\
rduser.cpp rduser.h\
rduserlistmodel.cpp rduserlistmodel.h\
rdversion.cpp rdversion.h\
rdwavedata.cpp rdwavedata.h\
rdwavedata_dialog.cpp rdwavedata_dialog.h\
@ -359,6 +360,7 @@ nodist_librd_la_SOURCES = moc_rdadd_cart.cpp\
moc_rdttydevice.cpp\
moc_rdunixserver.cpp\
moc_rdunixsocket.cpp\
moc_rduserlistmodel.cpp\
moc_rdupload.cpp\
moc_rdwavedata_dialog.cpp\
moc_rdwidget.cpp

View File

@ -176,6 +176,7 @@ SOURCES += rdtty.cpp
SOURCES += rdttydevice.cpp
SOURCES += rdttyout.cpp
SOURCES += rduser.cpp
SOURCES += rduserlistmodel.cpp
SOURCES += rdversion.cpp
SOURCES += rdwavedata.cpp
SOURCES += rdwavefile.cpp
@ -328,6 +329,7 @@ HEADERS += rdtty.h
HEADERS += rdttydevice.h
HEADERS += rdttyout.h
HEADERS += rduser.h
HEADERS += rduserlistmodel.h
HEADERS += rdversion.h
HEADERS += rdwavedata.h
HEADERS += rdweb.h

View File

@ -877,6 +877,30 @@
<source>is invalid</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>System Administrator</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>RSS Feeds Administrator</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>External User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Administrator</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDAddCart</name>
@ -3544,4 +3568,31 @@ Zkuste to, prosím, znovu!</translation>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDUserListModel</name>
<message>
<source>Login Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Full Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>E-Mail Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Phone Number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local Auth</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -873,6 +873,30 @@
<source>is invalid</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>System Administrator</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>RSS Feeds Administrator</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>External User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Administrator</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDAddCart</name>
@ -3525,4 +3549,31 @@ bitte erneut versuchen!</translation>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDUserListModel</name>
<message>
<source>Login Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Full Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>E-Mail Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Phone Number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local Auth</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -873,6 +873,30 @@
<source>is invalid</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>System Administrator</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>RSS Feeds Administrator</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>External User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Administrator</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDAddCart</name>
@ -3513,4 +3537,31 @@ please try again!</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDUserListModel</name>
<message>
<source>Login Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Full Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>E-Mail Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Phone Number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local Auth</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -843,6 +843,30 @@
<source>is invalid</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>System Administrator</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>RSS Feeds Administrator</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>External User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Administrator</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDAddCart</name>
@ -2797,4 +2821,31 @@ please try again!</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDUserListModel</name>
<message>
<source>Login Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Full Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>E-Mail Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Phone Number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local Auth</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -873,6 +873,30 @@
<source>is invalid</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>System Administrator</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>RSS Feeds Administrator</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>External User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Administrator</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDAddCart</name>
@ -3414,4 +3438,31 @@ prøv ein gong til!</translation>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDUserListModel</name>
<message>
<source>Login Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Full Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>E-Mail Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Phone Number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local Auth</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -873,6 +873,30 @@
<source>is invalid</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>System Administrator</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>RSS Feeds Administrator</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>External User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Administrator</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDAddCart</name>
@ -3414,4 +3438,31 @@ prøv ein gong til!</translation>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDUserListModel</name>
<message>
<source>Login Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Full Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>E-Mail Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Phone Number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local Auth</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -873,6 +873,30 @@
<source>is invalid</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>System Administrator</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>RSS Feeds Administrator</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>External User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Administrator</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDAddCart</name>
@ -3460,4 +3484,31 @@ por favor, tente novamente!</translation>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDUserListModel</name>
<message>
<source>Login Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Full Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>E-Mail Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Phone Number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local Auth</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -2,7 +2,7 @@
//
// Icons for Rivendell log events.
//
// (C) Copyright 2020 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2021 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -39,6 +39,11 @@
#include "../icons/mic16.xpm"
#include "../icons/traffic.xpm"
#include "../icons/localuser.xpm"
#include "../icons/user.xpm"
#include "../icons/rss.xpm"
#include "../icons/admin.xpm"
RDLogIcons::RDLogIcons()
{
d_list_icons.push_back(QPixmap(greencheckmark_xpm));
@ -59,6 +64,14 @@ RDLogIcons::RDLogIcons()
log_type_icons[RDLogLine::MusicLink]=QPixmap(music_xpm);
log_type_icons[RDLogLine::TrafficLink]=QPixmap(traffic_xpm);
log_track_cart_icon=QPixmap(track_cart_xpm);
//
// User Icons
//
d_user_icons[RDUser::TypeAdminConfig]=QPixmap(admin_xpm);
d_user_icons[RDUser::TypeAdminRss]=QPixmap(rss_xpm);
d_user_icons[RDUser::TypeLocalUser]=QPixmap(localuser_xpm);
d_user_icons[RDUser::TypeExternalUser]=QPixmap(user_xpm);
}
@ -75,3 +88,9 @@ QPixmap RDLogIcons::typeIcon(RDLogLine::Type type,RDLogLine::Source src) const
}
return log_type_icons.value(type);
}
QPixmap RDLogIcons::userIcon(RDUser::Type type) const
{
return d_user_icons.value(type);
}

View File

@ -2,7 +2,7 @@
//
// Icons for Rivendell log events.
//
// (C) Copyright 2020 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2020-2021 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -25,6 +25,7 @@
#include <QPixmap>
#include <rdlog_line.h>
#include <rduser.h>
class RDLogIcons
{
@ -35,11 +36,13 @@ class RDLogIcons
QPixmap listIcon(IconType type) const;
QPixmap typeIcon(RDLogLine::Type type,
RDLogLine::Source src=RDLogLine::Manual) const;
QPixmap userIcon(RDUser::Type type) const;
private:
QList<QPixmap> d_list_icons;
QMap<RDLogLine::Type,QPixmap> log_type_icons;
QPixmap log_track_cart_icon;
QMap<RDUser::Type,QPixmap> d_user_icons;
};

View File

@ -56,6 +56,36 @@ void RDUser::setName(const QString &name)
}
RDUser::Type RDUser::type() const
{
QString sql;
RDSqlQuery *q=NULL;
RDUser::Type type=RDUser::TypeAll;
sql=QString("select ")+
"ADMIN_CONFIG_PRIV,"+ // 00
"ADMIN_RSS_PRIV "+ // 01
"from USERS where "+
"LOGIN_NAME=\""+RDEscapeString(user_name)+"\"";
q=new RDSqlQuery(sql);
if(q->first()) {
if(q->value(0).toString()=="Y") {
type=RDUser::TypeAdminConfig;
}
else {
if(q->value(1).toString()=="Y") {
type=RDUser::TypeAdminRss;
}
else {
type=RDUser::TypeLocalUser;
}
}
}
return type;
}
bool RDUser::exists() const
{
return RDDoesRowExist("USERS","LOGIN_NAME",user_name);
@ -733,6 +763,42 @@ QString RDUser::emailContact(const QString &addr,const QString &fullname)
}
QString RDUser::typeText(RDUser::Type type)
{
QString ret=QObject::tr("Unknown");
switch(type) {
case RDUser::TypeAdminConfig:
ret=QObject::tr("System Administrator");
case RDUser::TypeAdminRss:
ret=QObject::tr("RSS Feeds Administrator");
case RDUser::TypeExternalUser:
ret=QObject::tr("External User");
break;
case RDUser::TypeLocalUser:
ret=QObject::tr("Local User");
break;
case RDUser::TypeUser:
ret=QObject::tr("User");
break;
case RDUser::TypeAdmin:
ret=QObject::tr("Administrator");
break;
case RDUser::TypeAll:
case RDUser::TypeLast:
break;
}
return ret;
}
void RDUser::SetRow(const QString &param,const QString &value) const
{
RDSqlQuery *q;

View File

@ -27,11 +27,14 @@
class RDUser
{
public:
enum Type {TypeAll=0,TypeAdminConfig=1,TypeAdminRss=2,TypeLocalUser=3,
TypeExternalUser=4,TypeAdmin=5,TypeUser=6,TypeLast=7};
RDUser(const QString &name);
RDUser();
QString name() const;
void setName(const QString &name);
bool exists() const;
Type type() const;
bool authenticated(bool webuser) const;
bool checkPassword(const QString &password,bool webuser);
QString password() const;
@ -109,6 +112,7 @@ class RDUser
QString *username=NULL,QDateTime *expire_dt=NULL);
static bool emailIsValid(const QString &addr);
static QString emailContact(const QString &addr,const QString &fullname);
static QString typeText(Type type);
private:
void SetRow(const QString &param,const QString &value) const;

403
lib/rduserlistmodel.cpp Normal file
View File

@ -0,0 +1,403 @@
// rduserlistmodel.cpp
//
// Data model for Rivendell users
//
// (C) Copyright 2021 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#include "rdapplication.h"
#include "rdescape_string.h"
#include "rduserlistmodel.h"
RDUserListModel::RDUserListModel(QObject *parent)
: QAbstractTableModel(parent)
{
d_type_filter=RDUser::TypeLast;
d_log_icons=new RDLogIcons();
//
// Column Attributes
//
unsigned left=Qt::AlignLeft|Qt::AlignVCenter;
unsigned center=Qt::AlignCenter;
// unsigned right=Qt::AlignRight|Qt::AlignVCenter;
d_headers.push_back(tr("Login Name"));
d_alignments.push_back(left);
d_headers.push_back(tr("Full Name"));
d_alignments.push_back(left);
d_headers.push_back(tr("Description"));
d_alignments.push_back(left);
d_headers.push_back(tr("E-Mail Address"));
d_alignments.push_back(center);
d_headers.push_back(tr("Phone Number"));
d_alignments.push_back(left);
d_headers.push_back(tr("Local Auth"));
d_alignments.push_back(center);
}
RDUserListModel::~RDUserListModel()
{
delete d_log_icons;
}
QPalette RDUserListModel::palette()
{
return d_palette;
}
void RDUserListModel::setPalette(const QPalette &pal)
{
d_palette=pal;
}
void RDUserListModel::setFont(const QFont &font)
{
d_font=font;
}
int RDUserListModel::columnCount(const QModelIndex &parent) const
{
return d_headers.size();
}
int RDUserListModel::rowCount(const QModelIndex &parent) const
{
return d_texts.size();
}
QVariant RDUserListModel::headerData(int section,Qt::Orientation orient,
int role) const
{
if((orient==Qt::Horizontal)&&(role==Qt::DisplayRole)) {
return d_headers.at(section);
}
return QVariant();
}
QVariant RDUserListModel::data(const QModelIndex &index,int role) const
{
QString str;
int col=index.column();
int row=index.row();
if(row<d_texts.size()) {
switch((Qt::ItemDataRole)role) {
case Qt::DisplayRole:
return d_texts.at(row).at(col);
case Qt::DecorationRole:
if(col==0) {
return d_icons.at(row);
}
break;
case Qt::TextAlignmentRole:
return d_alignments.at(col);
case Qt::FontRole:
return d_font;
case Qt::TextColorRole:
// Nothing to do!
break;
case Qt::BackgroundRole:
// Nothing to do!
break;
default:
break;
}
}
return QVariant();
}
QString RDUserListModel::userName(const QModelIndex &row) const
{
return d_texts.at(row.row()).at(0).toString();
}
QModelIndex RDUserListModel::addUser(const QString &username)
{
//
// Find the insertion offset
//
int offset=d_texts.size();
for(int i=0;i<d_texts.size();i++) {
if(username<d_texts.at(i).at(0).toString()) {
offset=i;
break;
}
}
beginInsertRows(QModelIndex(),offset,offset);
QList<QVariant> list;
for(int i=0;i<columnCount();i++) {
list.push_back(QVariant());
}
list[0]=username;
d_texts.insert(offset,list);
d_icons.insert(offset,QVariant());
updateRowLine(offset);
endInsertRows();
return createIndex(offset,0);
}
void RDUserListModel::removeUser(const QModelIndex &row)
{
beginRemoveRows(QModelIndex(),row.row(),row.row());
d_texts.removeAt(row.row());
d_icons.removeAt(row.row());
endRemoveRows();
}
void RDUserListModel::removeUser(const QString &username)
{
for(int i=0;i<d_texts.size();i++) {
if(d_texts.at(i).at(0)==username) {
removeUser(createIndex(i,0));
return;
}
}
}
void RDUserListModel::refresh(const QModelIndex &row)
{
if(row.row()<d_texts.size()) {
QString sql=sqlFields()+
"where LOGIN_NAME=\""+
RDEscapeString(d_texts.at(row.row()).at(0).toString())+
"\"";
RDSqlQuery *q=new RDSqlQuery(sql);
if(q->first()) {
updateRow(row.row(),q);
emit dataChanged(createIndex(row.row(),0),
createIndex(row.row(),columnCount()));
}
delete q;
}
}
void RDUserListModel::refresh(const QString &grpname)
{
for(int i=0;i<d_texts.size();i++) {
if(d_texts.at(i).at(0)==grpname) {
updateRowLine(i);
return;
}
}
}
RDUser::Type RDUserListModel::typeFilter() const
{
return d_type_filter;
}
void RDUserListModel::setTypeFilter(RDUser::Type type)
{
if(type!=d_type_filter) {
beginResetModel();
d_type_filter=type;
updateModel();
endResetModel();
}
}
void RDUserListModel::updateModel()
{
QList<QVariant> texts;
QList<QVariant> icons;
RDSqlQuery *q=NULL;
QString sql=sqlFields()+filterSql("");
sql+="order by LOGIN_NAME ";
beginResetModel();
d_texts.clear();
d_icons.clear();
printf("SQL: %s\n",sql.toUtf8().constData());
q=new RDSqlQuery(sql);
while(q->next()) {
d_texts.push_back(texts);
d_icons.push_back(icons);
updateRow(d_texts.size()-1,q);
}
delete q;
endResetModel();
}
void RDUserListModel::updateRowLine(int line)
{
if(line<d_texts.size()) {
QString sql=sqlFields()+
filterSql(d_texts.at(line).at(0).toString());
RDSqlQuery *q=new RDSqlQuery(sql);
if(q->first()) {
updateRow(line,q);
}
delete q;
}
}
void RDUserListModel::updateRow(int row,RDSqlQuery *q)
{
QList<QVariant> texts;
// Login Name
texts.push_back(q->value(0));
if(q->value(1).toString()=="Y") {
d_icons[row]=d_log_icons->userIcon(RDUser::TypeAdminConfig);
}
else {
if(q->value(2).toString()=="Y") {
d_icons[row]=d_log_icons->userIcon(RDUser::TypeAdminRss);
}
else {
if(q->value(7).toString()=="Y") {
d_icons[row]=d_log_icons->userIcon(RDUser::TypeLocalUser);
}
else {
d_icons[row]=d_log_icons->userIcon(RDUser::TypeExternalUser);
}
}
}
// Full Name
texts.push_back(q->value(3));
// Description
texts.push_back(q->value(4));
// E-Mail Address
texts.push_back(q->value(5));
// Phone Number
texts.push_back(q->value(6));
// Local Auth
texts.push_back(q->value(7));
d_texts[row]=texts;
}
QString RDUserListModel::sqlFields() const
{
QString sql=QString("select ")+
"USERS.LOGIN_NAME,"+ // 00
"USERS.ADMIN_CONFIG_PRIV,"+ // 01
"USERS.ADMIN_RSS_PRIV,"+ // 02
"USERS.FULL_NAME,"+ // 03
"USERS.DESCRIPTION,"+ // 04
"USERS.EMAIL_ADDRESS,"+ // 05
"USERS.PHONE_NUMBER,"+ // 06
"USERS.LOCAL_AUTH "+ // 07
"from USERS ";
return sql;
}
QString RDUserListModel::filterSql(const QString &username) const
{
QString sql=" ";
switch(d_type_filter) {
case RDUser::TypeAll:
if(!username.isEmpty()) {
sql=" where LOGIN_NAME=\""+RDEscapeString(username)+"\"";
}
break;
case RDUser::TypeAdminConfig:
sql=" where (ADMIN_CONFIG_PRIV=\"Y\")";
if(!username.isEmpty()) {
sql+=" && (LOGIN_NAME=\""+RDEscapeString(username)+"\")";
}
break;
case RDUser::TypeAdminRss:
sql=" where (ADMIN_RSS_PRIV=\"Y\")";
if(!username.isEmpty()) {
sql+=" && (LOGIN_NAME=\""+RDEscapeString(username)+"\")";
}
break;
case RDUser::TypeLocalUser:
sql=QString("where (ADMIN_CONFIG_PRIV='N')&&(ADMIN_RSS_PRIV='N')&&")+
"(LOCAL_AUTH='Y')";
if(!username.isEmpty()) {
sql+=" && (LOGIN_NAME=\""+RDEscapeString(username)+"\")";
}
break;
case RDUser::TypeExternalUser:
sql=QString("where (ADMIN_CONFIG_PRIV='N')&&(ADMIN_RSS_PRIV='N')&&")+
"(LOCAL_AUTH='N')";
if(!username.isEmpty()) {
sql+=" && (LOGIN_NAME=\""+RDEscapeString(username)+"\")";
}
break;
case RDUser::TypeUser:
sql=QString("where (ADMIN_CONFIG_PRIV='N')&&(ADMIN_RSS_PRIV='N')");
if(!username.isEmpty()) {
sql+=" && (LOGIN_NAME=\""+RDEscapeString(username)+"\")";
}
break;
case RDUser::TypeAdmin:
sql=QString("where ((ADMIN_CONFIG_PRIV='Y')||(ADMIN_RSS_PRIV='Y'))");
if(!username.isEmpty()) {
sql+=" && (LOGIN_NAME=\""+RDEscapeString(username)+"\")";
}
break;
case RDUser::TypeLast:
break;
}
return sql;
}

79
lib/rduserlistmodel.h Normal file
View File

@ -0,0 +1,79 @@
// rduserlistmodel.h
//
// Data model for Rivendell users
//
// (C) Copyright 2021 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#ifndef RDUSERLISTMODEL_H
#define RDUSERLISTMODEL_H
#include <QAbstractTableModel>
#include <QFont>
#include <QList>
#include <QPalette>
#include <rddb.h>
#include <rdlog_icons.h>
#include <rdnotification.h>
#include <rduser.h>
class RDUserListModel : public QAbstractTableModel
{
Q_OBJECT
public:
RDUserListModel(QObject *parent=0);
~RDUserListModel();
QPalette palette();
void setPalette(const QPalette &pal);
void setFont(const QFont &font);
int columnCount(const QModelIndex &parent=QModelIndex()) const;
int rowCount(const QModelIndex &parent=QModelIndex()) const;
QVariant headerData(int section,Qt::Orientation orient,
int role=Qt::DisplayRole) const;
QVariant data(const QModelIndex &index,int role=Qt::DisplayRole) const;
QString userName(const QModelIndex &row) const;
QModelIndex addUser(const QString &name);
void removeUser(const QModelIndex &row);
void removeUser(const QString &username);
void refresh(const QModelIndex &row);
void refresh(const QString &username);
RDUser::Type typeFilter() const;
public slots:
void setTypeFilter(RDUser::Type type);
protected:
void updateModel();
void updateRowLine(int line);
void updateRow(int row,RDSqlQuery *q);
QString sqlFields() const;
virtual QString filterSql(const QString &username) const;
private:
QPalette d_palette;
QFont d_font;
QStringList d_service_names;
QList<QVariant> d_headers;
QList<QVariant> d_alignments;
QList<QList<QVariant> > d_texts;
QList<QVariant> d_icons;
RDLogIcons *d_log_icons;
RDUser::Type d_type_filter;
};
#endif // RDUSERLISTMODEL_H

View File

@ -148,16 +148,16 @@ void AddUser::okData()
q=new RDSqlQuery(sql);
delete q;
delete user;
done(-1);
done(false);
return;
}
delete user;
*user_name=user_name_edit->text();
done(0);
done(true);
}
void AddUser::cancelData()
{
done(-1);
done(false);
}

View File

@ -658,11 +658,11 @@ void EditUser::okData()
user_user->setEditPodcast(user_edit_podcast_button->isChecked());
user_user->setDeletePodcast(user_delete_podcast_button->isChecked());
done(0);
done(true);
}
void EditUser::cancelData()
{
done(-1);
done(false);
}

View File

@ -2,7 +2,7 @@
//
// List Rivendell Users
//
// (C) Copyright 2002-2020 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2002-2021 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -30,18 +30,9 @@
#include "edit_user.h"
#include "list_users.h"
//
// Icons
//
#include "../icons/admin.xpm"
#include "../icons/localuser.xpm"
#include "../icons/rss.xpm"
#include "../icons/user.xpm"
ListUsers::ListUsers(const QString &admin_name,QWidget *parent)
: RDDialog(parent)
{
setModal(true);
list_admin_name=admin_name;
//
@ -52,14 +43,6 @@ ListUsers::ListUsers(const QString &admin_name,QWidget *parent)
setWindowTitle("RDAdmin - "+tr("Rivendell User List"));
//
// Create Icons
//
list_admin_map=new QPixmap(admin_xpm);
list_localuser_map=new QPixmap(localuser_xpm);
list_rss_map=new QPixmap(rss_xpm);
list_user_map=new QPixmap(user_xpm);
//
// Add Button
//
@ -96,31 +79,29 @@ ListUsers::ListUsers(const QString &admin_name,QWidget *parent)
//
// User List
//
list_users_view=new RDListView(this);
list_users_view->setAllColumnsShowFocus(true);
list_users_view->setItemMargin(5);
list_users_view->addColumn("");
list_users_view->addColumn(tr("Login Name"));
list_users_view->addColumn(tr("Full Name"));
list_users_view->addColumn(tr("Description"));
list_users_view->addColumn(tr("E-Mail Address"));
list_users_view->addColumn(tr("Phone Number"));
list_users_view->addColumn(tr("Local Auth"));
list_users_view->setColumnAlignment(6,Qt::AlignCenter);
QLabel *list_box_label=new QLabel(list_users_view,tr("&Users:"),this);
list_box_label->setFont(labelFont());
list_box_label->setGeometry(14,11,85,19);
connect(list_users_view,
SIGNAL(doubleClicked(Q3ListViewItem *,const QPoint &,int)),
this,
SLOT(doubleClickedData(Q3ListViewItem *,const QPoint &,int)));
list_users_view=new QTableView(this);
list_users_view->setSelectionBehavior(QAbstractItemView::SelectRows);
list_users_view->setSelectionMode(QAbstractItemView::SingleSelection);
list_users_view->setShowGrid(false);
list_users_view->setSortingEnabled(false);
list_users_view->setWordWrap(false);
list_users_model=new RDUserListModel(this);
list_users_model->setFont(defaultFont());
list_users_model->setPalette(palette());
list_users_view->setModel(list_users_model);
connect(list_users_view,SIGNAL(doubleClicked(const QModelIndex &)),
this,SLOT(doubleClickedData(const QModelIndex &)));
connect(list_users_model,SIGNAL(modelReset()),
list_users_view,SLOT(resizeColumnsToContents()));
RefreshList();
list_users_model->setTypeFilter(RDUser::TypeAll);
}
ListUsers::~ListUsers()
{
delete list_users_view;
delete list_users_model;
}
@ -140,67 +121,67 @@ void ListUsers::addData()
{
QString user;
AddUser *add_user=new AddUser(&user,this);
if(add_user->exec()<0) {
delete add_user;
AddUser *d=new AddUser(&user,this);
if(!d->exec()) {
delete d;
return;
}
delete add_user;
add_user=NULL;
RDListViewItem *item=new RDListViewItem(list_users_view);
item->setText(1,user);
RefreshItem(item);
item->setSelected(true);
list_users_view->setCurrentItem(item);
list_users_view->ensureItemVisible(item);
delete d;
QModelIndex index=list_users_model->addUser(user);
if(index.isValid()) {
list_users_view->selectRow(index.row());
list_users_view->scrollTo(index,QAbstractItemView::PositionAtCenter);
}
}
void ListUsers::editData()
{
RDListViewItem *item=(RDListViewItem *)list_users_view->selectedItem();
if(item==NULL) {
QModelIndexList rows=list_users_view->selectionModel()->selectedRows();
if(rows.size()!=1) {
return;
}
EditUser *edit_user=new EditUser(item->text(1),this);
if(edit_user->exec()==0) {
RefreshItem(item);
EditUser *d=new EditUser(list_users_model->userName(rows.first()),this);
if(d->exec()) {
list_users_model->refresh(rows.first());
}
delete edit_user;
delete d;
}
void ListUsers::deleteData()
{
RDListViewItem *item=(RDListViewItem *)list_users_view->selectedItem();
if(item==NULL) {
QString sql;
RDSqlQuery *q;
QString warning;
QString str;
QModelIndexList rows=list_users_view->selectionModel()->selectedRows();
if(rows.size()!=1) {
return;
}
if(list_admin_name==item->text(1)) {
QString username=list_users_model->userName(rows.first());
if(list_admin_name==username) {
QMessageBox::warning(this,tr("Delete User"),
tr("You cannot delete yourself!"));
return;
}
QString sql;
RDSqlQuery *q;
QString warning;
QString str;
QString username=RDEscapeString(item->text(1));
//
// Check for default user assignments
//
sql=QString("select NAME from STATIONS where ")+
sql=QString("select ")+
"NAME "+ // 00
"from STATIONS where "+
"DEFAULT_NAME=\""+RDEscapeString(username)+"\"";
q=new RDSqlQuery(sql);
if(q->size()>0) {
if(q->first()) {
str=tr("This user is set as the default user for the following hosts:\n\n");
while(q->next()) {
do {
str+=(" "+q->value(0).toString()+"\n");
}
} while(q->next());
str+="\n";
str+=tr("You must change this before deleting the user.");
delete q;
@ -210,15 +191,10 @@ void ListUsers::deleteData()
delete q;
str=QString(tr("Are you sure you want to delete user"));
warning+=str+" \""+item->text(1)+"\"?";
switch(QMessageBox::warning(this,"RDAdmin - "+tr("Delete User"),warning,
QMessageBox::Yes,QMessageBox::No)) {
case QMessageBox::No:
case Qt::NoButton:
warning+=str+" \""+username+"\"?";
if(QMessageBox::warning(this,"RDAdmin - "+tr("Delete User"),warning,
QMessageBox::Yes,QMessageBox::No)!=QMessageBox::Yes) {
return;
default:
break;
}
//
@ -226,40 +202,34 @@ void ListUsers::deleteData()
//
sql=QString("delete from FEED_PERMS where ")+
"USER_NAME=\""+RDEscapeString(username)+"\"";
q=new RDSqlQuery(sql);
delete q;
RDSqlQuery::apply(sql);
//
// Delete Member User Perms
//
sql=QString("delete from USER_PERMS where ")+
"USER_NAME=\""+RDEscapeString(username)+"\"";
q=new RDSqlQuery(sql);
delete q;
RDSqlQuery::apply(sql);
//
// Delete from User List
//
sql=QString("delete from USERS where ")+
"LOGIN_NAME=\""+RDEscapeString(username)+"\"";
q=new RDSqlQuery(sql);
delete q;
RDSqlQuery::apply(sql);
//
// Delete from Cached Web Connections
//
sql=QString("delete from WEB_CONNECTIONS where ")+
"LOGIN_NAME=\""+RDEscapeString(username)+"\"";
q=new RDSqlQuery(sql);
delete q;
RDSqlQuery::apply(sql);
item->setSelected(false);
delete item;
list_users_model->removeUser(username);
}
void ListUsers::doubleClickedData(Q3ListViewItem *item,const QPoint &pt,
int col)
void ListUsers::doubleClickedData(const QModelIndex &index)
{
editData();
}
@ -267,7 +237,7 @@ void ListUsers::doubleClickedData(Q3ListViewItem *item,const QPoint &pt,
void ListUsers::closeData()
{
done(0);
done(true);
}
@ -279,93 +249,3 @@ void ListUsers::resizeEvent(QResizeEvent *e)
list_close_button->setGeometry(size().width()-90,size().height()-60,80,50);
list_users_view->setGeometry(10,30,size().width()-120,size().height()-40);
}
void ListUsers::RefreshList()
{
QString sql;
RDSqlQuery *q;
RDListViewItem *item;
list_users_view->clear();
sql=QString("select ")+
"ADMIN_CONFIG_PRIV,"+ // 00
"ADMIN_RSS_PRIV,"+ // 01
"LOGIN_NAME,"+ // 02
"FULL_NAME,"+ // 03
"DESCRIPTION,"+ // 04
"EMAIL_ADDRESS,"+ // 05
"PHONE_NUMBER,"+ // 06
"LOCAL_AUTH "+ // 07
"from USERS";
q=new RDSqlQuery(sql);
while (q->next()) {
item=new RDListViewItem(list_users_view);
if(q->value(0).toString()=="Y") {
item->setPixmap(0,*list_admin_map);
}
else {
if(q->value(1).toString()=="Y") {
item->setPixmap(0,*list_rss_map);
}
else {
if(q->value(7).toString()=="Y") {
item->setPixmap(0,*list_localuser_map);
}
else {
item->setPixmap(0,*list_user_map);
}
}
}
item->setText(1,q->value(2).toString());
item->setText(2,q->value(3).toString());
item->setText(3,q->value(4).toString());
item->setText(4,q->value(5).toString());
item->setText(5,q->value(6).toString());
item->setText(6,q->value(7).toString());
}
delete q;
}
void ListUsers::RefreshItem(RDListViewItem *item)
{
QString sql;
RDSqlQuery *q;
sql=QString("select ")+
"ADMIN_CONFIG_PRIV,"+ // 00
"ADMIN_RSS_PRIV,"+ // 01
"FULL_NAME,"+ // 02
"DESCRIPTION,"+ // 03
"EMAIL_ADDRESS,"+ // 04
"PHONE_NUMBER,"+ // 05
"LOCAL_AUTH "+ // 06
"from USERS where "+
"LOGIN_NAME=\""+RDEscapeString(item->text(1))+"\"";
q=new RDSqlQuery(sql);
if(q->first()) {
if(q->value(0).toString()=="Y") {
item->setPixmap(0,*list_admin_map);
}
else {
if(q->value(1).toString()=="Y") {
item->setPixmap(0,*list_rss_map);
}
else {
if(q->value(6).toString()=="Y") {
item->setPixmap(0,*list_localuser_map);
}
else {
item->setPixmap(0,*list_user_map);
}
}
}
item->setText(2,q->value(2).toString());
item->setText(3,q->value(3).toString());
item->setText(4,q->value(4).toString());
item->setText(5,q->value(5).toString());
item->setText(6,q->value(6).toString());
}
delete q;
}

View File

@ -2,7 +2,7 @@
//
// List Rivendell Users
//
// (C) Copyright 2002-2020 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2002-2021 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -21,12 +21,14 @@
#ifndef LIST_USERS_H
#define LIST_USERS_H
#include <qpixmap.h>
#include <qpushbutton.h>
#include <QPixmap>
#include <QPushButton>
#include <QTableView>
#include <rddb.h>
#include <rddialog.h>
#include <rdlistviewitem.h>
#include <rduserlistmodel.h>
class ListUsers : public RDDialog
{
@ -41,25 +43,20 @@ class ListUsers : public RDDialog
void addData();
void editData();
void deleteData();
void doubleClickedData(Q3ListViewItem *item,const QPoint &pt,int col);
void doubleClickedData(const QModelIndex &index);
void closeData();
protected:
void resizeEvent(QResizeEvent *e);
private:
void RefreshList();
void RefreshItem(RDListViewItem *item);
RDListView *list_users_view;
QTableView *list_users_view;
RDUserListModel *list_users_model;
QPushButton *list_add_button;
QPushButton *list_edit_button;
QPushButton *list_delete_button;
QPushButton *list_close_button;
QString list_admin_name;
QPixmap *list_admin_map;
QPixmap *list_localuser_map;
QPixmap *list_rss_map;
QPixmap *list_user_map;
};

View File

@ -6197,7 +6197,7 @@ Stále ještě chcete pokračovat?</translation>
</message>
<message>
<source>&amp;Users:</source>
<translation>&amp;Uživatelé:</translation>
<translation type="obsolete">&amp;Uživatelé:</translation>
</message>
<message>
<source>DESCRIPTION</source>
@ -6213,51 +6213,27 @@ Stále ještě chcete pokračovat?</translation>
</message>
<message>
<source>Are you sure you want to delete user</source>
<translation>Opravdu chcete smazat tohoto uživatele</translation>
<translation type="unfinished">Opravdu chcete smazat tohoto uživatele</translation>
</message>
<message>
<source>Delete User</source>
<translation>Smazat uživatele</translation>
<translation type="unfinished">Smazat uživatele</translation>
</message>
<message>
<source>You must change this before deleting the user.</source>
<translation>Toto musíte před smazáním uživatele změnit.</translation>
<translation type="unfinished">Toto musíte před smazáním uživatele změnit.</translation>
</message>
<message>
<source>This user is set as the default user for the following hosts:
</source>
<translation>Tento uživatel je nastaven jako výchozí u následujících serverů:
<translation type="unfinished">Tento uživatel je nastaven jako výchozí u následujících serverů:
</translation>
</message>
<message>
<source>You cannot delete yourself!</source>
<translation>Nemůžete vymazat sám sebe!</translation>
</message>
<message>
<source>Login Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Full Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>E-Mail Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Phone Number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local Auth</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Nemůžete vymazat sám sebe!</translation>
</message>
</context>
<context>

View File

@ -5893,7 +5893,7 @@ Wollen Sie immernoch fortfahren?</translation>
</message>
<message>
<source>&amp;Users:</source>
<translation>&amp;Benutzer:</translation>
<translation type="obsolete">&amp;Benutzer:</translation>
</message>
<message>
<source>DESCRIPTION</source>
@ -5909,51 +5909,27 @@ Wollen Sie immernoch fortfahren?</translation>
</message>
<message>
<source>Are you sure you want to delete user</source>
<translation>Sind Sie sicher, daß sie diesen Benutzer löschen wollen</translation>
<translation type="unfinished">Sind Sie sicher, daß sie diesen Benutzer löschen wollen</translation>
</message>
<message>
<source>Delete User</source>
<translation>Benutzer löschen</translation>
<translation type="unfinished">Benutzer löschen</translation>
</message>
<message>
<source>You must change this before deleting the user.</source>
<translation>Sie müssen dies ändern, bevor sie den Benutzer löschen können.</translation>
<translation type="unfinished">Sie müssen dies ändern, bevor sie den Benutzer löschen können.</translation>
</message>
<message>
<source>This user is set as the default user for the following hosts:
</source>
<translation>Dieser Benutzer ist der Standardbenutzer folgender Hosts:
<translation type="unfinished">Dieser Benutzer ist der Standardbenutzer folgender Hosts:
</translation>
</message>
<message>
<source>You cannot delete yourself!</source>
<translation>Die können sich nicht selbst löschen!</translation>
</message>
<message>
<source>Login Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Full Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>E-Mail Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Phone Number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local Auth</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Die können sich nicht selbst löschen!</translation>
</message>
</context>
<context>

View File

@ -6151,7 +6151,7 @@ Do you still want to proceed?</source>
</message>
<message>
<source>&amp;Users:</source>
<translation>&amp;Usuarios:</translation>
<translation type="obsolete">&amp;Usuarios:</translation>
</message>
<message>
<source>DESCRIPTION</source>
@ -6167,51 +6167,27 @@ Do you still want to proceed?</source>
</message>
<message>
<source>Are you sure you want to delete user</source>
<translation>Está seguro de querer eliminar el usuario</translation>
<translation type="unfinished">Está seguro de querer eliminar el usuario</translation>
</message>
<message>
<source>Delete User</source>
<translation>Eliminar usuario</translation>
<translation type="unfinished">Eliminar usuario</translation>
</message>
<message>
<source>You must change this before deleting the user.</source>
<translation>Usted debe cambiar esto antes de eliminar el usuario.</translation>
<translation type="unfinished">Usted debe cambiar esto antes de eliminar el usuario.</translation>
</message>
<message>
<source>This user is set as the default user for the following hosts:
</source>
<translation>Este usuario es el predeterminado en los siguientes equipos:
<translation type="unfinished">Este usuario es el predeterminado en los siguientes equipos:
</translation>
</message>
<message>
<source>You cannot delete yourself!</source>
<translation>¡Ud. no puede borrarse a mismo!</translation>
</message>
<message>
<source>Login Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Full Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>E-Mail Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Phone Number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local Auth</source>
<translation type="unfinished"></translation>
<translation type="unfinished">¡Ud. no puede borrarse a mismo!</translation>
</message>
</context>
<context>

View File

@ -4879,20 +4879,12 @@ Carts</source>
<source>&amp;Close</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&amp;Users:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Are you sure you want to delete user</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>You must change this before deleting the user.</source>
<source>You cannot delete yourself!</source>
<translation type="unfinished"></translation>
</message>
<message>
@ -4902,31 +4894,11 @@ Carts</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>You cannot delete yourself!</source>
<source>You must change this before deleting the user.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Login Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Full Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>E-Mail Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Phone Number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local Auth</source>
<source>Are you sure you want to delete user</source>
<translation type="unfinished"></translation>
</message>
</context>

View File

@ -5754,7 +5754,7 @@ Er du sikker på at du vil halda fram?</translation>
</message>
<message>
<source>&amp;Users:</source>
<translation>Br&amp;ukarar:</translation>
<translation type="obsolete">Br&amp;ukarar:</translation>
</message>
<message>
<source>Can&apos;t Delete User</source>
@ -5762,15 +5762,15 @@ Er du sikker på at du vil halda fram?</translation>
</message>
<message>
<source>You cannot delete yourself!</source>
<translation>Du kan ikkje sletta deg sjølv!</translation>
<translation type="unfinished">Du kan ikkje sletta deg sjølv!</translation>
</message>
<message>
<source>Are you sure you want to delete user</source>
<translation>Er du sikker at du vil sletta brukaren</translation>
<translation type="unfinished">Er du sikker at du vil sletta brukaren</translation>
</message>
<message>
<source>Delete User</source>
<translation>Slett brukaren</translation>
<translation type="unfinished">Slett brukaren</translation>
</message>
<message>
<source>DESCRIPTION</source>
@ -5786,30 +5786,6 @@ Er du sikker på at du vil halda fram?</translation>
<source>You must change this before deleting the user.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Login Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Full Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>E-Mail Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Phone Number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local Auth</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Login</name>

View File

@ -5754,7 +5754,7 @@ Er du sikker på at du vil halda fram?</translation>
</message>
<message>
<source>&amp;Users:</source>
<translation>Br&amp;ukarar:</translation>
<translation type="obsolete">Br&amp;ukarar:</translation>
</message>
<message>
<source>Can&apos;t Delete User</source>
@ -5762,15 +5762,15 @@ Er du sikker på at du vil halda fram?</translation>
</message>
<message>
<source>You cannot delete yourself!</source>
<translation>Du kan ikkje sletta deg sjølv!</translation>
<translation type="unfinished">Du kan ikkje sletta deg sjølv!</translation>
</message>
<message>
<source>Are you sure you want to delete user</source>
<translation>Er du sikker at du vil sletta brukaren</translation>
<translation type="unfinished">Er du sikker at du vil sletta brukaren</translation>
</message>
<message>
<source>Delete User</source>
<translation>Slett brukaren</translation>
<translation type="unfinished">Slett brukaren</translation>
</message>
<message>
<source>DESCRIPTION</source>
@ -5786,30 +5786,6 @@ Er du sikker på at du vil halda fram?</translation>
<source>You must change this before deleting the user.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Login Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Full Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>E-Mail Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Phone Number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local Auth</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Login</name>

View File

@ -5877,55 +5877,31 @@ Você quer proceder?</translation>
</message>
<message>
<source>&amp;Users:</source>
<translation>&amp;Usuários: </translation>
<translation type="obsolete">&amp;Usuários: </translation>
</message>
<message>
<source>Delete User</source>
<translation>Deletar Usuário</translation>
<translation type="unfinished">Deletar Usuário</translation>
</message>
<message>
<source>You cannot delete yourself!</source>
<translation>Você não pode se deletar!</translation>
<translation type="unfinished">Você não pode se deletar!</translation>
</message>
<message>
<source>This user is set as the default user for the following hosts:
</source>
<translation>Este usuário é o padrão para os seguintes clientes:
<translation type="unfinished">Este usuário é o padrão para os seguintes clientes:
</translation>
</message>
<message>
<source>You must change this before deleting the user.</source>
<translation>Você deve mudar isto antes de deletar o usuário.</translation>
<translation type="unfinished">Você deve mudar isto antes de deletar o usuário.</translation>
</message>
<message>
<source>Are you sure you want to delete user</source>
<translation>Tem certeza que quer deletar este Usuário?</translation>
</message>
<message>
<source>Login Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Full Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>E-Mail Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Phone Number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Local Auth</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Tem certeza que quer deletar este Usuário?</translation>
</message>
</context>
<context>