Skip to content

Commit

Permalink
Create dialog and add to main window
Browse files Browse the repository at this point in the history
  • Loading branch information
Liquid369 committed Jul 8, 2024
1 parent 8b088b4 commit 29d7758
Show file tree
Hide file tree
Showing 4 changed files with 259 additions and 4 deletions.
13 changes: 11 additions & 2 deletions src/mainApp.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from constants import user_dir, SECONDS_IN_2_MONTHS
from qt.dlg_configureRPCservers import ConfigureRPCservers_dlg
from qt.dlg_signmessage import SignMessage_dlg

from qt.dlg_configureExplorer import ConfigureExplorerServers_dlg

class ServiceExit(Exception):
"""
Expand Down Expand Up @@ -99,6 +99,9 @@ def initUI(self, imgDir):
self.rpcConfMenu = QAction(self.pivx_icon, 'RPC Servers config...', self)
self.rpcConfMenu.triggered.connect(self.onEditRPCServer)
confMenu.addAction(self.rpcConfMenu)
self.explorerConfMenu = QAction(self.pivx_icon, 'Explorer Servers config...', self)
self.explorerConfMenu.triggered.connect(self.onEditExplorerServer)
confMenu.addAction(self.explorerConfMenu)
toolsMenu = mainMenu.addMenu('Tools')
self.signVerifyAction = QAction('Sign/Verify message', self)
self.signVerifyAction.triggered.connect(self.onSignVerifyMessage)
Expand Down Expand Up @@ -141,8 +144,14 @@ def onEditRPCServer(self):
if ui.exec():
printDbg("Configuring RPC Servers...")

def onEditExplorerServer(self):
# Create Dialog
ui = ConfigureExplorerServers_dlg(self)
if ui.exec():
printDbg("Configuring Explorer Servers...")

def onSignVerifyMessage(self):
# Create Dialog
ui = SignMessage_dlg(self.mainWindow)
if ui.exec():
printDbg("Sign/Verify message...")
printDbg("Sign/Verify message...")
67 changes: 65 additions & 2 deletions src/mainWindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from PyQt5.QtCore import pyqtSignal, Qt, QThread
from PyQt5.QtGui import QPixmap, QColor, QPalette, QTextCursor, QFont, QIcon
from PyQt5.QtWidgets import QWidget, QPushButton, QHBoxLayout, QGroupBox, QVBoxLayout, \
QFileDialog, QTextEdit, QTabWidget, QLabel, QSplitter
QFileDialog, QTextEdit, QTabWidget, QLabel, QSplitter, QAction, QMenuBar

from apiClient import ApiClient
from constants import starting_height, DefaultCache, wqueue
Expand All @@ -38,6 +38,9 @@ class MainWindow(QWidget):
# signal: RPC list has been reloaded (emitted by updateRPClist)
sig_RPClistReloaded = pyqtSignal()

# signal: Explorer list has been reloaded (emitted by updateExplorerList)
sig_ExplorerListReloaded = pyqtSignal()

# signal: UTXO list loading percent (emitted by load_utxos_thread in tabRewards)
sig_UTXOsLoading = pyqtSignal(int)

Expand All @@ -49,6 +52,10 @@ def __init__(self, parent, imgDir):
self.runInThread = ThreadFuns.runInThread
self.lock = threading.Lock()

# Set default value for selectedExplorer_index if it does not exist
if 'selectedExplorer_index' not in self.parent.cache:
self.parent.cache['selectedExplorer_index'] = 0

# -- Create clients and statuses
self.hwStatus = 0
self.hwModel = 0
Expand All @@ -61,6 +68,12 @@ def __init__(self, parent, imgDir):
# Changes when an RPC client is connected (affecting API client)
self.isTestnetRPC = self.parent.cache['isTestnetRPC']

# -- Default explorer servers list
self.explorerServersList = [
{"id": 1, "url": "https://explorer.duddino.com/", "isCustom": False},
{"id": 2, "url": "https://testnet.duddino.com/", "isCustom": False}
]

# -- Load icons & images
self.loadIcons()
# -- Create main layout
Expand All @@ -79,7 +92,7 @@ def __init__(self, parent, imgDir):
self.hwdevice = HWdevice(self)

# -- init Api Client
self.apiClient = ApiClient(self.isTestnetRPC)
self.apiClient = ApiClient(self) # Pass 'self' as main_wnd reference

# -- Create Queue to redirect stdout
self.queue = wqueue
Expand Down Expand Up @@ -130,6 +143,9 @@ def __init__(self, parent, imgDir):
self.mnode_to_change = None
printOK("Hello! Welcome to " + parent.title)

# Load Explorer Servers list
self.updateExplorerList()

def append_to_console(self, text):
self.consoleArea.moveCursor(QTextCursor.End)
self.consoleArea.insertHtml(text)
Expand Down Expand Up @@ -175,6 +191,9 @@ def getRPCserver(self):

def getServerListIndex(self, server):
return self.header.rpcClientsBox.findData(server)

def getExplorerListIndex(self, server):
return self.header.explorerClientsBox.findData(server)

def initConsole(self):
self.console = QGroupBox()
Expand Down Expand Up @@ -425,6 +444,50 @@ def updateRPClist(self):
# reload servers in configure dialog
self.sig_RPClistReloaded.emit()

def updateExplorerList(self):
# Clear old stuff
self.header.explorerClientsBox.clear()
public_servers = self.parent.db.getExplorerServers(custom=False)
custom_servers = self.parent.db.getExplorerServers(custom=True)
self.explorerServersList = public_servers + custom_servers
# Add public servers (italics)
italicsFont = QFont("Times", italic=True)
for s in public_servers:
url = s["url"]
self.header.explorerClientsBox.addItem(url, s)
self.header.explorerClientsBox.setItemData(self.getExplorerListIndex(s), italicsFont, Qt.FontRole)
# Add custom servers
for s in custom_servers:
url = s["url"]
self.header.explorerClientsBox.addItem(url, s)
# reset index
if self.parent.cache['selectedExplorer_index'] >= self.header.explorerClientsBox.count():
# (if manually removed from the config files) replace default index
self.parent.cache['selectedExplorer_index'] = persistCacheSetting('cache_Explorerindex', DefaultCache["selectedExplorer_index"])

self.header.explorerClientsBox.setCurrentIndex(self.parent.cache['selectedExplorer_index'])
# reload servers in configure dialog
self.sig_ExplorerListReloaded.emit()

def getExplorerURL(self, network):
for server in self.explorerServersList:
if (network == 'mainnet' and 'mainnet' in server['url']) or (network == 'testnet' and 'testnet' in server['url']):
return server['url']
# Fallback if no matching server found
return self.explorerServersList[0]['url']

def saveExplorerServers(self):
self.parent.cache['explorerServersList'] = self.explorerServersList
saveCacheSettings(self.parent.cache)
self.updateExplorerList()

def loadExplorerServers(self):
if 'explorerServersList' in self.parent.cache:
self.explorerServersList = self.parent.cache['explorerServersList']
else:
self.explorerServersList = []
self.updateExplorerList()

def updateRPCstatus(self, ctrl, fDebug=False):
rpc_index, rpc_protocol, rpc_host, rpc_user, rpc_password = self.getRPCserver()
if fDebug:
Expand Down
174 changes: 174 additions & 0 deletions src/qt/dlg_configureExplorer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Liquid369 (https://github.com/liquid369/)
# Distributed under the MIT software license, see the accompanying
# file LICENSE.txt or http://www.opensource.org/licenses/mit-license.php.

from PyQt5.QtWidgets import QDialog, QHBoxLayout, QVBoxLayout, QLabel, \
QListWidget, QFrame, QFormLayout, QComboBox, QLineEdit, QListWidgetItem, \
QWidget, QPushButton, QMessageBox

from misc import myPopUp

class ConfigureExplorerServers_dlg(QDialog):
def __init__(self, main_wnd):
QDialog.__init__(self, parent=main_wnd)
self.main_wnd = main_wnd
self.setWindowTitle('Explorer Servers Configuration')
self.changing_index = None
self.initUI()
self.loadServers()
self.main_wnd.mainWindow.sig_ExplorerListReloaded.connect(self.loadServers)

def clearEditFrame(self):
self.ui.url_edt.clear()

def initUI(self):
self.ui = Ui_ConfigureExplorerServersDlg()
self.ui.setupUi(self)

def insert_server_list(self, server):
id = server['id']
index = self.main_wnd.mainWindow.getExplorerListIndex(server)
server_line = QWidget()
server_row = QHBoxLayout()
server_text = server['url']
if not server['isCustom']:
server_text = "<em style='color: purple'>%s</em>" % server_text
server_row.addWidget(QLabel(server_text))
server_row.addStretch(1)
# -- Edit button
editBtn = QPushButton()
editBtn.setIcon(self.main_wnd.mainWindow.editMN_icon)
editBtn.setToolTip("Edit server configuration")
if not server['isCustom']:
editBtn.setDisabled(True)
editBtn.setToolTip('Default servers are not editable')
editBtn.clicked.connect(lambda: self.onAddServer(index))
server_row.addWidget(editBtn)
# -- Remove button
removeBtn = QPushButton()
removeBtn.setIcon(self.main_wnd.mainWindow.removeMN_icon)
removeBtn.setToolTip("Remove server configuration")
if not server['isCustom']:
removeBtn.setDisabled(True)
removeBtn.setToolTip('Cannot remove default servers')
removeBtn.clicked.connect(lambda: self.onRemoveServer(index))
server_row.addWidget(removeBtn)
# --
server_line.setLayout(server_row)
self.serverItems[id] = QListWidgetItem()
self.serverItems[id].setSizeHint(server_line.sizeHint())
self.ui.serversBox.addItem(self.serverItems[id])
self.ui.serversBox.setItemWidget(self.serverItems[id], server_line)

def loadServers(self):
# Clear serversBox
self.ui.serversBox.clear()
# Fill serversBox
self.serverItems = {}
for server in self.main_wnd.mainWindow.explorerServersList:
self.insert_server_list(server)

def loadEditFrame(self, index):
server = self.main_wnd.mainWindow.explorerServersList[index]
self.ui.url_edt.setText(server['url'])

def onAddServer(self, index=None):
# Save current index (None for new entry)
self.changing_index = index
# Hide 'Add' and 'Close' buttons and disable serversBox
self.ui.addServer_btn.hide()
self.ui.close_btn.hide()
self.ui.serversBox.setEnabled(False)
# Show edit-frame
self.ui.editFrame.setHidden(False)
# If we are adding a new server, clear edit-frame
if index is None:
self.clearEditFrame()
# else pre-load data
else:
self.loadEditFrame(index)

def onCancel(self):
# Show 'Add' and 'Close' buttons and enable serversBox
self.ui.addServer_btn.show()
self.ui.close_btn.show()
self.ui.serversBox.setEnabled(True)
# Hide edit-frame
self.ui.editFrame.setHidden(True)
# Clear edit-frame
self.clearEditFrame()

def onClose(self):
# close dialog
self.close()

def onRemoveServer(self, index):
mess = "Are you sure you want to remove server with index %d (%s) from list?" % (
index, self.main_wnd.mainWindow.explorerServersList[index].get('url'))
ans = myPopUp(self, QMessageBox.Question, 'PET4L - remove server', mess)
if ans == QMessageBox.Yes:
# Remove entry from database
id = self.main_wnd.mainWindow.explorerServersList[index].get('id')
self.main_wnd.db.removeExplorerServer(id)

def onSave(self):
# Get new config data
url = self.ui.url_edt.text()
# Check malformed URL
if url:
if self.changing_index is None:
# Save new entry in DB.
self.main_wnd.db.addExplorerServer(url)
else:
# Edit existing entry in DB.
id = self.main_wnd.mainWindow.explorerServersList[self.changing_index].get('id')
self.main_wnd.db.editExplorerServer(url, id)

# call onCancel
self.onCancel()


class Ui_ConfigureExplorerServersDlg(object):
def setupUi(self, ConfigureExplorerServersDlg):
ConfigureExplorerServersDlg.setModal(True)
# -- Layout
self.layout = QVBoxLayout(ConfigureExplorerServersDlg)
self.layout.setSpacing(10)
# -- Servers List
self.serversBox = QListWidget()
self.layout.addWidget(self.serversBox)
# -- 'Add Server' button
self.addServer_btn = QPushButton("Add Explorer Server")
self.layout.addWidget(self.addServer_btn)
# -- 'Close' button
hBox = QHBoxLayout()
hBox.addStretch(1)
self.close_btn = QPushButton("Close")
hBox.addWidget(self.close_btn)
self.layout.addLayout(hBox)
# -- Edit section
self.editFrame = QFrame()
frameLayout = QFormLayout()
frameLayout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow)
frameLayout.setContentsMargins(5, 10, 5, 5)
frameLayout.setSpacing(7)
self.url_edt = QLineEdit()
frameLayout.addRow(QLabel("Explorer URL"), self.url_edt)
hBox2 = QHBoxLayout()
self.cancel_btn = QPushButton("Cancel")
self.save_btn = QPushButton("Save")
hBox2.addWidget(self.cancel_btn)
hBox2.addWidget(self.save_btn)
frameLayout.addRow(hBox2)
self.editFrame.setLayout(frameLayout)
self.layout.addWidget(self.editFrame)
self.editFrame.setHidden(True)
ConfigureExplorerServersDlg.setMinimumWidth(500)
ConfigureExplorerServersDlg.setMinimumHeight(500)
# Connect main buttons
self.addServer_btn.clicked.connect(lambda: ConfigureExplorerServersDlg.onAddServer())
self.close_btn.clicked.connect(lambda: ConfigureExplorerServersDlg.onClose())
self.cancel_btn.clicked.connect(lambda: ConfigureExplorerServersDlg.onCancel())
self.save_btn.clicked.connect(lambda: ConfigureExplorerServersDlg.onSave())
9 changes: 9 additions & 0 deletions src/qt/guiHeader.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ def __init__(self, caller, *args, **kwargs):
self.hwLed.setToolTip("status: %s" % caller.hwStatusMess)
self.hwLed.setPixmap(caller.ledGrayH_icon)
self.centralBox.addWidget(self.hwLed, 1, 3)
# -- 1c) Select & Check Explorer
label4 = QLabel("Explorer")
self.centralBox.addWidget(label4, 2, 0)
self.explorerClientsBox = QComboBox()
self.explorerClientsBox.setToolTip("Select Explorer Server")
#self.explorerClientsBox.setItemDelegate(AlignDelegate())
self.centralBox.addWidget(self.explorerClientsBox, 2, 1)

layout.addLayout(self.centralBox)
layout.addStretch(1)

self.setLayout(layout)

0 comments on commit 29d7758

Please sign in to comment.