void UsersManagerWidget::addUser(const repo::core::model::RepoUser &user)
{
    QList<QStandardItem *> row;
    //--------------------------------------------------------------------------
    // User object itself
    QVariant var;
    var.setValue(user);

    repo::gui::primitive::RepoStandardItem *item =
            new repo::gui::primitive::RepoStandardItem(user.getUserName());

    item->setData(var);
//    item->setCheckable(true);
//    item->setCheckState(Qt::Checked);
//    item->setTristate(false);

    // Add avatar image if present
    const std::vector<char> image = user.getAvatarAsRawData();
    if (image.size())
    {
        QImage qimage = QImage::fromData((uchar*)&(image.at(0)), image.size());
        item->setIcon(QIcon(QPixmap::fromImage(qimage.scaled(QSize(32,32), Qt::IgnoreAspectRatio))));
    }
    else
    {
        QPixmap px(32,32);
        px.fill(QColor(0,0,0,0));
        item->setIcon(QIcon(px));
    }
    row.append(item);

    // First Name
    row.append(new repo::gui::primitive::RepoStandardItem(user.getFirstName()));

    // Last Name
    row.append(new repo::gui::primitive::RepoStandardItem(user.getLastName()));

    // Email
    row.append(new repo::gui::primitive::RepoStandardItem(user.getEmail()));

    // Roles count
    row.append(new repo::gui::primitive::RepoStandardItem(user.getRolesList().size()));

    // API Keys count
    row.append(new repo::gui::primitive::RepoStandardItem(user.getAPIKeysList().size()));

    //--------------------------------------------------------------------------
    getFilterableTree()->addTopLevelRow(row);
}
UserDialog::UserDialog(
        const repo::RepoToken *token,
        repo::RepoController *controller,
        const repo::core::model::RepoUser &user,
        const std::map<std::string, std::list<std::string> > &databasesWithProjects,
        const std::list<std::string> &customRolesList,
        const bool isCopy,
        QWidget *parent)
    : QDialog(parent)
    , controller(controller)
	, token(token)
    , user(user)
    , ui(new Ui::UserDialog)
{
    ui->setupUi(this);
    setWindowIcon(getIcon());


    //--------------------------------------------------------------------------
    // Connections
    QObject::connect(
        ui->avatarPushButton, &QPushButton::pressed,
        this, &UserDialog::openImageFileDialog);

    ui->rolesUnfilterableTreeWidget->registerTabWidget(ui->tabWidget, (int) Tab::ROLES);
    ui->apiKeysUnfilterableTreeWidget->registerTabWidget(ui->tabWidget, (int) Tab::API_KEYS);

    //--------------------------------------------------------------------------
    ui->avatarPushButton->setIcon(repo::gui::primitive::RepoFontAwesome::getInstance().getIcon(
                                       repo::gui::primitive::RepoFontAwesome::fa_user,
                                       QColor(Qt::gray)));

    if (!user.isEmpty() && user.isValid())
    {        
		setAvatar(user.getAvatarAsRawData());
    }

    //--------------------------------------------------------------------------
    // Databases
    QMap<std::string, std::list<std::string> > databasesMapping(databasesWithProjects);
    std::list<std::string> databases = databasesMapping.keys().toStdList();
    databases.sort();

    //--------------------------------------------------------------------------
    // DB Roles
    repo::gui::primitive::RepoComboBoxEditor::SeparatedEntries dbEntries;
    dbEntries << databases;
    repo::gui::primitive::RepoComboBoxEditor::SeparatedEntries dbRoleEntries;
    dbRoleEntries << customRolesList << controller->getStandardDatabaseRoles(token);

    //------------------------------------------------------------------------
    // Any DB Roles
    QList<repo::gui::primitive::RepoComboBoxEditor::SeparatedEntries> anyDBRolesLists;
    anyDBRolesLists << dbEntries << dbRoleEntries;

    //--------------------------------------------------------------------------
    // Admin DB Roles (any roles + admin only roles)
	dbRoleEntries << controller->getAdminDatabaseRoles(token);
    QList<repo::gui::primitive::RepoComboBoxEditor::SeparatedEntries> adminDBRolesLists;
    adminDBRolesLists << dbEntries << dbRoleEntries;

    //--------------------------------------------------------------------------
    // Populate Delegates

    QHash<QString, repo::gui::primitive::RepoComboBoxDelegate *> rolesDelegates;
    QHash<QString, repo::gui::primitive::RepoComboBoxDelegate *> projectsDelegates;

    for (auto database : databases)
    {
        QString qDatabase = QString::fromStdString(database);

        //----------------------------------------------------------------------
        // Projects delegate
        std::list<std::string> projects = databasesWithProjects.find(database)->second;
        repo::gui::primitive::RepoComboBoxEditor::SeparatedEntries projectsEntries;
        projectsEntries << projects;
        QList<repo::gui::primitive::RepoComboBoxEditor::SeparatedEntries> projectsLists;
        projectsLists << dbEntries << projectsEntries;
        projectsDelegates.insert(qDatabase, new repo::gui::primitive::RepoComboBoxDelegate(projectsLists));

        //----------------------------------------------------------------------
        // Roles delegate
        repo::gui::primitive::RepoComboBoxDelegate *rolesDelegate =
            (controller->getNameOfAdminDatabase(token) == database)
                ? new repo::gui::primitive::RepoComboBoxDelegate(adminDBRolesLists)
                : new repo::gui::primitive::RepoComboBoxDelegate(anyDBRolesLists);
        rolesDelegates.insert(qDatabase, rolesDelegate);
    }

    // Projects
    QStringList defaultRow = {tr("admin"), tr("<empty>")};

    // Roles
    ui->rolesUnfilterableTreeWidget->setHeaders({tr("Database"), tr("Role")});
    ui->rolesUnfilterableTreeWidget->setNewRowText(defaultRow);
    ui->rolesUnfilterableTreeWidget->setDelegates(rolesDelegates);

    // API Keys
    ui->apiKeysUnfilterableTreeWidget->setHeaders({tr("Label"), tr("API Key")});
    setNextAPIKey();

    //--------------------------------------------------------------------------
    // Populate user data
    if (!user.isEmpty())
    {
        QString username = QString::fromStdString(user.getUserName());
        if (isCopy)
        {
            username += " " + tr("(Copy)");
        }
        else
            ui->passwordLineEdit->setText(QString::fromStdString(user.getPassword()));

        ui->usernameLineEdit->setText(username);

        ui->firstNameLineEdit->setText(QString::fromStdString(user.getFirstName()));
        ui->lastNameLineEdit->setText(QString::fromStdString(user.getLastName()));
        ui->emailLineEdit->setText(QString::fromStdString(user.getEmail()));

        ui->credentialsGroupBox->setChecked(isCopy && !user.isEmpty());

        //----------------------------------------------------------------------
        // Acess Rights
        ui->rolesUnfilterableTreeWidget->addRows(user.getRolesList());
        ui->apiKeysUnfilterableTreeWidget->addRows(user.getAPIKeysList());
    }


    QObject::connect(ui->apiKeysUnfilterableTreeWidget,
                     &repo::gui::widget::UnfilterableTreeWidget::rowCountChanged,
                     this, &UserDialog::setNextAPIKey);

    //--------------------------------------------------------------------------
    // Regular expression validator for email
    // See http://www.regular-expressions.info/email.html
    QRegExp emailRegularExpression("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$", Qt::CaseInsensitive);
    emailValidator = new QRegExpValidator(emailRegularExpression);
    ui->emailLineEdit->setValidator(emailValidator);

}