diff --git a/res/ui/network_tab.ui b/res/ui/network_tab.ui index ff6022e1bf8048d243bccdc742b9f1d6cfcf4163..9398b9b6f43dd936bb775fc00effd0a9054beeba 100644 --- a/res/ui/network_tab.ui +++ b/res/ui/network_tab.ui @@ -18,6 +18,9 @@ <layout class="QVBoxLayout" name="verticalLayout"> <item> <widget class="QTableView" name="table_network"> + <property name="contextMenuPolicy"> + <enum>Qt::CustomContextMenu</enum> + </property> <property name="horizontalScrollBarPolicy"> <enum>Qt::ScrollBarAlwaysOff</enum> </property> @@ -46,5 +49,25 @@ </layout> </widget> <resources/> - <connections/> + <connections> + <connection> + <sender>table_network</sender> + <signal>customContextMenuRequested(QPoint)</signal> + <receiver>NetworkTabWidget</receiver> + <slot>node_context_menu()</slot> + <hints> + <hint type="sourcelabel"> + <x>199</x> + <y>149</y> + </hint> + <hint type="destinationlabel"> + <x>199</x> + <y>149</y> + </hint> + </hints> + </connection> + </connections> + <slots> + <slot>node_context_menu()</slot> + </slots> </ui> diff --git a/src/cutecoin/core/net/network.py b/src/cutecoin/core/net/network.py index 32efffdf4152f7e08bde91ff11cb5ba4e49b1f69..34f533ccc91e5567ce64db14b82aa7903f44a319 100644 --- a/src/cutecoin/core/net/network.py +++ b/src/cutecoin/core/net/network.py @@ -188,6 +188,14 @@ class Network(Watcher): ''' return node in self._root_nodes + def root_node_index(self, index): + ''' + Get the index of a root node from its index + in all nodes list + ''' + node = self.nodes[index] + return self._root_nodes.index(node) + def moveToThread(self, thread): for n in self.nodes: n.moveToThread(thread) diff --git a/src/cutecoin/gui/network_tab.py b/src/cutecoin/gui/network_tab.py index f1c127ea8d98cf962920a396bcb12321872fc230..bd97eda945c8d2e48e7f0d1c6fa2f923870b7237 100644 --- a/src/cutecoin/gui/network_tab.py +++ b/src/cutecoin/gui/network_tab.py @@ -5,8 +5,9 @@ Created on 20 févr. 2015 ''' import logging -from PyQt5.QtWidgets import QWidget -from PyQt5.QtCore import Qt, QThread, pyqtSlot +from PyQt5.QtGui import QCursor +from PyQt5.QtWidgets import QWidget, QMenu, QAction +from PyQt5.QtCore import Qt, QModelIndex, pyqtSlot from ..models.network import NetworkTableModel, NetworkFilterProxyModel from ..gen_resources.network_tab_uic import Ui_NetworkTabWidget @@ -29,8 +30,46 @@ class NetworkTabWidget(QWidget, Ui_NetworkTabWidget): self.table_network.sortByColumn(0, Qt.DescendingOrder) self.table_network.resizeColumnsToContents() community.network.nodes_changed.connect(self.refresh_nodes) + self.community = community @pyqtSlot() def refresh_nodes(self): logging.debug("Refresh nodes") self.table_network.model().sourceModel().modelReset.emit() + + def node_context_menu(self, point): + index = self.table_network.indexAt(point) + model = self.table_network.model() + if index.row() < model.rowCount(QModelIndex()): + source_index = model.mapToSource(index) + is_root_col = model.sourceModel().columns_types.index('is_root') + is_root_index = model.sourceModel().index(source_index.row(), is_root_col) + is_root = model.sourceModel().data(is_root_index, Qt.DisplayRole) + + menu = QMenu() + if is_root: + unset_root = QAction(self.tr("Unset root node"), self) + unset_root.triggered.connect(self.unset_root_node) + unset_root.setData(self.community.network.root_node_index(source_index.row())) + if len(self.community.network.root_nodes) > 1: + menu.addAction(unset_root) + else: + set_root = QAction(self.tr("Set as root node"), self) + set_root.triggered.connect(self.set_root_node) + set_root.setData(self.community.network.nodes[source_index.row()]) + menu.addAction(set_root) + # Show the context menu. + menu.exec_(QCursor.pos()) + + @pyqtSlot() + def set_root_node(self): + node = self.sender().data() + self.community.network.add_root_node(node) + + @pyqtSlot() + def unset_root_node(self): + index = self.sender().data() + self.community.network.remove_root_node(index) + + + diff --git a/src/cutecoin/gui/transactions_tab.py b/src/cutecoin/gui/transactions_tab.py index 1e085303356c79fb31c68834f222e66c6e0e21b8..01bcb08735432283c8928f291b2d96be4c512067 100644 --- a/src/cutecoin/gui/transactions_tab.py +++ b/src/cutecoin/gui/transactions_tab.py @@ -118,12 +118,12 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget): if index.row() < model.rowCount(QModelIndex()): menu = QMenu(self.tr("Actions"), self) source_index = model.mapToSource(index) - state_col = model.sourceModel().column_types.index('state') + state_col = model.sourceModel().columns_types.index('state') state_index = model.sourceModel().index(source_index.row(), state_col) state_data = model.sourceModel().data(state_index, Qt.DisplayRole) - pubkey_col = model.sourceModel().column_types.index('pubkey') + pubkey_col = model.sourceModel().columns_types.index('pubkey') person_index = model.sourceModel().index(source_index.row(), pubkey_col) person = model.sourceModel().data(person_index, Qt.DisplayRole) diff --git a/src/cutecoin/models/network.py b/src/cutecoin/models/network.py index 258007ea6c84f6724bd24a8fb97d4467cb7a7454..bb10397b3a26e2f82f07f1fbd53bee758778c99e 100644 --- a/src/cutecoin/models/network.py +++ b/src/cutecoin/models/network.py @@ -52,19 +52,19 @@ class NetworkFilterProxyModel(QSortFilterProxyModel): if not source_index.isValid(): return QVariant() source_data = source_model.data(source_index, role) - if index.column() == self.sourceModel().column_types.index('is_member') \ + if index.column() == self.sourceModel().columns_types.index('is_member') \ and role == Qt.DisplayRole: value = {True: 'yes', False: 'no', None: 'offline'} return value[source_data] if role == Qt.TextAlignmentRole: - if source_index.column() == source_model.column_types.index('address') or source_index.column() == self.sourceModel().column_types.index('current_block'): + if source_index.column() == source_model.columns_types.index('address') or source_index.column() == self.sourceModel().columns_types.index('current_block'): return Qt.AlignRight | Qt.AlignVCenter - if source_index.column() == source_model.column_types.index('is_member'): + if source_index.column() == source_model.columns_types.index('is_member'): return Qt.AlignCenter if role == Qt.FontRole: - is_root_col = source_model.column_types.index('is_root') + is_root_col = source_model.columns_types.index('is_root') index_root_col = source_model.index(source_index.row(), is_root_col) if source_model.data(index_root_col, Qt.DisplayRole): font = QFont() @@ -85,7 +85,7 @@ class NetworkTableModel(QAbstractTableModel): ''' super().__init__(parent) self.community = community - self.column_types = ( + self.columns_types = ( 'address', 'port', 'current_block', @@ -115,13 +115,13 @@ class NetworkTableModel(QAbstractTableModel): return len(self.nodes) def columnCount(self, parent): - return len(self.column_types) + return len(self.columns_types) def headerData(self, section, orientation, role): if role != Qt.DisplayRole: return QVariant() - return self.column_types[section] + return self.columns_types[section] def data_node(self, node: Node) -> tuple: """ diff --git a/src/cutecoin/models/txhistory.py b/src/cutecoin/models/txhistory.py index a704fc9674397728b95ac6d0e04002018f17c8e7..3b214211102b3c5515a34c89198b65d54ced78c0 100644 --- a/src/cutecoin/models/txhistory.py +++ b/src/cutecoin/models/txhistory.py @@ -40,20 +40,20 @@ class TxFilterProxyModel(QSortFilterProxyModel): return date_ts in range(self.ts_from, self.ts_to) source_model = self.sourceModel() - date_col = source_model.column_types.index('date') + date_col = source_model.columns_types.index('date') source_index = source_model.index(sourceRow, date_col) date = source_model.data(source_index, Qt.DisplayRole) if in_period(date): # calculate sum total payments payment = source_model.data( - source_model.index(sourceRow, source_model.column_types.index('payment')), + source_model.index(sourceRow, source_model.columns_types.index('payment')), Qt.DisplayRole ) if payment: self.payments += int(payment) # calculate sum total deposits deposit = source_model.data( - source_model.index(sourceRow, source_model.column_types.index('deposit')), + source_model.index(sourceRow, source_model.columns_types.index('deposit')), Qt.DisplayRole ) if deposit: @@ -81,7 +81,7 @@ class TxFilterProxyModel(QSortFilterProxyModel): elif right_data == "": return self.sortOrder() == Qt.AscendingOrder if left_data == right_data: - txid_col = source_model.column_types.index('txid') + txid_col = source_model.columns_types.index('txid') txid_left = source_model.index(left.row(), txid_col) txid_right = source_model.index(right.row(), txid_col) return (txid_left < txid_right) @@ -92,17 +92,17 @@ class TxFilterProxyModel(QSortFilterProxyModel): source_index = self.mapToSource(index) model = self.sourceModel() source_data = model.data(source_index, role) - state_col = model.column_types.index('state') + state_col = model.columns_types.index('state') state_index = model.index(source_index.row(), state_col) state_data = model.data(state_index, Qt.DisplayRole) if role == Qt.DisplayRole: - if source_index.column() == model.column_types.index('uid'): + if source_index.column() == model.columns_types.index('uid'): return source_data - if source_index.column() == model.column_types.index('date'): + if source_index.column() == model.columns_types.index('date'): date = QDateTime.fromTime_t(source_data) return date.date() - if source_index.column() == model.column_types.index('payment') or \ - source_index.column() == model.column_types.index('deposit'): + if source_index.column() == model.columns_types.index('payment') or \ + source_index.column() == model.columns_types.index('deposit'): if source_data is not "": amount_ref = self.account.units_to_diff_ref(source_data, self.community) @@ -130,14 +130,14 @@ class TxFilterProxyModel(QSortFilterProxyModel): return QColor(Qt.blue) if role == Qt.TextAlignmentRole: - if source_index.column() == self.sourceModel().column_types.index( - 'deposit') or source_index.column() == self.sourceModel().column_types.index('payment'): + if source_index.column() == self.sourceModel().columns_types.index( + 'deposit') or source_index.column() == self.sourceModel().columns_types.index('payment'): return Qt.AlignRight | Qt.AlignVCenter - if source_index.column() == self.sourceModel().column_types.index('date'): + if source_index.column() == self.sourceModel().columns_types.index('date'): return Qt.AlignCenter if role == Qt.ToolTipRole: - if source_index.column() == self.sourceModel().column_types.index('date'): + if source_index.column() == self.sourceModel().columns_types.index('date'): return QDateTime.fromTime_t(source_data).toString(Qt.SystemLocaleLongDate) return source_data @@ -159,7 +159,7 @@ class HistoryTableModel(QAbstractTableModel): self.transfers_data = [] self.refresh_transfers() - self.column_types = ( + self.columns_types = ( 'date', 'uid', 'payment', @@ -234,11 +234,11 @@ class HistoryTableModel(QAbstractTableModel): return len(self.transfers) def columnCount(self, parent): - return len(self.column_types) + return len(self.columns_types) def headerData(self, section, orientation, role): if role == Qt.DisplayRole: - if self.column_types[section] == 'payment' or self.column_types[section] == 'deposit': + if self.columns_types[section] == 'payment' or self.columns_types[section] == 'deposit': return '{:}\n({:})'.format( self.column_headers[section], self.account.diff_ref_name(self.community.short_currency)