Edouard@2334: #!/usr/bin/env python Edouard@2334: # -*- coding: utf-8 -*- Edouard@2334: Edouard@2334: # See COPYING file for copyrights details. Edouard@2334: Edouard@2334: from __future__ import absolute_import Edouard@2334: import os Edouard@2334: import wx Edouard@2334: import wx.dataview as dv Edouard@2339: import PSKManagement as PSK Edouard@2339: from PSKManagement import COL_ID,COL_URI,COL_DESC,COL_LAST Edouard@2334: Edouard@2336: class IDBrowserModel(dv.PyDataViewIndexListModel): Edouard@2334: def __init__(self, psk_path, columncount): Edouard@2334: self.psk_path = psk_path Edouard@2334: self.columncount = columncount Edouard@2339: self.data = PSK.GetData(psk_path) Edouard@2334: dv.PyDataViewIndexListModel.__init__(self, len(self.data)) Edouard@2334: Edouard@2334: def _saveData(self): Edouard@2339: PSK.SaveData(self.psk_path, self.data) Edouard@2334: Edouard@2334: def GetColumnType(self, col): Edouard@2334: return "string" Edouard@2334: Edouard@2334: def GetValueByRow(self, row, col): Edouard@2334: return self.data[row][col] Edouard@2334: Edouard@2334: def SetValueByRow(self, value, row, col): Edouard@2334: self.data[row][col] = value Edouard@2334: self._saveData() Edouard@2334: Edouard@2334: def GetColumnCount(self): Edouard@2334: return len(self.data[0]) if self.data else self.columncount Edouard@2334: Edouard@2334: def GetCount(self): Edouard@2334: return len(self.data) Edouard@2334: Edouard@2334: def GetAttrByRow(self, row, col, attr): Edouard@2334: if col == 3: Edouard@2334: attr.SetColour('blue') Edouard@2334: attr.SetBold(True) Edouard@2334: return True Edouard@2334: return False Edouard@2334: Edouard@2334: Edouard@2334: def Compare(self, item1, item2, col, ascending): Edouard@2334: if not ascending: # swap sort order? Edouard@2334: item2, item1 = item1, item2 Edouard@2334: row1 = self.GetRow(item1) Edouard@2334: row2 = self.GetRow(item2) Edouard@2334: if col == 0: Edouard@2334: return cmp(int(self.data[row1][col]), int(self.data[row2][col])) Edouard@2334: else: Edouard@2334: return cmp(self.data[row1][col], self.data[row2][col]) Edouard@2334: Edouard@2334: def DeleteRows(self, rows): Edouard@2334: rows = list(rows) Edouard@2334: rows.sort(reverse=True) Edouard@2334: Edouard@2334: for row in rows: Edouard@2339: PSK.DeleteID(self.psk_path, self.data[row][COL_ID]) Edouard@2334: del self.data[row] Edouard@2334: self.RowDeleted(row) Edouard@2334: self._saveData() Edouard@2334: Edouard@2334: def AddRow(self, value): Edouard@2334: self.data.append(value) Edouard@2334: self.RowAppended() Edouard@2334: self._saveData() Edouard@2334: Edouard@2334: colflags = dv.DATAVIEW_COL_RESIZABLE|dv.DATAVIEW_COL_SORTABLE Edouard@2334: Edouard@2336: class IDBrowser(wx.Panel): Edouard@2335: def __init__(self, parent, ctr, SelectURICallBack=None, SelectIDCallBack=None, **kwargs): Edouard@2334: wx.Panel.__init__(self, parent, -1, size=(400,200)) Edouard@2334: Edouard@2335: self.isManager = SelectURICallBack is None and SelectIDCallBack is None Edouard@2334: self.SelectURICallBack = SelectURICallBack Edouard@2335: self.SelectIDCallBack = SelectIDCallBack Edouard@2334: Edouard@2334: dvStyle = wx.BORDER_THEME | dv.DV_ROW_LINES Edouard@2334: if self.isManager : Edouard@2334: # no multiple selection in selector mode Edouard@2334: dvStyle |= dv.DV_MULTIPLE Edouard@2334: self.dvc = dv.DataViewCtrl(self, style = dvStyle) Edouard@2334: Edouard@2334: args = lambda *a,**k:(a,k) Edouard@2334: Edouard@2334: ColumnsDesc = [ Edouard@2335: args(_("ID"), COL_ID, width = 100), Edouard@2335: args(_("Last URI"), COL_URI, width = 80), Edouard@2335: args(_("Description"), COL_DESC, width = 200, Edouard@2334: mode = dv.DATAVIEW_CELL_EDITABLE Edouard@2334: if self.isManager Edouard@2334: else dv.DATAVIEW_CELL_INERT), Edouard@2335: args(_("Last connection"), COL_LAST, width = 100), Edouard@2334: ] Edouard@2334: Edouard@2339: self.model = IDBrowserModel(ctr.ProjectPath, len(ColumnsDesc)) Edouard@2334: self.dvc.AssociateModel(self.model) Edouard@2334: Edouard@2334: for a,k in ColumnsDesc: Edouard@2334: self.dvc.AppendTextColumn(*a,**dict(k, flags = colflags)) Edouard@2334: Edouard@2334: # TODO : when select, Edouard@2334: # - update ID field of scheme editor Edouard@2334: # - enable use URI button Edouard@2334: Edouard@2334: self.Sizer = wx.BoxSizer(wx.VERTICAL) Edouard@2334: self.Sizer.Add(self.dvc, 1, wx.EXPAND) Edouard@2334: Edouard@2334: btnbox = wx.BoxSizer(wx.HORIZONTAL) Edouard@2334: if self.isManager : Edouard@2334: Edouard@2334: # deletion of secret and metadata Edouard@2334: deleteButton = wx.Button(self, label=_("Delete ID")) Edouard@2334: self.Bind(wx.EVT_BUTTON, self.OnDeleteButton, deleteButton) Edouard@2334: btnbox.Add(deleteButton, 0, wx.LEFT|wx.RIGHT, 5) Edouard@2334: Edouard@2334: # export all Edouard@2334: exportButton = wx.Button(self, label=_("Export all")) Edouard@2334: self.Bind(wx.EVT_BUTTON, self.OnExportButton, exportButton) Edouard@2334: btnbox.Add(exportButton, 0, wx.LEFT|wx.RIGHT, 5) Edouard@2334: Edouard@2334: # import with a merge -> duplicates are asked for Edouard@2334: importButton = wx.Button(self, label=_("Import")) Edouard@2334: self.Bind(wx.EVT_BUTTON, self.OnImportButton, importButton) Edouard@2334: btnbox.Add(importButton, 0, wx.LEFT|wx.RIGHT, 5) Edouard@2334: Edouard@2334: else : Edouard@2334: # selector mode Edouard@2334: # use last known URI button Edouard@2334: # TODO : disable use URI button until something selected Edouard@2335: self.useURIButton = wx.Button(self, label=_("Use last URI")) Edouard@2335: self.Bind(wx.EVT_BUTTON, self.OnUseURIButton, self.useURIButton) Edouard@2335: self.useURIButton.Disable() Edouard@2335: btnbox.Add(self.useURIButton, 0, wx.LEFT|wx.RIGHT, 5) Edouard@2334: Edouard@2334: self.Sizer.Add(btnbox, 0, wx.TOP|wx.BOTTOM, 5) Edouard@2335: self.Bind(dv.EVT_DATAVIEW_SELECTION_CHANGED, self.OnSelectionChanged, self.dvc) Edouard@2335: Edouard@2334: Edouard@2334: def OnDeleteButton(self, evt): Edouard@2334: items = self.dvc.GetSelections() Edouard@2334: rows = [self.model.GetRow(item) for item in items] Edouard@2334: Edouard@2334: # Ask if user really wants to delete Edouard@2334: if wx.MessageBox(_('Are you sure to delete selected IDs?'), Edouard@2334: _('Delete IDs'), Edouard@2334: wx.YES_NO | wx.CENTRE | wx.NO_DEFAULT) != wx.YES: Edouard@2334: return Edouard@2334: Edouard@2334: self.model.DeleteRows(rows) Edouard@2334: Edouard@2335: def OnSelectionChanged(self, evt): Edouard@2335: if not self.isManager : Edouard@2335: items = self.dvc.GetSelections() Edouard@2335: somethingSelected = len(items) > 0 Edouard@2335: self.useURIButton.Enable(somethingSelected) Edouard@2335: if somethingSelected: Edouard@2335: row = self.model.GetRow(items[0]) Edouard@2335: ID = self.model.GetValueByRow(row, COL_ID) Edouard@2335: self.SelectIDCallBack(ID) Edouard@2335: Edouard@2335: Edouard@2335: def OnUseURIButton(self, evt): Edouard@2335: row = self.model.GetRow(self.dvc.GetSelections()[0]) Edouard@2335: URI = self.model.GetValueByRow(row, COL_URI) Edouard@2335: if URI: Edouard@2335: self.SelectURICallBack(URI) Edouard@2334: Edouard@2334: def OnExportButton(self, evt): Edouard@2334: # TODO Edouard@2334: wx.MessageBox(_('?'), Edouard@2334: _('Mhe'), Edouard@2334: wx.YES_NO | wx.CENTRE | wx.NO_DEFAULT) Edouard@2334: Edouard@2334: def OnImportButton(self, evt): Edouard@2334: # TODO Edouard@2334: wx.MessageBox(_('?'), Edouard@2334: _('Mhe'), Edouard@2334: wx.YES_NO | wx.CENTRE | wx.NO_DEFAULT) Edouard@2334: