Skip to content

Commit

Permalink
add missing functionality to remote widget in manager
Browse files Browse the repository at this point in the history
  • Loading branch information
drogenlied committed Jul 31, 2015
1 parent 20230bc commit a9bc2f7
Show file tree
Hide file tree
Showing 5 changed files with 265 additions and 14 deletions.
20 changes: 12 additions & 8 deletions core/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from pyqtgraph.Qt import QtCore
from urllib.parse import urlparse
from rpyc.utils.server import ThreadedServer
from .util.models import DictTableModel, ListTableModel
import rpyc
import socket

Expand All @@ -38,8 +39,10 @@ def __init__(self, threadManager, logger):
self.tm = threadManager
self.logger = logger
#self.logger.logMsg('Nameserver is: {0}'.format(self.nameserver._pyroUri), msgType='status')
self.remoteModules = list()
self.sharedModules = dict()
self.remoteModules = ListTableModel()
self.remoteModules.headers[0] = 'Remote Modules'
self.sharedModules = DictTableModel()
self.sharedModules.headers[0] = 'Shared Modules'

def makeRemoteService(self):
""" A function that returns a class containing a module list hat can be manipulated from the host.
Expand Down Expand Up @@ -68,9 +71,10 @@ def exposed_getModule(self, name):
@return object: reference to the module
"""
if name in self.modules:
return self.modules[name]
if name in self.modules.storage:
return self.modules.storage[name]
else:
self.logMsg('Client requested a module that is not shared.', msgType='error')
return None

return RemoteModuleService
Expand Down Expand Up @@ -106,19 +110,19 @@ def shareModule(self, name, obj):
@param str name: unique name that is used to access the module
@param object obj: a reference to the module
"""
if name in self.sharedModules:
if name in self.sharedModules.storage:
self.logger.logMsg('Module {0} already shared.'.format(name), msgType='warning')
self.sharedModules[name] = obj
self.sharedModules.add(name, obj)
self.logger.logMsg('Shared module {0}.'.format(name), msgType='status')

def unshareModule(self, name):
""" Remove a module from the shared module list.
@param str name: unique name of the module that should not be accessible any more
"""
if name in self.sharedModules:
if name in self.sharedModules.storage:
self.logger.logMsg('Module {0} was not shared.'.format(name), msgType='error')
self.sharedModules.popKey(name, None)
self.sharedModules.pop(name)

def getRemoteModuleUrl(self, url):
""" Get a remote module via its URL.
Expand Down
225 changes: 225 additions & 0 deletions core/util/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
# -*- coding: utf-8 -*-
"""
This file contains Qt models for Python data structures.
QuDi is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QuDi 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 QuDi. If not, see <http://www.gnu.org/licenses/>.
Copyright (C) 2015 Jan M. Binder jan.binder@uni-ulm.de
"""

from pyqtgraph.Qt import QtCore
from collections import OrderedDict
from .mutex import Mutex

class DictTableModel(QtCore.QAbstractTableModel):

def __init__(self):
super().__init__()
self.lock = Mutex()
self.headers = ['Name']
self.storage = OrderedDict()

def getKeyByNumber(self, n):
i = 0
length = len(self.storage)
if n < 0 or n >= length:
raise IndexError
it = iter(self.storage)
key = next(it)
while(i<n):
key = next(it)
i += 1
return key

def getNumberByKey(self, key):
i = 0
it = iter(self.storage)
newkey = next(it)
while(key != newkey):
newkey = next(it)
i += 1
return i

def rowCount(self, parent = QtCore.QModelIndex()):
""" Gives the number of stored items.
@return int: number of items
"""
return len(self.storage)

def columnCount(self, parent = QtCore.QModelIndex()):
""" Gives the number of data fields.
@return int: number of data fields
"""
return len(self.headers)

def flags(self, index):
""" Determines what can be done with entry cells in the table view.
@param QModelIndex index: cell fo which the flags are requested
@return Qt.ItemFlags: actins allowed fotr this cell
"""
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

def data(self, index, role):
""" Get data from model for a given cell. Data can have a role that affects display.
@param QModelIndex index: cell for which data is requested
@param ItemDataRole role: role for which data is requested
@return QVariant: data for given cell and role
"""
if not index.isValid():
return None
elif role == QtCore.Qt.DisplayRole:
key = self.getKeyByNumber(index.row())
if index.column() == 0:
return key
elif index.column() == 1:
return self.storage[key]
else:
return None
else:
return None

def headerData(self, section, orientation, role = QtCore.Qt.DisplayRole):
""" Data for the table view headers.
@param int section: number of the column to get header data for
@param Qt.Orientation: orientation of header (horizontal or vertical)
@param ItemDataRole: role for which to get data
@return QVariant: header data for given column and role
"""
if section < 0 and section > len(self.headers):
return None
elif role != QtCore.Qt.DisplayRole:
return None
elif orientation != QtCore.Qt.Horizontal:
return None
else:
return self.header[section]

def add(self, key, data):
with self.lock:
if key in self.storage:
return None
row = len(self.storage)
self.beginInsertRows(QtCore.QModelIndex(), row, row)
self.storage[key] = data
self.endInsertRows()

def pop(self, key):
with self.lock:
if key in self.storage:
row = self.getNumberByKey(key)
self.beginRemoveRows(QtCore.QModelIndex(), row, row)
ret = self.storage.pop(key)
self.endRemoveRows()
return ret


class ListTableModel(QtCore.QAbstractTableModel):

def __init__(self):
super().__init__()
self.lock = Mutex()
self.headers = ['Name']
self.storage = list()

def rowCount(self, parent = QtCore.QModelIndex()):
""" Gives the number of stored items.
@return int: number of items
"""
return len(self.storage)

def columnCount(self, parent = QtCore.QModelIndex()):
""" Gives the number of data fields.
@return int: number of data fields
"""
return len(self.headers)

def flags(self, index):
""" Determines what can be done with entry cells in the table view.
@param QModelIndex index: cell fo which the flags are requested
@return Qt.ItemFlags: actins allowed fotr this cell
"""
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

def data(self, index, role):
""" Get data from model for a given cell. Data can have a role that affects display.
@param QModelIndex index: cell for which data is requested
@param ItemDataRole role: role for which data is requested
@return QVariant: data for given cell and role
"""
if not index.isValid():
return None
elif role == QtCore.Qt.DisplayRole:
if index.column() == 0:
return self.storage[index.row()]
#elif index.column() == 1:
# return item[1].thread
else:
return None
else:
return None

def headerData(self, section, orientation, role = QtCore.Qt.DisplayRole):
""" Data for the table view headers.
@param int section: number of the column to get header data for
@param Qt.Orientation: orientation of header (horizontal or vertical)
@param ItemDataRole: role for which to get data
@return QVariant: header data for given column and role
"""
if section < 0 and section > len(self.headers):
return None
elif role != QtCore.Qt.DisplayRole:
return None
elif orientation != QtCore.Qt.Horizontal:
return None
else:
return self.header[section]

def insert(self, n, data):
with self.lock:
if n >= 0 and n <= len(self.storage):
self.beginInsertRows(QtCore.QModelIndex(), n, n)
self.storage.insert(n, data)
self.endInsertRows()

def append(self, data):
with self.lock:
n = len(self.storage)
self.beginInsertRows(QtCore.QModelIndex(), n, n)
self.storage.append(data)
self.endInsertRows()

def pop(self, n):
with self.lock:
if n >= 0 and n < len(self.storage):
self.beginRemoveRows(QtCore.QModelIndex(), n, n)
ret = self.storage.pop(n)
self.endRemoveRows()
return ret

2 changes: 2 additions & 0 deletions gui/manager/managergui.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ def activation(self, e=None):
# remote widget
self._mw.remoteWidget.hostLabel.setText('URL:')
self._mw.remoteWidget.portLabel.setText('rpyc://{0}:{1}/'.format(self._manager.rm.hostname, self._manager.rm.server.port))
self._mw.remoteWidget.remoteModuleListView.setModel(self._manager.rm.remoteModules)
self._mw.remoteWidget.sharedModuleListView.setModel(self._manager.rm.sharedModules)

self._mw.config_display_dockWidget.hide()
self._mw.remoteDockWidget.hide()
Expand Down
5 changes: 4 additions & 1 deletion gui/manager/ui_logwidget.ui
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,11 @@
<property name="textElideMode">
<enum>Qt::ElideNone</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerItem</enum>
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="gridStyle">
<enum>Qt::NoPen</enum>
Expand Down
27 changes: 22 additions & 5 deletions gui/manager/ui_remotewidget.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<width>356</width>
<height>300</height>
</rect>
</property>
Expand All @@ -21,16 +21,33 @@
</property>
</widget>
</item>
<item row="0" column="1">
<item row="1" column="0" colspan="2">
<widget class="QListView" name="sharedModuleListView">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="uniformItemSizes">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QListView" name="remoteModuleListView">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="uniformItemSizes">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="portLabel">
<property name="text">
<string>port</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QListView" name="listView"/>
</item>
</layout>
</widget>
<resources/>
Expand Down

0 comments on commit a9bc2f7

Please # to comment.