diff --git a/gui/wxpython/core/settings.py b/gui/wxpython/core/settings.py index 4861e278830..12d90caed3f 100644 --- a/gui/wxpython/core/settings.py +++ b/gui/wxpython/core/settings.py @@ -257,6 +257,8 @@ def _defaultSettings(self): "encoding": { "value": "", }, + "enableHiddenCols": {"enabled": True}, + "hiddenCols": {}, }, # # Command diff --git a/gui/wxpython/dbmgr/base.py b/gui/wxpython/dbmgr/base.py index 5acddb8a92e..dc21eab50e6 100644 --- a/gui/wxpython/dbmgr/base.py +++ b/gui/wxpython/dbmgr/base.py @@ -152,6 +152,190 @@ def __init__(self, parent, log, dbMgrData, layer, pages): self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColumnSort) self.Bind(wx.EVT_LIST_COL_RIGHT_CLICK, self.OnColumnMenu) + def _colExist(self, colName): + """Checking if table column exist and update + hidden columns settings + + :param str colName: column name + + :return bool: True if column exist + """ + exist = colName in self.columns.keys() + if not exist: + self._updateHiddenColsSettings( + colName, + removeCol=True, + ) + return exist + + def _getHiddenColsSettings(self, currentVectMap=True): + """Get attribute table manager hidden columns settings + + :param bool currentVectMap: True for the getting current vector map + hidden columns settings or False for getting + all vector maps hidden columns settings for + the current mapset path + + :return dict: Current vector map hidden columns settings + or all vector maps hidden columns settings + for current mapset path + """ + UserSettings.ReadSettingsFile() + settings = UserSettings.Get(group="atm", key="hiddenCols") + if settings: + mapsetPath = self._getMapsetPath() + mapsetPathHiddenColsSettings = settings.get(mapsetPath) + if currentVectMap and mapsetPathHiddenColsSettings: + return mapsetPathHiddenColsSettings.get(self.dbMgrData["vectName"]) + return mapsetPathHiddenColsSettings + + def _getMapsetPath(self): + """Get mapset path""" + gisEnv = gs.gisenv() + return f"{gisEnv['GISDBASE']}/{gisEnv['LOCATION_NAME']}/{gisEnv['MAPSET']}" + + def _hideCol(self): + """Hide column""" + currentVectMapsHiddenColsSettings = self._getHiddenColsSettings() + if currentVectMapsHiddenColsSettings: + currentTableColsSettings = currentVectMapsHiddenColsSettings.get( + self.mapDBInfo.layers[self.layer]["table"] + ) + for colName in currentTableColsSettings: + if self._colExist(colName): + # Get column order + colOrder = self.GetColOrder(colName) + if colOrder: + # Delete column data + self.DeleteColumnWithData(colOrder) + + def ShowAllCols(self): + """Show all columns""" + self.Update() + + def _updateHiddenColsSettings( + self, + colName=None, + colOrder=None, + removeCol=False, + remove=False, + ): + """Update atribute table manager hidden columns settings + + :param str colName: column name, with default None value + :param int colOrder: column order, with default None value + :param bool removeCol: True for removing hidden column from the + settings, default value is False + :param bool remove: True for removing hidden column settings key, + default value is False + """ + hiddenColsKey = "hiddenCols" + atmKey = "atm" + curentTableHiddenCols = [] + otherTablesHiddenCols = {} + currentVectMapsHiddenColsSettings = None + + if not removeCol and not remove: + curentTableHiddenCols = [colName] + + allVectMapsHiddenColsSettings = self._getHiddenColsSettings( + currentVectMap=False + ) + if allVectMapsHiddenColsSettings: + currentVectMapsHiddenColsSettings = allVectMapsHiddenColsSettings.get( + self.dbMgrData["vectName"], + None, + ) + if currentVectMapsHiddenColsSettings: + # Update hidden col settings with existed hidden cols + currentVectMapTable = currentVectMapsHiddenColsSettings.pop( + self.mapDBInfo.layers[self.layer]["table"], {} + ) + curentTableHiddenCols.extend(currentVectMapTable) + otherTablesHiddenCols.update(currentVectMapsHiddenColsSettings) + + # Remove column if was dropped from the table + if removeCol: + curentTableHiddenCols.remove(colName) + + if remove: + if otherTablesHiddenCols: + # Remove current vector map table settings dict key + UserSettings.Append( + dict=UserSettings.userSettings, + group=atmKey, + key=hiddenColsKey, + subkey=[ + self._getMapsetPath(), + self.dbMgrData["vectName"], + ], + value=otherTablesHiddenCols, + ) + elif ( + len( + [ + mapName + for mapName in allVectMapsHiddenColsSettings + if mapName != self.dbMgrData["vectName"] + ] + ) + > 0 + ): + # Remove curent vector map settings dict key + del UserSettings.userSettings[atmKey][hiddenColsKey][ + self._getMapsetPath() + ][self.dbMgrData["vectName"]] + else: + # Remove current mapset path settings dict key + del UserSettings.userSettings[atmKey][hiddenColsKey][ + self._getMapsetPath() + ] + else: + # Append new hidden column + UserSettings.Append( + dict=UserSettings.userSettings, + group=atmKey, + key=hiddenColsKey, + subkey=[ + self._getMapsetPath(), + self.dbMgrData["vectName"], + ], + value=dict( + {self.mapDBInfo.layers[self.layer]["table"]: curentTableHiddenCols}, + **otherTablesHiddenCols, + ), + ) + + jsonSettings = {} + UserSettings.ReadSettingsFile(settings=jsonSettings) + jsonSettings[atmKey][hiddenColsKey] = UserSettings.Get( + group=atmKey, + key=hiddenColsKey, + settings_type="user", + ) + UserSettings.SaveToFile(settings=jsonSettings) + + def GetColOrder(self, colName): + """Get column order + + :param str colName: column name + + :return int: columnn order + """ + return { + self.GetColumn(colIdx).GetText(): colIdx + for colIdx in range(self.GetColumnCount()) + }.pop(colName, None) + + def DeleteColumnWithData(self, colOrder): + """Delete column with data + + :param int colOrder: column order + """ + for row in range(self.GetItemCount()): + del self.itemDataMap[row][colOrder] + self.DeleteColumn(colOrder) + def Update(self, mapDBInfo=None): """Update list according new mapDBInfo description""" if mapDBInfo: @@ -368,6 +552,14 @@ def LoadData(self, layer, columns=None, where=None, sql=None): self.SetColumnWidth(col=i, width=width) i += 1 + # Hide column + if UserSettings.Get( + group="atm", + key="enableHiddenCols", + subkey="enabled", + ): + self._hideCol() + self.SendSizeEvent() self.log.write(_("Number of loaded records: %d") % self.GetItemCount()) @@ -490,6 +682,11 @@ def OnGetItemText(self, item, col): def OnColumnMenu(self, event): """Column heading right mouse button -> pop-up menu""" self._col = event.GetColumn() + enableHiddenCols = UserSettings.Get( + group="atm", + key="enableHiddenCols", + subkey="enabled", + ) popupMenu = Menu() @@ -509,6 +706,13 @@ def OnColumnMenu(self, event): "calculator": NewId(), "stats": NewId(), } + if enableHiddenCols: + self.popupId.update( + { + "hideCol": NewId(), + "showAllCols": NewId(), + } + ) popupMenu.Append(self.popupId["sortAsc"], _("Sort ascending")) popupMenu.Append(self.popupId["sortDesc"], _("Sort descending")) @@ -520,6 +724,14 @@ def OnColumnMenu(self, event): ) popupMenu.Append(self.popupId["calculator"], _("Field calculator")) popupMenu.AppendSeparator() + if enableHiddenCols: + catKeyCol = self.GetMapCatKeyColumn() + if self._col != catKeyCol["index"]: + popupMenu.Append(self.popupId["hideCol"], _("Hide column")) + currentVectMapHiddenCols = self._getHiddenColsSettings() + if currentVectMapHiddenCols: + popupMenu.Append(self.popupId["showAllCols"], _("Show all columns")) + popupMenu.AppendSeparator() popupMenu.Append(self.popupId["stats"], _("Statistics")) if not self.pages["manageTable"]: @@ -553,6 +765,12 @@ def OnColumnMenu(self, event): self.Bind(wx.EVT_MENU, self.OnColumnSortAsc, id=self.popupId["sortAsc"]) self.Bind(wx.EVT_MENU, self.OnColumnSortDesc, id=self.popupId["sortDesc"]) self.Bind(wx.EVT_MENU, self.OnFieldCalculator, id=self.popupId["calculator"]) + if enableHiddenCols: + self.Bind(wx.EVT_MENU, self.OnHideColumn, id=self.popupId["hideCol"]) + if currentVectMapHiddenCols: + self.Bind( + wx.EVT_MENU, self.OnShowColumn, id=self.popupId["showAllCols"] + ) self.Bind(wx.EVT_MENU, self.OnFieldStatistics, id=self.popupId["stats"]) if not self.pages["manageTable"]: self.Bind(wx.EVT_MENU, self.OnAddColumn, id=self.popupId["addCol"]) @@ -685,6 +903,22 @@ def OnAddColumn(self, event): ) dlg.Destroy() + def OnHideColumn(self, event): + """Hide column""" + # Get column order + colOrder = self.GetColOrder(colName=self.GetColumn(self._col).GetText()) + if colOrder: + self._updateHiddenColsSettings( + colName=self.GetColumn(self._col).GetText(), + colOrder=self._col, + ) + self.DeleteColumnWithData(colOrder) + + def OnShowColumn(self, event): + """Show column""" + self._updateHiddenColsSettings(remove=True) + self.ShowAllCols() + def SortItems(self, sorter=cmp): """Sort items""" wx.BeginBusyCursor() @@ -739,6 +973,21 @@ def _updateColSortFlag(self): """ self._colSortFlag.extend([0] * (len(self.columns) - len(self._colSortFlag))) + def RefreshListMixColsLength(self): + currentVectMapsHiddenColsSettings = self._getHiddenColsSettings() + if currentVectMapsHiddenColsSettings: + currentTableColsSettings = currentVectMapsHiddenColsSettings.get( + self.mapDBInfo.layers[self.layer]["table"] + ) + listmix.ColumnSorterMixin.SetColumnCount( + self, + len(self.columns) - len(currentTableColsSettings), + ) + + def SortListItems(self, *args, **kwargs): + self.RefreshListMixColsLength() + return super().SortListItems(*args, **kwargs) + class DbMgrBase: def __init__( @@ -1173,14 +1422,18 @@ def AddLayer(self, layer, pos=-1): ) listSizer = wx.StaticBoxSizer(listBox, wx.VERTICAL) - win = VirtualAttributeList(panel, self.log, self.dbMgrData, layer, self.pages) - if win.IsEmpty(): + self.virtualAttributeListWin = VirtualAttributeList( + panel, self.log, self.dbMgrData, layer, self.pages + ) + if self.virtualAttributeListWin.IsEmpty(): panel.Destroy() return False self.layers.append(layer) - win.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnDataItemActivated) + self.virtualAttributeListWin.Bind( + wx.EVT_LIST_ITEM_ACTIVATED, self.OnDataItemActivated + ) self.layerPage[layer] = {"browsePage": panel.GetId()} @@ -1208,16 +1461,29 @@ def AddLayer(self, layer, pos=-1): sqlSizer = wx.StaticBoxSizer(sqlBox, wx.VERTICAL) - win.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnDataRightUp) # wxMSW - win.Bind(wx.EVT_RIGHT_UP, self.OnDataRightUp) # wxGTK + self.virtualAttributeListWin.Bind( + wx.EVT_COMMAND_RIGHT_CLICK, self.OnDataRightUp + ) # wxMSW + self.virtualAttributeListWin.Bind(wx.EVT_RIGHT_UP, self.OnDataRightUp) # wxGTK if UserSettings.Get(group="atm", key="leftDbClick", subkey="selection") == 0: - win.Bind(wx.EVT_LEFT_DCLICK, self.OnDataItemEdit) - win.Bind(wx.EVT_COMMAND_LEFT_DCLICK, self.OnDataItemEdit) + self.virtualAttributeListWin.Bind(wx.EVT_LEFT_DCLICK, self.OnDataItemEdit) + self.virtualAttributeListWin.Bind( + wx.EVT_COMMAND_LEFT_DCLICK, self.OnDataItemEdit + ) else: - win.Bind(wx.EVT_LEFT_DCLICK, self.OnDataDrawSelected) - win.Bind(wx.EVT_COMMAND_LEFT_DCLICK, self.OnDataDrawSelected) + self.virtualAttributeListWin.Bind( + wx.EVT_LEFT_DCLICK, self.OnDataDrawSelected + ) + self.virtualAttributeListWin.Bind( + wx.EVT_COMMAND_LEFT_DCLICK, self.OnDataDrawSelected + ) - listSizer.Add(win, proportion=1, flag=wx.EXPAND | wx.ALL, border=3) + listSizer.Add( + self.virtualAttributeListWin, + proportion=1, + flag=wx.EXPAND | wx.ALL, + border=3, + ) # sql statement box sqlNtb = GNotebook( @@ -1357,7 +1623,7 @@ def AddLayer(self, layer, pos=-1): sqlNtb.Bind(wx.EVT_SIZE, self.OnSqlQuerySizeWrap(layer)) - self.layerPage[layer]["data"] = win.GetId() + self.layerPage[layer]["data"] = self.virtualAttributeListWin.GetId() self.layerPage[layer]["sqlNtb"] = sqlNtb.GetId() self.layerPage[layer]["whereColumn"] = sqlWhereColumn.GetId() self.layerPage[layer]["whereOperator"] = sqlWhereCond.GetId() diff --git a/gui/wxpython/dbmgr/manager.py b/gui/wxpython/dbmgr/manager.py index 584dd713413..877dd6ea28e 100644 --- a/gui/wxpython/dbmgr/manager.py +++ b/gui/wxpython/dbmgr/manager.py @@ -34,6 +34,7 @@ else: import wx.lib.flatnotebook as FN +from core.settings import UserSettings from core.gcmd import GMessage from dbmgr.base import DbMgrBase from gui_core.widgets import GNotebook @@ -146,6 +147,16 @@ def __init__( else: wx.CallAfter(self.notebook.SetSelection, 0) # select browse tab + # checkbox + self.checkHiddenCols = wx.CheckBox( + parent=self.panel, + label=_("Enable hide / show columns"), + ) + self.checkHiddenCols.SetValue( + UserSettings.Get(group="atm", key="enableHiddenCols", subkey="enabled") + ) + self.Bind(wx.EVT_CHECKBOX, self.OnCheckHiddenCols, self.checkHiddenCols) + # buttons self.btnClose = CloseButton(parent=self.panel) self.btnClose.SetToolTip(_("Close Attribute Table Manager")) @@ -188,6 +199,7 @@ def _layout(self): btnSizer.Add(self.btnClose, proportion=1, flag=wx.ALL, border=5) mainSizer.Add(self.notebook, proportion=1, flag=wx.EXPAND) + mainSizer.Add(self.checkHiddenCols, flag=wx.ALL, border=5) mainSizer.Add(btnSizer, flag=wx.ALIGN_RIGHT | wx.ALL, border=5) self.panel.SetAutoLayout(True) @@ -208,6 +220,21 @@ def OnCloseWindow(self, event): event.Skip() + def OnCheckHiddenCols(self, event): + checkbox = event.GetEventObject() + isChecked = checkbox.GetValue() + UserSettings.Set( + group="atm", + key="enableHiddenCols", + subkey="enabled", + value=checkbox.GetValue(), + ) + UserSettings.SaveToFile() + if isChecked: + self.OnReloadData(event=None) + else: + self.pages["browse"].virtualAttributeListWin.ShowAllCols() + def OnReloadData(self, event): """Reload data""" if self.pages["browse"]: