diff --git a/plugins/org.jkiss.dbeaver.ext.postgresql/plugin.properties b/plugins/org.jkiss.dbeaver.ext.postgresql/plugin.properties
index 2d4cfe966635ebe50f0dfedfa656deddd412ab5b..988fa1f3b73bfa8156d73c0634b9ca8a1b404db8 100644
--- a/plugins/org.jkiss.dbeaver.ext.postgresql/plugin.properties
+++ b/plugins/org.jkiss.dbeaver.ext.postgresql/plugin.properties
@@ -444,4 +444,4 @@ tree.roles.node.name=Roles
tree.role.member.node.name=Role
tree.role.members.node.name=Members
tree.role.belong.node.name=Role
-tree.role.belongs.node.name=Belongs
+tree.role.belongs.node.name=Roles
diff --git a/plugins/org.jkiss.dbeaver.ext.postgresql/plugin.xml b/plugins/org.jkiss.dbeaver.ext.postgresql/plugin.xml
index 71681eb7f651e86e227943eea14b57e036c263f0..3adaf581e0d5ae1990891e23702e040c13448a13 100644
--- a/plugins/org.jkiss.dbeaver.ext.postgresql/plugin.xml
+++ b/plugins/org.jkiss.dbeaver.ext.postgresql/plugin.xml
@@ -259,6 +259,11 @@
contributor="org.jkiss.dbeaver.ui.editors.sql.SQLEditorContributorNested" type="folder">
+
+
+
diff --git a/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreRole.java b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreRole.java
index b3bd29550e2ae673d57d5369d254c44e3abc0e82..72f421bdddf9474be76a065fd42b77b53b32dd4b 100644
--- a/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreRole.java
+++ b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreRole.java
@@ -35,6 +35,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Date;
+import java.util.List;
/**
* PostgreRole
@@ -212,6 +213,10 @@ public class PostgreRole implements PostgreObject {
return belongsCache.getAllObjects(monitor, this);
}
+ public List getPrivileges(DBRProgressMonitor monitor) throws DBException {
+ return null;
+ }
+
@Override
public String toString() {
return getName();
diff --git a/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreRolePrivilege.java b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreRolePrivilege.java
new file mode 100644
index 0000000000000000000000000000000000000000..dbbd89e2de81ec64e5f8fbb18723f1ab3310d488
--- /dev/null
+++ b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreRolePrivilege.java
@@ -0,0 +1,82 @@
+/*
+ * DBeaver - Universal Database Manager
+ * Copyright (C) 2010-2016 Serge Rieder (serge@jkiss.org)
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package org.jkiss.dbeaver.ext.postgresql.model;
+
+import org.jkiss.code.NotNull;
+import org.jkiss.code.Nullable;
+import org.jkiss.dbeaver.model.meta.Property;
+import org.jkiss.dbeaver.model.struct.DBSObject;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * PostgreRolePrivilege
+ */
+public class PostgreRolePrivilege implements DBSObject {
+
+ private final PostgreDatabase database;
+
+ public PostgreRolePrivilege(PostgreDatabase database, ResultSet dbResult)
+ throws SQLException
+ {
+ this.database = database;
+ }
+
+ @Nullable
+ @Override
+ public String getDescription() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public DBSObject getParentObject() {
+ return database;
+ }
+
+ @NotNull
+ @Override
+ public PostgreDataSource getDataSource() {
+ return database.getDataSource();
+ }
+
+ @Override
+ public boolean isPersisted() {
+ return true;
+ }
+
+ @NotNull
+ @Override
+ @Property(viewable = true, order = 1)
+ public String getName()
+ {
+ return "";
+ }
+
+ @NotNull
+ public PostgreDatabase getDatabase() {
+ return database;
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+}
+
diff --git a/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/ui/editors/PostgresRolePrivilegesEditor.java b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/ui/editors/PostgresRolePrivilegesEditor.java
new file mode 100644
index 0000000000000000000000000000000000000000..b308acbb8b642411263cae89588180a3838bd600
--- /dev/null
+++ b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/ui/editors/PostgresRolePrivilegesEditor.java
@@ -0,0 +1,219 @@
+/*
+ * DBeaver - Universal Database Manager
+ * Copyright (C) 2010-2016 Serge Rieder (serge@jkiss.org)
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package org.jkiss.dbeaver.ext.postgresql.ui.editors;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.jkiss.dbeaver.DBException;
+import org.jkiss.dbeaver.Log;
+import org.jkiss.dbeaver.ext.postgresql.model.PostgreRole;
+import org.jkiss.dbeaver.ext.postgresql.model.PostgreRolePrivilege;
+import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
+import org.jkiss.dbeaver.model.runtime.load.DatabaseLoadService;
+import org.jkiss.dbeaver.ui.LoadingJob;
+import org.jkiss.dbeaver.ui.UIUtils;
+import org.jkiss.dbeaver.ui.controls.ProgressPageControl;
+import org.jkiss.dbeaver.ui.editors.AbstractDatabaseObjectEditor;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+/**
+ * PostgresRolePrivilegesEditor
+ */
+public class PostgresRolePrivilegesEditor extends AbstractDatabaseObjectEditor
+{
+ private static final Log log = Log.getLog(PostgresRolePrivilegesEditor.class);
+
+ private PageControl pageControl;
+
+ private Font boldFont;
+ private boolean isLoaded;
+
+ @Override
+ public void createPartControl(Composite parent)
+ {
+ boldFont = UIUtils.makeBoldFont(parent.getFont());
+
+ pageControl = new PageControl(parent);
+
+ Composite container = UIUtils.createPlaceholder(pageControl, 2, 5);
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ container.setLayoutData(gd);
+
+ Composite leftPane = UIUtils.createPlaceholder(container, 2);
+ leftPane.setLayoutData(new GridData(GridData.FILL_BOTH));
+ leftPane.setLayout(new GridLayout(2, true));
+/*
+ {
+ Composite catalogGroup = UIUtils.createControlGroup(leftPane, MySQLMessages.editors_user_editor_privileges_group_catalogs, 1, GridData.FILL_BOTH, 0);
+
+ catalogsTable = new Table(catalogGroup, SWT.BORDER | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
+ catalogsTable.setHeaderVisible(true);
+ gd = new GridData(GridData.FILL_BOTH);
+ catalogsTable.setLayoutData(gd);
+ catalogsTable.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ int selIndex = catalogsTable.getSelectionIndex();
+ if (selIndex <= 0) {
+ selectedCatalog = null;
+ } else {
+ selectedCatalog = (MySQLCatalog) catalogsTable.getItem(selIndex).getData();
+ }
+ showCatalogTables();
+ showGrants();
+ }
+ });
+ UIUtils.createTableColumn(catalogsTable, SWT.LEFT, MySQLMessages.editors_user_editor_privileges_column_catalog);
+ {
+ TableItem item = new TableItem(catalogsTable, SWT.NONE);
+ item.setText("% (All)"); //$NON-NLS-1$
+ item.setImage(DBeaverIcons.getImage(DBIcon.TREE_DATABASE));
+ }
+ for (MySQLCatalog catalog : getDatabaseObject().getDataSource().getCatalogs()) {
+ TableItem item = new TableItem(catalogsTable, SWT.NONE);
+ item.setText(catalog.getName());
+ item.setImage(DBeaverIcons.getImage(DBIcon.TREE_DATABASE));
+ item.setData(catalog);
+ }
+ UIUtils.packColumns(catalogsTable);
+ }
+
+ {
+ Composite tablesGroup = UIUtils.createControlGroup(leftPane, MySQLMessages.editors_user_editor_privileges_group_tables, 1, GridData.FILL_BOTH, 0);
+
+ tablesTable = new Table(tablesGroup, SWT.BORDER | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
+ tablesTable.setHeaderVisible(true);
+ gd = new GridData(GridData.FILL_BOTH);
+ tablesTable.setLayoutData(gd);
+ tablesTable.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ int selIndex = tablesTable.getSelectionIndex();
+ if (selIndex <= 0) {
+ selectedTable = null;
+ } else {
+ selectedTable = (MySQLTableBase) tablesTable.getItem(selIndex).getData();
+ }
+ showGrants();
+ }
+ });
+ UIUtils.createTableColumn(tablesTable, SWT.LEFT, MySQLMessages.editors_user_editor_privileges_column_table);
+ UIUtils.packColumns(tablesTable);
+ }
+ Composite ph = UIUtils.createPlaceholder(container, 1);
+ ph.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ tablePrivilegesTable = new PrivilegeTableControl(ph, MySQLMessages.editors_user_editor_privileges_control_table_privileges);
+ gd = new GridData(GridData.FILL_BOTH);
+ tablePrivilegesTable.setLayoutData(gd);
+
+ otherPrivilegesTable = new PrivilegeTableControl(ph, MySQLMessages.editors_user_editor_privileges_control_other_privileges);
+ gd = new GridData(GridData.FILL_BOTH);
+ otherPrivilegesTable.setLayoutData(gd);
+
+ catalogsTable.setSelection(0);
+ showCatalogTables();
+
+ pageControl.createProgressPanel();
+
+ parent.addDisposeListener(new DisposeListener() {
+ @Override
+ public void widgetDisposed(DisposeEvent e)
+ {
+ UIUtils.dispose(boldFont);
+ }
+ });
+
+ addGrantListener(tablePrivilegesTable);
+ addGrantListener(otherPrivilegesTable);
+*/
+ }
+
+ @Override
+ public void setFocus() {
+
+ }
+
+ @Override
+ public synchronized void activatePart()
+ {
+ if (isLoaded) {
+ return;
+ }
+ isLoaded = true;
+ LoadingJob.createService(
+ new DatabaseLoadService>("Load privileges", getExecutionContext()) {
+ @Override
+ public List evaluate(DBRProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ try {
+ return getDatabaseObject().getPrivileges(monitor);
+ } catch (DBException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ },
+ pageControl.createPrivilegesLoadVisualizer())
+ .schedule();
+ }
+
+ @Override
+ public void refreshPart(Object source, boolean force)
+ {
+ // do nothing
+ }
+
+ private class PageControl extends ProgressPageControl {
+ public PageControl(Composite parent) {
+ super(parent, SWT.NONE);
+ }
+
+ public ProgressPageControl.ProgressVisualizer> createPrivilegesLoadVisualizer() {
+ return new ProgressPageControl.ProgressVisualizer>() {
+ @Override
+ public void completeLoading(List privs) {
+ super.completeLoading(privs);
+/*
+ List otherPrivs = new ArrayList<>();
+ List tablePrivs = new ArrayList<>();
+ for (MySQLPrivilege priv : privs) {
+ if (priv.getKind() == MySQLPrivilege.Kind.ADMIN) {
+ continue;
+ }
+ if (priv.getContext().contains("Table")) {
+ tablePrivs.add(priv);
+ } else {
+ otherPrivs.add(priv);
+ }
+ }
+ tablePrivilegesTable.fillPrivileges(tablePrivs);
+ otherPrivilegesTable.fillPrivileges(otherPrivs);
+ loadGrants();
+*/
+ }
+ };
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/plugins/org.jkiss.dbeaver.model/icons/tree/permissions.png b/plugins/org.jkiss.dbeaver.model/icons/tree/permissions.png
new file mode 100644
index 0000000000000000000000000000000000000000..88b606b9fa493365063192860e8c7ab60df86fa5
Binary files /dev/null and b/plugins/org.jkiss.dbeaver.model/icons/tree/permissions.png differ
diff --git a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/DBIcon.java b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/DBIcon.java
index 80c8bf2e72804f2c0168806dcdb48ea4032ecf36..36f61ea3fd78c00b59bf948b2f33f99af001a550 100644
--- a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/DBIcon.java
+++ b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/DBIcon.java
@@ -67,6 +67,7 @@ public class DBIcon implements DBPImage
public static final DBIcon TREE_TRIGGER = new DBIcon("trigger", "tree/trigger.png"); //$NON-NLS-1$ //$NON-NLS-2$
public static final DBIcon TREE_USER = new DBIcon("user", "tree/user.png"); //$NON-NLS-1$ //$NON-NLS-2$
public static final DBIcon TREE_USER_GROUP = new DBIcon("user_group", "tree/group.png"); //$NON-NLS-1$ //$NON-NLS-2$
+ public static final DBIcon TREE_PERMISSIONS = new DBIcon("permissions", "tree/permissions.png"); //$NON-NLS-1$ //$NON-NLS-2$
public static final DBIcon TREE_PAGE = new DBIcon("page", "tree/page.png"); //$NON-NLS-1$ //$NON-NLS-2$
public static final DBIcon TREE_INFO = new DBIcon("info", "tree/info.png"); //$NON-NLS-1$ //$NON-NLS-2$
public static final DBIcon TREE_SESSIONS = new DBIcon("sessions", "tree/sessions.png"); //$NON-NLS-1$ //$NON-NLS-2$