summaryrefslogtreecommitdiff
path: root/grc/src
diff options
context:
space:
mode:
Diffstat (limited to 'grc/src')
-rw-r--r--grc/src/Makefile.am32
-rw-r--r--grc/src/__init__.py1
-rw-r--r--grc/src/grc_gnuradio/Makefile.am31
-rw-r--r--grc/src/grc_gnuradio/__init__.py1
-rw-r--r--grc/src/grc_gnuradio/blks2/Makefile.am33
-rw-r--r--grc/src/grc_gnuradio/blks2/__init__.py28
-rw-r--r--grc/src/grc_gnuradio/blks2/error_rate.py137
-rw-r--r--grc/src/grc_gnuradio/blks2/packet.py241
-rw-r--r--grc/src/grc_gnuradio/blks2/probe.py123
-rw-r--r--grc/src/grc_gnuradio/blks2/selector.py128
-rw-r--r--grc/src/grc_gnuradio/blks2/tcp.py66
-rw-r--r--grc/src/grc_gnuradio/blks2/variable_sink.py64
-rw-r--r--grc/src/grc_gnuradio/usrp/Makefile.am30
-rw-r--r--grc/src/grc_gnuradio/usrp/__init__.py26
-rw-r--r--grc/src/grc_gnuradio/usrp/common.py75
-rw-r--r--grc/src/grc_gnuradio/usrp/dual_usrp.py132
-rw-r--r--grc/src/grc_gnuradio/usrp/simple_usrp.py113
-rw-r--r--grc/src/grc_gnuradio/wxgui/Makefile.am27
-rw-r--r--grc/src/grc_gnuradio/wxgui/__init__.py21
-rw-r--r--grc/src/grc_gnuradio/wxgui/top_block_gui.py100
-rw-r--r--grc/src/gui/ActionHandler.py408
-rw-r--r--grc/src/gui/Actions.py167
-rw-r--r--grc/src/gui/Bars.py137
-rw-r--r--grc/src/gui/BlockTreeWindow.py168
-rw-r--r--grc/src/gui/Constants.py48
-rw-r--r--grc/src/gui/Dialogs.py100
-rw-r--r--grc/src/gui/DrawingArea.py126
-rw-r--r--grc/src/gui/FileDialogs.py160
-rw-r--r--grc/src/gui/MainWindow.py299
-rw-r--r--grc/src/gui/Makefile.am41
-rw-r--r--grc/src/gui/Messages.py105
-rw-r--r--grc/src/gui/NotebookPage.py197
-rw-r--r--grc/src/gui/ParamsDialog.py144
-rw-r--r--grc/src/gui/Preferences.py86
-rw-r--r--grc/src/gui/StateCache.py92
-rw-r--r--grc/src/gui/__init__.py1
-rw-r--r--grc/src/platforms/Makefile.am31
-rw-r--r--grc/src/platforms/__init__.py1
-rw-r--r--grc/src/platforms/base/Block.py259
-rw-r--r--grc/src/platforms/base/Connection.py94
-rw-r--r--grc/src/platforms/base/Constants.py.in30
-rw-r--r--grc/src/platforms/base/Element.py96
-rw-r--r--grc/src/platforms/base/FlowGraph.py224
-rw-r--r--grc/src/platforms/base/Makefile.am46
-rw-r--r--grc/src/platforms/base/Param.py271
-rw-r--r--grc/src/platforms/base/Platform.py143
-rw-r--r--grc/src/platforms/base/Port.py80
-rw-r--r--grc/src/platforms/base/__init__.py1
-rw-r--r--grc/src/platforms/gui/Block.py199
-rw-r--r--grc/src/platforms/gui/Colors.py37
-rw-r--r--grc/src/platforms/gui/Connection.py140
-rw-r--r--grc/src/platforms/gui/Constants.py44
-rw-r--r--grc/src/platforms/gui/Element.py226
-rw-r--r--grc/src/platforms/gui/FlowGraph.py488
-rw-r--r--grc/src/platforms/gui/Makefile.am37
-rw-r--r--grc/src/platforms/gui/Param.py103
-rw-r--r--grc/src/platforms/gui/Platform.py48
-rw-r--r--grc/src/platforms/gui/Port.py190
-rw-r--r--grc/src/platforms/gui/Utils.py82
-rw-r--r--grc/src/platforms/gui/__init__.py1
-rw-r--r--grc/src/platforms/python/Block.py152
-rw-r--r--grc/src/platforms/python/Connection.py34
-rw-r--r--grc/src/platforms/python/Constants.py.in54
-rw-r--r--grc/src/platforms/python/FlowGraph.py162
-rw-r--r--grc/src/platforms/python/Generator.py142
-rw-r--r--grc/src/platforms/python/Makefile.am48
-rw-r--r--grc/src/platforms/python/Param.py402
-rw-r--r--grc/src/platforms/python/Platform.py69
-rw-r--r--grc/src/platforms/python/Port.py129
-rw-r--r--grc/src/platforms/python/__init__.py1
-rw-r--r--grc/src/platforms/python/utils/Makefile.am30
-rw-r--r--grc/src/platforms/python/utils/__init__.py1
-rw-r--r--grc/src/platforms/python/utils/convert_hier.py78
-rw-r--r--grc/src/platforms/python/utils/expr_utils.py137
-rw-r--r--grc/src/platforms/python/utils/extract_docs.py92
-rw-r--r--grc/src/utils/Makefile.am30
-rw-r--r--grc/src/utils/ParseXML.py102
-rw-r--r--grc/src/utils/__init__.py20
-rw-r--r--grc/src/utils/converter.py248
-rw-r--r--grc/src/utils/odict.py93
80 files changed, 0 insertions, 8583 deletions
diff --git a/grc/src/Makefile.am b/grc/src/Makefile.am
deleted file mode 100644
index a726d4935..000000000
--- a/grc/src/Makefile.am
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Copyright 2008 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-include $(top_srcdir)/grc/Makefile.inc
-
-SUBDIRS = \
- platforms \
- grc_gnuradio \
- gui \
- utils
-
-ourpythondir = $(grc_src_prefix)
-
-ourpython_PYTHON = __init__.py
diff --git a/grc/src/__init__.py b/grc/src/__init__.py
deleted file mode 100644
index 8b1378917..000000000
--- a/grc/src/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/grc/src/grc_gnuradio/Makefile.am b/grc/src/grc_gnuradio/Makefile.am
deleted file mode 100644
index 767e8f670..000000000
--- a/grc/src/grc_gnuradio/Makefile.am
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Copyright 2008 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-include $(top_srcdir)/grc/Makefile.inc
-
-SUBDIRS = \
- blks2 \
- usrp \
- wxgui
-
-ourpythondir = $(grc_gnuradio_prefix)
-
-ourpython_PYTHON = __init__.py
diff --git a/grc/src/grc_gnuradio/__init__.py b/grc/src/grc_gnuradio/__init__.py
deleted file mode 100644
index 8b1378917..000000000
--- a/grc/src/grc_gnuradio/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/grc/src/grc_gnuradio/blks2/Makefile.am b/grc/src/grc_gnuradio/blks2/Makefile.am
deleted file mode 100644
index 89889605b..000000000
--- a/grc/src/grc_gnuradio/blks2/Makefile.am
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Copyright 2008, 2009 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-include $(top_srcdir)/grc/Makefile.inc
-
-ourpythondir = $(grc_gnuradio_prefix)/blks2
-
-ourpython_PYTHON = \
- __init__.py \
- error_rate.py \
- packet.py \
- probe.py \
- selector.py \
- tcp.py \
- variable_sink.py
diff --git a/grc/src/grc_gnuradio/blks2/__init__.py b/grc/src/grc_gnuradio/blks2/__init__.py
deleted file mode 100644
index cb1196f25..000000000
--- a/grc/src/grc_gnuradio/blks2/__init__.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright 2008, 2009 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from selector import selector, valve
-from packet import options, packet_encoder, packet_decoder, \
- packet_mod_b, packet_mod_s, packet_mod_i, packet_mod_f, packet_mod_c, \
- packet_demod_b, packet_demod_s, packet_demod_i, packet_demod_f, packet_demod_c
-from error_rate import error_rate
-from probe import probe_function, probe_avg_mag_sqrd_c, probe_avg_mag_sqrd_f, probe_density_b, probe_mpsk_snr_c
-from variable_sink import variable_sink_b, variable_sink_s, variable_sink_i, variable_sink_f, variable_sink_c
-from tcp import tcp_source, tcp_sink
diff --git a/grc/src/grc_gnuradio/blks2/error_rate.py b/grc/src/grc_gnuradio/blks2/error_rate.py
deleted file mode 100644
index 9b2df58ef..000000000
--- a/grc/src/grc_gnuradio/blks2/error_rate.py
+++ /dev/null
@@ -1,137 +0,0 @@
-# Copyright 2008 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-default_win_size = 1000
-
-from gnuradio import gr
-import gnuradio.gr.gr_threading as _threading
-import numpy
-
-#generate 1s counts array
-_1s_counts = [sum([1&(i>>j) for j in range(8)]) for i in range(2**8)]
-
-class input_watcher(_threading.Thread):
- """
- Read samples from the message queue and hand them to the callback.
- """
-
- def __init__(self, msgq, callback):
- self._msgq = msgq
- self._callback = callback
- _threading.Thread.__init__(self)
- self.setDaemon(1)
- self.keep_running = True
- self.start()
-
- def run(self):
- r = ''
- while True:
- msg = self._msgq.delete_head()
- itemsize = int(msg.arg1())
- nitems = int(msg.arg2())
- s = r + msg.to_string()
- i = (nitems-nitems%2)*itemsize
- r = s[i:]
- s = s[:i]
- samples = numpy.fromstring(s, numpy.int8)
- self._callback(samples)
-
-class error_rate(gr.hier_block2):
- """
- Sample the incoming data streams (byte) and calculate the bit or symbol error rate.
- Write the running rate to the output data stream (float).
- """
-
- def __init__(self, type='BER', win_size=default_win_size, bits_per_symbol=2):
- """
- Error rate constructor.
- @param type a string 'BER' or 'SER'
- @param win_size the number of samples to calculate over
- @param bits_per_symbol the number of information bits per symbol (BER only)
- """
- #init
- gr.hier_block2.__init__(
- self, 'error_rate',
- gr.io_signature(2, 2, gr.sizeof_char),
- gr.io_signature(1, 1, gr.sizeof_float),
- )
- assert type in ('BER', 'SER')
- self._max_samples = win_size
- self._bits_per_symbol = bits_per_symbol
- #setup message queue
- msg_source = gr.message_source(gr.sizeof_float, 1)
- self._msgq_source = msg_source.msgq()
- msgq_sink = gr.msg_queue(2)
- msg_sink = gr.message_sink(gr.sizeof_char, msgq_sink, False) #False -> blocking
- inter = gr.interleave(gr.sizeof_char)
- #start thread
- self._num_errs = 0
- self._err_index = 0
- self._num_samps = 0
- self._err_array = numpy.zeros(self._max_samples, numpy.int8)
- if type == 'BER':
- input_watcher(msgq_sink, self._handler_ber)
- elif type == 'SER':
- input_watcher(msgq_sink, self._handler_ser)
- #connect
- self.connect(msg_source, self)
- self.connect((self, 0), (inter, 0))
- self.connect((self, 1), (inter, 1))
- self.connect(inter, msg_sink)
-
- def _handler_ber(self, samples):
- num = len(samples)/2
- arr = numpy.zeros(num, numpy.float32)
- for i in range(num):
- old_err = self._err_array[self._err_index]
- #record error
- self._err_array[self._err_index] = _1s_counts[samples[i*2] ^ samples[i*2 + 1]]
- self._num_errs = self._num_errs + self._err_array[self._err_index] - old_err
- #increment index
- self._err_index = (self._err_index + 1)%self._max_samples
- self._num_samps = min(self._num_samps + 1, self._max_samples)
- #write sample
- arr[i] = float(self._num_errs)/float(self._num_samps*self._bits_per_symbol)
- #write message
- msg = gr.message_from_string(arr.tostring(), 0, gr.sizeof_float, num)
- self._msgq_source.insert_tail(msg)
-
- def _handler_ser(self, samples):
- num = len(samples)/2
- arr = numpy.zeros(num, numpy.float32)
- for i in range(num):
- old_err = self._err_array[self._err_index]
- #record error
- ref = samples[i*2]
- res = samples[i*2 + 1]
- if ref == res:
- self._err_array[self._err_index] = 0
- else:
- self._err_array[self._err_index] = 1
- #update number of errors
- self._num_errs = self._num_errs + self._err_array[self._err_index] - old_err
- #increment index
- self._err_index = (self._err_index + 1)%self._max_samples
- self._num_samps = min(self._num_samps + 1, self._max_samples)
- #write sample
- arr[i] = float(self._num_errs)/float(self._num_samps)
- #write message
- msg = gr.message_from_string(arr.tostring(), 0, gr.sizeof_float, num)
- self._msgq_source.insert_tail(msg)
diff --git a/grc/src/grc_gnuradio/blks2/packet.py b/grc/src/grc_gnuradio/blks2/packet.py
deleted file mode 100644
index 50de99ac9..000000000
--- a/grc/src/grc_gnuradio/blks2/packet.py
+++ /dev/null
@@ -1,241 +0,0 @@
-# Copyright 2008, 2009 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr, packet_utils
-import gnuradio.gr.gr_threading as _threading
-
-##payload length in bytes
-DEFAULT_PAYLOAD_LEN = 512
-
-##how many messages in a queue
-DEFAULT_MSGQ_LIMIT = 2
-
-##threshold for unmaking packets
-DEFAULT_THRESHOLD = 12
-
-##################################################
-## Options Class for OFDM
-##################################################
-class options(object):
- def __init__(self, **kwargs):
- for key, value in kwargs.iteritems(): setattr(self, key, value)
-
-##################################################
-## Packet Encoder
-##################################################
-class _packet_encoder_thread(_threading.Thread):
-
- def __init__(self, msgq, payload_length, send):
- self._msgq = msgq
- self._payload_length = payload_length
- self._send = send
- _threading.Thread.__init__(self)
- self.setDaemon(1)
- self.keep_running = True
- self.start()
-
- def run(self):
- sample = '' #residual sample
- while self.keep_running:
- msg = self._msgq.delete_head() #blocking read of message queue
- sample = sample + msg.to_string() #get the body of the msg as a string
- while len(sample) >= self._payload_length:
- payload = sample[:self._payload_length]
- sample = sample[self._payload_length:]
- self._send(payload)
-
-class packet_encoder(gr.hier_block2):
- """
- Hierarchical block for wrapping packet-based modulators.
- """
-
- def __init__(self, samples_per_symbol, bits_per_symbol, access_code='', pad_for_usrp=True):
- """
- packet_mod constructor.
- @param samples_per_symbol number of samples per symbol
- @param bits_per_symbol number of bits per symbol
- @param access_code AKA sync vector
- @param pad_for_usrp If true, packets are padded such that they end up a multiple of 128 samples
- @param payload_length number of bytes in a data-stream slice
- """
- #setup parameters
- self._samples_per_symbol = samples_per_symbol
- self._bits_per_symbol = bits_per_symbol
- self._pad_for_usrp = pad_for_usrp
- if not access_code: #get access code
- access_code = packet_utils.default_access_code
- if not packet_utils.is_1_0_string(access_code):
- raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
- self._access_code = access_code
- self._pad_for_usrp = pad_for_usrp
- #create blocks
- msg_source = gr.message_source(gr.sizeof_char, DEFAULT_MSGQ_LIMIT)
- self._msgq_out = msg_source.msgq()
- #initialize hier2
- gr.hier_block2.__init__(
- self,
- "packet_encoder",
- gr.io_signature(0, 0, 0), # Input signature
- gr.io_signature(1, 1, gr.sizeof_char) # Output signature
- )
- #connect
- self.connect(msg_source, self)
-
- def send_pkt(self, payload):
- """
- Wrap the payload in a packet and push onto the message queue.
- @param payload string, data to send
- """
- packet = packet_utils.make_packet(
- payload,
- self._samples_per_symbol,
- self._bits_per_symbol,
- self._access_code,
- self._pad_for_usrp
- )
- msg = gr.message_from_string(packet)
- self._msgq_out.insert_tail(msg)
-
-##################################################
-## Packet Decoder
-##################################################
-class _packet_decoder_thread(_threading.Thread):
-
- def __init__(self, msgq, callback):
- _threading.Thread.__init__(self)
- self.setDaemon(1)
- self._msgq = msgq
- self.callback = callback
- self.keep_running = True
- self.start()
-
- def run(self):
- while self.keep_running:
- msg = self._msgq.delete_head()
- ok, payload = packet_utils.unmake_packet(msg.to_string(), int(msg.arg1()))
- if self.callback:
- self.callback(ok, payload)
-
-class packet_decoder(gr.hier_block2):
- """
- Hierarchical block for wrapping packet-based demodulators.
- """
-
- def __init__(self, access_code='', threshold=-1, callback=None):
- """
- packet_demod constructor.
- @param access_code AKA sync vector
- @param threshold detect access_code with up to threshold bits wrong (0 -> use default)
- @param callback a function of args: ok, payload
- """
- #access code
- if not access_code: #get access code
- access_code = packet_utils.default_access_code
- if not packet_utils.is_1_0_string(access_code):
- raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
- self._access_code = access_code
- #threshold
- if threshold < 0: threshold = DEFAULT_THRESHOLD
- self._threshold = threshold
- #blocks
- msgq = gr.msg_queue(DEFAULT_MSGQ_LIMIT) #holds packets from the PHY
- correlator = gr.correlate_access_code_bb(self._access_code, self._threshold)
- framer_sink = gr.framer_sink_1(msgq)
- #initialize hier2
- gr.hier_block2.__init__(
- self,
- "packet_decoder",
- gr.io_signature(1, 1, gr.sizeof_char), # Input signature
- gr.io_signature(0, 0, 0) # Output signature
- )
- #connect
- self.connect(self, correlator, framer_sink)
- #start thread
- _packet_decoder_thread(msgq, callback)
-
-##################################################
-## Packet Mod for OFDM Mod and Packet Encoder
-##################################################
-class packet_mod_base(gr.hier_block2):
- """
- Hierarchical block for wrapping packet source block.
- """
-
- def __init__(self, packet_source=None, payload_length=0):
- if not payload_length: #get payload length
- payload_length = DEFAULT_PAYLOAD_LEN
- if payload_length%self._item_size_in != 0: #verify that packet length is a multiple of the stream size
- raise ValueError, 'The payload length: "%d" is not a mutiple of the stream size: "%d".'%(payload_length, self._item_size_in)
- #initialize hier2
- gr.hier_block2.__init__(
- self,
- "ofdm_mod",
- gr.io_signature(1, 1, self._item_size_in), # Input signature
- gr.io_signature(1, 1, packet_source._hb.output_signature().sizeof_stream_item(0)) # Output signature
- )
- #create blocks
- msgq = gr.msg_queue(DEFAULT_MSGQ_LIMIT)
- msg_sink = gr.message_sink(self._item_size_in, msgq, False) #False -> blocking
- #connect
- self.connect(self, msg_sink)
- self.connect(packet_source, self)
- #start thread
- _packet_encoder_thread(msgq, payload_length, packet_source.send_pkt)
-
-class packet_mod_b(packet_mod_base): _item_size_in = gr.sizeof_char
-class packet_mod_s(packet_mod_base): _item_size_in = gr.sizeof_short
-class packet_mod_i(packet_mod_base): _item_size_in = gr.sizeof_int
-class packet_mod_f(packet_mod_base): _item_size_in = gr.sizeof_float
-class packet_mod_c(packet_mod_base): _item_size_in = gr.sizeof_gr_complex
-
-##################################################
-## Packet Demod for OFDM Demod and Packet Decoder
-##################################################
-class packet_demod_base(gr.hier_block2):
- """
- Hierarchical block for wrapping packet sink block.
- """
-
- def __init__(self, packet_sink=None):
- #initialize hier2
- gr.hier_block2.__init__(
- self,
- "ofdm_mod",
- gr.io_signature(1, 1, packet_sink._hb.input_signature().sizeof_stream_item(0)), # Input signature
- gr.io_signature(1, 1, self._item_size_out) # Output signature
- )
- #create blocks
- msg_source = gr.message_source(self._item_size_out, DEFAULT_MSGQ_LIMIT)
- self._msgq_out = msg_source.msgq()
- #connect
- self.connect(self, packet_sink)
- self.connect(msg_source, self)
- if packet_sink._hb.output_signature().sizeof_stream_item(0):
- self.connect(packet_sink, gr.null_sink(packet_sink._hb.output_signature().sizeof_stream_item(0)))
-
- def recv_pkt(self, ok, payload):
- msg = gr.message_from_string(payload, 0, self._item_size_out, len(payload)/self._item_size_out)
- if ok: self._msgq_out.insert_tail(msg)
-
-class packet_demod_b(packet_demod_base): _item_size_out = gr.sizeof_char
-class packet_demod_s(packet_demod_base): _item_size_out = gr.sizeof_short
-class packet_demod_i(packet_demod_base): _item_size_out = gr.sizeof_int
-class packet_demod_f(packet_demod_base): _item_size_out = gr.sizeof_float
-class packet_demod_c(packet_demod_base): _item_size_out = gr.sizeof_gr_complex
diff --git a/grc/src/grc_gnuradio/blks2/probe.py b/grc/src/grc_gnuradio/blks2/probe.py
deleted file mode 100644
index 8db81f057..000000000
--- a/grc/src/grc_gnuradio/blks2/probe.py
+++ /dev/null
@@ -1,123 +0,0 @@
-#
-# Copyright 2008 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr
-import threading
-import numpy
-import time
-
-#######################################################################################
-## Probe: Function
-#######################################################################################
-class probe_function(gr.hier_block2, threading.Thread):
- """
- The thread polls the function for values and writes to a message source.
- """
-
- def __init__(self, probe_callback, probe_rate):
- #init hier block
- gr.hier_block2.__init__(
- self, 'probe_function',
- gr.io_signature(0, 0, 0),
- gr.io_signature(1, 1, gr.sizeof_float),
- )
- self._probe_callback = probe_callback
- self.set_probe_rate(probe_rate)
- #create message source
- message_source = gr.message_source(gr.sizeof_float, 1)
- self._msgq = message_source.msgq()
- #connect
- self.connect(message_source, self)
- #setup thread
- threading.Thread.__init__(self)
- self.setDaemon(True)
- self.start()
-
- def run(self):
- """
- Infinite polling loop.
- """
- while True:
- time.sleep(1.0/self._probe_rate)
- arr = numpy.array(self._probe_callback(), numpy.float32)
- msg = gr.message_from_string(arr.tostring(), 0, gr.sizeof_float, 1)
- self._msgq.insert_tail(msg)
-
- def set_probe_rate(self, probe_rate):
- self._probe_rate = probe_rate
-
-class _probe_base(gr.hier_block2):
- def __init__(self, probe_block, probe_callback, probe_rate):
- #init hier block
- gr.hier_block2.__init__(
- self, 'probe',
- gr.io_signature(1, 1, probe_block.input_signature().sizeof_stream_items()[0]),
- gr.io_signature(1, 1, gr.sizeof_float),
- )
- probe_function_block = probe_function(probe_callback, probe_rate)
- #forward callbacks
- self.set_probe_rate = probe_function_block.set_probe_rate
- #connect
- self.connect(self, probe_block)
- self.connect(probe_function_block, self)
-
-#######################################################################################
-## Probe: Average Magnitude Squared
-#######################################################################################
-class _probe_avg_mag_sqrd_base(_probe_base):
- def __init__(self, threshold, alpha, probe_rate):
- #create block
- probe_block = self._probe_block_contructor[0](threshold, alpha)
- #forward callbacks
- self.set_alpha = probe_block.set_alpha
- self.set_threshold = probe_block.set_threshold
- #init
- _probe_base.__init__(self, probe_block, probe_block.level, probe_rate)
-
-class probe_avg_mag_sqrd_c(_probe_avg_mag_sqrd_base): _probe_block_contructor = (gr.probe_avg_mag_sqrd_c,)
-class probe_avg_mag_sqrd_f(_probe_avg_mag_sqrd_base): _probe_block_contructor = (gr.probe_avg_mag_sqrd_f,)
-
-#######################################################################################
-## Probe: Density
-#######################################################################################
-class probe_density_b(_probe_base):
- def __init__(self, alpha, probe_rate):
- #create block
- probe_block = gr.probe_density_b(alpha)
- #forward callbacks
- self.set_alpha = probe_block.set_alpha
- #init
- _probe_base.__init__(self, probe_block, probe_block.density, probe_rate)
-
-#######################################################################################
-## Probe: MPSK SNR
-#######################################################################################
-class probe_mpsk_snr_c(_probe_base):
- def __init__(self, type, alpha, probe_rate):
- """
- Type can be "snr", "signal_mean", or "noise_variance"
- """
- #create block
- probe_block = gr.probe_mpsk_snr_c(alpha)
- #forward callbacks
- self.set_alpha = probe_block.set_alpha
- #init
- _probe_base.__init__(self, probe_block, getattr(probe_block, type), probe_rate)
diff --git a/grc/src/grc_gnuradio/blks2/selector.py b/grc/src/grc_gnuradio/blks2/selector.py
deleted file mode 100644
index f0f6d5dd7..000000000
--- a/grc/src/grc_gnuradio/blks2/selector.py
+++ /dev/null
@@ -1,128 +0,0 @@
-#
-# Copyright 2008 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr
-
-class selector(gr.hier_block2):
- """A hier2 block with N inputs and M outputs, where data is only forwarded through input n to output m."""
- def __init__(self, item_size, num_inputs, num_outputs, input_index, output_index):
- """
- Selector constructor.
- @param item_size the size of the gr data stream in bytes
- @param num_inputs the number of inputs (integer)
- @param num_outputs the number of outputs (integer)
- @param input_index the index for the source data
- @param output_index the index for the destination data
- """
- gr.hier_block2.__init__(
- self, 'selector',
- gr.io_signature(num_inputs, num_inputs, item_size),
- gr.io_signature(num_outputs, num_outputs, item_size),
- )
- #terminator blocks for unused inputs and outputs
- self.input_terminators = [gr.null_sink(item_size) for i in range(num_inputs)]
- self.output_terminators = [gr.head(item_size, 0) for i in range(num_outputs)]
- self.copy = gr.kludge_copy(item_size)
- #connections
- for i in range(num_inputs): self.connect((self, i), self.input_terminators[i])
- for i in range(num_outputs): self.connect(gr.null_source(item_size), self.output_terminators[i], (self, i))
- self.item_size = item_size
- self.input_index = input_index
- self.output_index = output_index
- self.num_inputs = num_inputs
- self.num_outputs = num_outputs
- self._connect_current()
-
- def _indexes_valid(self):
- """
- Are the input and output indexes within range of the number of inputs and outputs?
- @return true if input index and output index are in range
- """
- return self.input_index in range(self.num_inputs) and self.output_index in range(self.num_outputs)
-
- def _connect_current(self):
- """If the input and output indexes are valid:
- disconnect the blocks at the input and output index from their terminators,
- and connect them to one another. Then connect the terminators to one another."""
- if self._indexes_valid():
- self.disconnect((self, self.input_index), self.input_terminators[self.input_index])
- self.disconnect(self.output_terminators[self.output_index], (self, self.output_index))
- self.connect((self, self.input_index), self.copy)
- self.connect(self.copy, (self, self.output_index))
- self.connect(self.output_terminators[self.output_index], self.input_terminators[self.input_index])
-
- def _disconnect_current(self):
- """If the input and output indexes are valid:
- disconnect the blocks at the input and output index from one another,
- and the terminators at the input and output index from one another.
- Reconnect the blocks to the terminators."""
- if self._indexes_valid():
- self.disconnect((self, self.input_index), self.copy)
- self.disconnect(self.copy, (self, self.output_index))
- self.disconnect(self.output_terminators[self.output_index], self.input_terminators[self.input_index])
- self.connect((self, self.input_index), self.input_terminators[self.input_index])
- self.connect(self.output_terminators[self.output_index], (self, self.output_index))
-
- def set_input_index(self, input_index):
- """
- Change the block to the new input index if the index changed.
- @param input_index the new input index
- """
- if self.input_index != input_index:
- self.lock()
- self._disconnect_current()
- self.input_index = input_index
- self._connect_current()
- self.unlock()
-
- def set_output_index(self, output_index):
- """
- Change the block to the new output index if the index changed.
- @param output_index the new output index
- """
- if self.output_index != output_index:
- self.lock()
- self._disconnect_current()
- self.output_index = output_index
- self._connect_current()
- self.unlock()
-
-class valve(selector):
- """Wrapper for selector with 1 input and 1 output."""
-
- def __init__(self, item_size, open):
- """
- Constructor for valve.
- @param item_size the size of the gr data stream in bytes
- @param open true if initial valve state is open
- """
- if open: output_index = -1
- else: output_index = 0
- selector.__init__(self, item_size, 1, 1, 0, output_index)
-
- def set_open(self, open):
- """
- Callback to set open state.
- @param open true to set valve state to open
- """
- if open: output_index = -1
- else: output_index = 0
- self.set_output_index(output_index)
diff --git a/grc/src/grc_gnuradio/blks2/tcp.py b/grc/src/grc_gnuradio/blks2/tcp.py
deleted file mode 100644
index c6739b711..000000000
--- a/grc/src/grc_gnuradio/blks2/tcp.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#
-# Copyright 2009 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr
-import socket
-import os
-
-def _get_sock_fd(addr, port, server):
- """
- Get the file descriptor for the socket.
- As a client, block on connect, dup the socket descriptor.
- As a server, block on accept, dup the client descriptor.
- @param addr the ip address string
- @param port the tcp port number
- @param server true for server mode, false for client mode
- @return the file descriptor number
- """
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- if server:
- sock.bind((addr, port))
- sock.listen(1)
- clientsock, address = sock.accept()
- return os.dup(clientsock.fileno())
- else:
- sock.connect((addr, port))
- return os.dup(sock.fileno())
-
-class tcp_source(gr.hier_block2):
- def __init__(self, itemsize, addr, port, server=True):
- #init hier block
- gr.hier_block2.__init__(
- self, 'tcp_source',
- gr.io_signature(0, 0, 0),
- gr.io_signature(1, 1, itemsize),
- )
- fd = _get_sock_fd(addr, port, server)
- self.connect(gr.file_descriptor_source(itemsize, fd), self)
-
-class tcp_sink(gr.hier_block2):
- def __init__(self, itemsize, addr, port, server=False):
- #init hier block
- gr.hier_block2.__init__(
- self, 'tcp_sink',
- gr.io_signature(1, 1, itemsize),
- gr.io_signature(0, 0, 0),
- )
- fd = _get_sock_fd(addr, port, server)
- self.connect(self, gr.file_descriptor_sink(itemsize, fd))
diff --git a/grc/src/grc_gnuradio/blks2/variable_sink.py b/grc/src/grc_gnuradio/blks2/variable_sink.py
deleted file mode 100644
index cad3b8b04..000000000
--- a/grc/src/grc_gnuradio/blks2/variable_sink.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#
-# Copyright 2009 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr
-import threading
-import numpy
-
-class _variable_sink_base(gr.hier_block2, threading.Thread):
- """
- The thread polls the message queue for values and writes to a callback.
- """
-
- def __init__(self, vlen, decim, callback):
- self._vlen = vlen
- self._callback = callback
- self._item_size = self._size*self._vlen
- #init hier block
- gr.hier_block2.__init__(
- self, 'variable_sink',
- gr.io_signature(1, 1, self._item_size),
- gr.io_signature(0, 0, 0),
- )
- #create blocks
- self._decimator = gr.keep_one_in_n(self._item_size, decim)
- self._msgq = gr.msg_queue(2)
- message_sink = gr.message_sink(self._item_size, self._msgq, False)
- #connect
- self.connect(self, self._decimator, message_sink)
- #setup thread
- threading.Thread.__init__(self)
- self.setDaemon(True)
- self.start()
-
- def set_decim(self, decim): self._decimator.set_n(decim)
-
- def run(self):
- while True: #truncate to item size, convert to array, callback
- msg = self._msgq.delete_head().to_string()[-self._item_size:]
- arr = map(self._cast, numpy.fromstring(msg, self._numpy))
- self._callback(self._vlen > 1 and arr or arr[0])
-
-class variable_sink_b(_variable_sink_base): _numpy, _size, _cast = numpy.int8, gr.sizeof_char, int
-class variable_sink_s(_variable_sink_base): _numpy, _size, _cast = numpy.int16, gr.sizeof_short, int
-class variable_sink_i(_variable_sink_base): _numpy, _size, _cast = numpy.int32, gr.sizeof_int, int
-class variable_sink_f(_variable_sink_base): _numpy, _size, _cast = numpy.float32, gr.sizeof_float, float
-class variable_sink_c(_variable_sink_base): _numpy, _size, _cast = numpy.complex64, gr.sizeof_gr_complex, complex
diff --git a/grc/src/grc_gnuradio/usrp/Makefile.am b/grc/src/grc_gnuradio/usrp/Makefile.am
deleted file mode 100644
index 136a5dacd..000000000
--- a/grc/src/grc_gnuradio/usrp/Makefile.am
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright 2008 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-include $(top_srcdir)/grc/Makefile.inc
-
-ourpythondir = $(grc_gnuradio_prefix)/usrp
-
-ourpython_PYTHON = \
- __init__.py \
- common.py \
- dual_usrp.py \
- simple_usrp.py
diff --git a/grc/src/grc_gnuradio/usrp/__init__.py b/grc/src/grc_gnuradio/usrp/__init__.py
deleted file mode 100644
index 1956bbd5b..000000000
--- a/grc/src/grc_gnuradio/usrp/__init__.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2008 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from simple_usrp import \
- simple_source_c, simple_source_s, \
- simple_sink_c, simple_sink_s
-from dual_usrp import \
- dual_source_c, dual_source_s, \
- dual_sink_c, dual_sink_s
diff --git a/grc/src/grc_gnuradio/usrp/common.py b/grc/src/grc_gnuradio/usrp/common.py
deleted file mode 100644
index 65c1e7e29..000000000
--- a/grc/src/grc_gnuradio/usrp/common.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright 2009 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-import sys
-from gnuradio import usrp, gr
-
-##################################################
-# USRP base class with common methods
-##################################################
-class usrp_helper(object):
- def _make_usrp(self, *args, **kwargs): self._u = self._usrp_args[0](*args, **kwargs)
- def _get_u(self): return self._u
- def _get_io_size(self): return self._usrp_args[1]
- def _set_frequency(self, chan, subdev, frequency, verbose=False):
- """
- Set the carrier frequency for the given subdevice.
- @param chan specifies the DDC/DUC number
- @param frequency the carrier frequency in Hz
- @param verbose if true, print usrp tuning information
- """
- r = self._get_u().tune(chan, subdev, frequency)
- if not verbose: return
- print subdev.side_and_name()
- if r:
- print "\tr.baseband_frequency =", r.baseband_freq
- print "\tr.dxc_frequency =", r.dxc_freq
- print "\tr.residual_frequency =", r.residual_freq
- print "\tr.inverted =", r.inverted, "\n"
- else: print >> sys.stderr, 'Error calling tune on subdevice.'
- def set_format(self, width, shift): self._get_u().set_format(self._get_u().make_format(width, shift))
-
-##################################################
-# Classes to associate usrp constructor w/ io size
-##################################################
-class usrp_source_c(usrp_helper): _usrp_args = (usrp.source_c, gr.sizeof_gr_complex)
-class usrp_source_s(usrp_helper): _usrp_args = (usrp.source_s, gr.sizeof_short)
-class usrp_sink_c(usrp_helper): _usrp_args = (usrp.sink_c, gr.sizeof_gr_complex)
-class usrp_sink_s(usrp_helper): _usrp_args = (usrp.sink_s, gr.sizeof_short)
-
-##################################################
-# Side spec and antenna spec functions
-##################################################
-def is_flex(rx_ant): return rx_ant.upper() in ('TX/RX', 'RX2')
-def to_spec(side, rx_ant='RXA'):
- """
- Convert the side to a spec number.
- @param side A or B
- @param rx_ant antenna type
- @return the spec (0/1, 0/1/2)
- """
- #determine the side spec
- try: side_spec = {'A': 0, 'B': 1}[side.upper()]
- except: raise ValueError, 'Side A or B expected.'
- #determine the subdevice spec
- if rx_ant.upper() == 'RXB': subdev_spec = 1
- elif rx_ant.upper() == 'RXAB': subdev_spec = 2
- else: subdev_spec = 0
- return (side_spec, subdev_spec)
diff --git a/grc/src/grc_gnuradio/usrp/dual_usrp.py b/grc/src/grc_gnuradio/usrp/dual_usrp.py
deleted file mode 100644
index 1ecf7c47f..000000000
--- a/grc/src/grc_gnuradio/usrp/dual_usrp.py
+++ /dev/null
@@ -1,132 +0,0 @@
-# Copyright 2009 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-import common
-from gnuradio import gr, usrp
-
-####################################################################
-# Dual USRP Source
-####################################################################
-class _dual_source(gr.hier_block2):
- """A dual usrp source of IO type short or complex."""
-
- def __init__(self, which, rx_ant_a='RXA', rx_ant_b='RXA'):
- """
- USRP dual source contructor.
- @param which the unit number
- @param rx_ant_a the antenna choice
- @param rx_ant_b the antenna choice
- """
- #initialize hier2 block
- gr.hier_block2.__init__(
- self, 'usrp_dual_source',
- gr.io_signature(0, 0, 0),
- gr.io_signature(2, 2, self._get_io_size()),
- )
- #create usrp object
- self._make_usrp(which=which, nchan=2)
- subdev_spec_a = common.to_spec('A', rx_ant_a)
- subdev_spec_b = common.to_spec('B', rx_ant_b)
- self._get_u().set_mux(self._get_u().determine_rx_mux_value(subdev_spec_a, subdev_spec_b))
- self._subdev_a = self._get_u().selected_subdev(subdev_spec_a)
- self._subdev_b = self._get_u().selected_subdev(subdev_spec_b)
- #connect
- deinter = gr.deinterleave(self._get_io_size())
- self.connect(self._get_u(), deinter)
- for i in range(2): self.connect((deinter, i), (self, i))
-
- def set_decim_rate(self, decim): self._get_u().set_decim_rate(int(decim))
- def set_frequency_a(self, frequency, verbose=False):
- self._set_frequency(
- chan=0, #ddc0
- subdev=self._subdev_a,
- frequency=frequency,
- verbose=verbose,
- )
- def set_frequency_b(self, frequency, verbose=False):
- self._set_frequency(
- chan=1, #ddc1
- subdev=self._subdev_b,
- frequency=frequency,
- verbose=verbose,
- )
- def set_lo_offset_a(self, lo_offset): self._subdev_a.set_lo_offset(lo_offset)
- def set_lo_offset_b(self, lo_offset): self._subdev_b.set_lo_offset(lo_offset)
- def set_gain_a(self, gain): self._subdev_a.set_gain(gain)
- def set_gain_b(self, gain): self._subdev_b.set_gain(gain)
-
-class dual_source_c(_dual_source, common.usrp_source_c): pass
-class dual_source_s(_dual_source, common.usrp_source_s): pass
-
-####################################################################
-# Dual USRP Sink
-####################################################################
-class _dual_sink(gr.hier_block2):
- """A dual usrp sink of IO type short or complex."""
-
- def __init__(self, which):
- """
- USRP simple sink contructor.
- @param which the unit number
- """
- #initialize hier2 block
- gr.hier_block2.__init__(
- self, 'usrp_dual_sink',
- gr.io_signature(2, 2, self._get_io_size()),
- gr.io_signature(0, 0, 0),
- )
- #create usrp object
- self._make_usrp(which=which, nchan=2)
- subdev_spec_a = common.to_spec('A')
- subdev_spec_b = common.to_spec('B')
- self._get_u().set_mux(self._get_u().determine_tx_mux_value(subdev_spec_a, subdev_spec_b))
- self._subdev_a = self._get_u().selected_subdev(subdev_spec_a)
- self._subdev_b = self._get_u().selected_subdev(subdev_spec_b)
- #connect
- inter = gr.interleave(self._get_io_size())
- self.connect(inter, self._get_u())
- for i in range(2): self.connect((self, i), (inter, i))
-
- def set_interp_rate(self, interp): self._get_u().set_interp_rate(int(interp))
- def set_frequency_a(self, frequency, verbose=False):
- self._set_frequency(
- chan=self._subdev_a.which(),
- subdev=self._subdev_a,
- frequency=frequency,
- verbose=verbose,
- )
- def set_frequency_b(self, frequency, verbose=False):
- self._set_frequency(
- chan=self._subdev_b.which(),
- subdev=self._subdev_b,
- frequency=frequency,
- verbose=verbose,
- )
- def set_lo_offset_a(self, lo_offset): self._subdev_a.set_lo_offset(lo_offset)
- def set_lo_offset_b(self, lo_offset): self._subdev_b.set_lo_offset(lo_offset)
- def set_gain_a(self, gain): self._subdev_a.set_gain(gain)
- def set_gain_b(self, gain): self._subdev_b.set_gain(gain)
- def set_enable_a(self, enable): self._subdev_a.set_enable(enable)
- def set_enable_b(self, enable): self._subdev_b.set_enable(enable)
- def set_auto_tr_a(self, auto_tr): self._subdev_a.set_auto_tr(auto_tr)
- def set_auto_tr_b(self, auto_tr): self._subdev_b.set_auto_tr(auto_tr)
-
-class dual_sink_c(_dual_sink, common.usrp_sink_c): pass
-class dual_sink_s(_dual_sink, common.usrp_sink_s): pass
diff --git a/grc/src/grc_gnuradio/usrp/simple_usrp.py b/grc/src/grc_gnuradio/usrp/simple_usrp.py
deleted file mode 100644
index 9065c7fe9..000000000
--- a/grc/src/grc_gnuradio/usrp/simple_usrp.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# Copyright 2009 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-import common
-from gnuradio import gr, usrp
-
-####################################################################
-# Simple USRP Source
-####################################################################
-class _simple_source(gr.hier_block2):
- """A single usrp source of IO type short or complex."""
-
- def __init__(self, which, side='A', rx_ant='RXA', no_hb=False):
- """
- USRP simple source contructor.
- @param which the unit number
- @param side the usrp side A or B
- @param rx_ant the antenna choice
- @param no_hb disable half band filters
- """
- self._no_hb = no_hb
- #initialize hier2 block
- gr.hier_block2.__init__(
- self, 'usrp_simple_source',
- gr.io_signature(0, 0, 0),
- gr.io_signature(1, 1, self._get_io_size()),
- )
- #create usrp object
- if self._no_hb: self._make_usrp(which=which, nchan=1, fpga_filename="std_4rx_0tx.rbf")
- else: self._make_usrp(which=which, nchan=1)
- subdev_spec = common.to_spec(side, rx_ant)
- self._get_u().set_mux(self._get_u().determine_rx_mux_value(subdev_spec))
- self._subdev = self._get_u().selected_subdev(subdev_spec)
- if common.is_flex(rx_ant): self._subdev.select_rx_antenna(rx_ant)
- #connect
- self.connect(self._get_u(), self)
-
- def set_decim_rate(self, decim):
- self._get_u().set_decim_rate(int(decim))
- if self._no_hb: #set the BW to half the sample rate
- self._subdev.set_bw(self._get_u().converter_rate()/decim/2)
- def set_lo_offset(self, lo_offset): self._subdev.set_lo_offset(lo_offset)
- def set_frequency(self, frequency, verbose=False):
- self._set_frequency(
- chan=0, #ddc0
- subdev=self._subdev,
- frequency=frequency,
- verbose=verbose,
- )
- def set_gain(self, gain): self._subdev.set_gain(gain)
-
-class simple_source_c(_simple_source, common.usrp_source_c): pass
-class simple_source_s(_simple_source, common.usrp_source_s): pass
-
-####################################################################
-# Simple USRP Sink
-####################################################################
-class _simple_sink(gr.hier_block2):
- """A single usrp sink of IO type short or complex."""
-
- def __init__(self, which, side='A'):
- """
- USRP simple sink contructor.
- @param which the unit number
- @param side the usrp side A or B
- """
- #initialize hier2 block
- gr.hier_block2.__init__(
- self, 'usrp_simple_sink',
- gr.io_signature(1, 1, self._get_io_size()),
- gr.io_signature(0, 0, 0),
- )
- #create usrp object
- self._make_usrp(which=which, nchan=1)
- subdev_spec = common.to_spec(side)
- self._get_u().set_mux(self._get_u().determine_tx_mux_value(subdev_spec))
- self._subdev = self._get_u().selected_subdev(subdev_spec)
- #connect
- self.connect(self, self._get_u())
-
- def set_interp_rate(self, interp): self._get_u().set_interp_rate(int(interp))
- def set_frequency(self, frequency, verbose=False):
- self._set_frequency(
- chan=self._subdev.which(),
- subdev=self._subdev,
- frequency=frequency,
- verbose=verbose,
- )
- def set_lo_offset(self, lo_offset): self._subdev.set_lo_offset(lo_offset)
- def set_gain(self, gain): self._subdev.set_gain(gain)
- def set_enable(self, enable): self._subdev.set_enable(enable)
- def set_auto_tr(self, auto_tr): self._subdev.set_auto_tr(auto_tr)
-
-class simple_sink_c(_simple_sink, common.usrp_sink_c): pass
-class simple_sink_s(_simple_sink, common.usrp_sink_s): pass
-
diff --git a/grc/src/grc_gnuradio/wxgui/Makefile.am b/grc/src/grc_gnuradio/wxgui/Makefile.am
deleted file mode 100644
index 2e5e7ebd0..000000000
--- a/grc/src/grc_gnuradio/wxgui/Makefile.am
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Copyright 2008 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-include $(top_srcdir)/grc/Makefile.inc
-
-ourpythondir = $(grc_gnuradio_prefix)/wxgui
-ourpython_PYTHON = \
- __init__.py \
- top_block_gui.py
diff --git a/grc/src/grc_gnuradio/wxgui/__init__.py b/grc/src/grc_gnuradio/wxgui/__init__.py
deleted file mode 100644
index 94a0adb8a..000000000
--- a/grc/src/grc_gnuradio/wxgui/__init__.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright 2008 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from top_block_gui import top_block_gui
diff --git a/grc/src/grc_gnuradio/wxgui/top_block_gui.py b/grc/src/grc_gnuradio/wxgui/top_block_gui.py
deleted file mode 100644
index f3305d7c5..000000000
--- a/grc/src/grc_gnuradio/wxgui/top_block_gui.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# Copyright 2008 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-import wx
-import sys, os
-from gnuradio import gr
-from gnuradio.gr.pubsub import pubsub
-
-default_gui_size = (200, 100)
-
-class top_block_gui(gr.top_block, pubsub):
- """gr top block with wx gui app and grid sizer."""
-
- def __init__(self, title='', size=default_gui_size, icon=None):
- """
- Initialize the gr top block.
- Create the wx gui elements.
- @param title the main window title
- @param size the main window size tuple in pixels
- @param icon the file path to an icon or None
- """
- #initialize
- gr.top_block.__init__(self)
- pubsub.__init__(self)
- self._size = size
- #set the icon
- if icon and os.path.isfile(icon): self._icon = icon
- else: self._icon = None
- #create gui elements
- self._wx_app = wx.App()
- self._wx_frame = wx.Frame(None , -1, title)
- self._wx_grid = wx.GridBagSizer(5, 5)
- self._wx_vbox = wx.BoxSizer(wx.VERTICAL)
-
- def GetWin(self):
- """
- Get the window for wx elements to fit within.
- @return the wx frame
- """
- return self._wx_frame
-
- def Add(self, win):
- """
- Add a window to the wx vbox.
- @param win the wx window
- """
- self._wx_vbox.Add(win, 0, wx.EXPAND)
-
- def GridAdd(self, win, row, col, row_span=1, col_span=1):
- """
- Add a window to the wx grid at the given position.
- @param win the wx window
- @param row the row specification (integer >= 0)
- @param col the column specification (integer >= 0)
- @param row_span the row span specification (integer >= 1)
- @param col_span the column span specification (integer >= 1)
- """
- self._wx_grid.Add(win, wx.GBPosition(row, col), wx.GBSpan(row_span, col_span), wx.EXPAND)
-
- def Run(self):
- """
- Setup the wx gui elements.
- Start the gr top block.
- Block with the wx main loop.
- """
- #set wx app icon
- if self._icon: self._wx_frame.SetIcon(wx.Icon(self._icon, wx.BITMAP_TYPE_ANY))
- #set minimal window size
- self._wx_frame.SetSizeHints(*self._size)
- #create callback for quit
- def _quit(event):
- gr.top_block.stop(self)
- self._wx_frame.Destroy()
- #setup app
- self._wx_vbox.Add(self._wx_grid, 0, wx.EXPAND)
- self._wx_frame.Bind(wx.EVT_CLOSE, _quit)
- self._wx_frame.SetSizerAndFit(self._wx_vbox)
- self._wx_frame.Show()
- self._wx_app.SetTopWindow(self._wx_frame)
- #start flow graph
- gr.top_block.start(self)
- #blocking main loop
- self._wx_app.MainLoop()
diff --git a/grc/src/gui/ActionHandler.py b/grc/src/gui/ActionHandler.py
deleted file mode 100644
index 06e998b31..000000000
--- a/grc/src/gui/ActionHandler.py
+++ /dev/null
@@ -1,408 +0,0 @@
-"""
-Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import os
-import signal
-from Constants import IMAGE_FILE_EXTENSION
-import Actions
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
-import Preferences
-from threading import Thread
-import Messages
-from .. utils import ParseXML
-import random
-from .. platforms.gui.Platform import Platform
-from MainWindow import MainWindow
-from ParamsDialog import ParamsDialog
-import Dialogs
-from FileDialogs import OpenFlowGraphFileDialog, SaveFlowGraphFileDialog, SaveImageFileDialog
-
-gobject.threads_init()
-
-class ActionHandler:
- """
- The action handler will setup all the major window components,
- and handle button presses and flow graph operations from the GUI.
- """
-
- def __init__(self, file_paths, platform):
- """
- ActionHandler constructor.
- Create the main window, setup the message handler, import the preferences,
- and connect all of the action handlers. Finally, enter the gtk main loop and block.
- @param file_paths a list of flow graph file passed from command line
- @param platform platform module
- """
- self.clipboard = None
- platform = Platform(platform)
- for action in Actions.get_all_actions(): action.connect('activate', self._handle_actions)
- #setup the main window
- self.main_window = MainWindow(self.handle_states, platform)
- self.main_window.connect('delete_event', self._quit)
- self.main_window.connect('key-press-event', self._handle_key_press)
- self.get_page = self.main_window.get_page
- self.get_flow_graph = self.main_window.get_flow_graph
- self.get_focus_flag = self.main_window.get_focus_flag
- #setup the messages
- Messages.register_messenger(self.main_window.add_report_line)
- Messages.send_init()
- #initialize
- self.init_file_paths = file_paths
- self.handle_states(Actions.APPLICATION_INITIALIZE)
- #enter the mainloop
- gtk.main()
-
- def _handle_key_press(self, widget, event):
- """
- Handle key presses from the keyboard and translate key combinations into actions.
- This key press handler is called prior to the gtk key press handler.
- This handler bypasses built in accelerator key handling when in focus because
- * some keys are ignored by the accelerators like the direction keys,
- * some keys are not registered to any accelerators but are still used.
- When not in focus, gtk and the accelerators handle the the key press.
- @return false to let gtk handle the key action
- """
- #dont allow key presses to queue up
- if gtk.events_pending(): return True
- #extract action name from this key press
- key_name = gtk.gdk.keyval_name(event.keyval)
- mod_mask = event.state
- action_name = Actions.get_action_name_from_key_name(key_name, mod_mask)
- #handle the action if flow graph is in focus
- if action_name and self.get_focus_flag():
- self.handle_states(action_name)
- return True #handled by this method
- return False #let gtk handle the key press
-
- def _quit(self, window, event):
- """
- Handle the delete event from the main window.
- Generated by pressing X to close, alt+f4, or right click+close.
- This method in turns calls the state handler to quit.
- @return true
- """
- self.handle_states(Actions.APPLICATION_QUIT)
- return True
-
- def _handle_actions(self, event):
- """
- Handle all of the activate signals from the gtk actions.
- The action signals derive from clicking on a toolbar or menu bar button.
- Forward the action to the state handler.
- """
- self.handle_states(event.get_name())
-
- def handle_states(self, state=''):
- """
- Handle the state changes in the GUI.
- Handle all of the state changes that arise from the action handler or other gui and
- inputs in the application. The state passed to the handle_states method is a string descriping
- the change. A series of if/elif statements handle the state by greying out action buttons, causing
- changes in the flow graph, saving/opening files... The handle_states method is passed to the
- contructors of many of the classes used in this application enabling them to report any state change.
- @param state a string describing the state change
- """
- #print state
- ##################################################
- # Initalize/Quit
- ##################################################
- if state == Actions.APPLICATION_INITIALIZE:
- for action in Actions.get_all_actions(): action.set_sensitive(False) #set all actions disabled
- # enable a select few actions
- for action in (
- Actions.APPLICATION_QUIT, Actions.FLOW_GRAPH_NEW,
- Actions.FLOW_GRAPH_OPEN, Actions.FLOW_GRAPH_SAVE_AS,
- Actions.FLOW_GRAPH_CLOSE, Actions.ABOUT_WINDOW_DISPLAY,
- Actions.FLOW_GRAPH_SCREEN_CAPTURE, Actions.HELP_WINDOW_DISPLAY,
- ): Actions.get_action_from_name(action).set_sensitive(True)
- if not self.init_file_paths:
- self.init_file_paths = Preferences.files_open()
- if not self.init_file_paths: self.init_file_paths = ['']
- for file_path in self.init_file_paths:
- if file_path: self.main_window.new_page(file_path) #load pages from file paths
- if Preferences.file_open() in self.init_file_paths:
- self.main_window.new_page(Preferences.file_open(), show=True)
- if not self.get_page(): self.main_window.new_page() #ensure that at least a blank page exists
- elif state == Actions.APPLICATION_QUIT:
- if self.main_window.close_pages():
- gtk.main_quit()
- exit(0)
- ##################################################
- # Selections
- ##################################################
- elif state == Actions.ELEMENT_SELECT:
- pass #do nothing, update routines below
- elif state == Actions.NOTHING_SELECT:
- self.get_flow_graph().unselect()
- ##################################################
- # Enable/Disable
- ##################################################
- elif state == Actions.BLOCK_ENABLE:
- if self.get_flow_graph().enable_selected(True):
- self.get_flow_graph().update()
- self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
- self.get_page().set_saved(False)
- elif state == Actions.BLOCK_DISABLE:
- if self.get_flow_graph().enable_selected(False):
- self.get_flow_graph().update()
- self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
- self.get_page().set_saved(False)
- ##################################################
- # Cut/Copy/Paste
- ##################################################
- elif state == Actions.BLOCK_CUT:
- self.handle_states(Actions.BLOCK_COPY)
- self.handle_states(Actions.ELEMENT_DELETE)
- elif state == Actions.BLOCK_COPY:
- self.clipboard = self.get_flow_graph().copy_to_clipboard()
- elif state == Actions.BLOCK_PASTE:
- if self.clipboard:
- self.get_flow_graph().paste_from_clipboard(self.clipboard)
- self.get_flow_graph().update()
- self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
- self.get_page().set_saved(False)
- ##################################################
- # Move/Rotate/Delete/Create
- ##################################################
- elif state == Actions.BLOCK_MOVE:
- self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
- self.get_page().set_saved(False)
- elif state == Actions.BLOCK_ROTATE_CCW:
- if self.get_flow_graph().rotate_selected(90):
- self.get_flow_graph().update()
- self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
- self.get_page().set_saved(False)
- elif state == Actions.BLOCK_ROTATE_CW:
- if self.get_flow_graph().rotate_selected(-90):
- self.get_flow_graph().update()
- self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
- self.get_page().set_saved(False)
- elif state == Actions.ELEMENT_DELETE:
- if self.get_flow_graph().remove_selected():
- self.get_flow_graph().update()
- self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
- self.handle_states(Actions.NOTHING_SELECT)
- self.get_page().set_saved(False)
- elif state == Actions.ELEMENT_CREATE:
- self.get_flow_graph().update()
- self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
- self.handle_states(Actions.NOTHING_SELECT)
- self.get_page().set_saved(False)
- elif state == Actions.BLOCK_INC_TYPE:
- if self.get_flow_graph().type_controller_modify_selected(1):
- self.get_flow_graph().update()
- self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
- self.get_page().set_saved(False)
- elif state == Actions.BLOCK_DEC_TYPE:
- if self.get_flow_graph().type_controller_modify_selected(-1):
- self.get_flow_graph().update()
- self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
- self.get_page().set_saved(False)
- elif state == Actions.PORT_CONTROLLER_INC:
- if self.get_flow_graph().port_controller_modify_selected(1):
- self.get_flow_graph().update()
- self.get_flow_graph().update() #2 times
- self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
- self.get_page().set_saved(False)
- elif state == Actions.PORT_CONTROLLER_DEC:
- if self.get_flow_graph().port_controller_modify_selected(-1):
- self.get_flow_graph().update()
- self.get_flow_graph().update() #2 times
- self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
- self.get_page().set_saved(False)
- ##################################################
- # Window stuff
- ##################################################
- elif state == Actions.ABOUT_WINDOW_DISPLAY:
- Dialogs.AboutDialog()
- elif state == Actions.HELP_WINDOW_DISPLAY:
- Dialogs.HelpDialog()
- ##################################################
- # Param Modifications
- ##################################################
- elif state == Actions.BLOCK_PARAM_MODIFY:
- selected_block = self.get_flow_graph().get_selected_block()
- if selected_block and ParamsDialog(selected_block).run():
- self.get_flow_graph().update()
- self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
- self.get_page().set_saved(False)
- ##################################################
- # Undo/Redo
- ##################################################
- elif state == Actions.FLOW_GRAPH_UNDO:
- n = self.get_page().get_state_cache().get_prev_state()
- if n:
- self.get_flow_graph().unselect()
- self.get_flow_graph().import_data(n)
- self.get_flow_graph().update()
- self.get_page().set_saved(False)
- elif state == Actions.FLOW_GRAPH_REDO:
- n = self.get_page().get_state_cache().get_next_state()
- if n:
- self.get_flow_graph().unselect()
- self.get_flow_graph().import_data(n)
- self.get_flow_graph().update()
- self.get_page().set_saved(False)
- ##################################################
- # New/Open/Save/Close
- ##################################################
- elif state == Actions.FLOW_GRAPH_NEW:
- self.main_window.new_page()
- elif state == Actions.FLOW_GRAPH_OPEN:
- file_paths = OpenFlowGraphFileDialog(self.get_page().get_file_path()).run()
- if file_paths: #open a new page for each file, show only the first
- for i,file_path in enumerate(file_paths):
- self.main_window.new_page(file_path, show=(i==0))
- elif state == Actions.FLOW_GRAPH_CLOSE:
- self.main_window.close_page()
- elif state == Actions.FLOW_GRAPH_SAVE:
- #read-only or undefined file path, do save-as
- if self.get_page().get_read_only() or not self.get_page().get_file_path():
- self.handle_states(Actions.FLOW_GRAPH_SAVE_AS)
- #otherwise try to save
- else:
- try:
- ParseXML.to_file(self.get_flow_graph().export_data(), self.get_page().get_file_path())
- self.get_page().set_saved(True)
- except IOError:
- Messages.send_fail_save(self.get_page().get_file_path())
- self.get_page().set_saved(False)
- elif state == Actions.FLOW_GRAPH_SAVE_AS:
- file_path = SaveFlowGraphFileDialog(self.get_page().get_file_path()).run()
- if file_path is not None:
- self.get_page().set_file_path(file_path)
- self.handle_states(Actions.FLOW_GRAPH_SAVE)
- elif state == Actions.FLOW_GRAPH_SCREEN_CAPTURE:
- file_path = SaveImageFileDialog(self.get_page().get_file_path()).run()
- if file_path is not None:
- pixmap = self.get_flow_graph().get_pixmap()
- width, height = pixmap.get_size()
- pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, 0, 8, width, height)
- pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), 0, 0, 0, 0, width, height)
- pixbuf.save(file_path, IMAGE_FILE_EXTENSION[1:])
- ##################################################
- # Gen/Exec/Stop
- ##################################################
- elif state == Actions.FLOW_GRAPH_GEN:
- if not self.get_page().get_pid():
- if not self.get_page().get_saved() or not self.get_page().get_file_path():
- self.handle_states(Actions.FLOW_GRAPH_SAVE) #only save if file path missing or not saved
- if self.get_page().get_saved() and self.get_page().get_file_path():
- generator = self.get_page().get_generator()
- try:
- Messages.send_start_gen(generator.get_file_path())
- generator.write()
- except Exception,e: Messages.send_fail_gen(e)
- else: self.generator = None
- elif state == Actions.FLOW_GRAPH_EXEC:
- if not self.get_page().get_pid():
- self.handle_states(Actions.FLOW_GRAPH_GEN)
- if self.get_page().get_saved() and self.get_page().get_file_path():
- ExecFlowGraphThread(self)
- elif state == Actions.FLOW_GRAPH_KILL:
- if self.get_page().get_pid():
- try: os.kill(self.get_page().get_pid(), signal.SIGKILL)
- except: print "could not kill pid: %s"%self.get_page().get_pid()
- elif state == '': #pass and run the global actions
- pass
- else: print '!!! State "%s" not handled !!!'%state
- ##################################################
- # Global Actions for all States
- ##################################################
- #update general buttons
- Actions.get_action_from_name(Actions.ELEMENT_DELETE).set_sensitive(bool(self.get_flow_graph().get_selected_elements()))
- Actions.get_action_from_name(Actions.BLOCK_PARAM_MODIFY).set_sensitive(bool(self.get_flow_graph().get_selected_block()))
- Actions.get_action_from_name(Actions.BLOCK_ROTATE_CCW).set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
- Actions.get_action_from_name(Actions.BLOCK_ROTATE_CW).set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
- #update cut/copy/paste
- Actions.get_action_from_name(Actions.BLOCK_CUT).set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
- Actions.get_action_from_name(Actions.BLOCK_COPY).set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
- Actions.get_action_from_name(Actions.BLOCK_PASTE).set_sensitive(bool(self.clipboard))
- #update enable/disable
- Actions.get_action_from_name(Actions.BLOCK_ENABLE).set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
- Actions.get_action_from_name(Actions.BLOCK_DISABLE).set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
- #set the exec and stop buttons
- self.update_exec_stop()
- #saved status
- Actions.get_action_from_name(Actions.FLOW_GRAPH_SAVE).set_sensitive(not self.get_page().get_saved())
- self.main_window.update()
- try: #set the size of the flow graph area (if changed)
- new_size = self.get_flow_graph().get_option('window_size')
- if self.get_flow_graph().get_size() != tuple(new_size):
- self.get_flow_graph().set_size(*new_size)
- except: pass
- #draw the flow graph
- self.get_flow_graph().update_selected()
- self.get_flow_graph().queue_draw()
-
- def update_exec_stop(self):
- """
- Update the exec and stop buttons.
- Lock and unlock the mutex for race conditions with exec flow graph threads.
- """
- sensitive = self.get_flow_graph().is_valid() and not self.get_page().get_pid()
- Actions.get_action_from_name(Actions.FLOW_GRAPH_GEN).set_sensitive(sensitive)
- Actions.get_action_from_name(Actions.FLOW_GRAPH_EXEC).set_sensitive(sensitive)
- Actions.get_action_from_name(Actions.FLOW_GRAPH_KILL).set_sensitive(self.get_page().get_pid() != None)
-
-class ExecFlowGraphThread(Thread):
- """Execute the flow graph as a new process and wait on it to finish."""
-
- def __init__ (self, action_handler):
- """
- ExecFlowGraphThread constructor.
- @param action_handler an instance of an ActionHandler
- """
- Thread.__init__(self)
- self.update_exec_stop = action_handler.update_exec_stop
- self.flow_graph = action_handler.get_flow_graph()
- #store page and dont use main window calls in run
- self.page = action_handler.get_page()
- Messages.send_start_exec(self.page.get_generator().get_file_path())
- #get the popen
- try:
- self.p = self.page.get_generator().get_popen()
- self.page.set_pid(self.p.pid)
- #update
- self.update_exec_stop()
- self.start()
- except Exception, e:
- Messages.send_verbose_exec(str(e))
- Messages.send_end_exec()
-
- def run(self):
- """
- Wait on the executing process by reading from its stdout.
- Use gobject.idle_add when calling functions that modify gtk objects.
- """
- #handle completion
- r = "\n"
- while(r):
- gobject.idle_add(Messages.send_verbose_exec, r)
- r = os.read(self.p.stdout.fileno(), 1024)
- gobject.idle_add(self.done)
-
- def done(self):
- """Perform end of execution tasks."""
- Messages.send_end_exec()
- self.page.set_pid(None)
- self.update_exec_stop()
diff --git a/grc/src/gui/Actions.py b/grc/src/gui/Actions.py
deleted file mode 100644
index 9b687df7e..000000000
--- a/grc/src/gui/Actions.py
+++ /dev/null
@@ -1,167 +0,0 @@
-"""
-Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-
-######################################################################################################
-# Action Names
-######################################################################################################
-APPLICATION_INITIALIZE = 'app init'
-APPLICATION_QUIT = 'app quit'
-PARAM_MODIFY = 'param modify'
-BLOCK_MOVE = 'block move'
-BLOCK_ROTATE_CCW = 'block rotate ccw'
-BLOCK_ROTATE_CW = 'block rotate cw'
-BLOCK_PARAM_MODIFY = 'block param modify'
-BLOCK_INC_TYPE = 'block increment type'
-BLOCK_DEC_TYPE = 'block decrement type'
-BLOCK_ENABLE = 'block enable'
-BLOCK_DISABLE = 'block disable'
-BLOCK_CUT = 'block cut'
-BLOCK_COPY = 'block copy'
-BLOCK_PASTE = 'block paste'
-PORT_CONTROLLER_INC = 'port controller increment'
-PORT_CONTROLLER_DEC = 'port controller decrement'
-ELEMENT_CREATE = 'element create'
-ELEMENT_DELETE = 'element delete'
-ELEMENT_SELECT = 'element select'
-NOTHING_SELECT = 'nothing select'
-FLOW_GRAPH_OPEN = 'flow graph open'
-FLOW_GRAPH_UNDO = 'flow graph undo'
-FLOW_GRAPH_REDO = 'flow graph redo'
-FLOW_GRAPH_SAVE = 'flow graph save'
-FLOW_GRAPH_SAVE_AS = 'flow graph save as'
-FLOW_GRAPH_CLOSE = 'flow graph close'
-FLOW_GRAPH_NEW = 'flow graph new'
-FLOW_GRAPH_GEN = 'flow graph gen'
-FLOW_GRAPH_EXEC = 'flow graph exec'
-FLOW_GRAPH_KILL = 'flow graph kill'
-FLOW_GRAPH_SCREEN_CAPTURE = 'flow graph screen capture'
-ABOUT_WINDOW_DISPLAY = 'about window display'
-HELP_WINDOW_DISPLAY = 'help window display'
-
-######################################################################################################
-# Action Key Map
-######################################################################################################
-_actions_key_list = (
- #action name, key name, mod mask
- (FLOW_GRAPH_NEW, 'n', gtk.gdk.CONTROL_MASK),
- (FLOW_GRAPH_OPEN, 'o', gtk.gdk.CONTROL_MASK),
- (FLOW_GRAPH_SAVE, 's', gtk.gdk.CONTROL_MASK),
- (FLOW_GRAPH_SAVE_AS, 's', gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK),
- (FLOW_GRAPH_CLOSE, 'w', gtk.gdk.CONTROL_MASK),
- (APPLICATION_QUIT, 'q', gtk.gdk.CONTROL_MASK),
- (FLOW_GRAPH_UNDO, 'z', gtk.gdk.CONTROL_MASK),
- (FLOW_GRAPH_REDO, 'y', gtk.gdk.CONTROL_MASK),
- (ELEMENT_DELETE, 'Delete', 0),
- (BLOCK_ROTATE_CCW, 'Left', 0),
- (BLOCK_ROTATE_CW, 'Right', 0),
- (BLOCK_DEC_TYPE, 'Up', 0),
- (BLOCK_INC_TYPE, 'Down', 0),
- (BLOCK_PARAM_MODIFY, 'Return', 0),
- (BLOCK_ENABLE, 'e', 0),
- (BLOCK_DISABLE, 'd', 0),
- (BLOCK_CUT, 'x', gtk.gdk.CONTROL_MASK),
- (BLOCK_COPY, 'c', gtk.gdk.CONTROL_MASK),
- (BLOCK_PASTE, 'v', gtk.gdk.CONTROL_MASK),
- (FLOW_GRAPH_GEN, 'F5', 0),
- (FLOW_GRAPH_EXEC, 'F6', 0),
- (FLOW_GRAPH_KILL, 'F7', 0),
- (FLOW_GRAPH_SCREEN_CAPTURE, 'Print', 0),
- (HELP_WINDOW_DISPLAY, 'F1', 0),
- #the following have no associated gtk.Action
- (PORT_CONTROLLER_INC, 'equal', 0),
- (PORT_CONTROLLER_INC, 'plus', 0),
- (PORT_CONTROLLER_INC, 'KP_Add', 0),
- (PORT_CONTROLLER_DEC, 'minus', 0),
- (PORT_CONTROLLER_DEC, 'KP_Subtract', 0),
-)
-
-_actions_key_dict = dict(((key_name, mod_mask), action_name) for action_name, key_name, mod_mask in _actions_key_list)
-def get_action_name_from_key_name(key_name, mod_mask=0):
- """
- Get the action name associated with the key name and mask.
- Both keyname and mask have to match.
- @param key_name the name of the key
- @param mod_mask the key press mask (shift, ctrl) 0 for none
- @return the action name or blank string
- """
- key_name_mod_mask = (key_name, mod_mask)
- if key_name_mod_mask in _actions_key_dict: return _actions_key_dict[key_name_mod_mask]
- return ''
-
-######################################################################################################
-# Actions
-######################################################################################################
-_actions_list = (
- gtk.Action(FLOW_GRAPH_NEW, '_New', 'Create a new flow graph', gtk.STOCK_NEW),
- gtk.Action(FLOW_GRAPH_OPEN, '_Open', 'Open an existing flow graph', gtk.STOCK_OPEN),
- gtk.Action(FLOW_GRAPH_SAVE, '_Save', 'Save the current flow graph', gtk.STOCK_SAVE),
- gtk.Action(FLOW_GRAPH_SAVE_AS, 'Save _As', 'Save the current flow graph as...', gtk.STOCK_SAVE_AS),
- gtk.Action(FLOW_GRAPH_CLOSE, '_Close', 'Close the current flow graph', gtk.STOCK_CLOSE),
- gtk.Action(APPLICATION_QUIT, '_Quit', 'Quit program', gtk.STOCK_QUIT),
- gtk.Action(FLOW_GRAPH_UNDO, '_Undo', 'Undo a change to the flow graph', gtk.STOCK_UNDO),
- gtk.Action(FLOW_GRAPH_REDO, '_Redo', 'Redo a change to the flow graph', gtk.STOCK_REDO),
- gtk.Action(ELEMENT_DELETE, '_Delete', 'Delete the selected blocks', gtk.STOCK_DELETE),
- gtk.Action(BLOCK_ROTATE_CCW, 'Rotate Counterclockwise', 'Rotate the selected blocks 90 degrees to the left', gtk.STOCK_GO_BACK),
- gtk.Action(BLOCK_ROTATE_CW, 'Rotate Clockwise', 'Rotate the selected blocks 90 degrees to the right', gtk.STOCK_GO_FORWARD),
- gtk.Action(BLOCK_PARAM_MODIFY, '_Properties', 'Modify params for the selected block', gtk.STOCK_PROPERTIES),
- gtk.Action(BLOCK_ENABLE, 'E_nable', 'Enable the selected blocks', gtk.STOCK_CONNECT),
- gtk.Action(BLOCK_DISABLE, 'D_isable', 'Disable the selected blocks', gtk.STOCK_DISCONNECT),
- gtk.Action(BLOCK_CUT, 'Cu_t', 'Cut', gtk.STOCK_CUT),
- gtk.Action(BLOCK_COPY, '_Copy', 'Copy', gtk.STOCK_COPY),
- gtk.Action(BLOCK_PASTE, '_Paste', 'Paste', gtk.STOCK_PASTE),
- gtk.Action(ABOUT_WINDOW_DISPLAY, '_About', 'About this program', gtk.STOCK_ABOUT),
- gtk.Action(HELP_WINDOW_DISPLAY, '_Help', 'Usage Tips', gtk.STOCK_HELP),
- gtk.Action(FLOW_GRAPH_GEN, '_Generate', 'Generate the flow graph', gtk.STOCK_CONVERT),
- gtk.Action(FLOW_GRAPH_EXEC, '_Execute', 'Execute the flow graph', gtk.STOCK_EXECUTE),
- gtk.Action(FLOW_GRAPH_KILL, '_Kill', 'Kill the flow graph', gtk.STOCK_STOP),
- gtk.Action(FLOW_GRAPH_SCREEN_CAPTURE, 'S_creen Capture', 'Create a screen capture of the flow graph', gtk.STOCK_PRINT),
-)
-def get_all_actions(): return _actions_list
-
-_actions_dict = dict((action.get_name(), action) for action in _actions_list)
-def get_action_from_name(action_name):
- """
- Retrieve the action from the action list.
- Search the list and find an action with said name.
- @param action_name the action name(string)
- @throw KeyError bad action name
- @return a gtk action object
- """
- if action_name in _actions_dict: return _actions_dict[action_name]
- raise KeyError('Action Name: "%s" does not exist'%action_name)
-
-######################################################################################################
-# Accelerators
-######################################################################################################
-_accel_group = gtk.AccelGroup()
-def get_accel_group(): return _accel_group
-
-#set the accelerator group, and accelerator path
-#register the key name and mod mask with the accelerator path
-for action_name, key_name, mod_mask in _actions_key_list:
- try:
- accel_path = '<main>/'+action_name
- get_action_from_name(action_name).set_accel_group(get_accel_group())
- get_action_from_name(action_name).set_accel_path(accel_path)
- gtk.accel_map_add_entry(accel_path, gtk.gdk.keyval_from_name(key_name), mod_mask)
- except KeyError: pass #no action was created for this action name
diff --git a/grc/src/gui/Bars.py b/grc/src/gui/Bars.py
deleted file mode 100644
index 52e7ba1f8..000000000
--- a/grc/src/gui/Bars.py
+++ /dev/null
@@ -1,137 +0,0 @@
-"""
-Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import Actions
-import pygtk
-pygtk.require('2.0')
-import gtk
-
-##The list of actions for the toolbar.
-TOOLBAR_LIST = (
- Actions.FLOW_GRAPH_NEW,
- Actions.FLOW_GRAPH_OPEN,
- Actions.FLOW_GRAPH_SAVE,
- Actions.FLOW_GRAPH_CLOSE,
- None,
- Actions.FLOW_GRAPH_SCREEN_CAPTURE,
- None,
- Actions.BLOCK_CUT,
- Actions.BLOCK_COPY,
- Actions.BLOCK_PASTE,
- Actions.ELEMENT_DELETE,
- None,
- Actions.FLOW_GRAPH_UNDO,
- Actions.FLOW_GRAPH_REDO,
- None,
- Actions.FLOW_GRAPH_GEN,
- Actions.FLOW_GRAPH_EXEC,
- Actions.FLOW_GRAPH_KILL,
- None,
- Actions.BLOCK_ROTATE_CCW,
- Actions.BLOCK_ROTATE_CW,
- None,
- Actions.BLOCK_ENABLE,
- Actions.BLOCK_DISABLE,
-)
-
-##The list of actions and categories for the menu bar.
-MENU_BAR_LIST = (
- (gtk.Action('File', '_File', None, None), [
- Actions.FLOW_GRAPH_NEW,
- Actions.FLOW_GRAPH_OPEN,
- None,
- Actions.FLOW_GRAPH_SAVE,
- Actions.FLOW_GRAPH_SAVE_AS,
- None,
- Actions.FLOW_GRAPH_SCREEN_CAPTURE,
- None,
- Actions.FLOW_GRAPH_CLOSE,
- Actions.APPLICATION_QUIT,
- ]),
- (gtk.Action('Edit', '_Edit', None, None), [
- Actions.FLOW_GRAPH_UNDO,
- Actions.FLOW_GRAPH_REDO,
- None,
- Actions.BLOCK_CUT,
- Actions.BLOCK_COPY,
- Actions.BLOCK_PASTE,
- Actions.ELEMENT_DELETE,
- None,
- Actions.BLOCK_ROTATE_CCW,
- Actions.BLOCK_ROTATE_CW,
- None,
- Actions.BLOCK_ENABLE,
- Actions.BLOCK_DISABLE,
- None,
- Actions.BLOCK_PARAM_MODIFY,
- ]),
- (gtk.Action('Build', '_Build', None, None), [
- Actions.FLOW_GRAPH_GEN,
- Actions.FLOW_GRAPH_EXEC,
- Actions.FLOW_GRAPH_KILL,
- ]),
- (gtk.Action('Help', '_Help', None, None), [
- Actions.HELP_WINDOW_DISPLAY,
- None,
- Actions.ABOUT_WINDOW_DISPLAY,
- ]),
-)
-
-class Toolbar(gtk.Toolbar):
- """The gtk toolbar with actions added from the toolbar list."""
-
- def __init__(self):
- """
- Parse the list of action names in the toolbar list.
- Look up the action for each name in the action list and add it to the toolbar.
- """
- gtk.Toolbar.__init__(self)
- self.set_style(gtk.TOOLBAR_ICONS)
- for action_name in TOOLBAR_LIST:
- if action_name: #add a tool item
- action = Actions.get_action_from_name(action_name)
- self.add(action.create_tool_item())
- #this reset of the tooltip property is required (after creating the tool item) for the tooltip to show
- action.set_property('tooltip', action.get_property('tooltip'))
- else: self.add(gtk.SeparatorToolItem())
-
-class MenuBar(gtk.MenuBar):
- """The gtk menu bar with actions added from the menu bar list."""
-
- def __init__(self):
- """
- Parse the list of submenus from the menubar list.
- For each submenu, get a list of action names.
- Look up the action for each name in the action list and add it to the submenu.
- Add the submenu to the menu bar.
- """
- gtk.MenuBar.__init__(self)
- for main_action,action_names in MENU_BAR_LIST:
- #create the main menu item
- main_menu_item = main_action.create_menu_item()
- self.append(main_menu_item)
- #create the menu
- main_menu = gtk.Menu()
- main_menu_item.set_submenu(main_menu)
- for action_name in action_names:
- if action_name: #append a menu item
- action = Actions.get_action_from_name(action_name)
- main_menu.append(action.create_menu_item())
- else: main_menu.append(gtk.SeparatorMenuItem())
- main_menu.show_all() #this show all is required for the separators to show
diff --git a/grc/src/gui/BlockTreeWindow.py b/grc/src/gui/BlockTreeWindow.py
deleted file mode 100644
index 99056252c..000000000
--- a/grc/src/gui/BlockTreeWindow.py
+++ /dev/null
@@ -1,168 +0,0 @@
-"""
-Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from Constants import DEFAULT_BLOCKS_WINDOW_WIDTH, DND_TARGETS
-from .. platforms.gui import Utils
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
-
-NAME_INDEX = 0
-KEY_INDEX = 1
-DOC_INDEX = 2
-
-class BlockTreeWindow(gtk.VBox):
- """The block selection panel."""
-
- def __init__(self, platform, get_flow_graph):
- """
- BlockTreeWindow constructor.
- Create a tree view of the possible blocks in the platform.
- The tree view nodes will be category names, the leaves will be block names.
- A mouse double click or button press action will trigger the add block event.
- @param platform the particular platform will all block prototypes
- @param get_flow_graph get the selected flow graph
- """
- gtk.VBox.__init__(self)
- self.platform = platform
- self.get_flow_graph = get_flow_graph
- #make the tree model for holding blocks
- self.treestore = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
- self.treeview = gtk.TreeView(self.treestore)
- self.treeview.set_enable_search(False) #disable pop up search box
- self.treeview.add_events(gtk.gdk.BUTTON_PRESS_MASK)
- self.treeview.connect('button_press_event', self._handle_mouse_button_press)
- selection = self.treeview.get_selection()
- selection.set_mode('single')
- selection.connect('changed', self._handle_selection_change)
- renderer = gtk.CellRendererText()
- column = gtk.TreeViewColumn('Blocks', renderer, text=NAME_INDEX)
- self.treeview.append_column(column)
- #try to enable the tooltips (available in pygtk 2.12 and above)
- try: self.treeview.set_tooltip_column(DOC_INDEX)
- except: pass
- #setup drag and drop
- self.treeview.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, DND_TARGETS, gtk.gdk.ACTION_COPY)
- self.treeview.connect('drag-data-get', self._handle_drag_get_data)
- #make the scrolled window to hold the tree view
- scrolled_window = gtk.ScrolledWindow()
- scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- scrolled_window.add_with_viewport(self.treeview)
- scrolled_window.set_size_request(DEFAULT_BLOCKS_WINDOW_WIDTH, -1)
- self.pack_start(scrolled_window)
- #add button
- self.add_button = gtk.Button(None, gtk.STOCK_ADD)
- self.add_button.connect('clicked', self._handle_add_button)
- self.pack_start(self.add_button, False)
- #map categories to iters, automatic mapping for root
- self._categories = {tuple(): None}
- #add blocks and categories
- self.platform.load_block_tree(self)
- #initialize
- self._update_add_button()
-
- ############################################################
- ## Block Tree Methods
- ############################################################
- def add_block(self, category, block=None):
- """
- Add a block with category to this selection window.
- Add only the category when block is None.
- @param category the category list or path string
- @param block the block object or None
- """
- if isinstance(category, str): category = category.split('/')
- category = tuple(filter(lambda x: x, category)) #tuple is hashable
- #add category and all sub categories
- for i, cat_name in enumerate(category):
- sub_category = category[:i+1]
- if sub_category not in self._categories:
- iter = self.treestore.insert_before(self._categories[sub_category[:-1]], None)
- self.treestore.set_value(iter, NAME_INDEX, '[ %s ]'%cat_name)
- self.treestore.set_value(iter, KEY_INDEX, '')
- self.treestore.set_value(iter, DOC_INDEX, Utils.xml_encode('Category: %s'%cat_name))
- self._categories[sub_category] = iter
- #add block
- if block is None: return
- iter = self.treestore.insert_before(self._categories[category], None)
- self.treestore.set_value(iter, NAME_INDEX, block.get_name())
- self.treestore.set_value(iter, KEY_INDEX, block.get_key())
- self.treestore.set_value(iter, DOC_INDEX, Utils.xml_encode(block.get_doc() or 'undocumented'))
-
- ############################################################
- ## Helper Methods
- ############################################################
- def _get_selected_block_key(self):
- """
- Get the currently selected block key.
- @return the key of the selected block or a empty string
- """
- selection = self.treeview.get_selection()
- treestore, iter = selection.get_selected()
- return iter and treestore.get_value(iter, KEY_INDEX) or ''
-
- def _update_add_button(self):
- """
- Update the add button's sensitivity.
- The button should be active only if a block is selected.
- """
- key = self._get_selected_block_key()
- self.add_button.set_sensitive(bool(key))
-
- def _add_selected_block(self):
- """
- Add the selected block with the given key to the flow graph.
- """
- key = self._get_selected_block_key()
- if key: self.get_flow_graph().add_new_block(key)
-
- ############################################################
- ## Event Handlers
- ############################################################
- def _handle_drag_get_data(self, widget, drag_context, selection_data, info, time):
- """
- Handle a drag and drop by setting the key to the selection object.
- This will call the destination handler for drag and drop.
- Only call set when the key is valid to ignore DND from categories.
- """
- key = self._get_selected_block_key()
- if key: selection_data.set(selection_data.target, 8, key)
-
- def _handle_mouse_button_press(self, widget, event):
- """
- Handle the mouse button press.
- If a left double click is detected, call add selected block.
- """
- if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS:
- self._add_selected_block()
-
- def _handle_selection_change(self, selection):
- """
- Handle a selection change in the tree view.
- If a selection changes, set the add button sensitive.
- """
- self._update_add_button()
-
- def _handle_add_button(self, widget):
- """
- Handle the add button clicked signal.
- Call add selected block.
- """
- self._add_selected_block()
diff --git a/grc/src/gui/Constants.py b/grc/src/gui/Constants.py
deleted file mode 100644
index f23ab8b13..000000000
--- a/grc/src/gui/Constants.py
+++ /dev/null
@@ -1,48 +0,0 @@
-"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-import os
-
-##default path for the open/save dialogs
-DEFAULT_FILE_PATH = os.getcwd()
-
-##file extensions
-IMAGE_FILE_EXTENSION = '.png'
-
-##name for new/unsaved flow graphs
-NEW_FLOGRAPH_TITLE = 'untitled'
-
-##main window constraints
-MIN_WINDOW_WIDTH = 600
-MIN_WINDOW_HEIGHT = 400
-##dialog constraints
-MIN_DIALOG_WIDTH = 500
-MIN_DIALOG_HEIGHT = 500
-##default sizes
-DEFAULT_BLOCKS_WINDOW_WIDTH = 100
-DEFAULT_REPORTS_WINDOW_WIDTH = 100
-
-##The size of the state saving cache in the flow graph (for undo/redo functionality)
-STATE_CACHE_SIZE = 42
-
-##Shared targets for drag and drop of blocks
-DND_TARGETS = [('STRING', gtk.TARGET_SAME_APP, 0)]
diff --git a/grc/src/gui/Dialogs.py b/grc/src/gui/Dialogs.py
deleted file mode 100644
index d526b97b4..000000000
--- a/grc/src/gui/Dialogs.py
+++ /dev/null
@@ -1,100 +0,0 @@
-"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-from .. platforms.base.Constants import PACKAGE, VERSION
-import Preferences
-
-class TextDisplay(gtk.TextView):
- """A non editable gtk text view."""
-
- def __init__(self, text=''):
- """
- TextDisplay constructor.
- @param text the text to display (string)
- """
- text_buffer = gtk.TextBuffer()
- text_buffer.set_text(text)
- self.set_text = text_buffer.set_text
- self.insert = lambda line: text_buffer.insert(text_buffer.get_end_iter(), line)
- gtk.TextView.__init__(self, text_buffer)
- self.set_editable(False)
- self.set_cursor_visible(False)
- self.set_wrap_mode(gtk.WRAP_WORD_CHAR)
-
-def MessageDialogHelper(type, buttons, title=None, markup=None):
- """
- Create a modal message dialog and run it.
- @param type the type of message: gtk.MESSAGE_INFO, gtk.MESSAGE_WARNING, gtk.MESSAGE_QUESTION or gtk.MESSAGE_ERROR
- @param buttons the predefined set of buttons to use:
- gtk.BUTTONS_NONE, gtk.BUTTONS_OK, gtk.BUTTONS_CLOSE, gtk.BUTTONS_CANCEL, gtk.BUTTONS_YES_NO, gtk.BUTTONS_OK_CANCEL
- @param tittle the title of the window (string)
- @param markup the message text with pango markup
- @return the gtk response from run()
- """
- message_dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, type, buttons)
- if title != None: message_dialog.set_title(title)
- if markup != None: message_dialog.set_markup(markup)
- response = message_dialog.run()
- message_dialog.destroy()
- return response
-
-class AboutDialog(gtk.AboutDialog):
- """A cute little about dialog."""
-
- def __init__(self):
- """AboutDialog constructor."""
- gtk.AboutDialog.__init__(self)
- self.set_name(PACKAGE)
- self.set_version(VERSION)
- self.set_license(__doc__)
- self.set_copyright(__doc__.strip().splitlines()[0])
- self.set_website('http://gnuradio.org/trac/wiki/GNURadioCompanion')
- self.set_comments("""\
-Thank you to all those from the mailing list who tested GNU Radio Companion and offered advice.
------
-Special Thanks:
-A. Brinton Cooper -> starting the project
-Patrick Mulligan -> starting the project
-CER Technology Fellowship Grant -> initial funding
-William R. Kenan Jr. Fund -> usrp & computers
-Patrick Strasser -> the GRC icon
-Achilleas Anastasopoulos -> trellis support
------""")
- self.run()
- self.destroy()
-
-def HelpDialog():
- MessageDialogHelper(
- type=gtk.MESSAGE_INFO,
- buttons=gtk.BUTTONS_CLOSE,
- title='Help',
- markup="""\
-<b>Usage Tips</b>
-
-<u>Add block</u>: drag and drop or double click a block in the block selection window.
-<u>Rotate block</u>: Select a block, press left/right on the keyboard.
-<u>Change type</u>: Select a block, press up/down on the keyboard.
-<u>Edit parameters</u>: double click on a block in the flow graph.
-<u>Make connection</u>: click on the source port of one block, then click on the sink port of another block.
-<u>Remove connection</u>: select the connection and press delete, or drag the connection.
-
-* See the menu for other keyboard shortcuts.""")
diff --git a/grc/src/gui/DrawingArea.py b/grc/src/gui/DrawingArea.py
deleted file mode 100644
index 6f90049c5..000000000
--- a/grc/src/gui/DrawingArea.py
+++ /dev/null
@@ -1,126 +0,0 @@
-"""
-Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-from Constants import MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT, DND_TARGETS
-
-class DrawingArea(gtk.DrawingArea):
- """
- DrawingArea is the gtk pixel map that graphical elements may draw themselves on.
- The drawing area also responds to mouse and key events.
- """
-
- def __init__(self, flow_graph):
- """
- DrawingArea contructor.
- Connect event handlers.
- @param main_window the main_window containing all flow graphs
- """
- self.ctrl_mask = False
- self._flow_graph = flow_graph
- gtk.DrawingArea.__init__(self)
- self.set_size_request(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT)
- self.connect('realize', self._handle_window_realize)
- self.connect('configure-event', self._handle_window_configure)
- self.connect('expose-event', self._handle_window_expose)
- self.connect('motion-notify-event', self._handle_mouse_motion)
- self.connect('button-press-event', self._handle_mouse_button_press)
- self.connect('button-release-event', self._handle_mouse_button_release)
- self.add_events(
- gtk.gdk.BUTTON_PRESS_MASK | \
- gtk.gdk.POINTER_MOTION_MASK | \
- gtk.gdk.BUTTON_RELEASE_MASK | \
- gtk.gdk.LEAVE_NOTIFY_MASK | \
- gtk.gdk.ENTER_NOTIFY_MASK
- )
- #setup drag and drop
- self.drag_dest_set(gtk.DEST_DEFAULT_ALL, DND_TARGETS, gtk.gdk.ACTION_COPY)
- self.connect('drag-data-received', self._handle_drag_data_received)
- #setup the focus flag
- self._focus_flag = False
- self.get_focus_flag = lambda: self._focus_flag
- def _handle_focus_event(widget, event, focus_flag): self._focus_flag = focus_flag
- self.connect('leave-notify-event', _handle_focus_event, False)
- self.connect('enter-notify-event', _handle_focus_event, True)
-
- def new_pixmap(self, width, height): return gtk.gdk.Pixmap(self.window, width, height, -1)
-
- ##########################################################################
- ## Handlers
- ##########################################################################
- def _handle_drag_data_received(self, widget, drag_context, x, y, selection_data, info, time):
- """
- Handle a drag and drop by adding a block at the given coordinate.
- """
- self._flow_graph.add_new_block(selection_data.data, (x, y))
-
- def _handle_mouse_button_press(self, widget, event):
- """
- Forward button click information to the flow graph.
- """
- self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
- self._flow_graph.handle_mouse_button_press(
- left_click=(event.button == 1),
- double_click=(event.type == gtk.gdk._2BUTTON_PRESS),
- coordinate=(event.x, event.y),
- )
-
- def _handle_mouse_button_release(self, widget, event):
- """
- Forward button release information to the flow graph.
- """
- self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
- self._flow_graph.handle_mouse_button_release(
- left_click=(event.button == 1),
- coordinate=(event.x, event.y),
- )
-
- def _handle_mouse_motion(self, widget, event):
- """
- Forward mouse motion information to the flow graph.
- """
- self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
- self._flow_graph.handle_mouse_motion(
- coordinate=(event.x, event.y),
- )
-
- def _handle_window_realize(self, widget):
- """
- Called when the window is realized.
- Update the flowgraph, which calls new pixmap.
- """
- self._flow_graph.update()
-
- def _handle_window_configure(self, widget, event):
- """
- Called when the window is resized.
- Create a new pixmap for background buffer.
- """
- self._pixmap = self.new_pixmap(*self.get_size_request())
-
- def _handle_window_expose(self, widget, event):
- """
- Called when window is exposed, or queue_draw is called.
- Double buffering: draw to pixmap, then draw pixmap to window.
- """
- gc = self.window.new_gc()
- self._flow_graph.draw(gc, self._pixmap)
- self.window.draw_drawable(gc, self._pixmap, 0, 0, 0, 0, -1, -1)
diff --git a/grc/src/gui/FileDialogs.py b/grc/src/gui/FileDialogs.py
deleted file mode 100644
index 7c10d9844..000000000
--- a/grc/src/gui/FileDialogs.py
+++ /dev/null
@@ -1,160 +0,0 @@
-"""
-Copyright 2007 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-from Dialogs import MessageDialogHelper
-from Constants import \
- DEFAULT_FILE_PATH, IMAGE_FILE_EXTENSION, \
- NEW_FLOGRAPH_TITLE
-import Preferences
-from os import path
-
-OPEN_FLOW_GRAPH = 'open flow graph'
-SAVE_FLOW_GRAPH = 'save flow graph'
-SAVE_IMAGE = 'save image'
-
-##the filter for flow graph files
-def get_flow_graph_files_filter():
- filter = gtk.FileFilter()
- filter.set_name('Flow Graph Files')
- filter.add_pattern('*'+Preferences.file_extension())
- filter.add_pattern('*.xml') #TEMP
- return filter
-
-##the filter for image files
-def get_image_files_filter():
- filter = gtk.FileFilter()
- filter.set_name('Image Files')
- filter.add_pattern('*'+IMAGE_FILE_EXTENSION)
- return filter
-
-##the filter for all files
-def get_all_files_filter():
- filter = gtk.FileFilter()
- filter.set_name('All Files')
- filter.add_pattern('*')
- return filter
-
-class FileDialogHelper(gtk.FileChooserDialog):
- """
- A wrapper class for the gtk file chooser dialog.
- Implement a file chooser dialog with only necessary parameters.
- """
-
- def __init__(self, action, title):
- """
- FileDialogHelper contructor.
- Create a save or open dialog with cancel and ok buttons.
- Use standard settings: no multiple selection, local files only, and the * filter.
- @param action gtk.FILE_CHOOSER_ACTION_OPEN or gtk.FILE_CHOOSER_ACTION_SAVE
- @param title the title of the dialog (string)
- """
- ok_stock = {gtk.FILE_CHOOSER_ACTION_OPEN : 'gtk-open', gtk.FILE_CHOOSER_ACTION_SAVE : 'gtk-save'}[action]
- gtk.FileChooserDialog.__init__(self, title, None, action, ('gtk-cancel', gtk.RESPONSE_CANCEL, ok_stock, gtk.RESPONSE_OK))
- self.set_select_multiple(False)
- self.set_local_only(True)
- self.add_filter(get_all_files_filter())
-
-class FileDialog(FileDialogHelper):
- """A dialog box to save or open flow graph files. This is a base class, do not use."""
-
- def __init__(self, current_file_path=''):
- """
- FileDialog constructor.
- @param current_file_path the current directory or path to the open flow graph
- """
- if not current_file_path: current_file_path = path.join(DEFAULT_FILE_PATH, NEW_FLOGRAPH_TITLE + Preferences.file_extension())
- if self.type == OPEN_FLOW_GRAPH:
- FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_OPEN, 'Open a Flow Graph from a File...')
- self.add_and_set_filter(get_flow_graph_files_filter())
- self.set_select_multiple(True)
- elif self.type == SAVE_FLOW_GRAPH:
- FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_SAVE, 'Save a Flow Graph to a File...')
- self.add_and_set_filter(get_flow_graph_files_filter())
- self.set_current_name(path.basename(current_file_path)) #show the current filename
- elif self.type == SAVE_IMAGE:
- FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_SAVE, 'Save a Flow Graph Screen Shot...')
- self.add_and_set_filter(get_image_files_filter())
- current_file_path = current_file_path + IMAGE_FILE_EXTENSION
- self.set_current_name(path.basename(current_file_path)) #show the current filename
- self.set_current_folder(path.dirname(current_file_path)) #current directory
-
- def add_and_set_filter(self, filter):
- """
- Add the gtk file filter to the list of filters and set it as the default file filter.
- @param filter a gtk file filter.
- """
- self.add_filter(filter)
- self.set_filter(filter)
-
- def get_rectified_filename(self):
- """
- Run the dialog and get the filename.
- If this is a save dialog and the file name is missing the extension, append the file extension.
- If the file name with the extension already exists, show a overwrite dialog.
- If this is an open dialog, return a list of filenames.
- @return the complete file path
- """
- if gtk.FileChooserDialog.run(self) != gtk.RESPONSE_OK: return None #response was cancel
- #############################################
- # Handle Save Dialogs
- #############################################
- if self.type in (SAVE_FLOW_GRAPH, SAVE_IMAGE):
- filename = self.get_filename()
- extension = {
- SAVE_FLOW_GRAPH: Preferences.file_extension(),
- SAVE_IMAGE: IMAGE_FILE_EXTENSION,
- }[self.type]
- #append the missing file extension if the filter matches
- if path.splitext(filename)[1].lower() != extension: filename += extension
- self.set_current_name(path.basename(filename)) #show the filename with extension
- if path.exists(filename): #ask the user to confirm overwrite
- if MessageDialogHelper(
- gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, 'Confirm Overwrite!',
- 'File <b>"%s"</b> Exists!\nWould you like to overwrite the existing file?'%filename,
- ) == gtk.RESPONSE_NO: return self.get_rectified_filename()
- return filename
- #############################################
- # Handle Open Dialogs
- #############################################
- elif self.type in (OPEN_FLOW_GRAPH,):
- filenames = self.get_filenames()
- for filename in filenames:
- if not path.exists(filename): #show a warning and re-run
- MessageDialogHelper(
- gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, 'Cannot Open!',
- 'File <b>"%s"</b> Does not Exist!'%filename,
- )
- return self.get_rectified_filename()
- return filenames
-
- def run(self):
- """
- Get the filename and destroy the dialog.
- @return the filename or None if a close/cancel occured.
- """
- filename = self.get_rectified_filename()
- self.destroy()
- return filename
-
-class OpenFlowGraphFileDialog(FileDialog): type = OPEN_FLOW_GRAPH
-class SaveFlowGraphFileDialog(FileDialog): type = SAVE_FLOW_GRAPH
-class SaveImageFileDialog(FileDialog): type = SAVE_IMAGE
diff --git a/grc/src/gui/MainWindow.py b/grc/src/gui/MainWindow.py
deleted file mode 100644
index bd5f73a80..000000000
--- a/grc/src/gui/MainWindow.py
+++ /dev/null
@@ -1,299 +0,0 @@
-"""
-Copyright 2008 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from Constants import \
- NEW_FLOGRAPH_TITLE, DEFAULT_REPORTS_WINDOW_WIDTH
-from Actions import \
- APPLICATION_QUIT, FLOW_GRAPH_KILL, \
- FLOW_GRAPH_SAVE, get_accel_group
-import pygtk
-pygtk.require('2.0')
-import gtk
-import Bars
-from BlockTreeWindow import BlockTreeWindow
-from Dialogs import TextDisplay, MessageDialogHelper
-from NotebookPage import NotebookPage
-import Preferences
-import Messages
-import os
-
-############################################################
-# Main window
-############################################################
-
-class MainWindow(gtk.Window):
- """The topmost window with menus, the tool bar, and other major windows."""
-
- def __init__(self, handle_states, platform):
- """
- MainWindow contructor.
- @param handle_states the callback function
- """
- self._platform = platform
- #setup window
- self.handle_states = handle_states
- gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
- vbox = gtk.VBox()
- self.hpaned = gtk.HPaned()
- self.add(vbox)
- #create the menu bar and toolbar
- self.add_accel_group(get_accel_group())
- vbox.pack_start(Bars.MenuBar(), False)
- vbox.pack_start(Bars.Toolbar(), False)
- vbox.pack_start(self.hpaned)
- #create the notebook
- self.notebook = gtk.Notebook()
- self.page_to_be_closed = None
- self.current_page = None
- self.notebook.set_show_border(False)
- self.notebook.set_scrollable(True) #scroll arrows for page tabs
- self.notebook.connect('switch-page', self._handle_page_change)
- #setup containers
- self.flow_graph_vpaned = gtk.VPaned()
- #flow_graph_box.pack_start(self.scrolled_window)
- self.flow_graph_vpaned.pack1(self.notebook)
- self.hpaned.pack1(self.flow_graph_vpaned)
- self.hpaned.pack2(BlockTreeWindow(platform, self.get_flow_graph), False) #dont allow resize
- #create the reports window
- self.text_display = TextDisplay()
- #house the reports in a scrolled window
- self.reports_scrolled_window = gtk.ScrolledWindow()
- self.reports_scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- self.reports_scrolled_window.add_with_viewport(self.text_display)
- self.reports_scrolled_window.set_size_request(-1, DEFAULT_REPORTS_WINDOW_WIDTH)
- self.flow_graph_vpaned.pack2(self.reports_scrolled_window, False) #dont allow resize
- #load preferences and show the main window
- Preferences.load(platform)
- self.resize(*Preferences.main_window_size())
- self.flow_graph_vpaned.set_position(Preferences.reports_window_position())
- self.hpaned.set_position(Preferences.blocks_window_position())
- self.show_all()
-
- ############################################################
- # Event Handlers
- ############################################################
-
- def _quit(self, window, event):
- """
- Handle the delete event from the main window.
- Generated by pressing X to close, alt+f4, or right click+close.
- This method in turns calls the state handler to quit.
- @return true
- """
- self.handle_states(APPLICATION_QUIT)
- return True
-
- def _handle_page_change(self, notebook, page, page_num):
- """
- Handle a page change. When the user clicks on a new tab,
- reload the flow graph to update the vars window and
- call handle states (select nothing) to update the buttons.
- @param notebook the notebook
- @param page new page
- @param page_num new page number
- """
- self.current_page = self.notebook.get_nth_page(page_num)
- Messages.send_page_switch(self.current_page.get_file_path())
- self.handle_states()
-
- ############################################################
- # Report Window
- ############################################################
-
- def add_report_line(self, line):
- """
- Place line at the end of the text buffer, then scroll its window all the way down.
- @param line the new text
- """
- self.text_display.insert(line)
- vadj = self.reports_scrolled_window.get_vadjustment()
- vadj.set_value(vadj.upper)
- vadj.emit('changed')
-
- ############################################################
- # Pages: create and close
- ############################################################
-
- def new_page(self, file_path='', show=False):
- """
- Create a new notebook page.
- Set the tab to be selected.
- @param file_path optional file to load into the flow graph
- @param show true if the page should be shown after loading
- """
- #if the file is already open, show the open page and return
- if file_path and file_path in self._get_files(): #already open
- page = self.notebook.get_nth_page(self._get_files().index(file_path))
- self._set_page(page)
- return
- try: #try to load from file
- if file_path: Messages.send_start_load(file_path)
- flow_graph = self._platform.get_new_flow_graph()
- page = NotebookPage(
- self,
- flow_graph=flow_graph,
- file_path=file_path,
- )
- if file_path: Messages.send_end_load()
- except Exception, e: #return on failure
- Messages.send_fail_load(e)
- return
- #add this page to the notebook
- self.notebook.append_page(page, page.get_tab())
- try: self.notebook.set_tab_reorderable(page, True)
- except: pass #gtk too old
- self.notebook.set_tab_label_packing(page, False, False, gtk.PACK_START)
- #only show if blank or manual
- if not file_path or show: self._set_page(page)
-
- def close_pages(self):
- """
- Close all the pages in this notebook.
- @return true if all closed
- """
- open_files = filter(lambda file: file, self._get_files()) #filter blank files
- open_file = self.get_page().get_file_path()
- #close each page
- for page in self._get_pages():
- self.page_to_be_closed = page
- self.close_page(False)
- if self.notebook.get_n_pages(): return False
- #save state before closing
- Preferences.files_open(open_files)
- Preferences.file_open(open_file)
- Preferences.main_window_size(self.get_size())
- Preferences.reports_window_position(self.flow_graph_vpaned.get_position())
- Preferences.blocks_window_position(self.hpaned.get_position())
- Preferences.save()
- return True
-
- def close_page(self, ensure=True):
- """
- Close the current page.
- If the notebook becomes empty, and ensure is true,
- call new page upon exit to ensure that at least one page exists.
- @param ensure boolean
- """
- if not self.page_to_be_closed: self.page_to_be_closed = self.get_page()
- #show the page if it has an executing flow graph or is unsaved
- if self.page_to_be_closed.get_pid() or not self.page_to_be_closed.get_saved():
- self._set_page(self.page_to_be_closed)
- #unsaved? ask the user
- if not self.page_to_be_closed.get_saved() and self._save_changes():
- self.handle_states(FLOW_GRAPH_SAVE) #try to save
- if not self.page_to_be_closed.get_saved(): #still unsaved?
- self.page_to_be_closed = None #set the page to be closed back to None
- return
- #stop the flow graph if executing
- if self.page_to_be_closed.get_pid(): self.handle_states(FLOW_GRAPH_KILL)
- #remove the page
- self.notebook.remove_page(self.notebook.page_num(self.page_to_be_closed))
- if ensure and self.notebook.get_n_pages() == 0: self.new_page() #no pages, make a new one
- self.page_to_be_closed = None #set the page to be closed back to None
-
- ############################################################
- # Misc
- ############################################################
-
- def update(self):
- """
- Set the title of the main window.
- Set the titles on the page tabs.
- Show/hide the reports window.
- @param title the window title
- """
- title = ''.join((
- self._platform.get_name(),
- ' - Editing: ',
- (self.get_page().get_file_path() or NEW_FLOGRAPH_TITLE),
- (self.get_page().get_saved() and ' ' or '*'), #blank must be non empty
- (self.get_page().get_read_only() and ' (read-only)' or ''),
- )
- )
- gtk.Window.set_title(self, title)
- #set tab titles
- for page in self._get_pages():
- #get filename and strip out file extension
- title = os.path.splitext(os.path.basename(page.get_file_path()))[0]
- page.set_text(''.join((
- (title or NEW_FLOGRAPH_TITLE),
- (page.get_saved() and ' ' or '*'), #blank must be non empty
- (page.get_read_only() and ' (ro)' or ''),
- )
- )
- )
- #show/hide notebook tabs
- self.notebook.set_show_tabs(len(self._get_pages()) > 1)
-
- def get_page(self):
- """
- Get the selected page.
- @return the selected page
- """
- return self.current_page
-
- def get_flow_graph(self):
- """
- Get the selected flow graph.
- @return the selected flow graph
- """
- return self.get_page().get_flow_graph()
-
- def get_focus_flag(self):
- """
- Get the focus flag from the current page.
- @return the focus flag
- """
- return self.get_page().get_drawing_area().get_focus_flag()
-
- ############################################################
- # Helpers
- ############################################################
-
- def _set_page(self, page):
- """
- Set the current page.
- @param page the page widget
- """
- self.current_page = page
- self.notebook.set_current_page(self.notebook.page_num(self.current_page))
-
- def _save_changes(self):
- """
- Save changes to flow graph?
- @return true if yes
- """
- return MessageDialogHelper(
- gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, 'Unsaved Changes!',
- 'Would you like to save changes before closing?'
- ) == gtk.RESPONSE_YES
-
- def _get_files(self):
- """
- Get the file names for all the pages, in order.
- @return list of file paths
- """
- return map(lambda page: page.get_file_path(), self._get_pages())
-
- def _get_pages(self):
- """
- Get a list of all pages in the notebook.
- @return list of pages
- """
- return [self.notebook.get_nth_page(page_num) for page_num in range(self.notebook.get_n_pages())]
diff --git a/grc/src/gui/Makefile.am b/grc/src/gui/Makefile.am
deleted file mode 100644
index a6639af44..000000000
--- a/grc/src/gui/Makefile.am
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-# Copyright 2008 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-include $(top_srcdir)/grc/Makefile.inc
-
-ourpythondir = $(grc_src_prefix)/gui
-
-ourpython_PYTHON = \
- ActionHandler.py \
- Actions.py \
- Bars.py \
- BlockTreeWindow.py \
- Constants.py \
- Dialogs.py \
- DrawingArea.py \
- FileDialogs.py \
- MainWindow.py \
- Messages.py \
- NotebookPage.py \
- ParamsDialog.py \
- Preferences.py \
- StateCache.py \
- __init__.py
diff --git a/grc/src/gui/Messages.py b/grc/src/gui/Messages.py
deleted file mode 100644
index e8939402d..000000000
--- a/grc/src/gui/Messages.py
+++ /dev/null
@@ -1,105 +0,0 @@
-"""
-Copyright 2007 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from .. platforms.base.Constants import PACKAGE, VERSION
-import traceback
-import sys
-
-## A list of functions that can receive a message.
-MESSENGERS_LIST = list()
-
-def register_messenger(messenger):
- """
- Append the given messenger to the list of messengers.
- @param messenger a method thats takes a string
- """
- MESSENGERS_LIST.append(messenger)
-
-def send(message):
- """
- Give the message to each of the messengers.
- @param message a message string
- """
- for messenger in MESSENGERS_LIST: messenger(message)
-
-#register stdout by default
-register_messenger(sys.stdout.write)
-
-###########################################################################
-# Special functions for specific program functionalities
-###########################################################################
-def send_init():
- send("""<<< Welcome to %s %s >>>\n"""%(PACKAGE, VERSION))
-
-def send_page_switch(file_path):
- send('\nShowing: "%s"\n'%file_path)
-
-################# functions for loading flow graphs ########################################
-def send_start_load(file_path):
- send('\nLoading: "%s"'%file_path + '\n')
-
-def send_error_load(error):
- send('>>> Error: %s\n'%error)
- traceback.print_exc()
-
-def send_end_load():
- send('>>> Done\n')
-
-def send_fail_load(error):
- send('Error: %s\n'%error)
- send('>>> Failue\n')
- traceback.print_exc()
-
-################# functions for generating flow graphs ########################################
-def send_start_gen(file_path):
- send('\nGenerating: "%s"'%file_path + '\n')
-
-def send_fail_gen(error):
- send('Generate Error: %s\n'%error)
- send('>>> Failue\n')
- traceback.print_exc()
-
-################# functions for executing flow graphs ########################################
-def send_start_exec(file_path):
- send('\nExecuting: "%s"'%file_path + '\n')
-
-def send_verbose_exec(verbose):
- send(verbose)
-
-def send_end_exec():
- send('\n>>> Done\n')
-
-################# functions for saving flow graphs ########################################
-def send_fail_save(file_path):
- send('>>> Error: Cannot save: %s\n'%file_path)
-
-################# functions for connections ########################################
-def send_fail_connection():
- send('>>> Error: Cannot create connection.\n')
-
-################# functions for preferences ########################################
-def send_fail_load_preferences(prefs_file_path):
- send('>>> Error: Cannot load preferences file: "%s"\n'%prefs_file_path)
-
-def send_fail_save_preferences(prefs_file_path):
- send('>>> Error: Cannot save preferences file: "%s"\n'%prefs_file_path)
-
-################# functions for warning ########################################
-def send_warning(warning):
- send('>>> Warning: %s\n'%warning)
diff --git a/grc/src/gui/NotebookPage.py b/grc/src/gui/NotebookPage.py
deleted file mode 100644
index a3ec5b4e2..000000000
--- a/grc/src/gui/NotebookPage.py
+++ /dev/null
@@ -1,197 +0,0 @@
-"""
-Copyright 2008 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from Actions import FLOW_GRAPH_CLOSE
-import pygtk
-pygtk.require('2.0')
-import gtk
-from .. utils import ParseXML
-from StateCache import StateCache
-from .. platforms.base.Constants import FLOW_GRAPH_DTD
-from Constants import MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT
-from DrawingArea import DrawingArea
-import os
-
-############################################################
-## Notebook Page
-############################################################
-
-class NotebookPage(gtk.HBox):
- """A page in the notebook."""
-
- def __init__(self, main_window, flow_graph, file_path=''):
- """
- Page constructor.
- @param main_window main window
- @param file_path path to a flow graph file
- """
- self._flow_graph = flow_graph
- self.set_pid(None)
- #import the file
- self.main_window = main_window
- self.set_file_path(file_path)
- file_path = file_path or flow_graph.get_parent().get_default_flow_graph()
- open(file_path, 'r') #test open
- ############################################################
- from .. utils import converter
- converter.convert(file_path, flow_graph.get_parent())
- ############################################################
- ParseXML.validate_dtd(file_path, FLOW_GRAPH_DTD)
- initial_state = ParseXML.from_file(file_path)
- self.state_cache = StateCache(initial_state)
- self.set_saved(True)
- #import the data to the flow graph
- self.get_flow_graph().import_data(initial_state)
- #initialize page gui
- gtk.HBox.__init__(self, False, 0)
- self.show()
- #tab box to hold label and close button
- self.tab = gtk.HBox(False, 0)
- #setup tab label
- self.label = gtk.Label()
- self.tab.pack_start(self.label, False)
- #setup button image
- image = gtk.Image()
- image.set_from_stock('gtk-close', gtk.ICON_SIZE_MENU)
- #setup image box
- image_box = gtk.HBox(False, 0)
- image_box.pack_start(image, True, False, 0)
- #setup the button
- button = gtk.Button()
- button.connect("clicked", self._handle_button)
- button.set_relief(gtk.RELIEF_NONE)
- button.add(image_box)
- #button size
- w, h = gtk.icon_size_lookup_for_settings(button.get_settings(), gtk.ICON_SIZE_MENU)
- button.set_size_request(w+6, h+6)
- self.tab.pack_start(button, False)
- self.tab.show_all()
- #setup scroll window and drawing area
- self.scrolled_window = gtk.ScrolledWindow()
- self.scrolled_window.set_size_request(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT)
- self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- self.drawing_area = DrawingArea(self.get_flow_graph())
- self.scrolled_window.add_with_viewport(self.get_drawing_area())
- self.pack_start(self.scrolled_window)
- #inject drawing area and handle states into flow graph
- self.get_flow_graph().drawing_area = self.get_drawing_area()
- self.get_flow_graph().handle_states = main_window.handle_states
- self.show_all()
-
- def get_drawing_area(self): return self.drawing_area
-
- def get_generator(self):
- """
- Get the generator object for this flow graph.
- @return generator
- """
- return self.get_flow_graph().get_parent().get_generator()(
- self.get_flow_graph(),
- self.get_file_path(),
- )
-
- def _handle_button(self, button):
- """
- The button was clicked.
- Make the current page selected, then close.
- @param the button
- """
- self.main_window.page_to_be_closed = self
- self.main_window.handle_states(FLOW_GRAPH_CLOSE)
-
- def set_text(self, text):
- """
- Set the text in this label.
- @param text the new text
- """
- self.label.set_text(text)
-
- def get_tab(self):
- """
- Get the gtk widget for this page's tab.
- @return gtk widget
- """
- return self.tab
-
- def get_pid(self):
- """
- Get the pid for the flow graph.
- @return the pid number
- """
- return self.pid
-
- def set_pid(self, pid):
- """
- Set the pid number.
- @param pid the new pid number
- """
- self.pid = pid
-
- def get_flow_graph(self):
- """
- Get the flow graph.
- @return the flow graph
- """
- return self._flow_graph
-
- def get_read_only(self):
- """
- Get the read-only state of the file.
- Always false for empty path.
- @return true for read-only
- """
- if not self.get_file_path(): return False
- return os.path.exists(self.get_file_path()) and \
- not os.access(self.get_file_path(), os.W_OK)
-
- def get_file_path(self):
- """
- Get the file path for the flow graph.
- @return the file path or ''
- """
- return self.file_path
-
- def set_file_path(self, file_path=''):
- """
- Set the file path, '' for no file path.
- @param file_path file path string
- """
- if file_path: self.file_path = os.path.abspath(file_path)
- else: self.file_path = ''
-
- def get_saved(self):
- """
- Get the saved status for the flow graph.
- @return true if saved
- """
- return self.saved
-
- def set_saved(self, saved=True):
- """
- Set the saved status.
- @param saved boolean status
- """
- self.saved = saved
-
- def get_state_cache(self):
- """
- Get the state cache for the flow graph.
- @return the state cache
- """
- return self.state_cache
diff --git a/grc/src/gui/ParamsDialog.py b/grc/src/gui/ParamsDialog.py
deleted file mode 100644
index 6cc42e8fc..000000000
--- a/grc/src/gui/ParamsDialog.py
+++ /dev/null
@@ -1,144 +0,0 @@
-"""
-Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-
-from Dialogs import TextDisplay
-from Constants import MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT
-
-def get_title_label(title):
- """
- Get a title label for the params window.
- The title will be bold, underlined, and left justified.
- @param title the text of the title
- @return a gtk object
- """
- label = gtk.Label()
- label.set_markup('\n<b><span underline="low">%s</span>:</b>\n'%title)
- hbox = gtk.HBox()
- hbox.pack_start(label, False, False, padding=11)
- return hbox
-
-class ParamsDialog(gtk.Dialog):
- """A dialog box to set block parameters."""
-
- def __init__(self, block):
- """
- SignalBlockParamsDialog contructor.
- @param block the signal block
- """
- gtk.Dialog.__init__(self,
- title='Properties: %s'%block.get_name(),
- buttons=(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE),
- )
- self.block = block
- self.set_size_request(MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT)
- vbox = gtk.VBox()
- #Add the title label
- vbox.pack_start(get_title_label('Parameters'), False)
- #Create the scrolled window to hold all the parameters
- scrolled_window = gtk.ScrolledWindow()
- scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- scrolled_window.add_with_viewport(vbox)
- self.vbox.pack_start(scrolled_window, True)
- #Error Messages for the block
- self._error_box = gtk.VBox()
- self._error_messages_text_display = TextDisplay()
- self._error_box.pack_start(gtk.Label(), False, False, 7) #spacing
- self._error_box.pack_start(get_title_label('Error Messages'), False)
- self._error_box.pack_start(self._error_messages_text_display, False)
- #Docs for the block
- self._docs_box = err_box = gtk.VBox()
- self._docs_text_display = TextDisplay()
- self._docs_box.pack_start(gtk.Label(), False, False, 7) #spacing
- self._docs_box.pack_start(get_title_label('Documentation'), False)
- self._docs_box.pack_start(self._docs_text_display, False)
- #Add all the parameters
- for param in self.block.get_params():
- vbox.pack_start(param.get_input_object(self._handle_changed), False)
- #Add the error and docs box
- vbox.pack_start(self._error_box, False)
- vbox.pack_start(self._docs_box, False)
- #connect and show
- self.connect('key_press_event', self._handle_key_press)
- self.show_all()
- #initial update
- for param in self.block.get_params(): param.update()
- self._update()
-
- def _update(self):
- """
- Update the error messages box.
- Hide the box if there are no errors.
- Update the documentation block.
- Hide the box if there are no docs.
- """
- #update the errors box
- if self.block.is_valid(): self._error_box.hide()
- else: self._error_box.show()
- messages = '\n\n'.join(self.block.get_error_messages())
- self._error_messages_text_display.set_text(messages)
- #update the docs box
- if self.block.get_doc(): self._docs_box.show()
- else: self._docs_box.hide()
- self._docs_text_display.set_text(self.block.get_doc())
-
- def _handle_key_press(self, widget, event):
- """
- Handle key presses from the keyboard.
- Call the ok response when enter is pressed.
- @return false to forward the keypress
- """
- keyname = gtk.gdk.keyval_name(event.keyval)
- if keyname == 'Return': self.response(gtk.RESPONSE_OK)
- return False #forward the keypress
-
- def _handle_changed(self, param):
- """
- A change occured, update any dependent parameters:
- The enum inside the variable type may have changed and,
- the variable param will need an external update.
- @param param the graphical parameter that initiated the callback
- """
- #update dependent params
- if param.is_enum():
- for other_param in param.get_parent().get_params():
- if param.get_key() is not other_param.get_key() and (
- param.get_key() in other_param._type or \
- param.get_key() in other_param._hide): other_param.update()
- #update
- self._update()
- return True
-
- def run(self):
- """
- Call run().
- @return true if a change occured.
- """
- original_data = list()
- for param in self.block.get_params():
- original_data.append(param.get_value())
- gtk.Dialog.run(self)
- self.destroy()
- new_data = list()
- for param in self.block.get_params():
- new_data.append(param.get_value())
- return original_data != new_data
diff --git a/grc/src/gui/Preferences.py b/grc/src/gui/Preferences.py
deleted file mode 100644
index 1d89920dd..000000000
--- a/grc/src/gui/Preferences.py
+++ /dev/null
@@ -1,86 +0,0 @@
-"""
-Copyright 2008 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import ConfigParser
-import os
-
-_platform = None
-_config_parser = ConfigParser.ConfigParser()
-
-def file_extension(): return '.'+_platform.get_key()
-def _prefs_file(): return os.path.join(os.path.expanduser('~'), file_extension())
-
-def load(platform):
- global _platform
- _platform = platform
- #create sections
- _config_parser.add_section('main')
- _config_parser.add_section('files_open')
- try: _config_parser.read(_prefs_file())
- except: pass
-def save():
- try: _config_parser.write(open(_prefs_file(), 'w'))
- except: pass
-
-###########################################################################
-# Special methods for specific program functionalities
-###########################################################################
-
-def main_window_size(size=None):
- if size is not None:
- _config_parser.set('main', 'main_window_width', size[0])
- _config_parser.set('main', 'main_window_height', size[1])
- else:
- try: return (
- _config_parser.getint('main', 'main_window_width'),
- _config_parser.getint('main', 'main_window_height'),
- )
- except: return (1, 1)
-
-def file_open(file=None):
- if file is not None: _config_parser.set('main', 'file_open', file)
- else:
- try: return _config_parser.get('main', 'file_open')
- except: return ''
-
-def files_open(files=None):
- if files is not None:
- _config_parser.remove_section('files_open') #clear section
- _config_parser.add_section('files_open')
- for i, file in enumerate(files):
- _config_parser.set('files_open', 'file_open_%d'%i, file)
- else:
- files = list()
- i = 0
- while True:
- try: files.append(_config_parser.get('files_open', 'file_open_%d'%i))
- except: return files
- i = i + 1
-
-def reports_window_position(pos=None):
- if pos is not None: _config_parser.set('main', 'reports_window_position', pos)
- else:
- try: return _config_parser.getint('main', 'reports_window_position') or 1 #greater than 0
- except: return -1
-
-def blocks_window_position(pos=None):
- if pos is not None: _config_parser.set('main', 'blocks_window_position', pos)
- else:
- try: return _config_parser.getint('main', 'blocks_window_position') or 1 #greater than 0
- except: return -1
diff --git a/grc/src/gui/StateCache.py b/grc/src/gui/StateCache.py
deleted file mode 100644
index 04b18b18a..000000000
--- a/grc/src/gui/StateCache.py
+++ /dev/null
@@ -1,92 +0,0 @@
-"""
-Copyright 2007 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from Actions import FLOW_GRAPH_UNDO, FLOW_GRAPH_REDO, get_action_from_name
-from Constants import STATE_CACHE_SIZE
-
-class StateCache(object):
- """
- The state cache is an interface to a list to record data/states and to revert to previous states.
- States are recorded into the list in a circular fassion by using an index for the current state,
- and counters for the range where states are stored.
- """
-
- def __init__(self, initial_state):
- """
- StateCache constructor.
- @param initial_state the intial state (nested data)
- """
- self.states = [None] * STATE_CACHE_SIZE #fill states
- self.current_state_index = 0
- self.num_prev_states = 0
- self.num_next_states = 0
- self.states[0] = initial_state
- self.update_actions()
-
- def save_new_state(self, state):
- """
- Save a new state.
- Place the new state at the next index and add one to the number of previous states.
- @param state the new state
- """
- self.current_state_index = (self.current_state_index + 1)%STATE_CACHE_SIZE
- self.states[self.current_state_index] = state
- self.num_prev_states = self.num_prev_states + 1
- if self.num_prev_states == STATE_CACHE_SIZE: self.num_prev_states = STATE_CACHE_SIZE - 1
- self.num_next_states = 0
- self.update_actions()
-
- def get_current_state(self):
- """
- Get the state at the current index.
- @return the current state (nested data)
- """
- self.update_actions()
- return self.states[self.current_state_index]
-
- def get_prev_state(self):
- """
- Get the previous state and decrement the current index.
- @return the previous state or None
- """
- if self.num_prev_states > 0:
- self.current_state_index = (self.current_state_index + STATE_CACHE_SIZE -1)%STATE_CACHE_SIZE
- self.num_next_states = self.num_next_states + 1
- self.num_prev_states = self.num_prev_states - 1
- return self.get_current_state()
- return None
-
- def get_next_state(self):
- """
- Get the nest state and increment the current index.
- @return the next state or None
- """
- if self.num_next_states > 0:
- self.current_state_index = (self.current_state_index + 1)%STATE_CACHE_SIZE
- self.num_next_states = self.num_next_states - 1
- self.num_prev_states = self.num_prev_states + 1
- return self.get_current_state()
- return None
-
- def update_actions(self):
- """
- Update the undo and redo actions based on the number of next and prev states.
- """
- get_action_from_name(FLOW_GRAPH_REDO).set_sensitive(self.num_next_states != 0)
- get_action_from_name(FLOW_GRAPH_UNDO).set_sensitive(self.num_prev_states != 0)
diff --git a/grc/src/gui/__init__.py b/grc/src/gui/__init__.py
deleted file mode 100644
index 8b1378917..000000000
--- a/grc/src/gui/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/grc/src/platforms/Makefile.am b/grc/src/platforms/Makefile.am
deleted file mode 100644
index 1d3c385c2..000000000
--- a/grc/src/platforms/Makefile.am
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Copyright 2008 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-include $(top_srcdir)/grc/Makefile.inc
-
-SUBDIRS = \
- base \
- gui \
- python
-
-ourpythondir = $(grc_src_prefix)/platforms
-
-ourpython_PYTHON = __init__.py
diff --git a/grc/src/platforms/__init__.py b/grc/src/platforms/__init__.py
deleted file mode 100644
index 8b1378917..000000000
--- a/grc/src/platforms/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/grc/src/platforms/base/Block.py b/grc/src/platforms/base/Block.py
deleted file mode 100644
index 25688472c..000000000
--- a/grc/src/platforms/base/Block.py
+++ /dev/null
@@ -1,259 +0,0 @@
-"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from ... utils import odict
-from Element import Element
-from Param import Param
-from Port import Port
-
-from Cheetah.Template import Template
-from UserDict import UserDict
-
-class TemplateArg(UserDict):
- """
- A cheetah template argument created from a param.
- The str of this class evaluates to the param's to code method.
- The use of this class as a dictionary (enum only) will reveal the enum opts.
- The __call__ or () method can return the param evaluated to a raw python data type.
- """
-
- def __init__(self, param):
- UserDict.__init__(self)
- self._param = param
- if param.is_enum():
- for key in param.get_opt_keys():
- self[key] = str(param.get_opt(key))
-
- def __str__(self):
- return str(self._param.to_code())
-
- def __call__(self):
- return self._param.evaluate()
-
-class Block(Element):
-
- def __init__(self, flow_graph, n):
- """
- Make a new block from nested data.
- @param flow graph the parent element
- @param n the nested odict
- @return block a new block
- """
- #build the block
- Element.__init__(self, flow_graph)
- #grab the data
- params = n.findall('param')
- sources = n.findall('source')
- sinks = n.findall('sink')
- self._name = n.find('name')
- self._key = n.find('key')
- self._category = n.find('category') or ''
- self._block_wrapper_path = n.find('block_wrapper_path')
- #create the param objects
- self._params = odict()
- #add the id param
- self._params['id'] = self.get_parent().get_parent().Param(
- self,
- odict({
- 'name': 'ID',
- 'key': 'id',
- 'type': 'id',
- })
- )
- self._params['_enabled'] = self.get_parent().get_parent().Param(
- self,
- odict({
- 'name': 'Enabled',
- 'key': '_enabled',
- 'type': 'raw',
- 'value': 'True',
- 'hide': 'all',
- })
- )
- for param in map(lambda n: self.get_parent().get_parent().Param(self, n), params):
- key = param.get_key()
- #test against repeated keys
- try: assert(key not in self.get_param_keys())
- except AssertionError: self._exit_with_error('Key "%s" already exists in params'%key)
- #store the param
- self._params[key] = param
- #create the source objects
- self._sources = odict()
- for source in map(lambda n: self.get_parent().get_parent().Source(self, n), sources):
- key = source.get_key()
- #test against repeated keys
- try: assert(key not in self.get_source_keys())
- except AssertionError: self._exit_with_error('Key "%s" already exists in sources'%key)
- #store the port
- self._sources[key] = source
- #create the sink objects
- self._sinks = odict()
- for sink in map(lambda n: self.get_parent().get_parent().Sink(self, n), sinks):
- key = sink.get_key()
- #test against repeated keys
- try: assert(key not in self.get_sink_keys())
- except AssertionError: self._exit_with_error('Key "%s" already exists in sinks'%key)
- #store the port
- self._sinks[key] = sink
- #begin the testing
- self.test()
-
- def test(self):
- """
- Call test on all children.
- """
- map(lambda c: c.test(), self.get_params() + self.get_sinks() + self.get_sources())
-
- def get_enabled(self):
- """
- Get the enabled state of the block.
- @return true for enabled
- """
- try: return eval(self.get_param('_enabled').get_value())
- except: return True
-
- def set_enabled(self, enabled):
- """
- Set the enabled state of the block.
- @param enabled true for enabled
- """
- self.get_param('_enabled').set_value(str(enabled))
-
- def validate(self):
- """
- Validate the block.
- All ports and params must be valid.
- All checks must evaluate to true.
- """
- for c in self.get_params() + self.get_ports() + self.get_connections():
- try: assert(c.is_valid())
- except AssertionError:
- for msg in c.get_error_messages():
- self._add_error_message('>>> %s:\n\t%s'%(c, msg))
-
- def __str__(self): return 'Block - %s - %s(%s)'%(self.get_id(), self.get_name(), self.get_key())
-
- def get_id(self): return self.get_param('id').get_value()
- def is_block(self): return True
- def get_name(self): return self._name
- def get_key(self): return self._key
- def get_category(self): return self._category
- def get_doc(self): return ''
- def get_ports(self): return self.get_sources() + self.get_sinks()
- def get_block_wrapper_path(self): return self._block_wrapper_path
-
- ##############################################
- # Access Params
- ##############################################
- def get_param_keys(self): return self._params.keys()
- def get_param(self, key): return self._params[key]
- def get_params(self): return self._params.values()
-
- ##############################################
- # Access Sinks
- ##############################################
- def get_sink_keys(self): return self._sinks.keys()
- def get_sink(self, key): return self._sinks[key]
- def get_sinks(self): return self._sinks.values()
-
- ##############################################
- # Access Sources
- ##############################################
- def get_source_keys(self): return self._sources.keys()
- def get_source(self, key): return self._sources[key]
- def get_sources(self): return self._sources.values()
-
- def get_connections(self):
- return sum([port.get_connections() for port in self.get_ports()], [])
-
- def resolve_dependencies(self, tmpl):
- """
- Resolve a paramater dependency with cheetah templates.
- @param tmpl the string with dependencies
- @return the resolved value
- """
- tmpl = str(tmpl)
- if '$' not in tmpl: return tmpl
- n = dict((p.get_key(), TemplateArg(p)) for p in self.get_params())
- try: return str(Template(tmpl, n))
- except Exception, e: return "-------->\n%s: %s\n<--------"%(e, tmpl)
-
- ##############################################
- # Controller Modify
- ##############################################
- def type_controller_modify(self, direction):
- """
- Change the type controller.
- @param direction +1 or -1
- @return true for change
- """
- changed = False
- type_param = None
- for param in filter(lambda p: p.is_enum(), self.get_params()):
- children = self.get_ports() + self.get_params()
- #priority to the type controller
- if param.get_key() in ' '.join(map(lambda p: p._type, children)): type_param = param
- #use param if type param is unset
- if not type_param: type_param = param
- if type_param:
- #try to increment the enum by direction
- try:
- keys = type_param.get_option_keys()
- old_index = keys.index(type_param.get_value())
- new_index = (old_index + direction + len(keys))%len(keys)
- type_param.set_value(keys[new_index])
- changed = True
- except: pass
- return changed
-
- def port_controller_modify(self, direction):
- """
- Change the port controller.
- @param direction +1 or -1
- @return true for change
- """
- return False
-
- ##############################################
- ## Import/Export Methods
- ##############################################
- def export_data(self):
- """
- Export this block's params to nested data.
- @return a nested data odict
- """
- n = odict()
- n['key'] = self.get_key()
- n['param'] = map(lambda p: p.export_data(), self.get_params())
- return n
-
- def import_data(self, n):
- """
- Import this block's params from nested data.
- Any param keys that do not exist will be ignored.
- @param n the nested data odict
- """
- params_n = n.findall('param')
- for param_n in params_n:
- key = param_n.find('key')
- value = param_n.find('value')
- #the key must exist in this block's params
- if key in self.get_param_keys():
- self.get_param(key).set_value(value)
- self.validate()
diff --git a/grc/src/platforms/base/Connection.py b/grc/src/platforms/base/Connection.py
deleted file mode 100644
index b8b75ac13..000000000
--- a/grc/src/platforms/base/Connection.py
+++ /dev/null
@@ -1,94 +0,0 @@
-"""
-Copyright 2008 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from Element import Element
-from ... utils import odict
-
-class Connection(Element):
-
- def __init__(self, flow_graph, porta, portb):
- """
- Make a new connection given the parent and 2 ports.
- @param flow_graph the parent of this element
- @param porta a port (any direction)
- @param portb a port (any direction)
- @throws Error cannot make connection
- @return a new connection
- """
- Element.__init__(self, flow_graph)
- source = sink = None
- #separate the source and sink
- for port in (porta, portb):
- if port.is_source(): source = port
- if port.is_sink(): sink = port
- assert(source and sink)
- #ensure that this connection (source -> sink) is unique
- for connection in self.get_parent().get_connections():
- assert not (connection.get_source() is source and connection.get_sink() is sink)
- self._source = source
- self._sink = sink
-
- def __str__(self):
- return 'Connection (\n\t%s\n\t\t%s\n\t%s\n\t\t%s\n)'%(
- self.get_source().get_parent(),
- self.get_source(),
- self.get_sink().get_parent(),
- self.get_sink(),
- )
-
- def is_connection(self): return True
-
- def validate(self):
- """
- Validate the connections.
- The ports must match in type.
- """
- source_type = self.get_source().get_type()
- sink_type = self.get_sink().get_type()
- try: assert source_type == sink_type
- except AssertionError: self._add_error_message('Source type "%s" does not match sink type "%s".'%(source_type, sink_type))
-
- def get_enabled(self):
- """
- Get the enabled state of this connection.
- @return true if source and sink blocks are enabled
- """
- return self.get_source().get_parent().get_enabled() and \
- self.get_sink().get_parent().get_enabled()
-
- #############################
- # Access Ports
- #############################
- def get_sink(self): return self._sink
- def get_source(self): return self._source
-
- ##############################################
- ## Import/Export Methods
- ##############################################
- def export_data(self):
- """
- Export this connection's info.
- @return a nested data odict
- """
- n = odict()
- n['source_block_id'] = self.get_source().get_parent().get_id()
- n['sink_block_id'] = self.get_sink().get_parent().get_id()
- n['source_key'] = self.get_source().get_key()
- n['sink_key'] = self.get_sink().get_key()
- return n
diff --git a/grc/src/platforms/base/Constants.py.in b/grc/src/platforms/base/Constants.py.in
deleted file mode 100644
index da958a6f4..000000000
--- a/grc/src/platforms/base/Constants.py.in
+++ /dev/null
@@ -1,30 +0,0 @@
-"""
-Copyright 2008 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import os
-
-#package and version constants
-PACKAGE = '@PACKAGE@'
-VERSION = '@VERSION@'
-
-#setup paths
-PKG_DIR = os.environ.get('GR_DATADIR', '@pkgdatadir@')
-DATA_DIR = os.path.join(PKG_DIR, '@reldatadir@')
-FLOW_GRAPH_DTD = os.path.join(DATA_DIR, 'flow_graph.dtd')
-BLOCK_TREE_DTD = os.path.join(DATA_DIR, 'block_tree.dtd')
diff --git a/grc/src/platforms/base/Element.py b/grc/src/platforms/base/Element.py
deleted file mode 100644
index a16be9127..000000000
--- a/grc/src/platforms/base/Element.py
+++ /dev/null
@@ -1,96 +0,0 @@
-"""
-Copyright 2008 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-class Element(object):
-
- def __init__(self, parent=None):
- self._parent = parent
- self._error_messages = []
- self.flag()
-
- def test(self):
- """
- Test the element against failures.
- Overload this method in sub-classes.
- """
- pass
-
- def validate(self):
- """
- Validate the data in this element.
- Set the error message non blank for errors.
- Overload this method in sub-classes.
- """
- pass
-
- def is_valid(self):
- self._error_messages = []#reset err msgs
- if self.get_enabled():
- try: self.validate()
- except: pass
- return not self.get_error_messages()
-
- def get_enabled(self): return True
-
- def _add_error_message(self, msg):
- self._error_messages.append(msg)
-
- def get_error_messages(self):
- return self._error_messages
-
- def get_parent(self):
- return self._parent
-
- def _exit_with_error(self, error):
- parent = self
- #build hier list of elements
- elements = list()
- while(parent):
- elements.insert(0, parent)
- parent = parent.get_parent()
- #build error string
- err_str = ">>> Error:"
- for i, element in enumerate(elements + [error]):
- err_str = err_str + '\n' + ''.join(' '*(i+2)) + str(element)
- err_str = err_str + '\n'
- exit(err_str)
-
- ##############################################
- ## Update flagging
- ##############################################
- def is_flagged(self): return self._flag
- def flag(self):
- self._flag = True
- if self.get_parent(): self.get_parent().flag()
- def deflag(self):
- self._flag = False
- if self.get_parent(): self.get_parent().deflag()
-
- ##############################################
- ## Type testing methods
- ##############################################
- def is_element(self): return True
- def is_platform(self): return False
- def is_flow_graph(self): return False
- def is_connection(self): return False
- def is_block(self): return False
- def is_source(self): return False
- def is_sink(self): return False
- def is_port(self): return False
- def is_param(self): return False
diff --git a/grc/src/platforms/base/FlowGraph.py b/grc/src/platforms/base/FlowGraph.py
deleted file mode 100644
index 6aeef2fa7..000000000
--- a/grc/src/platforms/base/FlowGraph.py
+++ /dev/null
@@ -1,224 +0,0 @@
-"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from ... utils import odict
-from Element import Element
-from Block import Block
-from Connection import Connection
-from ... gui import Messages
-
-class FlowGraph(Element):
-
- def __init__(self, platform):
- """
- Make a flow graph from the arguments.
- @param platform a platforms with blocks and contrcutors
- @return the flow graph object
- """
- #initialize
- Element.__init__(self, platform)
- #inital blank import
- self.import_data()
-
- def _get_unique_id(self, base_id=''):
- """
- Get a unique id starting with the base id.
- @param base_id the id starts with this and appends a count
- @return a unique id
- """
- index = 0
- while True:
- id = '%s_%d'%(base_id, index)
- index = index + 1
- #make sure that the id is not used by another block
- if not filter(lambda b: b.get_id() == id, self.get_blocks()): return id
-
- def __str__(self): return 'FlowGraph - %s(%s)'%(self.get_option('title'), self.get_option('id'))
-
- def get_option(self, key):
- """
- Get the option for a given key.
- The option comes from the special options block.
- @param key the param key for the options block
- @return the value held by that param
- """
- return self._options_block.get_param(key).evaluate()
-
- def is_flow_graph(self): return True
-
- ##############################################
- ## Access Elements
- ##############################################
- def get_block(self, id): return filter(lambda b: b.get_id() == id, self.get_blocks())[0]
- def get_blocks(self): return filter(lambda e: e.is_block(), self.get_elements())
- def get_connections(self): return filter(lambda e: e.is_connection(), self.get_elements())
- def get_elements(self):
- """
- Get a list of all the elements.
- Always ensure that the options block is in the list (only once).
- @return the element list
- """
- options_block_count = self._elements.count(self._options_block)
- if not options_block_count:
- self._elements.append(self._options_block)
- for i in range(options_block_count-1):
- self._elements.remove(self._options_block)
- return self._elements
-
- def get_enabled_blocks(self):
- """
- Get a list of all blocks that are enabled.
- @return a list of blocks
- """
- return filter(lambda b: b.get_enabled(), self.get_blocks())
-
- def get_enabled_connections(self):
- """
- Get a list of all connections that are enabled.
- @return a list of connections
- """
- return filter(lambda c: c.get_enabled(), self.get_connections())
-
- def get_new_block(self, key):
- """
- Get a new block of the specified key.
- Add the block to the list of elements.
- @param key the block key
- @return the new block or None if not found
- """
- self.flag()
- if key not in self.get_parent().get_block_keys(): return None
- block = self.get_parent().get_new_block(self, key)
- self.get_elements().append(block)
- return block
-
- def connect(self, porta, portb):
- """
- Create a connection between porta and portb.
- @param porta a port
- @param portb another port
- @throw Exception bad connection
- @return the new connection
- """
- self.flag()
- connection = self.get_parent().Connection(self, porta, portb)
- self.get_elements().append(connection)
- return connection
-
- def remove_element(self, element):
- """
- Remove the element from the list of elements.
- If the element is a port, remove the whole block.
- If the element is a block, remove its connections.
- If the element is a connection, just remove the connection.
- """
- self.flag()
- if element not in self.get_elements(): return
- #found a port, set to parent signal block
- if element.is_port():
- element = element.get_parent()
- #remove block, remove all involved connections
- if element.is_block():
- for port in element.get_ports():
- map(self.remove_element, port.get_connections())
- self.get_elements().remove(element)
-
- def evaluate(self, expr):
- """
- Evaluate the expression.
- @param expr the string expression
- @throw NotImplementedError
- """
- raise NotImplementedError
-
- def validate(self):
- """
- Validate the flow graph.
- All connections and blocks must be valid.
- """
- for c in self.get_elements():
- try: assert c.is_valid()
- except AssertionError: self._add_error_message('Element "%s" is not valid.'%c)
-
- ##############################################
- ## Import/Export Methods
- ##############################################
- def export_data(self):
- """
- Export this flow graph to nested data.
- Export all block and connection data.
- @return a nested data odict
- """
- import time
- n = odict()
- n['timestamp'] = time.ctime()
- n['block'] = [block.export_data() for block in self.get_blocks()]
- n['connection'] = [connection.export_data() for connection in self.get_connections()]
- return odict({'flow_graph': n})
-
- def import_data(self, n=None):
- """
- Import blocks and connections into this flow graph.
- Clear this flowgraph of all previous blocks and connections.
- Any blocks or connections in error will be ignored.
- @param n the nested data odict
- """
- #remove previous elements
- self._elements = list()
- #use blank data if none provided
- fg_n = n and n.find('flow_graph') or odict()
- blocks_n = fg_n.findall('block')
- connections_n = fg_n.findall('connection')
- #create option block
- self._options_block = self.get_parent().get_new_block(self, 'options')
- #build the blocks
- for block_n in blocks_n:
- key = block_n.find('key')
- if key == 'options': block = self._options_block
- else: block = self.get_new_block(key)
- #only load the block when the block key was valid
- if block: block.import_data(block_n)
- else: Messages.send_error_load('Block key "%s" not found in %s'%(key, self.get_parent()))
- #build the connections
- for connection_n in connections_n:
- #try to make the connection
- try:
- #get the block ids
- source_block_id = connection_n.find('source_block_id')
- sink_block_id = connection_n.find('sink_block_id')
- #get the port keys
- source_key = connection_n.find('source_key')
- sink_key = connection_n.find('sink_key')
- #verify the blocks
- block_ids = map(lambda b: b.get_id(), self.get_blocks())
- assert(source_block_id in block_ids)
- assert(sink_block_id in block_ids)
- #get the blocks
- source_block = self.get_block(source_block_id)
- sink_block = self.get_block(sink_block_id)
- #verify the ports
- assert(source_key in source_block.get_source_keys())
- assert(sink_key in sink_block.get_sink_keys())
- #get the ports
- source = source_block.get_source(source_key)
- sink = sink_block.get_sink(sink_key)
- #build the connection
- self.connect(source, sink)
- except AssertionError: Messages.send_error_load('Connection between %s(%s) and %s(%s) could not be made.'%(source_block_id, source_key, sink_block_id, sink_key))
- self.validate()
diff --git a/grc/src/platforms/base/Makefile.am b/grc/src/platforms/base/Makefile.am
deleted file mode 100644
index 805c7b2b3..000000000
--- a/grc/src/platforms/base/Makefile.am
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# Copyright 2008,2009 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-include $(top_srcdir)/grc/Makefile.inc
-
-ourpythondir = $(grc_src_prefix)/platforms/base
-
-ourpython_PYTHON = \
- Block.py \
- Connection.py \
- Constants.py \
- Element.py \
- FlowGraph.py \
- Param.py \
- Platform.py \
- Port.py \
- __init__.py
-
-Constants.py: $(srcdir)/Constants.py.in Makefile
- sed \
- -e 's|@PACKAGE[@]|$(PACKAGE)|g' \
- -e 's|@VERSION[@]|$(VERSION)|g' \
- -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' \
- -e 's|@reldatadir[@]|$(grc_base_data_reldir)|g' \
- $< > $@
-
-EXTRA_DIST = $(srcdir)/Constants.py.in
-BUILT_SOURCES = Constants.py
diff --git a/grc/src/platforms/base/Param.py b/grc/src/platforms/base/Param.py
deleted file mode 100644
index 81783c791..000000000
--- a/grc/src/platforms/base/Param.py
+++ /dev/null
@@ -1,271 +0,0 @@
-"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from ... utils import odict
-from Element import Element
-import pygtk
-pygtk.require('2.0')
-import gtk
-
-class InputParam(gtk.HBox):
- """The base class for an input parameter inside the input parameters dialog."""
-
- def __init__(self, param, _handle_changed):
- gtk.HBox.__init__(self)
- self.param = param
- self._handle_changed = _handle_changed
- self.label = gtk.Label('') #no label, markup is added by set_markup
- self.label.set_size_request(150, -1)
- self.pack_start(self.label, False)
- self.set_markup = lambda m: self.label.set_markup(m)
- self.tp = None
- def set_color(self, color): pass
-
-class EntryParam(InputParam):
- """Provide an entry box for strings and numbers."""
-
- def __init__(self, *args, **kwargs):
- InputParam.__init__(self, *args, **kwargs)
- self.entry = input = gtk.Entry()
- input.set_text(self.param.get_value())
- input.connect('changed', self._handle_changed)
- self.pack_start(input, True)
- self.get_text = input.get_text
- #tool tip
- self.tp = gtk.Tooltips()
- self.tp.set_tip(self.entry, '')
- self.tp.enable()
- def set_color(self, color): self.entry.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
-
-class EnumParam(InputParam):
- """Provide an entry box for Enum types with a drop down menu."""
-
- def __init__(self, *args, **kwargs):
- InputParam.__init__(self, *args, **kwargs)
- self._input = gtk.combo_box_new_text()
- for option in self.param.get_options(): self._input.append_text(option.get_name())
- self._input.set_active(self.param.get_option_keys().index(self.param.get_value()))
- self._input.connect('changed', self._handle_changed)
- self.pack_start(self._input, False)
- def get_text(self): return self.param.get_option_keys()[self._input.get_active()]
-
-class EnumEntryParam(InputParam):
- """Provide an entry box and drop down menu for Raw Enum types."""
-
- def __init__(self, *args, **kwargs):
- InputParam.__init__(self, *args, **kwargs)
- self._input = gtk.combo_box_entry_new_text()
- for option in self.param.get_options(): self._input.append_text(option.get_name())
- try: self._input.set_active(self.param.get_option_keys().index(self.param.get_value()))
- except:
- self._input.set_active(-1)
- self._input.get_child().set_text(self.param.get_value())
- self._input.connect('changed', self._handle_changed)
- self._input.get_child().connect('changed', self._handle_changed)
- self.pack_start(self._input, False)
- def get_text(self):
- if self._input.get_active() == -1: return self._input.get_child().get_text()
- return self.param.get_option_keys()[self._input.get_active()]
- def set_color(self, color):
- if self._input.get_active() == -1: #custom entry, use color
- self._input.get_child().modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
- else: #from enum, make white background
- self._input.get_child().modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse('#ffffff'))
-
-class Option(Element):
-
- def __init__(self, param, n):
- Element.__init__(self, param)
- self._name = n.find('name')
- self._key = n.find('key')
- self._opts = dict()
- opts = n.findall('opt')
- #test against opts when non enum
- try: assert self.get_parent().is_enum() or not opts
- except AssertionError: self._exit_with_error('Options for non-enum types cannot have sub-options')
- #extract opts
- for opt in opts:
- #separate the key:value
- try: key, value = opt.split(':')
- except: self._exit_with_error('Error separating "%s" into key:value'%opt)
- #test against repeated keys
- try: assert not self._opts.has_key(key)
- except AssertionError: self._exit_with_error('Key "%s" already exists in option'%key)
- #store the option
- self._opts[key] = value
-
- def __str__(self): return 'Option %s(%s)'%(self.get_name(), self.get_key())
- def get_name(self): return self._name
- def get_key(self): return self._key
-
- ##############################################
- # Access Opts
- ##############################################
- def get_opt_keys(self): return self._opts.keys()
- def get_opt(self, key): return self._opts[key]
- def get_opts(self): return self._opts.values()
-
-class Param(Element):
-
- ##possible param types
- TYPES = ['enum', 'raw']
-
- def __init__(self, block, n):
- """
- Make a new param from nested data.
- @param block the parent element
- @param n the nested odict
- @return a new param
- """
- #grab the data
- self._name = n.find('name')
- self._key = n.find('key')
- value = n.find('value') or ''
- self._type = n.find('type')
- self._hide = n.find('hide') or ''
- #build the param
- Element.__init__(self, block)
- #create the Option objects from the n data
- self._options = odict()
- for option in map(lambda o: Option(self, o), n.findall('option')):
- key = option.get_key()
- #test against repeated keys
- try: assert(key not in self.get_option_keys())
- except AssertionError: self._exit_with_error('Key "%s" already exists in options'%key)
- #store the option
- self._options[key] = option
- #test the enum options
- if self.is_enum():
- #test against options with identical keys
- try: assert(len(set(self.get_option_keys())) == len(self._options))
- except AssertionError: self._exit_with_error('Options keys "%s" are not unique.'%self.get_option_keys())
- #test against inconsistent keys in options
- opt_keys = self._options.values()[0].get_opt_keys()
- for option in self._options.values():
- try: assert(set(opt_keys) == set(option.get_opt_keys()))
- except AssertionError: self._exit_with_error('Opt keys "%s" are not identical across all options.'%opt_keys)
- #if a value is specified, it must be in the options keys
- self._value = value or self.get_option_keys()[0]
- try: assert(self.get_value() in self.get_option_keys())
- except AssertionError: self._exit_with_error('The value "%s" is not in the possible values of "%s".'%(self.get_value(), self.get_option_keys()))
- else: self._value = value or ''
-
- def test(self):
- """
- call test on all children
- """
- map(lambda c: c.test(), self.get_options())
-
- def validate(self):
- """
- Validate the param.
- The value must be evaluated and type must a possible type.
- """
- try:
- assert(self.get_type() in self.TYPES)
- try: self.evaluate()
- except:
- #if the evaluate failed but added no error messages, add the generic one below
- if not self.get_error_messages():
- self._add_error_message('Value "%s" cannot be evaluated.'%self.get_value())
- except AssertionError: self._add_error_message('Type "%s" is not a possible type.'%self.get_type())
-
- def evaluate(self):
- """
- Evaluate the value of this param.
- @throw NotImplementedError
- """
- raise NotImplementedError
-
- def to_code(self):
- """
- Convert the value to code.
- @throw NotImplementedError
- """
- raise NotImplementedError
-
- def get_color(self): return '#FFFFFF'
- def __str__(self): return 'Param - %s(%s)'%(self.get_name(), self.get_key())
- def is_param(self): return True
- def get_name(self): return self._name
- def get_key(self): return self._key
- def get_hide(self): return self.get_parent().resolve_dependencies(self._hide)
-
- def get_value(self):
- value = self._value
- if self.is_enum() and value not in self.get_option_keys():
- value = self.get_option_keys()[0]
- self.set_value(value)
- return value
-
- def set_value(self, value):
- self.flag()
- self._value = str(value) #must be a string
-
- def get_type(self): return self.get_parent().resolve_dependencies(self._type)
- def is_enum(self): return self._type == 'enum'
-
- def __repr__(self):
- """
- Get the repr (nice string format) for this param.
- Just return the value (special case enum).
- Derived classes can handle complex formatting.
- @return the string representation
- """
- if self.is_enum(): return self.get_option(self.get_value()).get_name()
- return self.get_value()
-
- def get_input_class(self):
- """
- Get the graphical gtk class to represent this parameter.
- An enum requires and combo parameter.
- A non-enum with options gets a combined entry/combo parameter.
- All others get a standard entry parameter.
- @return gtk input class
- """
- if self.is_enum(): return EnumParam
- if self.get_options(): return EnumEntryParam
- return EntryParam
-
- ##############################################
- # Access Options
- ##############################################
- def get_option_keys(self): return self._options.keys()
- def get_option(self, key): return self._options[key]
- def get_options(self): return self._options.values()
-
- ##############################################
- # Access Opts
- ##############################################
- def get_opt_keys(self): return self._options[self.get_value()].get_opt_keys()
- def get_opt(self, key): return self._options[self.get_value()].get_opt(key)
- def get_opts(self): return self._options[self.get_value()].get_opts()
-
- ##############################################
- ## Import/Export Methods
- ##############################################
- def export_data(self):
- """
- Export this param's key/value.
- @return a nested data odict
- """
- n = odict()
- n['key'] = self.get_key()
- n['value'] = self.get_value()
- return n
diff --git a/grc/src/platforms/base/Platform.py b/grc/src/platforms/base/Platform.py
deleted file mode 100644
index 35227d99f..000000000
--- a/grc/src/platforms/base/Platform.py
+++ /dev/null
@@ -1,143 +0,0 @@
-"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import os
-from ... utils import ParseXML
-from Element import Element as _Element
-from FlowGraph import FlowGraph as _FlowGraph
-from Connection import Connection as _Connection
-from Block import Block as _Block
-from Port import Port as _Port
-from Param import Param as _Param
-from Constants import BLOCK_TREE_DTD
-
-class Platform(_Element):
-
- def __init__(self, name, key, block_paths, block_dtd, block_tree, default_flow_graph, generator):
- """
- Make a platform from the arguments.
- @param name the platform name
- @param key the unique platform key
- @param block_paths the file paths to blocks in this platform
- @param block_dtd the dtd validator for xml block wrappers
- @param block_tree the nested tree of block keys and categories
- @param default_flow_graph the default flow graph file path
- @param load_one a single file to load into this platform or None
- @return a platform object
- """
- _Element.__init__(self)
- self._name = name
- self._key = key
- self._block_paths = block_paths
- self._block_dtd = block_dtd
- self._block_tree = block_tree
- self._default_flow_graph = default_flow_graph
- self._generator = generator
- #create a dummy flow graph for the blocks
- self._flow_graph = _Element(self)
- #load the blocks
- self._blocks = dict()
- self._blocks_n = dict()
- for block_path in self._block_paths:
- if os.path.isfile(block_path): self._load_blocks(block_path)
- elif os.path.isdir(block_path):
- for dirpath, dirnames, filenames in os.walk(block_path):
- for filename in filter(lambda f: f.endswith('.xml'), filenames):
- self._load_blocks(os.path.join(dirpath, filename))
-
- def _load_blocks(self, f):
- """
- Load the block wrappers from the file path.
- The block wrapper must pass validation.
- If any of the checks fail, exit with error.
- @param f the file path
- """
- try: ParseXML.validate_dtd(f, self._block_dtd)
- except ParseXML.XMLSyntaxError, e: self._exit_with_error('Block definition "%s" failed: \n\t%s'%(f, e))
- n = ParseXML.from_file(f).find('block')
- #inject block wrapper path
- n['block_wrapper_path'] = f
- block = self.Block(self._flow_graph, n)
- key = block.get_key()
- #test against repeated keys
- try: assert(key not in self.get_block_keys())
- except AssertionError: self._exit_with_error('Key "%s" already exists in blocks'%key)
- #store the block
- self._blocks[key] = block
- self._blocks_n[key] = n
-
- def load_block_tree(self, block_tree):
- """
- Load a block tree with categories and blocks.
- Step 1: Load all blocks from the xml specification.
- Step 2: Load blocks with builtin category specifications.
- @param block_tree the block tree object
- """
- #recursive function to load categories and blocks
- def load_category(cat_n, parent=[]):
- #add this category
- parent = parent + [cat_n.find('name')]
- block_tree.add_block(parent)
- #recursive call to load sub categories
- map(lambda c: load_category(c, parent), cat_n.findall('cat'))
- #add blocks in this category
- for block_key in cat_n.findall('block'):
- block_tree.add_block(parent, self.get_block(block_key))
- #load the block tree
- f = self._block_tree
- try: ParseXML.validate_dtd(f, BLOCK_TREE_DTD)
- except ParseXML.XMLSyntaxError, e: self._exit_with_error('Block tree "%s" failed: \n\t%s'%(f, e))
- #add all blocks in the tree
- load_category(ParseXML.from_file(f).find('cat'))
- #add all other blocks, use the catgory
- for block in self.get_blocks():
- #blocks with empty categories are in the xml block tree or hidden
- if block.get_category(): block_tree.add_block(block.get_category(), block)
-
- def __str__(self): return 'Platform - %s(%s)'%(self.get_key(), self.get_name())
-
- def is_platform(self): return True
-
- def get_new_flow_graph(self): return self.FlowGraph(self)
-
- def get_default_flow_graph(self): return self._default_flow_graph
-
- def get_generator(self): return self._generator
-
- ##############################################
- # Access Blocks
- ##############################################
- def get_block_keys(self): return self._blocks.keys()
- def get_block(self, key): return self._blocks[key]
- def get_blocks(self): return self._blocks.values()
- def get_new_block(self, flow_graph, key): return self.Block(flow_graph, n=self._blocks_n[key])
-
- def get_name(self): return self._name
-
- def get_key(self): return self._key
-
- ##############################################
- # Constructors
- ##############################################
- FlowGraph = _FlowGraph
- Connection = _Connection
- Block = _Block
- Source = _Port
- Sink = _Port
- Param = _Param
diff --git a/grc/src/platforms/base/Port.py b/grc/src/platforms/base/Port.py
deleted file mode 100644
index f46a81195..000000000
--- a/grc/src/platforms/base/Port.py
+++ /dev/null
@@ -1,80 +0,0 @@
-"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from Element import Element
-
-class Port(Element):
-
- ##possible port types
- TYPES = []
-
- def __init__(self, block, n):
- """
- Make a new port from nested data.
- @param block the parent element
- @param n the nested odict
- @return a new port
- """
- #grab the data
- name = n['name']
- key = n['key']
- type = n['type']
- #build the port
- Element.__init__(self, block)
- self._name = name
- self._key = key
- self._type = type
-
- def validate(self):
- """
- Validate the port.
- The port must be non-empty and type must a possible type.
- """
- try: assert(self.get_type() in self.TYPES)
- except AssertionError: self._add_error_message('Type "%s" is not a possible type.'%self.get_type())
-
- def __str__(self):
- if self.is_source():
- return 'Source - %s(%s)'%(self.get_name(), self.get_key())
- if self.is_sink():
- return 'Sink - %s(%s)'%(self.get_name(), self.get_key())
-
- def is_port(self): return True
- def get_color(self): return '#FFFFFF'
- def get_name(self): return self._name
- def get_key(self): return self._key
- def is_sink(self): return self in self.get_parent().get_sinks()
- def is_source(self): return self in self.get_parent().get_sources()
- def get_type(self): return self.get_parent().resolve_dependencies(self._type)
-
- def get_connections(self):
- """
- Get all connections that use this port.
- @return a list of connection objects
- """
- connections = self.get_parent().get_parent().get_connections()
- connections = filter(lambda c: c.get_source() is self or c.get_sink() is self, connections)
- return connections
-
- def get_enabled_connections(self):
- """
- Get all enabled connections that use this port.
- @return a list of connection objects
- """
- return filter(lambda c: c.get_enabled(), self.get_connections())
diff --git a/grc/src/platforms/base/__init__.py b/grc/src/platforms/base/__init__.py
deleted file mode 100644
index 8b1378917..000000000
--- a/grc/src/platforms/base/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/grc/src/platforms/gui/Block.py b/grc/src/platforms/gui/Block.py
deleted file mode 100644
index 862a59393..000000000
--- a/grc/src/platforms/gui/Block.py
+++ /dev/null
@@ -1,199 +0,0 @@
-"""
-Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from Element import Element
-import Utils
-import Colors
-from ... utils import odict
-from Constants import BORDER_PROXIMITY_SENSITIVITY
-from Constants import \
- BLOCK_LABEL_PADDING, \
- PORT_SEPARATION, LABEL_SEPARATION, \
- PORT_BORDER_SEPARATION, POSSIBLE_ROTATIONS
-import pygtk
-pygtk.require('2.0')
-import gtk
-
-BLOCK_MARKUP_TMPL="""\
-#set $foreground = $block.is_valid() and 'black' or 'red'
-<span foreground="$foreground" font_desc="Sans 8"><b>$encode($block.get_name())</b></span>"""
-
-class Block(Element):
- """The graphical signal block."""
-
- def __init__(self, *args, **kwargs):
- """
- Block contructor.
- Add graphics related params to the block.
- """
- #add the position param
- self._params['_coordinate'] = self.get_parent().get_parent().Param(
- self,
- odict({
- 'name': 'GUI Coordinate',
- 'key': '_coordinate',
- 'type': 'raw',
- 'value': '(0, 0)',
- 'hide': 'all',
- })
- )
- self._params['_rotation'] = self.get_parent().get_parent().Param(
- self,
- odict({
- 'name': 'GUI Rotation',
- 'key': '_rotation',
- 'type': 'raw',
- 'value': '0',
- 'hide': 'all',
- })
- )
- Element.__init__(self)
-
- def get_coordinate(self):
- """
- Get the coordinate from the position param.
- @return the coordinate tuple (x, y) or (0, 0) if failure
- """
- try: #should evaluate to tuple
- coor = eval(self.get_param('_coordinate').get_value())
- x, y = map(int, coor)
- fgW,fgH = self.get_parent().get_size()
- if x <= 0:
- x = 0
- elif x >= fgW - BORDER_PROXIMITY_SENSITIVITY:
- x = fgW - BORDER_PROXIMITY_SENSITIVITY
- if y <= 0:
- y = 0
- elif y >= fgH - BORDER_PROXIMITY_SENSITIVITY:
- y = fgH - BORDER_PROXIMITY_SENSITIVITY
- return (x, y)
- except:
- self.set_coordinate((0, 0))
- return (0, 0)
-
- def set_coordinate(self, coor):
- """
- Set the coordinate into the position param.
- @param coor the coordinate tuple (x, y)
- """
- self.get_param('_coordinate').set_value(str(coor))
-
- def get_rotation(self):
- """
- Get the rotation from the position param.
- @return the rotation in degrees or 0 if failure
- """
- try: #should evaluate to dict
- rotation = eval(self.get_param('_rotation').get_value())
- return int(rotation)
- except:
- self.set_rotation(POSSIBLE_ROTATIONS[0])
- return POSSIBLE_ROTATIONS[0]
-
- def set_rotation(self, rot):
- """
- Set the rotation into the position param.
- @param rot the rotation in degrees
- """
- self.get_param('_rotation').set_value(str(rot))
-
- def update(self):
- """Update the block, parameters, and ports when a change occurs."""
- self._bg_color = self.get_enabled() and Colors.BLOCK_ENABLED_COLOR or Colors.BLOCK_DISABLED_COLOR
- self.clear()
- self._create_labels()
- self.W = self.label_width + 2*BLOCK_LABEL_PADDING
- self.H = max(*(
- [self.label_height+2*BLOCK_LABEL_PADDING] + [2*PORT_BORDER_SEPARATION + \
- sum([port.H + PORT_SEPARATION for port in ports]) - PORT_SEPARATION
- for ports in (self.get_sources(), self.get_sinks())]
- ))
- if self.is_horizontal(): self.add_area((0, 0), (self.W, self.H))
- elif self.is_vertical(): self.add_area((0, 0), (self.H, self.W))
- map(lambda p: p.update(), self.get_ports())
-
- def _create_labels(self):
- """Create the labels for the signal block."""
- layouts = list()
- #create the main layout
- layout = gtk.DrawingArea().create_pango_layout('')
- layouts.append(layout)
- layout.set_markup(Utils.parse_template(BLOCK_MARKUP_TMPL, block=self))
- self.label_width, self.label_height = layout.get_pixel_size()
- #display the params
- for param in filter(lambda p: p.get_hide() not in ('all', 'part'), self.get_params()):
- layout = param.get_layout()
- layouts.append(layout)
- w,h = layout.get_pixel_size()
- self.label_width = max(w, self.label_width)
- self.label_height = self.label_height + h + LABEL_SEPARATION
- width = self.label_width
- height = self.label_height
- #setup the pixmap
- pixmap = self.get_parent().new_pixmap(width, height)
- gc = pixmap.new_gc()
- gc.set_foreground(self._bg_color)
- pixmap.draw_rectangle(gc, True, 0, 0, width, height)
- #draw the layouts
- h_off = 0
- for i,layout in enumerate(layouts):
- w,h = layout.get_pixel_size()
- if i == 0: w_off = (width-w)/2
- else: w_off = 0
- pixmap.draw_layout(gc, w_off, h_off, layout)
- h_off = h + h_off + LABEL_SEPARATION
- #create vertical and horizontal images
- self.horizontal_label = image = pixmap.get_image(0, 0, width, height)
- if self.is_vertical():
- self.vertical_label = vimage = gtk.gdk.Image(gtk.gdk.IMAGE_NORMAL, pixmap.get_visual(), height, width)
- for i in range(width):
- for j in range(height): vimage.put_pixel(j, width-i-1, image.get_pixel(i, j))
- map(lambda p: p._create_labels(), self.get_ports())
-
- def draw(self, gc, window):
- """
- Draw the signal block with label and inputs/outputs.
- @param gc the graphics context
- @param window the gtk window to draw on
- """
- x, y = self.get_coordinate()
- #draw main block
- Element.draw(
- self, gc, window, bg_color=self._bg_color,
- border_color=self.is_highlighted() and Colors.HIGHLIGHT_COLOR or Colors.BORDER_COLOR,
- )
- #draw label image
- if self.is_horizontal():
- window.draw_image(gc, self.horizontal_label, 0, 0, x+BLOCK_LABEL_PADDING, y+(self.H-self.label_height)/2, -1, -1)
- elif self.is_vertical():
- window.draw_image(gc, self.vertical_label, 0, 0, x+(self.H-self.label_height)/2, y+BLOCK_LABEL_PADDING, -1, -1)
- #draw ports
- for port in self.get_ports(): port.draw(gc, window)
-
- def what_is_selected(self, coor, coor_m=None):
- """
- Get the element that is selected.
- @param coor the (x,y) tuple
- @param coor_m the (x_m, y_m) tuple
- @return this block, a port, or None
- """
- for port in self.get_ports():
- port_selected = port.what_is_selected(coor, coor_m)
- if port_selected: return port_selected
- return Element.what_is_selected(self, coor, coor_m)
diff --git a/grc/src/platforms/gui/Colors.py b/grc/src/platforms/gui/Colors.py
deleted file mode 100644
index f0b989b37..000000000
--- a/grc/src/platforms/gui/Colors.py
+++ /dev/null
@@ -1,37 +0,0 @@
-"""
-Copyright 2008 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-
-_COLORMAP = gtk.gdk.colormap_get_system() #create all of the colors
-def get_color(color_code): return _COLORMAP.alloc_color(color_code, True, True)
-
-HIGHLIGHT_COLOR = get_color('#00FFFF')
-BORDER_COLOR = get_color('black')
-#flow graph color constants
-FLOWGRAPH_BACKGROUND_COLOR = get_color('#FFF9FF')
-#block color constants
-BLOCK_ENABLED_COLOR = get_color('#F1ECFF')
-BLOCK_DISABLED_COLOR = get_color('#CCCCCC')
-#connection color constants
-CONNECTION_ENABLED_COLOR = get_color('black')
-CONNECTION_DISABLED_COLOR = get_color('#999999')
-CONNECTION_ERROR_COLOR = get_color('red')
diff --git a/grc/src/platforms/gui/Connection.py b/grc/src/platforms/gui/Connection.py
deleted file mode 100644
index 013bcb00f..000000000
--- a/grc/src/platforms/gui/Connection.py
+++ /dev/null
@@ -1,140 +0,0 @@
-"""
-Copyright 2007, 2008 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import Utils
-from Element import Element
-import Colors
-from Constants import CONNECTOR_ARROW_BASE, CONNECTOR_ARROW_HEIGHT
-
-class Connection(Element):
- """
- A graphical connection for ports.
- The connection has 2 parts, the arrow and the wire.
- The coloring of the arrow and wire exposes the status of 3 states:
- enabled/disabled, valid/invalid, highlighted/non-highlighted.
- The wire coloring exposes the enabled and highlighted states.
- The arrow coloring exposes the enabled and valid states.
- """
-
- def get_coordinate(self):
- """
- Get the 0,0 coordinate.
- Coordinates are irrelevant in connection.
- @return 0, 0
- """
- return (0, 0)
-
- def get_rotation(self):
- """
- Get the 0 degree rotation.
- Rotations are irrelevant in connection.
- @return 0
- """
- return 0
-
- def update(self):
- """Precalculate relative coordinates."""
- self._sink_rot = None
- self._source_rot = None
- self._sink_coor = None
- self._source_coor = None
- #get the source coordinate
- connector_length = self.get_source().get_connector_length()
- self.x1, self.y1 = Utils.get_rotated_coordinate((connector_length, 0), self.get_source().get_rotation())
- #get the sink coordinate
- connector_length = self.get_sink().get_connector_length() + CONNECTOR_ARROW_HEIGHT
- self.x2, self.y2 = Utils.get_rotated_coordinate((-connector_length, 0), self.get_sink().get_rotation())
- #build the arrow
- self.arrow = [(0, 0),
- Utils.get_rotated_coordinate((-CONNECTOR_ARROW_HEIGHT, -CONNECTOR_ARROW_BASE/2), self.get_sink().get_rotation()),
- Utils.get_rotated_coordinate((-CONNECTOR_ARROW_HEIGHT, CONNECTOR_ARROW_BASE/2), self.get_sink().get_rotation()),
- ]
- self._update_after_move()
- if not self.get_enabled(): self._arrow_color = Colors.CONNECTION_DISABLED_COLOR
- elif not self.is_valid(): self._arrow_color = Colors.CONNECTION_ERROR_COLOR
- else: self._arrow_color = Colors.CONNECTION_ENABLED_COLOR
-
- def _update_after_move(self):
- """Calculate coordinates."""
- self.clear()
- #source connector
- source = self.get_source()
- X, Y = source.get_connector_coordinate()
- x1, y1 = self.x1 + X, self.y1 + Y
- self.add_line((x1, y1), (X, Y))
- #sink connector
- sink = self.get_sink()
- X, Y = sink.get_connector_coordinate()
- x2, y2 = self.x2 + X, self.y2 + Y
- self.add_line((x2, y2), (X, Y))
- #adjust arrow
- self._arrow = [(x+X, y+Y) for x,y in self.arrow]
- #add the horizontal and vertical lines in this connection
- if abs(source.get_connector_direction() - sink.get_connector_direction()) == 180:
- #2 possible point sets to create a 3-line connector
- mid_x, mid_y = (x1 + x2)/2.0, (y1 + y2)/2.0
- points = [((mid_x, y1), (mid_x, y2)), ((x1, mid_y), (x2, mid_y))]
- #source connector -> points[0][0] should be in the direction of source (if possible)
- if Utils.get_angle_from_coordinates((x1, y1), points[0][0]) != source.get_connector_direction(): points.reverse()
- #points[0][0] -> sink connector should not be in the direction of sink
- if Utils.get_angle_from_coordinates(points[0][0], (x2, y2)) == sink.get_connector_direction(): points.reverse()
- #points[0][0] -> source connector should not be in the direction of source
- if Utils.get_angle_from_coordinates(points[0][0], (x1, y1)) == source.get_connector_direction(): points.reverse()
- #create 3-line connector
- p1, p2 = map(int, points[0][0]), map(int, points[0][1])
- self.add_line((x1, y1), p1)
- self.add_line(p1, p2)
- self.add_line((x2, y2), p2)
- else:
- #2 possible points to create a right-angled connector
- points = [(x1, y2), (x2, y1)]
- #source connector -> points[0] should be in the direction of source (if possible)
- if Utils.get_angle_from_coordinates((x1, y1), points[0]) != source.get_connector_direction(): points.reverse()
- #points[0] -> sink connector should not be in the direction of sink
- if Utils.get_angle_from_coordinates(points[0], (x2, y2)) == sink.get_connector_direction(): points.reverse()
- #points[0] -> source connector should not be in the direction of source
- if Utils.get_angle_from_coordinates(points[0], (x1, y1)) == source.get_connector_direction(): points.reverse()
- #create right-angled connector
- self.add_line((x1, y1), points[0])
- self.add_line((x2, y2), points[0])
-
- def draw(self, gc, window):
- """
- Draw the connection.
- @param gc the graphics context
- @param window the gtk window to draw on
- """
- sink = self.get_sink()
- source = self.get_source()
- #check for changes
- if self._sink_rot != sink.get_rotation() or self._source_rot != source.get_rotation(): self.update()
- elif self._sink_coor != sink.get_coordinate() or self._source_coor != source.get_coordinate(): self._update_after_move()
- #cache values
- self._sink_rot = sink.get_rotation()
- self._source_rot = source.get_rotation()
- self._sink_coor = sink.get_coordinate()
- self._source_coor = source.get_coordinate()
- #draw
- if self.is_highlighted(): border_color = Colors.HIGHLIGHT_COLOR
- elif self.get_enabled(): border_color = Colors.CONNECTION_ENABLED_COLOR
- else: border_color = Colors.CONNECTION_DISABLED_COLOR
- Element.draw(self, gc, window, bg_color=None, border_color=border_color)
- #draw arrow on sink port
- gc.set_foreground(self._arrow_color)
- window.draw_polygon(gc, True, self._arrow)
diff --git a/grc/src/platforms/gui/Constants.py b/grc/src/platforms/gui/Constants.py
deleted file mode 100644
index 90c8c1c38..000000000
--- a/grc/src/platforms/gui/Constants.py
+++ /dev/null
@@ -1,44 +0,0 @@
-"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-#label constraint dimensions
-LABEL_SEPARATION = 3
-BLOCK_LABEL_PADDING = 7
-PORT_LABEL_PADDING = 2
-#port constraint dimensions
-PORT_SEPARATION = 17
-PORT_BORDER_SEPARATION = 9
-PORT_MIN_WIDTH = 20
-#minimal length of connector
-CONNECTOR_EXTENSION_MINIMAL = 11
-#increment length for connector
-CONNECTOR_EXTENSION_INCREMENT = 11
-#connection arrow dimensions
-CONNECTOR_ARROW_BASE = 13
-CONNECTOR_ARROW_HEIGHT = 17
-#possible rotations in degrees
-POSSIBLE_ROTATIONS = (0, 90, 180, 270)
-#How close can the mouse get to the window border before mouse events are ignored.
-BORDER_PROXIMITY_SENSITIVITY = 50
-#How close the mouse can get to the edge of the visible window before scrolling is invoked.
-SCROLL_PROXIMITY_SENSITIVITY = 30
-#When the window has to be scrolled, move it this distance in the required direction.
-SCROLL_DISTANCE = 15
-#How close the mouse click can be to a line and register a connection select.
-LINE_SELECT_SENSITIVITY = 5
diff --git a/grc/src/platforms/gui/Element.py b/grc/src/platforms/gui/Element.py
deleted file mode 100644
index 315191723..000000000
--- a/grc/src/platforms/gui/Element.py
+++ /dev/null
@@ -1,226 +0,0 @@
-"""
-Copyright 2007 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import Colors
-import pygtk
-pygtk.require('2.0')
-import gtk
-import pango
-from Constants import LINE_SELECT_SENSITIVITY
-from Constants import POSSIBLE_ROTATIONS
-
-class Element(object):
- """
- GraphicalElement is the base class for all graphical elements.
- It contains an X,Y coordinate, a list of rectangular areas that the element occupies,
- and methods to detect selection of those areas.
- """
-
- def __init__(self, *args, **kwargs):
- """
- Make a new list of rectangular areas and lines, and set the coordinate and the rotation.
- """
- self.set_rotation(POSSIBLE_ROTATIONS[0])
- self.set_coordinate((0, 0))
- self.clear()
- self.set_highlighted(False)
-
- def is_horizontal(self, rotation=None):
- """
- Is this element horizontal?
- If rotation is None, use this element's rotation.
- @param rotation the optional rotation
- @return true if rotation is horizontal
- """
- rotation = rotation or self.get_rotation()
- return rotation in (0, 180)
-
- def is_vertical(self, rotation=None):
- """
- Is this element vertical?
- If rotation is None, use this element's rotation.
- @param rotation the optional rotation
- @return true if rotation is vertical
- """
- rotation = rotation or self.get_rotation()
- return rotation in (90, 270)
-
- def draw(self, gc, window, border_color, bg_color):
- """
- Draw in the given window.
- @param gc the graphics context
- @param window the gtk window to draw on
- @param border_color the color for lines and rectangle borders
- @param bg_color the color for the inside of the rectangle
- """
- X,Y = self.get_coordinate()
- for (rX,rY),(W,H) in self.areas_dict[self.get_rotation()]:
- aX = X + rX
- aY = Y + rY
- gc.set_foreground(bg_color)
- window.draw_rectangle(gc, True, aX, aY, W, H)
- gc.set_foreground(border_color)
- window.draw_rectangle(gc, False, aX, aY, W, H)
- for (x1, y1),(x2, y2) in self.lines_dict[self.get_rotation()]:
- gc.set_foreground(border_color)
- window.draw_line(gc, X+x1, Y+y1, X+x2, Y+y2)
-
- def rotate(self, rotation):
- """
- Rotate all of the areas by 90 degrees.
- @param rotation multiple of 90 degrees
- """
- self.set_rotation((self.get_rotation() + rotation)%360)
-
- def clear(self):
- """Empty the lines and areas."""
- self.areas_dict = dict((rotation, list()) for rotation in POSSIBLE_ROTATIONS)
- self.lines_dict = dict((rotation, list()) for rotation in POSSIBLE_ROTATIONS)
-
- def set_coordinate(self, coor):
- """
- Set the reference coordinate.
- @param coor the coordinate tuple (x,y)
- """
- self.coor = coor
-
- def get_parent(self):
- """
- Get the parent of this element.
- @return the parent
- """
- return self.parent
-
- def set_highlighted(self, highlighted):
- """
- Set the highlight status.
- @param highlighted true to enable highlighting
- """
- self.highlighted = highlighted
-
- def is_highlighted(self):
- """
- Get the highlight status.
- @return true if highlighted
- """
- return self.highlighted
-
- def get_coordinate(self):
- """Get the coordinate.
- @return the coordinate tuple (x,y)
- """
- return self.coor
-
- def move(self, delta_coor):
- """
- Move the element by adding the delta_coor to the current coordinate.
- @param delta_coor (delta_x,delta_y) tuple
- """
- deltaX, deltaY = delta_coor
- X, Y = self.get_coordinate()
- self.set_coordinate((X+deltaX, Y+deltaY))
-
- def add_area(self, rel_coor, area, rotation=None):
- """
- Add an area to the area list.
- An area is actually a coordinate relative to the main coordinate
- with a width/height pair relative to the area coordinate.
- A positive width is to the right of the coordinate.
- A positive height is above the coordinate.
- The area is associated with a rotation.
- If rotation is not specified, the element's current rotation is used.
- @param rel_coor (x,y) offset from this element's coordinate
- @param area (width,height) tuple
- @param rotation rotation in degrees
- """
- self.areas_dict[rotation or self.get_rotation()].append((rel_coor, area))
-
- def add_line(self, rel_coor1, rel_coor2, rotation=None):
- """
- Add a line to the line list.
- A line is defined by 2 relative coordinates.
- Lines must be horizontal or vertical.
- The line is associated with a rotation.
- If rotation is not specified, the element's current rotation is used.
- @param rel_coor1 relative (x1,y1) tuple
- @param rel_coor2 relative (x2,y2) tuple
- @param rotation rotation in degrees
- """
- self.lines_dict[rotation or self.get_rotation()].append((rel_coor1, rel_coor2))
-
- def what_is_selected(self, coor, coor_m=None):
- """
- One coordinate specified:
- Is this element selected at given coordinate?
- ie: is the coordinate encompassed by one of the areas or lines?
- Both coordinates specified:
- Is this element within the rectangular region defined by both coordinates?
- ie: do any area corners or line endpoints fall within the region?
- @param coor the selection coordinate, tuple x, y
- @param coor_m an additional selection coordinate.
- @return self if one of the areas/lines encompasses coor, else None.
- """
- #function to test if p is between a and b (inclusive)
- in_between = lambda p, a, b: p >= min(a, b) and p <= max(a, b)
- #relative coordinate
- x, y = [a-b for a,b in zip(coor, self.get_coordinate())]
- if coor_m:
- x_m, y_m = [a-b for a,b in zip(coor_m, self.get_coordinate())]
- #handle rectangular areas
- for (x1,y1), (w,h) in self.areas_dict[self.get_rotation()]:
- if in_between(x1, x, x_m) and in_between(y1, y, y_m) or \
- in_between(x1+w, x, x_m) and in_between(y1, y, y_m) or \
- in_between(x1, x, x_m) and in_between(y1+h, y, y_m) or \
- in_between(x1+w, x, x_m) and in_between(y1+h, y, y_m):
- return self
- #handle horizontal or vertical lines
- for (x1, y1), (x2, y2) in self.lines_dict[self.get_rotation()]:
- if in_between(x1, x, x_m) and in_between(y1, y, y_m) or \
- in_between(x2, x, x_m) and in_between(y2, y, y_m):
- return self
- return None
- else:
- #handle rectangular areas
- for (x1,y1), (w,h) in self.areas_dict[self.get_rotation()]:
- if in_between(x, x1, x1+w) and in_between(y, y1, y1+h): return self
- #handle horizontal or vertical lines
- for (x1, y1), (x2, y2) in self.lines_dict[self.get_rotation()]:
- if x1 == x2: x1, x2 = x1-LINE_SELECT_SENSITIVITY, x2+LINE_SELECT_SENSITIVITY
- if y1 == y2: y1, y2 = y1-LINE_SELECT_SENSITIVITY, y2+LINE_SELECT_SENSITIVITY
- if in_between(x, x1, x2) and in_between(y, y1, y2): return self
- return None
-
- def get_rotation(self):
- """
- Get the rotation in degrees.
- @return the rotation
- """
- return self.rotation
-
- def set_rotation(self, rotation):
- """
- Set the rotation in degrees.
- @param rotation the rotation"""
- if rotation not in POSSIBLE_ROTATIONS:
- raise Exception('"%s" is not one of the possible rotations: (%s)'%(rotation, POSSIBLE_ROTATIONS))
- self.rotation = rotation
-
- def update(self):
- """Do nothing for the update. Dummy method."""
- pass
diff --git a/grc/src/platforms/gui/FlowGraph.py b/grc/src/platforms/gui/FlowGraph.py
deleted file mode 100644
index 40f391811..000000000
--- a/grc/src/platforms/gui/FlowGraph.py
+++ /dev/null
@@ -1,488 +0,0 @@
-"""
-Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from Constants import SCROLL_PROXIMITY_SENSITIVITY, SCROLL_DISTANCE
-from ... gui.Actions import \
- ELEMENT_CREATE, ELEMENT_SELECT, \
- BLOCK_PARAM_MODIFY, BLOCK_MOVE, \
- ELEMENT_DELETE
-import Colors
-import Utils
-from Element import Element
-from .. base import FlowGraph as _FlowGraph
-import pygtk
-pygtk.require('2.0')
-import gtk
-import random
-from ... gui import Messages
-
-class FlowGraph(Element):
- """
- FlowGraph is the data structure to store graphical signal blocks,
- graphical inputs and outputs,
- and the connections between inputs and outputs.
- """
-
- def __init__(self, *args, **kwargs):
- """
- FlowGraph contructor.
- Create a list for signal blocks and connections. Connect mouse handlers.
- """
- Element.__init__(self)
- #when is the flow graph selected? (used by keyboard event handler)
- self.is_selected = lambda: bool(self.get_selected_elements())
- #important vars dealing with mouse event tracking
- self.element_moved = False
- self.mouse_pressed = False
- self.unselect()
- self.press_coor = (0, 0)
- #selected ports
- self._old_selected_port = None
- self._new_selected_port = None
-
- ###########################################################################
- # Access Drawing Area
- ###########################################################################
- def get_drawing_area(self): return self.drawing_area
- def queue_draw(self): self.get_drawing_area().queue_draw()
- def get_size(self): return self.get_drawing_area().get_size_request()
- def set_size(self, *args): self.get_drawing_area().set_size_request(*args)
- def get_scroll_pane(self): return self.drawing_area.get_parent()
- def get_ctrl_mask(self): return self.drawing_area.ctrl_mask
- def new_pixmap(self, *args): return self.get_drawing_area().new_pixmap(*args)
-
- def add_new_block(self, key, coor=None):
- """
- Add a block of the given key to this flow graph.
- @param key the block key
- @param coor an optional coordinate or None for random
- """
- id = self._get_unique_id(key)
- #calculate the position coordinate
- h_adj = self.get_scroll_pane().get_hadjustment()
- v_adj = self.get_scroll_pane().get_vadjustment()
- if coor is None: coor = (
- int(random.uniform(.25, .75)*h_adj.page_size + h_adj.get_value()),
- int(random.uniform(.25, .75)*v_adj.page_size + v_adj.get_value()),
- )
- #get the new block
- block = self.get_new_block(key)
- block.set_coordinate(coor)
- block.set_rotation(0)
- block.get_param('id').set_value(id)
- self.handle_states(ELEMENT_CREATE)
-
- ###########################################################################
- # Copy Paste
- ###########################################################################
- def copy_to_clipboard(self):
- """
- Copy the selected blocks and connections into the clipboard.
- @return the clipboard
- """
- #get selected blocks
- blocks = self.get_selected_blocks()
- if not blocks: return None
- #calc x and y min
- x_min, y_min = blocks[0].get_coordinate()
- for block in blocks:
- x, y = block.get_coordinate()
- x_min = min(x, x_min)
- y_min = min(y, y_min)
- #get connections between selected blocks
- connections = filter(
- lambda c: c.get_source().get_parent() in blocks and c.get_sink().get_parent() in blocks,
- self.get_connections(),
- )
- clipboard = (
- (x_min, y_min),
- [block.export_data() for block in blocks],
- [connection.export_data() for connection in connections],
- )
- return clipboard
-
- def paste_from_clipboard(self, clipboard):
- """
- Paste the blocks and connections from the clipboard.
- @param clipboard the nested data of blocks, connections
- """
- selected = set()
- (x_min, y_min), blocks_n, connections_n = clipboard
- old_id2block = dict()
- #recalc the position
- h_adj = self.get_scroll_pane().get_hadjustment()
- v_adj = self.get_scroll_pane().get_vadjustment()
- x_off = h_adj.get_value() - x_min + h_adj.page_size/4
- y_off = v_adj.get_value() - y_min + v_adj.page_size/4
- #create blocks
- for block_n in blocks_n:
- block_key = block_n.find('key')
- if block_key == 'options': continue
- block = self.get_new_block(block_key)
- selected.add(block)
- #set params
- params_n = block_n.findall('param')
- for param_n in params_n:
- param_key = param_n.find('key')
- param_value = param_n.find('value')
- #setup id parameter
- if param_key == 'id':
- old_id2block[param_value] = block
- #if the block id is not unique, get a new block id
- if param_value in [block.get_id() for block in self.get_blocks()]:
- param_value = self._get_unique_id(param_value)
- #set value to key
- block.get_param(param_key).set_value(param_value)
- #move block to offset coordinate
- block.move((x_off, y_off))
- #update before creating connections
- self.update()
- #create connections
- for connection_n in connections_n:
- source = old_id2block[connection_n.find('source_block_id')].get_source(connection_n.find('source_key'))
- sink = old_id2block[connection_n.find('sink_block_id')].get_sink(connection_n.find('sink_key'))
- self.connect(source, sink)
- #set all pasted elements selected
- for block in selected: selected = selected.union(set(block.get_connections()))
- self._selected_elements = list(selected)
-
- ###########################################################################
- # Modify Selected
- ###########################################################################
- def type_controller_modify_selected(self, direction):
- """
- Change the registered type controller for the selected signal blocks.
- @param direction +1 or -1
- @return true for change
- """
- return any([sb.type_controller_modify(direction) for sb in self.get_selected_blocks()])
-
- def port_controller_modify_selected(self, direction):
- """
- Change port controller for the selected signal blocks.
- @param direction +1 or -1
- @return true for changed
- """
- return any([sb.port_controller_modify(direction) for sb in self.get_selected_blocks()])
-
- def enable_selected(self, enable):
- """
- Enable/disable the selected blocks.
- @param enable true to enable
- @return true if changed
- """
- changed = False
- for selected_block in self.get_selected_blocks():
- if selected_block.get_enabled() != enable:
- selected_block.set_enabled(enable)
- changed = True
- return changed
-
- def move_selected(self, delta_coordinate):
- """
- Move the element and by the change in coordinates.
- @param delta_coordinate the change in coordinates
- """
- for selected_block in self.get_selected_blocks():
- selected_block.move(delta_coordinate)
- self.element_moved = True
-
- def rotate_selected(self, rotation):
- """
- Rotate the selected blocks by multiples of 90 degrees.
- @param rotation the rotation in degrees
- @return true if changed, otherwise false.
- """
- if not self.get_selected_blocks(): return False
- #initialize min and max coordinates
- min_x, min_y = self.get_selected_block().get_coordinate()
- max_x, max_y = self.get_selected_block().get_coordinate()
- #rotate each selected block, and find min/max coordinate
- for selected_block in self.get_selected_blocks():
- selected_block.rotate(rotation)
- #update the min/max coordinate
- x, y = selected_block.get_coordinate()
- min_x, min_y = min(min_x, x), min(min_y, y)
- max_x, max_y = max(max_x, x), max(max_y, y)
- #calculate center point of slected blocks
- ctr_x, ctr_y = (max_x + min_x)/2, (max_y + min_y)/2
- #rotate the blocks around the center point
- for selected_block in self.get_selected_blocks():
- x, y = selected_block.get_coordinate()
- x, y = Utils.get_rotated_coordinate((x - ctr_x, y - ctr_y), rotation)
- selected_block.set_coordinate((x + ctr_x, y + ctr_y))
- return True
-
- def remove_selected(self):
- """
- Remove selected elements
- @return true if changed.
- """
- changed = False
- for selected_element in self.get_selected_elements():
- self.remove_element(selected_element)
- changed = True
- return changed
-
- def draw(self, gc, window):
- """
- Draw the background and grid if enabled.
- Draw all of the elements in this flow graph onto the pixmap.
- Draw the pixmap to the drawable window of this flow graph.
- """
- W,H = self.get_size()
- #draw the background
- gc.set_foreground(Colors.FLOWGRAPH_BACKGROUND_COLOR)
- window.draw_rectangle(gc, True, 0, 0, W, H)
- #draw multi select rectangle
- if self.mouse_pressed and (not self.get_selected_elements() or self.get_ctrl_mask()):
- #coordinates
- x1, y1 = self.press_coor
- x2, y2 = self.get_coordinate()
- #calculate top-left coordinate and width/height
- x, y = int(min(x1, x2)), int(min(y1, y2))
- w, h = int(abs(x1 - x2)), int(abs(y1 - y2))
- #draw
- gc.set_foreground(Colors.HIGHLIGHT_COLOR)
- window.draw_rectangle(gc, True, x, y, w, h)
- gc.set_foreground(Colors.BORDER_COLOR)
- window.draw_rectangle(gc, False, x, y, w, h)
- #draw blocks on top of connections
- for element in self.get_connections() + self.get_blocks():
- element.draw(gc, window)
- #draw selected blocks on top of selected connections
- for selected_element in self.get_selected_connections() + self.get_selected_blocks():
- selected_element.draw(gc, window)
-
- def update_selected(self):
- """
- Remove deleted elements from the selected elements list.
- Update highlighting so only the selected are highlighted.
- """
- selected_elements = self.get_selected_elements()
- elements = self.get_elements()
- #remove deleted elements
- for selected in selected_elements:
- if selected in elements: continue
- selected_elements.remove(selected)
- #update highlighting
- for element in elements:
- element.set_highlighted(element in selected_elements)
-
- def update(self):
- """
- Call update on all elements.
- """
- for element in self.get_elements(): element.update()
-
- ##########################################################################
- ## Get Selected
- ##########################################################################
- def unselect(self):
- """
- Set selected elements to an empty set.
- """
- self._selected_elements = []
-
- def what_is_selected(self, coor, coor_m=None):
- """
- What is selected?
- At the given coordinate, return the elements found to be selected.
- If coor_m is unspecified, return a list of only the first element found to be selected:
- Iterate though the elements backwards since top elements are at the end of the list.
- If an element is selected, place it at the end of the list so that is is drawn last,
- and hence on top. Update the selected port information.
- @param coor the coordinate of the mouse click
- @param coor_m the coordinate for multi select
- @return the selected blocks and connections or an empty list
- """
- selected_port = None
- selected = set()
- #check the elements
- for element in reversed(self.get_elements()):
- selected_element = element.what_is_selected(coor, coor_m)
- if not selected_element: continue
- #update the selected port information
- if selected_element.is_port():
- if not coor_m: selected_port = selected_element
- selected_element = selected_element.get_parent()
- selected.add(selected_element)
- #place at the end of the list
- self.get_elements().remove(element)
- self.get_elements().append(element)
- #single select mode, break
- if not coor_m: break
- #update selected ports
- self._old_selected_port = self._new_selected_port
- self._new_selected_port = selected_port
- return list(selected)
-
- def get_selected_connections(self):
- """
- Get a group of selected connections.
- @return sub set of connections in this flow graph
- """
- selected = set()
- for selected_element in self.get_selected_elements():
- if selected_element.is_connection(): selected.add(selected_element)
- return list(selected)
-
- def get_selected_blocks(self):
- """
- Get a group of selected blocks.
- @return sub set of blocks in this flow graph
- """
- selected = set()
- for selected_element in self.get_selected_elements():
- if selected_element.is_block(): selected.add(selected_element)
- return list(selected)
-
- def get_selected_block(self):
- """
- Get the selected block when a block or port is selected.
- @return a block or None
- """
- return self.get_selected_blocks() and self.get_selected_blocks()[0] or None
-
- def get_selected_elements(self):
- """
- Get the group of selected elements.
- @return sub set of elements in this flow graph
- """
- return self._selected_elements
-
- def get_selected_element(self):
- """
- Get the selected element.
- @return a block, port, or connection or None
- """
- return self.get_selected_elements() and self.get_selected_elements()[0] or None
-
- def update_selected_elements(self):
- """
- Update the selected elements.
- The update behavior depends on the state of the mouse button.
- When the mouse button pressed the selection will change when
- the control mask is set or the new selection is not in the current group.
- When the mouse button is released the selection will change when
- the mouse has moved and the control mask is set or the current group is empty.
- Attempt to make a new connection if the old and ports are filled.
- If the control mask is set, merge with the current elements.
- """
- selected_elements = None
- if self.mouse_pressed:
- new_selections = self.what_is_selected(self.get_coordinate())
- #update the selections if the new selection is not in the current selections
- #allows us to move entire selected groups of elements
- if self.get_ctrl_mask() or not (
- new_selections and new_selections[0] in self.get_selected_elements()
- ): selected_elements = new_selections
- else: #called from a mouse release
- if not self.element_moved and (not self.get_selected_elements() or self.get_ctrl_mask()):
- selected_elements = self.what_is_selected(self.get_coordinate(), self.press_coor)
- #this selection and the last were ports, try to connect them
- if self._old_selected_port and self._new_selected_port and \
- self._old_selected_port is not self._new_selected_port:
- try:
- self.connect(self._old_selected_port, self._new_selected_port)
- self.handle_states(ELEMENT_CREATE)
- except: Messages.send_fail_connection()
- self._old_selected_port = None
- self._new_selected_port = None
- return
- #update selected elements
- if selected_elements is None: return
- old_elements = set(self.get_selected_elements())
- self._selected_elements = list(set(selected_elements))
- new_elements = set(self.get_selected_elements())
- #if ctrl, set the selected elements to the union - intersection of old and new
- if self.get_ctrl_mask():
- self._selected_elements = list(
- set.union(old_elements, new_elements) - set.intersection(old_elements, new_elements)
- )
- self.handle_states(ELEMENT_SELECT)
-
- ##########################################################################
- ## Event Handlers
- ##########################################################################
- def handle_mouse_button_press(self, left_click, double_click, coordinate):
- """
- A mouse button is pressed, only respond to left clicks.
- Find the selected element. Attempt a new connection if possible.
- Open the block params window on a double click.
- Update the selection state of the flow graph.
- """
- if not left_click: return
- self.press_coor = coordinate
- self.set_coordinate(coordinate)
- self.time = 0
- self.mouse_pressed = True
- if double_click: self.unselect()
- self.update_selected_elements()
- #double click detected, bring up params dialog if possible
- if double_click and self.get_selected_block():
- self.mouse_pressed = False
- self.handle_states(BLOCK_PARAM_MODIFY)
-
- def handle_mouse_button_release(self, left_click, coordinate):
- """
- A mouse button is released, record the state.
- """
- if not left_click: return
- self.set_coordinate(coordinate)
- self.time = 0
- self.mouse_pressed = False
- if self.element_moved:
- self.handle_states(BLOCK_MOVE)
- self.element_moved = False
- self.update_selected_elements()
-
- def handle_mouse_motion(self, coordinate):
- """
- The mouse has moved, respond to mouse dragging.
- Move a selected element to the new coordinate.
- Auto-scroll the scroll bars at the boundaries.
- """
- #to perform a movement, the mouse must be pressed, no pending events
- if gtk.events_pending() or not self.mouse_pressed: return
- #perform autoscrolling
- width, height = self.get_size()
- x, y = coordinate
- h_adj = self.get_scroll_pane().get_hadjustment()
- v_adj = self.get_scroll_pane().get_vadjustment()
- for pos, length, adj, adj_val, adj_len in (
- (x, width, h_adj, h_adj.get_value(), h_adj.page_size),
- (y, height, v_adj, v_adj.get_value(), v_adj.page_size),
- ):
- #scroll if we moved near the border
- if pos-adj_val > adj_len-SCROLL_PROXIMITY_SENSITIVITY and adj_val+SCROLL_DISTANCE < length-adj_len:
- adj.set_value(adj_val+SCROLL_DISTANCE)
- adj.emit('changed')
- elif pos-adj_val < SCROLL_PROXIMITY_SENSITIVITY:
- adj.set_value(adj_val-SCROLL_DISTANCE)
- adj.emit('changed')
- #remove the connection if selected in drag event
- if len(self.get_selected_elements()) == 1 and self.get_selected_element().is_connection():
- self.handle_states(ELEMENT_DELETE)
- #move the selected elements and record the new coordinate
- X, Y = self.get_coordinate()
- if not self.get_ctrl_mask(): self.move_selected((int(x - X), int(y - Y)))
- self.set_coordinate((x, y))
- #queue draw for animation
- self.queue_draw()
diff --git a/grc/src/platforms/gui/Makefile.am b/grc/src/platforms/gui/Makefile.am
deleted file mode 100644
index 2e3972ef3..000000000
--- a/grc/src/platforms/gui/Makefile.am
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# Copyright 2008 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-include $(top_srcdir)/grc/Makefile.inc
-
-ourpythondir = $(grc_src_prefix)/platforms/gui
-
-ourpython_PYTHON = \
- Block.py \
- Colors.py \
- Constants.py \
- Connection.py \
- Element.py \
- FlowGraph.py \
- Param.py \
- Platform.py \
- Port.py \
- Utils.py \
- __init__.py
diff --git a/grc/src/platforms/gui/Param.py b/grc/src/platforms/gui/Param.py
deleted file mode 100644
index 33a9b1f52..000000000
--- a/grc/src/platforms/gui/Param.py
+++ /dev/null
@@ -1,103 +0,0 @@
-"""
-Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import Utils
-from Element import Element
-import pygtk
-pygtk.require('2.0')
-import gtk
-
-PARAM_MARKUP_TMPL="""\
-#set $foreground = $param.is_valid() and 'black' or 'red'
-#set $value = not $param.is_valid() and 'error' or repr($param)
-<span foreground="$foreground" font_desc="Sans 7.5"><b>$encode($param.get_name()): </b>$encode($value)</span>"""
-
-PARAM_LABEL_MARKUP_TMPL="""\
-#set $foreground = $param.is_valid() and 'black' or 'red'
-#set $underline = $has_cb and 'low' or 'none'
-<span underline="$underline" foreground="$foreground" font_desc="Sans 9">$encode($param.get_name())</span>"""
-
-TIP_MARKUP_TMPL="""\
-Key: $param.get_key()
-Type: $param.get_type()
-#if $param.is_valid()
-Value: $param.evaluate()
-#elif len($param.get_error_messages()) == 1
-Error: $(param.get_error_messages()[0])
-#else
-Error:
- #for $error_msg in $param.get_error_messages()
- * $error_msg
- #end for
-#end if"""
-
-class Param(Element):
- """The graphical parameter."""
-
- def update(self):
- """
- Called when an external change occurs.
- Update the graphical input by calling the change handler.
- """
- if hasattr(self, '_input'): self._handle_changed()
-
- def get_input_object(self, callback=None):
- """
- Get the graphical gtk object to represent this parameter.
- Create the input object with this data type and the handle changed method.
- @param callback a function of one argument(this param) to be called from the change handler
- @return gtk input object
- """
- self._callback = callback
- self._input = self.get_input_class()(self, self._handle_changed)
- if not self._callback: self.update()
- return self._input
-
- def _handle_changed(self, widget=None):
- """
- When the input changes, write the inputs to the data type.
- Finish by calling the exteral callback.
- """
- self.set_value(self._input.get_text())
- #is param is involved in a callback? #FIXME: messy
- has_cb = \
- hasattr(self.get_parent(), 'get_callbacks') and \
- filter(lambda c: self.get_key() in c, self.get_parent()._callbacks)
- self._input.set_markup(Utils.parse_template(PARAM_LABEL_MARKUP_TMPL, param=self, has_cb=has_cb))
- #hide/show
- if self.get_hide() == 'all': self._input.hide_all()
- else: self._input.show_all()
- #set the color
- self._input.set_color(self.get_color())
- #set the tooltip
- if self._input.tp: self._input.tp.set_tip(
- self._input.entry,
- Utils.parse_template(TIP_MARKUP_TMPL, param=self).strip(),
- )
- #execute the external callback
- if self._callback: self._callback(self)
-
- def get_layout(self):
- """
- Create a layout based on the current markup.
- @return the pango layout
- """
- layout = gtk.DrawingArea().create_pango_layout('')
- layout.set_markup(Utils.parse_template(PARAM_MARKUP_TMPL, param=self))
- return layout
diff --git a/grc/src/platforms/gui/Platform.py b/grc/src/platforms/gui/Platform.py
deleted file mode 100644
index a32b0209f..000000000
--- a/grc/src/platforms/gui/Platform.py
+++ /dev/null
@@ -1,48 +0,0 @@
-"""
-Copyright 2008 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from FlowGraph import FlowGraph
-from Connection import Connection
-from Block import Block
-from Port import Port
-from Param import Param
-
-def conjoin_classes(name, c1, c2):
- exec("""
-class %s(c1, c2):
- def __init__(self, *args, **kwargs):
- c1.__init__(self, *args, **kwargs)
- c2.__init__(self, *args, **kwargs)
-"""%name, locals())
- return locals()[name]
-
-def Platform(platform):
- #combine with gui class
- for attr, value in (
- ('FlowGraph', FlowGraph),
- ('Connection', Connection),
- ('Block', Block),
- ('Source', Port),
- ('Sink', Port),
- ('Param', Param),
- ):
- old_value = getattr(platform, attr)
- c = conjoin_classes(attr, old_value, value)
- setattr(platform, attr, c)
- return platform
diff --git a/grc/src/platforms/gui/Port.py b/grc/src/platforms/gui/Port.py
deleted file mode 100644
index d1f36f8b9..000000000
--- a/grc/src/platforms/gui/Port.py
+++ /dev/null
@@ -1,190 +0,0 @@
-"""
-Copyright 2007 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from Element import Element
-from Constants import \
- PORT_SEPARATION, CONNECTOR_EXTENSION_MINIMAL, \
- CONNECTOR_EXTENSION_INCREMENT, \
- PORT_LABEL_PADDING, PORT_MIN_WIDTH
-import Utils
-import Colors
-import pygtk
-pygtk.require('2.0')
-import gtk
-
-PORT_MARKUP_TMPL="""\
-<span foreground="black" font_desc="Sans 7.5">$encode($port.get_name())</span>"""
-
-class Port(Element):
- """The graphical port."""
-
- def __init__(self, *args, **kwargs):
- """
- Port contructor.
- Create list of connector coordinates.
- """
- Element.__init__(self)
- self.connector_coordinates = dict()
-
- def update(self):
- """Create new areas and labels for the port."""
- self.clear()
- #get current rotation
- rotation = self.get_rotation()
- #get all sibling ports
- if self.is_source(): ports = self.get_parent().get_sources()
- elif self.is_sink(): ports = self.get_parent().get_sinks()
- #get the max width
- self.W = max([port.W for port in ports] + [PORT_MIN_WIDTH])
- #get a numeric index for this port relative to its sibling ports
- index = ports.index(self)
- length = len(ports)
- #reverse the order of ports for these rotations
- if rotation in (180, 270): index = length-index-1
- offset = (self.get_parent().H - length*self.H - (length-1)*PORT_SEPARATION)/2
- #create areas and connector coordinates
- if (self.is_sink() and rotation == 0) or (self.is_source() and rotation == 180):
- x = -1*self.W
- y = (PORT_SEPARATION+self.H)*index+offset
- self.add_area((x, y), (self.W, self.H))
- self._connector_coordinate = (x-1, y+self.H/2)
- elif (self.is_source() and rotation == 0) or (self.is_sink() and rotation == 180):
- x = self.get_parent().W
- y = (PORT_SEPARATION+self.H)*index+offset
- self.add_area((x, y), (self.W, self.H))
- self._connector_coordinate = (x+1+self.W, y+self.H/2)
- elif (self.is_source() and rotation == 90) or (self.is_sink() and rotation == 270):
- y = -1*self.W
- x = (PORT_SEPARATION+self.H)*index+offset
- self.add_area((x, y), (self.H, self.W))
- self._connector_coordinate = (x+self.H/2, y-1)
- elif (self.is_sink() and rotation == 90) or (self.is_source() and rotation == 270):
- y = self.get_parent().W
- x = (PORT_SEPARATION+self.H)*index+offset
- self.add_area((x, y), (self.H, self.W))
- self._connector_coordinate = (x+self.H/2, y+1+self.W)
- #the connector length
- self._connector_length = CONNECTOR_EXTENSION_MINIMAL + CONNECTOR_EXTENSION_INCREMENT*index
-
- def _create_labels(self):
- """Create the labels for the socket."""
- self._bg_color = Colors.get_color(self.get_color())
- #create the layout
- layout = gtk.DrawingArea().create_pango_layout('')
- layout.set_markup(Utils.parse_template(PORT_MARKUP_TMPL, port=self))
- self.w, self.h = layout.get_pixel_size()
- self.W, self.H = 2*PORT_LABEL_PADDING+self.w, 2*PORT_LABEL_PADDING+self.h
- #create the pixmap
- pixmap = self.get_parent().get_parent().new_pixmap(self.w, self.h)
- gc = pixmap.new_gc()
- gc.set_foreground(self._bg_color)
- pixmap.draw_rectangle(gc, True, 0, 0, self.w, self.h)
- pixmap.draw_layout(gc, 0, 0, layout)
- #create the images
- self.horizontal_label = image = pixmap.get_image(0, 0, self.w, self.h)
- if self.is_vertical():
- self.vertical_label = vimage = gtk.gdk.Image(gtk.gdk.IMAGE_NORMAL, pixmap.get_visual(), self.h, self.w)
- for i in range(self.w):
- for j in range(self.h): vimage.put_pixel(j, self.w-i-1, image.get_pixel(i, j))
-
- def draw(self, gc, window):
- """
- Draw the socket with a label.
- @param gc the graphics context
- @param window the gtk window to draw on
- """
- Element.draw(
- self, gc, window, bg_color=self._bg_color,
- border_color=self.is_highlighted() and Colors.HIGHLIGHT_COLOR or Colors.BORDER_COLOR,
- )
- X,Y = self.get_coordinate()
- (x,y),(w,h) = self.areas_dict[self.get_rotation()][0] #use the first area's sizes to place the labels
- if self.is_horizontal():
- window.draw_image(gc, self.horizontal_label, 0, 0, x+X+(self.W-self.w)/2, y+Y+(self.H-self.h)/2, -1, -1)
- elif self.is_vertical():
- window.draw_image(gc, self.vertical_label, 0, 0, x+X+(self.H-self.h)/2, y+Y+(self.W-self.w)/2, -1, -1)
-
- def get_connector_coordinate(self):
- """
- Get the coordinate where connections may attach to.
- @return the connector coordinate (x, y) tuple
- """
- x,y = self._connector_coordinate
- X,Y = self.get_coordinate()
- return (x+X, y+Y)
-
- def get_connector_direction(self):
- """
- Get the direction that the socket points: 0,90,180,270.
- This is the rotation degree if the socket is an output or
- the rotation degree + 180 if the socket is an input.
- @return the direction in degrees
- """
- if self.is_source(): return self.get_rotation()
- elif self.is_sink(): return (self.get_rotation() + 180)%360
-
- def get_connector_length(self):
- """
- Get the length of the connector.
- The connector length increases as the port index changes.
- @return the length in pixels
- """
- return self._connector_length
-
- def get_rotation(self):
- """
- Get the parent's rotation rather than self.
- @return the parent's rotation
- """
- return self.get_parent().get_rotation()
-
- def move(self, delta_coor):
- """
- Move the parent rather than self.
- @param delta_corr the (delta_x, delta_y) tuple
- """
- self.get_parent().move(delta_coor)
-
- def rotate(self, direction):
- """
- Rotate the parent rather than self.
- @param direction degrees to rotate
- """
- self.get_parent().rotate(direction)
-
- def get_coordinate(self):
- """
- Get the parent's coordinate rather than self.
- @return the parents coordinate
- """
- return self.get_parent().get_coordinate()
-
- def set_highlighted(self, highlight):
- """
- Set the parent highlight rather than self.
- @param highlight true to enable highlighting
- """
- self.get_parent().set_highlighted(highlight)
-
- def is_highlighted(self):
- """
- Get the parent's is highlight rather than self.
- @return the parent's highlighting status
- """
- return self.get_parent().is_highlighted()
diff --git a/grc/src/platforms/gui/Utils.py b/grc/src/platforms/gui/Utils.py
deleted file mode 100644
index ee6dc6cdc..000000000
--- a/grc/src/platforms/gui/Utils.py
+++ /dev/null
@@ -1,82 +0,0 @@
-"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from Constants import POSSIBLE_ROTATIONS
-from Cheetah.Template import Template
-
-def get_rotated_coordinate(coor, rotation):
- """
- Rotate the coordinate by the given rotation.
- @param coor the coordinate x, y tuple
- @param rotation the angle in degrees
- @return the rotated coordinates
- """
- #handles negative angles
- rotation = (rotation + 360)%360
- assert rotation in POSSIBLE_ROTATIONS
- #determine the number of degrees to rotate
- cos_r, sin_r = {
- 0: (1, 0),
- 90: (0, 1),
- 180: (-1, 0),
- 270: (0, -1),
- }[rotation]
- x, y = coor
- return (x*cos_r + y*sin_r, -x*sin_r + y*cos_r)
-
-def get_angle_from_coordinates((x1,y1), (x2,y2)):
- """
- Given two points, calculate the vector direction from point1 to point2, directions are multiples of 90 degrees.
- @param (x1,y1) the coordinate of point 1
- @param (x2,y2) the coordinate of point 2
- @return the direction in degrees
- """
- if y1 == y2:#0 or 180
- if x2 > x1: return 0
- else: return 180
- else:#90 or 270
- if y2 > y1: return 270
- else: return 90
-
-def xml_encode(string):
- """
- Encode a string into an xml safe string by replacing special characters.
- Needed for gtk pango markup in labels.
- @param string the input string
- @return output string with safe characters
- """
- string = str(string)
- for char, safe in (
- ('&', '&amp;'),
- ('<', '&lt;'),
- ('>', '&gt;'),
- ('"', '&quot;'),
- ("'", '&apos;'),
- ): string = string.replace(char, safe)
- return string
-
-def parse_template(tmpl_str, **kwargs):
- """
- Parse the template string with the given args.
- Pass in the xml encode method for pango escape chars.
- @param tmpl_str the template as a string
- @return a string of the parsed template
- """
- kwargs['encode'] = xml_encode
- return str(Template(tmpl_str, kwargs))
diff --git a/grc/src/platforms/gui/__init__.py b/grc/src/platforms/gui/__init__.py
deleted file mode 100644
index 8b1378917..000000000
--- a/grc/src/platforms/gui/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/grc/src/platforms/python/Block.py b/grc/src/platforms/python/Block.py
deleted file mode 100644
index 341e5fdc3..000000000
--- a/grc/src/platforms/python/Block.py
+++ /dev/null
@@ -1,152 +0,0 @@
-"""
-Copyright 2008 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from .. base.Block import Block as _Block
-from utils import extract_docs
-
-class Block(_Block):
-
- ##for make source to keep track of indexes
- _source_count = 0
- ##for make sink to keep track of indexes
- _sink_count = 0
-
- def __init__(self, flow_graph, n):
- """
- Make a new block from nested data.
- @param flow graph the parent element
- @param n the nested odict
- @return block a new block
- """
- #grab the data
- doc = n.find('doc') or ''
- imports = map(lambda i: i.strip(), n.findall('import'))
- make = n.find('make')
- checks = n.findall('check')
- callbacks = n.findall('callback')
- #build the block
- _Block.__init__(
- self,
- flow_graph=flow_graph,
- n=n,
- )
- self._doc = doc
- self._imports = imports
- self._make = make
- self._callbacks = callbacks
- self._checks = checks
-
- def validate(self):
- """
- Validate this block.
- Call the base class validate.
- Evaluate the checks: each check must evaluate to True.
- Adjust the nports.
- """
- _Block.validate(self)
- #evaluate the checks
- for check in self._checks:
- check_res = self.resolve_dependencies(check)
- try:
- check_eval = self.get_parent().evaluate(check_res)
- try: assert check_eval
- except AssertionError: self._add_error_message('Check "%s" failed.'%check)
- except: self._add_error_message('Check "%s" did not evaluate.'%check)
- #adjust nports
- for ports, Port in (
- (self._sources, self.get_parent().get_parent().Source),
- (self._sinks, self.get_parent().get_parent().Sink),
- ):
- #how many ports?
- num_ports = len(ports)
- #do nothing for 0 ports
- if not num_ports: continue
- #get the nports setting
- port0 = ports[str(0)]
- nports = port0.get_nports()
- #do nothing for no nports
- if not nports: continue
- #do nothing if nports is already num ports
- if nports == num_ports: continue
- #remove excess ports and connections
- if nports < num_ports:
- #remove the connections
- for key in map(str, range(nports, num_ports)):
- port = ports[key]
- for connection in port.get_connections():
- self.get_parent().remove_element(connection)
- #remove the ports
- for key in map(str, range(nports, num_ports)): ports.pop(key)
- continue
- #add more ports
- if nports > num_ports:
- for key in map(str, range(num_ports, nports)):
- n = port0._n
- n['key'] = key
- port = Port(self, n)
- ports[key] = port
- continue
-
- def port_controller_modify(self, direction):
- """
- Change the port controller.
- @param direction +1 or -1
- @return true for change
- """
- changed = False
- #concat the nports string from the private nports settings of both port0
- nports_str = \
- (self.get_sinks() and self.get_sinks()[0]._nports or '') + \
- (self.get_sources() and self.get_sources()[0]._nports or '')
- #modify all params whose keys appear in the nports string
- for param in self.get_params():
- if param.is_enum() or param.get_key() not in nports_str: continue
- #try to increment the port controller by direction
- try:
- value = param.evaluate()
- value = value + direction
- assert 0 < value
- param.set_value(value)
- changed = True
- except: pass
- return changed
-
- def get_doc(self):
- doc = self._doc.strip('\n').replace('\\\n', '')
- #merge custom doc with doxygen docs
- return '\n'.join([doc, extract_docs.extract(self.get_key())]).strip('\n')
-
- def get_imports(self):
- """
- Resolve all import statements.
- Split each import statement at newlines.
- Combine all import statments into a list.
- Filter empty imports.
- @return a list of import statements
- """
- return filter(lambda i: i, sum(map(lambda i: self.resolve_dependencies(i).split('\n'), self._imports), []))
-
- def get_make(self): return self.resolve_dependencies(self._make)
-
- def get_callbacks(self):
- """
- Get a list of function callbacks for this block.
- @return a list of strings
- """
- return map(lambda c: self.get_id() + '.' + self.resolve_dependencies(c), self._callbacks)
diff --git a/grc/src/platforms/python/Connection.py b/grc/src/platforms/python/Connection.py
deleted file mode 100644
index f742ff63d..000000000
--- a/grc/src/platforms/python/Connection.py
+++ /dev/null
@@ -1,34 +0,0 @@
-"""
-Copyright 2008 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from .. base.Connection import Connection as _Connection
-
-class Connection(_Connection):
-
- def validate(self):
- """
- Validate the connections.
- The ports must match in type and vector length.
- """
- _Connection.validate(self) #checks type
- #check vector length
- source_vlen = self.get_source().get_vlen()
- sink_vlen = self.get_sink().get_vlen()
- try: assert(source_vlen == sink_vlen)
- except AssertionError: self._add_error_message('Source vector length "%s" does not match sink vector length "%s".'%(source_vlen, sink_vlen))
diff --git a/grc/src/platforms/python/Constants.py.in b/grc/src/platforms/python/Constants.py.in
deleted file mode 100644
index 4a43147fa..000000000
--- a/grc/src/platforms/python/Constants.py.in
+++ /dev/null
@@ -1,54 +0,0 @@
-"""
-Copyright 2008 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import os
-import sys
-import stat
-from .. base.Constants import PKG_DIR
-
-PYEXEC = '@PYTHONW@'
-
-#setup paths
-DOCS_DIR = os.path.join(os.environ.get('GR_DOCDIR', '@docdir@'), 'xml')
-DATA_DIR = os.path.join(PKG_DIR, '@reldatadir@')
-BLOCKS_DIR = os.path.join(PKG_DIR, '@relblocksdir@')
-HIER_BLOCKS_LIB_DIR = os.path.join(os.path.expanduser('~'), '.grc_gnuradio')
-
-#file creation modes
-TOP_BLOCK_FILE_MODE = stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP | stat.S_IROTH
-HIER_BLOCK_FILE_MODE = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH
-
-#data files
-FLOW_GRAPH_TEMPLATE = os.path.join(DATA_DIR, 'flow_graph.tmpl')
-BLOCK_DTD = os.path.join(DATA_DIR, 'block.dtd')
-BLOCK_TREE = os.path.join(DATA_DIR, 'block_tree.xml')
-DEFAULT_FLOW_GRAPH = os.path.join(DATA_DIR, 'default_flow_graph.grc')
-
-#coloring
-COMPLEX_COLOR_SPEC = '#3399FF'
-FLOAT_COLOR_SPEC = '#FF8C69'
-INT_COLOR_SPEC = '#00FF99'
-SHORT_COLOR_SPEC = '#FFFF66'
-BYTE_COLOR_SPEC = '#FF66FF'
-COMPLEX_VECTOR_COLOR_SPEC = '#3399AA'
-FLOAT_VECTOR_COLOR_SPEC = '#CC8C69'
-INT_VECTOR_COLOR_SPEC = '#00CC99'
-SHORT_VECTOR_COLOR_SPEC = '#CCCC33'
-BYTE_VECTOR_COLOR_SPEC = '#CC66CC'
-ID_COLOR_SPEC = '#DDDDDD'
diff --git a/grc/src/platforms/python/FlowGraph.py b/grc/src/platforms/python/FlowGraph.py
deleted file mode 100644
index d0b997a58..000000000
--- a/grc/src/platforms/python/FlowGraph.py
+++ /dev/null
@@ -1,162 +0,0 @@
-"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from utils import expr_utils
-from .. base.FlowGraph import FlowGraph as _FlowGraph
-from Block import Block
-from Connection import Connection
-
-def _get_value_expr(variable_block):
- """
- Get the expression to evaluate from the value param.
- Parameter blocks need to be evaluated so the stringify flag can be determined.
- @param variable_block the variable or parameter block
- @return the expression string
- """
- value_param = variable_block.get_param('value')
- if variable_block.get_key() == 'parameter': value_param.evaluate()
- return value_param.to_code()
-
-class FlowGraph(_FlowGraph):
-
- _eval_cache = dict()
- def _eval(self, code, namespace):
- """
- Evaluate the code with the given namespace.
- @param code a string with python code
- @param namespace a dict representing the namespace
- @return the resultant object
- """
- my_hash = hash(code + str(namespace))
- #cache if does not exist
- if not self._eval_cache.has_key(my_hash):
- self._eval_cache[my_hash] = eval(code, namespace, namespace)
- #return from cache
- return self._eval_cache[my_hash]
-
- def _get_io_signature(self, pad_key):
- """
- Get an io signature for this flow graph.
- The pad key determines the directionality of the io signature.
- @param pad_key a string of pad_source or pad_sink
- @return a dict with: type, nports, vlen, size
- """
- pads = filter(lambda b: b.get_key() == pad_key, self.get_enabled_blocks())
- if not pads: return {
- 'nports': '0',
- 'type': '',
- 'vlen': '0',
- 'size': '0',
- }
- pad = pads[0] #take only the first, user should not have more than 1
- #load io signature
- return {
- 'nports': str(pad.get_param('nports').evaluate()),
- 'type': str(pad.get_param('type').evaluate()),
- 'vlen': str(pad.get_param('vlen').evaluate()),
- 'size': pad.get_param('type').get_opt('size'),
- }
-
- def get_input_signature(self):
- """
- Get the io signature for the input side of this flow graph.
- The io signature with be "0", "0" if no pad source is present.
- @return a string tuple of type, num_ports, port_size
- """
- return self._get_io_signature('pad_source')
-
- def get_output_signature(self):
- """
- Get the io signature for the output side of this flow graph.
- The io signature with be "0", "0" if no pad sink is present.
- @return a string tuple of type, num_ports, port_size
- """
- return self._get_io_signature('pad_sink')
-
- def get_imports(self):
- """
- Get a set of all import statments in this flow graph namespace.
- @return a set of import statements
- """
- imports = sum([block.get_imports() for block in self.get_enabled_blocks()], [])
- imports = sorted(set(imports))
- return imports
-
- def get_variables(self):
- """
- Get a list of all variables in this flow graph namespace.
- Exclude paramterized variables.
- @return a sorted list of variable blocks in order of dependency (indep -> dep)
- """
- variables = filter(lambda b: b.get_key() in (
- 'variable', 'variable_slider', 'variable_chooser', 'variable_text_box'
- ), self.get_enabled_blocks())
- #map var id to variable block
- id2var = dict([(var.get_id(), var) for var in variables])
- #map var id to variable code
- #variable code is a concatenation of all param code (without the id param)
- id2expr = dict([(var.get_id(), var.get_param('value').get_value()) for var in variables])
- #sort according to dependency
- sorted_ids = expr_utils.sort_variables(id2expr)
- #create list of sorted variable blocks
- variables = [id2var[id] for id in sorted_ids]
- return variables
-
- def get_parameters(self):
- """
- Get a list of all paramterized variables in this flow graph namespace.
- @return a list of paramterized variables
- """
- parameters = filter(lambda b: b.get_key() == 'parameter', self.get_enabled_blocks())
- return parameters
-
- def evaluate(self, expr):
- """
- Evaluate the expression.
- @param expr the string expression
- @throw Exception bad expression
- @return the evaluated data
- """
- if self.is_flagged():
- self.deflag()
- #reload namespace
- n = dict()
- #load imports
- for imp in self.get_imports():
- try: exec imp in n
- except: pass
- #load parameters
- np = dict()
- for parameter in self.get_parameters():
- try:
- e = self._eval(_get_value_expr(parameter), n)
- np[parameter.get_id()] = e
- except: pass
- n.update(np) #merge param namespace
- #load variables
- for variable in self.get_variables():
- try:
- e = self._eval(_get_value_expr(variable), n)
- n[variable.get_id()] = e
- except: pass
- #make namespace public
- self.n = n
- #evaluate
- e = self._eval(expr, self.n)
- return e
diff --git a/grc/src/platforms/python/Generator.py b/grc/src/platforms/python/Generator.py
deleted file mode 100644
index 93321404a..000000000
--- a/grc/src/platforms/python/Generator.py
+++ /dev/null
@@ -1,142 +0,0 @@
-"""
-Copyright 2008 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import os
-import subprocess
-from Cheetah.Template import Template
-from utils import expr_utils
-from Constants import \
- TOP_BLOCK_FILE_MODE, HIER_BLOCK_FILE_MODE, \
- HIER_BLOCKS_LIB_DIR, PYEXEC, \
- FLOW_GRAPH_TEMPLATE
-from utils import convert_hier
-from ... gui import Messages
-
-class Generator(object):
-
- def __init__(self, flow_graph, file_path):
- """
- Initialize the generator object.
- Determine the file to generate.
- @param flow_graph the flow graph object
- @param file_path the path to write the file to
- """
- self._flow_graph = flow_graph
- self._generate_options = self._flow_graph.get_option('generate_options')
- if self._generate_options == 'hb':
- self._mode = HIER_BLOCK_FILE_MODE
- dirname = HIER_BLOCKS_LIB_DIR
- else:
- self._mode = TOP_BLOCK_FILE_MODE
- dirname = os.path.dirname(file_path)
- filename = self._flow_graph.get_option('id') + '.py'
- self._file_path = os.path.join(dirname, filename)
-
- def get_file_path(self): return self._file_path
-
- def write(self):
- #do throttle warning
- all_keys = ' '.join(map(lambda b: b.get_key(), self._flow_graph.get_enabled_blocks()))
- if ('usrp' not in all_keys) and ('audio' not in all_keys) and ('throttle' not in all_keys) and self._generate_options != 'hb':
- Messages.send_warning('''\
-This flow graph may not have flow control: no audio or usrp blocks found. \
-Add a Misc->Throttle block to your flow graph to avoid CPU congestion.''')
- #generate
- open(self.get_file_path(), 'w').write(str(self))
- if self._generate_options == 'hb':
- #convert hier block to xml wrapper
- convert_hier.convert_hier(self._flow_graph, self.get_file_path())
- os.chmod(self.get_file_path(), self._mode)
-
- def get_popen(self):
- """
- Execute this python flow graph.
- @return a popen object
- """
- #execute
- cmds = [PYEXEC, '-u', self.get_file_path()] #-u is unbuffered stdio
- if self._generate_options == 'no_gui':
- cmds = ['xterm', '-e'] + cmds
- p = subprocess.Popen(args=cmds, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=False, universal_newlines=True)
- return p
-
- def __str__(self):
- """
- Convert the flow graph to python code.
- @return a string of python code
- """
- imports = self._flow_graph.get_imports()
- variables = self._flow_graph.get_variables()
- parameters = self._flow_graph.get_parameters()
- #list of variables with controls
- controls = filter(lambda v: v.get_key().startswith('variable_'), variables)
- #list of blocks not including variables and imports and parameters and disabled
- blocks = sorted(self._flow_graph.get_enabled_blocks(), lambda x, y: cmp(x.get_id(), y.get_id()))
- probes = filter(lambda b: b.get_key().startswith('probe_'), blocks) #ensure probes are last in the block list
- blocks = filter(lambda b: b not in (imports + parameters + variables + probes), blocks) + probes
- #list of connections where each endpoint is enabled
- connections = self._flow_graph.get_enabled_connections()
- #list of variable names
- var_ids = [var.get_id() for var in parameters + variables]
- #list of callbacks (prepend self.)
- callbacks = [
- expr_utils.expr_prepend(cb, var_ids, 'self.')
- for cb in sum([block.get_callbacks() for block in self._flow_graph.get_enabled_blocks()], [])
- ]
- #map var id to the expression (prepend self.)
- var_id2expr = dict(
- [(var.get_id(), expr_utils.expr_prepend(var.get_make().split('\n')[0], var_ids, 'self.'))
- for var in parameters + variables]
- )
- #create graph structure for variables
- variable_graph = expr_utils.get_graph(var_id2expr)
- #map var id to direct dependents
- #for each var id, make a list of all 2nd order edges
- #use all edges of that id that are not also 2nd order edges
- #meaning: list variables the ONLY depend directly on this variable
- #and not variables that also depend indirectly on this variable
- var_id2deps = dict(
- [(var_id, filter(lambda e: e not in sum([list(variable_graph.get_edges(edge))
- for edge in variable_graph.get_edges(var_id)], []), variable_graph.get_edges(var_id)
- )
- )
- for var_id in var_ids]
- )
- #map var id to callbacks
- var_id2cbs = dict(
- [(var_id, filter(lambda c: var_id in expr_utils.expr_split(c), callbacks))
- for var_id in var_ids]
- )
- #load the namespace
- namespace = {
- 'imports': imports,
- 'flow_graph': self._flow_graph,
- 'variables': variables,
- 'controls': controls,
- 'parameters': parameters,
- 'blocks': blocks,
- 'connections': connections,
- 'generate_options': self._generate_options,
- 'var_id2expr': var_id2expr,
- 'var_id2deps': var_id2deps,
- 'var_id2cbs': var_id2cbs,
- }
- #build the template
- t = Template(open(FLOW_GRAPH_TEMPLATE, 'r').read(), namespace)
- return str(t)
diff --git a/grc/src/platforms/python/Makefile.am b/grc/src/platforms/python/Makefile.am
deleted file mode 100644
index c23d14792..000000000
--- a/grc/src/platforms/python/Makefile.am
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-# Copyright 2008,2009 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-include $(top_srcdir)/grc/Makefile.inc
-
-SUBDIRS = utils
-
-ourpythondir = $(grc_src_prefix)/platforms/python
-
-ourpython_PYTHON = \
- Block.py \
- Connection.py \
- Constants.py \
- FlowGraph.py \
- Generator.py \
- Param.py \
- Platform.py \
- Port.py \
- __init__.py
-
-Constants.py: $(srcdir)/Constants.py.in Makefile
- sed \
- -e 's|@PYTHONW[@]|$(PYTHONW)|g' \
- -e 's|@reldatadir[@]|$(grc_python_data_reldir)|g' \
- -e 's|@relblocksdir[@]|$(grc_blocks_data_reldir)|g' \
- -e 's|@docdir[@]|$(gr_docdir)|g' \
- $< > $@
-
-EXTRA_DIST = $(srcdir)/Constants.py.in
-BUILT_SOURCES = Constants.py
diff --git a/grc/src/platforms/python/Param.py b/grc/src/platforms/python/Param.py
deleted file mode 100644
index e5ac1dcf6..000000000
--- a/grc/src/platforms/python/Param.py
+++ /dev/null
@@ -1,402 +0,0 @@
-"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from utils import expr_utils
-from .. base.Param import Param as _Param, EntryParam
-import Constants
-import numpy
-import os
-import pygtk
-pygtk.require('2.0')
-import gtk
-from gnuradio import eng_notation
-
-class FileParam(EntryParam):
- """Provide an entry box for filename and a button to browse for a file."""
-
- def __init__(self, *args, **kwargs):
- EntryParam.__init__(self, *args, **kwargs)
- input = gtk.Button('...')
- input.connect('clicked', self._handle_clicked)
- self.pack_start(input, False)
-
- def _handle_clicked(self, widget=None):
- """
- If the button was clicked, open a file dialog in open/save format.
- Replace the text in the entry with the new filename from the file dialog.
- """
- #get the paths
- file_path = self.param.is_valid() and self.param.evaluate() or ''
- (dirname, basename) = os.path.isfile(file_path) and os.path.split(file_path) or (file_path, '')
- if not os.path.exists(dirname): dirname = os.getcwd() #fix bad paths
- #build the dialog
- if self.param.get_type() == 'file_open':
- file_dialog = gtk.FileChooserDialog('Open a Data File...', None,
- gtk.FILE_CHOOSER_ACTION_OPEN, ('gtk-cancel',gtk.RESPONSE_CANCEL,'gtk-open',gtk.RESPONSE_OK))
- elif self.param.get_type() == 'file_save':
- file_dialog = gtk.FileChooserDialog('Save a Data File...', None,
- gtk.FILE_CHOOSER_ACTION_SAVE, ('gtk-cancel',gtk.RESPONSE_CANCEL, 'gtk-save',gtk.RESPONSE_OK))
- file_dialog.set_do_overwrite_confirmation(True)
- file_dialog.set_current_name(basename) #show the current filename
- file_dialog.set_current_folder(dirname) #current directory
- file_dialog.set_select_multiple(False)
- file_dialog.set_local_only(True)
- if gtk.RESPONSE_OK == file_dialog.run(): #run the dialog
- file_path = file_dialog.get_filename() #get the file path
- self.entry.set_text(file_path)
- self._handle_changed()
- file_dialog.destroy() #destroy the dialog
-
-#blacklist certain ids, its not complete, but should help
-import __builtin__
-ID_BLACKLIST = ['options', 'gr', 'blks2', 'wxgui', 'wx', 'math', 'forms', 'firdes'] + dir(__builtin__)
-#define types, native python + numpy
-VECTOR_TYPES = (tuple, list, set, numpy.ndarray)
-COMPLEX_TYPES = [complex, numpy.complex, numpy.complex64, numpy.complex128]
-REAL_TYPES = [float, numpy.float, numpy.float32, numpy.float64]
-INT_TYPES = [int, long, numpy.int, numpy.int8, numpy.int16, numpy.int32, numpy.uint64,
- numpy.uint, numpy.uint8, numpy.uint16, numpy.uint32, numpy.uint64]
-#cast to tuple for isinstance, concat subtypes
-COMPLEX_TYPES = tuple(COMPLEX_TYPES + REAL_TYPES + INT_TYPES)
-REAL_TYPES = tuple(REAL_TYPES + INT_TYPES)
-INT_TYPES = tuple(INT_TYPES)
-
-class Param(_Param):
-
- _init = False
- _hostage_cells = list()
-
- ##possible param types
- TYPES = _Param.TYPES + [
- 'complex', 'real', 'int',
- 'complex_vector', 'real_vector', 'int_vector',
- 'hex', 'string',
- 'file_open', 'file_save',
- 'id',
- 'grid_pos', 'import',
- ]
-
- def __repr__(self):
- """
- Get the repr (nice string format) for this param.
- @return the string representation
- """
- if self.get_value() in self.get_option_keys(): return self.get_option(self.get_value()).get_name()
- ##################################################
- # display logic for numbers
- ##################################################
- def num_to_str(num):
- if isinstance(num, COMPLEX_TYPES):
- num = complex(num) #cast to python complex
- if num == 0: return '0' #value is zero
- elif num.imag == 0: return '%s'%eng_notation.num_to_str(num.real) #value is real
- elif num.real == 0: return '%sj'%eng_notation.num_to_str(num.imag) #value is imaginary
- elif num.imag < 0: return '%s-%sj'%(eng_notation.num_to_str(num.real), eng_notation.num_to_str(abs(num.imag)))
- else: return '%s+%sj'%(eng_notation.num_to_str(num.real), eng_notation.num_to_str(num.imag))
- else: return str(num)
- ##################################################
- # split up formatting by type
- ##################################################
- truncate = 0 #default center truncate
- max_len = max(27 - len(self.get_name()), 3)
- e = self.evaluate()
- t = self.get_type()
- if isinstance(e, COMPLEX_TYPES): dt_str = num_to_str(e)
- elif isinstance(e, VECTOR_TYPES): #vector types
- if len(e) > 8:
- dt_str = self.get_value() #large vectors use code
- truncate = 1
- else: dt_str = ', '.join(map(num_to_str, e)) #small vectors use eval
- elif t in ('file_open', 'file_save'):
- dt_str = self.get_value()
- truncate = -1
- else: dt_str = str(e) #other types
- ##################################################
- # truncate
- ##################################################
- if len(dt_str) > max_len:
- if truncate < 0: #front truncate
- dt_str = '...' + dt_str[3-max_len:]
- elif truncate == 0: #center truncate
- dt_str = dt_str[:max_len/2 -3] + '...' + dt_str[-max_len/2:]
- elif truncate > 0: #rear truncate
- dt_str = dt_str[:max_len-3] + '...'
- return dt_str
-
- def get_input_class(self):
- if self.get_type() in ('file_open', 'file_save'): return FileParam
- return _Param.get_input_class(self)
-
- def get_color(self):
- """
- Get the color that represents this param's type.
- @return a hex color code.
- """
- try:
- return {
- #number types
- 'complex': Constants.COMPLEX_COLOR_SPEC,
- 'real': Constants.FLOAT_COLOR_SPEC,
- 'int': Constants.INT_COLOR_SPEC,
- #vector types
- 'complex_vector': Constants.COMPLEX_VECTOR_COLOR_SPEC,
- 'real_vector': Constants.FLOAT_VECTOR_COLOR_SPEC,
- 'int_vector': Constants.INT_VECTOR_COLOR_SPEC,
- #special
- 'hex': Constants.INT_COLOR_SPEC,
- 'string': Constants.BYTE_VECTOR_COLOR_SPEC,
- 'id': Constants.ID_COLOR_SPEC,
- 'grid_pos': Constants.INT_VECTOR_COLOR_SPEC,
- }[self.get_type()]
- except: return _Param.get_color(self)
-
- def get_hide(self):
- """
- Get the hide value from the base class.
- Hide the ID parameter for most blocks. Exceptions below.
- If the parameter controls a port type, vlen, or nports, return part.
- If the parameter is an empty grid position, return part.
- These parameters are redundant to display in the flow graph view.
- @return hide the hide property string
- """
- hide = _Param.get_hide(self)
- if hide: return hide
- #hide ID in non variable blocks
- if self.get_key() == 'id' and self.get_parent().get_key() not in (
- 'variable', 'variable_slider', 'variable_chooser', 'variable_text_box', 'parameter', 'options'
- ): return 'part'
- #hide port controllers for type and nports
- if self.get_key() in ' '.join(map(
- lambda p: ' '.join([p._type, p._nports]), self.get_parent().get_ports())
- ): return 'part'
- #hide port controllers for vlen, when == 1
- if self.get_key() in ' '.join(map(
- lambda p: p._vlen, self.get_parent().get_ports())
- ):
- try:
- assert int(self.evaluate()) == 1
- return 'part'
- except: pass
- #hide empty grid positions
- if self.get_key() == 'grid_pos' and not self.get_value(): return 'part'
- return hide
-
- def evaluate(self):
- """
- Evaluate the value.
- @return evaluated type
- """
- self._lisitify_flag = False
- self._stringify_flag = False
- self._hostage_cells = list()
- def eval_string(v):
- try:
- e = self.get_parent().get_parent().evaluate(v)
- assert isinstance(e, str)
- return e
- except:
- self._stringify_flag = True
- return v
- t = self.get_type()
- v = self.get_value()
- #########################
- # Enum Type
- #########################
- if self.is_enum(): return v
- #########################
- # Numeric Types
- #########################
- elif t in ('raw', 'complex', 'real', 'int', 'complex_vector', 'real_vector', 'int_vector', 'hex'):
- #raise exception if python cannot evaluate this value
- try: e = self.get_parent().get_parent().evaluate(v)
- except Exception, e:
- self._add_error_message('Value "%s" cannot be evaluated: %s'%(v, e))
- raise Exception
- #raise an exception if the data is invalid
- if t == 'raw': return e
- elif t == 'complex':
- try: assert(isinstance(e, COMPLEX_TYPES))
- except AssertionError:
- self._add_error_message('Expression "%s" is invalid for type complex.'%str(e))
- raise Exception
- return e
- elif t == 'real':
- try: assert(isinstance(e, REAL_TYPES))
- except AssertionError:
- self._add_error_message('Expression "%s" is invalid for type real.'%str(e))
- raise Exception
- return e
- elif t == 'int':
- try: assert(isinstance(e, INT_TYPES))
- except AssertionError:
- self._add_error_message('Expression "%s" is invalid for type integer.'%str(e))
- raise Exception
- return e
- #########################
- # Numeric Vector Types
- #########################
- elif t == 'complex_vector':
- if not isinstance(e, VECTOR_TYPES):
- self._lisitify_flag = True
- e = [e]
- try:
- for ei in e:
- assert(isinstance(ei, COMPLEX_TYPES))
- except AssertionError:
- self._add_error_message('Expression "%s" is invalid for type complex vector.'%str(e))
- raise Exception
- return e
- elif t == 'real_vector':
- if not isinstance(e, VECTOR_TYPES):
- self._lisitify_flag = True
- e = [e]
- try:
- for ei in e:
- assert(isinstance(ei, REAL_TYPES))
- except AssertionError:
- self._add_error_message('Expression "%s" is invalid for type real vector.'%str(e))
- raise Exception
- return e
- elif t == 'int_vector':
- if not isinstance(e, VECTOR_TYPES):
- self._lisitify_flag = True
- e = [e]
- try:
- for ei in e:
- assert(isinstance(ei, INT_TYPES))
- except AssertionError:
- self._add_error_message('Expression "%s" is invalid for type integer vector.'%str(e))
- raise Exception
- return e
- elif t == 'hex':
- return hex(e)
- else: raise TypeError, 'Type "%s" not handled'%t
- #########################
- # String Types
- #########################
- elif t in ('string', 'file_open', 'file_save'):
- #do not check if file/directory exists, that is a runtime issue
- e = eval_string(v)
- return str(e)
- #########################
- # Unique ID Type
- #########################
- elif t == 'id':
- #can python use this as a variable?
- try:
- assert(len(v) > 0)
- assert(v[0].isalpha())
- for c in v: assert(c.isalnum() or c in ('_',))
- except AssertionError:
- self._add_error_message('ID "%s" must be alpha-numeric or underscored, and begin with a letter.'%v)
- raise Exception
- params = self.get_all_params('id')
- keys = [param.get_value() for param in params]
- try: assert keys.count(v) <= 1 #id should only appear once, or zero times if block is disabled
- except:
- self._add_error_message('ID "%s" is not unique.'%v)
- raise Exception
- try: assert v not in ID_BLACKLIST
- except:
- self._add_error_message('ID "%s" is blacklisted.'%v)
- raise Exception
- return v
- #########################
- # Grid Position Type
- #########################
- elif t == 'grid_pos':
- if not v: return '' #allow for empty grid pos
- e = self.get_parent().get_parent().evaluate(v)
- try:
- assert(isinstance(e, (list, tuple)) and len(e) == 4)
- for ei in e: assert(isinstance(ei, int))
- except AssertionError:
- self._add_error_message('A grid position must be a list of 4 integers.')
- raise Exception
- row, col, row_span, col_span = e
- #check row, col
- try: assert(row >= 0 and col >= 0)
- except AssertionError:
- self._add_error_message('Row and column must be non-negative.')
- raise Exception
- #check row span, col span
- try: assert(row_span > 0 and col_span > 0)
- except AssertionError:
- self._add_error_message('Row and column span must be greater than zero.')
- raise Exception
- #calculate hostage cells
- for r in range(row_span):
- for c in range(col_span):
- self._hostage_cells.append((row+r, col+c))
- #avoid collisions
- params = filter(lambda p: p is not self, self.get_all_params('grid_pos'))
- for param in params:
- for cell in param._hostage_cells:
- if cell in self._hostage_cells:
- self._add_error_message('Another graphical element is using cell "%s".'%str(cell))
- raise Exception
- return e
- #########################
- # Import Type
- #########################
- elif t == 'import':
- n = dict() #new namespace
- try: exec v in n
- except ImportError:
- self._add_error_message('Import "%s" failed.'%v)
- raise Exception
- except Exception:
- self._add_error_message('Bad import syntax: "%s".'%v)
- raise Exception
- return filter(lambda k: str(k) != '__builtins__', n.keys())
- #########################
- else: raise TypeError, 'Type "%s" not handled'%t
-
- def to_code(self):
- """
- Convert the value to code.
- @return a string representing the code
- """
- #run init tasks in evaluate
- #such as setting flags
- if not self._init:
- self.evaluate()
- self._init = True
- v = self.get_value()
- t = self.get_type()
- if t in ('string', 'file_open', 'file_save'): #string types
- if self._stringify_flag:
- return '"%s"'%v.replace('"', '\"')
- else:
- return v
- elif t in ('complex_vector', 'real_vector', 'int_vector'): #vector types
- if self._lisitify_flag:
- return '(%s, )'%v
- else:
- return '(%s)'%v
- else:
- return v
-
- def get_all_params(self, type):
- """
- Get all the params from the flowgraph that have the given type.
- @param type the specified type
- @return a list of params
- """
- return sum([filter(lambda p: p.get_type() == type, block.get_params()) for block in self.get_parent().get_parent().get_enabled_blocks()], [])
diff --git a/grc/src/platforms/python/Platform.py b/grc/src/platforms/python/Platform.py
deleted file mode 100644
index d2bb4627e..000000000
--- a/grc/src/platforms/python/Platform.py
+++ /dev/null
@@ -1,69 +0,0 @@
-"""
-Copyright 2008 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import os
-from .. base.Platform import Platform as _Platform
-from FlowGraph import FlowGraph as _FlowGraph
-from Connection import Connection as _Connection
-from Block import Block as _Block
-from Port import Source,Sink
-from Param import Param as _Param
-from Generator import Generator
-from Constants import \
- HIER_BLOCKS_LIB_DIR, BLOCK_DTD, \
- BLOCK_TREE, DEFAULT_FLOW_GRAPH, \
- BLOCKS_DIR
-
-_critical_blocks_only = map(lambda b: os.path.join(BLOCKS_DIR, b), ['options.xml', 'usrp_probe.xml', 'usrp2_probe.xml'])
-
-class Platform(_Platform):
-
- def __init__(self, extra_blocks=[], critical_only=False):
- """
- Make a platform for gnuradio.
- @param extra_blocks a list of block paths to load in addition to main block library
- @param critical_only only load critical blocks (used only for usrp probe scripts to speed up load time)
- """
- #ensure hier dir
- if not os.path.exists(HIER_BLOCKS_LIB_DIR): os.mkdir(HIER_BLOCKS_LIB_DIR)
- if critical_only: block_paths = _critical_blocks_only
- else: block_paths = extra_blocks + [HIER_BLOCKS_LIB_DIR, BLOCKS_DIR]
- #convert block paths to absolute paths, ensure uniqueness
- block_paths = set(map(os.path.abspath, block_paths))
- #init
- _Platform.__init__(
- self,
- name='GRC',
- key='grc',
- block_paths=block_paths,
- block_dtd=BLOCK_DTD,
- block_tree=BLOCK_TREE,
- default_flow_graph=DEFAULT_FLOW_GRAPH,
- generator=Generator,
- )
-
- ##############################################
- # Constructors
- ##############################################
- FlowGraph = _FlowGraph
- Connection = _Connection
- Block = _Block
- Source = Source
- Sink = Sink
- Param = _Param
diff --git a/grc/src/platforms/python/Port.py b/grc/src/platforms/python/Port.py
deleted file mode 100644
index b5bc9696b..000000000
--- a/grc/src/platforms/python/Port.py
+++ /dev/null
@@ -1,129 +0,0 @@
-"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from .. base.Port import Port as _Port
-import Constants
-
-class Port(_Port):
-
- ##possible port types
- TYPES = ['complex', 'float', 'int', 'short', 'byte']
-
- def __init__(self, block, n):
- """
- Make a new port from nested data.
- @param block the parent element
- @param n the nested odict
- @return a new port
- """
- vlen = n.find('vlen') or '1'
- nports = n.find('nports') or ''
- optional = n.find('optional') or ''
- #build the port
- _Port.__init__(
- self,
- block=block,
- n=n,
- )
- self._nports = nports
- self._vlen = vlen
- self._optional = bool(optional)
-
- def validate(self):
- _Port.validate(self)
- try: assert(self.get_enabled_connections() or self.get_optional())
- except AssertionError: self._add_error_message('Port is not connected.')
- try: assert(self.is_source() or len(self.get_enabled_connections()) <= 1)
- except AssertionError: self._add_error_message('Port has too many connections.')
-
- def get_vlen(self):
- """
- Get the vector length.
- If the evaluation of vlen cannot be cast to an integer, return 1.
- @return the vector length or 1
- """
- vlen = self.get_parent().resolve_dependencies(self._vlen)
- try: return int(self.get_parent().get_parent().evaluate(vlen))
- except: return 1
-
- def get_nports(self):
- """
- Get the number of ports.
- If already blank, return a blank
- If the evaluation of nports cannot be cast to an integer, return 1.
- @return the number of ports or 1
- """
- nports = self.get_parent().resolve_dependencies(self._nports)
- #return blank if nports is blank
- if not nports: return ''
- try:
- nports = int(self.get_parent().get_parent().evaluate(nports))
- assert 0 < nports
- return nports
- except: return 1
-
- def get_optional(self): return bool(self._optional)
-
- def get_color(self):
- """
- Get the color that represents this port's type.
- Codes differ for ports where the vec length is 1 or greater than 1.
- @return a hex color code.
- """
- try:
- if self.get_vlen() == 1:
- return {#vlen is 1
- 'complex': Constants.COMPLEX_COLOR_SPEC,
- 'float': Constants.FLOAT_COLOR_SPEC,
- 'int': Constants.INT_COLOR_SPEC,
- 'short': Constants.SHORT_COLOR_SPEC,
- 'byte': Constants.BYTE_COLOR_SPEC,
- }[self.get_type()]
- return {#vlen is non 1
- 'complex': Constants.COMPLEX_VECTOR_COLOR_SPEC,
- 'float': Constants.FLOAT_VECTOR_COLOR_SPEC,
- 'int': Constants.INT_VECTOR_COLOR_SPEC,
- 'short': Constants.SHORT_VECTOR_COLOR_SPEC,
- 'byte': Constants.BYTE_VECTOR_COLOR_SPEC,
- }[self.get_type()]
- except: return _Port.get_color(self)
-
-class Source(Port):
-
- def __init__(self, block, n):
- self._n = n #save n
- #key is port index
- n['key'] = str(block._source_count)
- block._source_count = block._source_count + 1
- Port.__init__(self, block, n)
-
- def __del__(self):
- self.get_parent()._source_count = self.get_parent()._source_count - 1
-
-class Sink(Port):
-
- def __init__(self, block, n):
- self._n = n #save n
- #key is port index
- n['key'] = str(block._sink_count)
- block._sink_count = block._sink_count + 1
- Port.__init__(self, block, n)
-
- def __del__(self):
- self.get_parent()._sink_count = self.get_parent()._sink_count - 1
diff --git a/grc/src/platforms/python/__init__.py b/grc/src/platforms/python/__init__.py
deleted file mode 100644
index 8b1378917..000000000
--- a/grc/src/platforms/python/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/grc/src/platforms/python/utils/Makefile.am b/grc/src/platforms/python/utils/Makefile.am
deleted file mode 100644
index b12e51d8e..000000000
--- a/grc/src/platforms/python/utils/Makefile.am
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright 2008 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-include $(top_srcdir)/grc/Makefile.inc
-
-ourpythondir = $(grc_src_prefix)/platforms/python/utils
-
-ourpython_PYTHON = \
- convert_hier.py \
- expr_utils.py \
- extract_docs.py \
- __init__.py
diff --git a/grc/src/platforms/python/utils/__init__.py b/grc/src/platforms/python/utils/__init__.py
deleted file mode 100644
index 8b1378917..000000000
--- a/grc/src/platforms/python/utils/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/grc/src/platforms/python/utils/convert_hier.py b/grc/src/platforms/python/utils/convert_hier.py
deleted file mode 100644
index 495358984..000000000
--- a/grc/src/platforms/python/utils/convert_hier.py
+++ /dev/null
@@ -1,78 +0,0 @@
-"""
-Copyright 2008 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from .. Constants import BLOCK_DTD
-from .... utils import ParseXML
-from .... utils import odict
-
-def convert_hier(flow_graph, python_file):
- #extract info from the flow graph
- input_sig = flow_graph.get_input_signature()
- output_sig = flow_graph.get_output_signature()
- parameters = flow_graph.get_parameters()
- block_key = flow_graph.get_option('id')
- block_name = flow_graph.get_option('title')
- block_category = flow_graph.get_option('category')
- block_desc = flow_graph.get_option('description')
- block_author = flow_graph.get_option('author')
- #build the nested data
- block_n = odict()
- block_n['name'] = block_name
- block_n['key'] = block_key
- block_n['category'] = block_category
- block_n['import'] = 'execfile("%s")'%python_file
- #make data
- block_n['make'] = '%s(\n\t%s,\n)'%(
- block_key,
- ',\n\t'.join(['%s=$%s'%(param.get_id(), param.get_id()) for param in parameters]),
- )
- #callback data
- block_n['callback'] = ['set_%s($%s)'%(param.get_id(), param.get_id()) for param in parameters]
- #param data
- params_n = list()
- for param in parameters:
- param_n = odict()
- param_n['name'] = param.get_param('label').get_value() or param.get_id()
- param_n['key'] = param.get_id()
- param_n['value'] = param.get_param('value').get_value()
- param_n['type'] = 'raw'
- params_n.append(param_n)
- block_n['param'] = params_n
- #sink data
- if int(input_sig['nports']):
- sink_n = odict()
- sink_n['name'] = 'in'
- sink_n['type'] = input_sig['type']
- sink_n['vlen'] = input_sig['vlen']
- sink_n['nports'] = input_sig['nports']
- block_n['sink'] = sink_n
- #source data
- if int(output_sig['nports']):
- source_n = odict()
- source_n['name'] = 'out'
- source_n['type'] = output_sig['type']
- source_n['vlen'] = output_sig['vlen']
- source_n['nports'] = output_sig['nports']
- block_n['source'] = source_n
- #doc data
- block_n['doc'] = "%s\n%s\n%s"%(block_author, block_desc, python_file)
- #write the block_n to file
- xml_file = python_file + '.xml'
- ParseXML.to_file({'block': block_n}, xml_file)
- ParseXML.validate_dtd(xml_file, BLOCK_DTD)
diff --git a/grc/src/platforms/python/utils/expr_utils.py b/grc/src/platforms/python/utils/expr_utils.py
deleted file mode 100644
index 40700993d..000000000
--- a/grc/src/platforms/python/utils/expr_utils.py
+++ /dev/null
@@ -1,137 +0,0 @@
-"""
-Copyright 2008 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-import string
-VAR_CHARS = string.letters + string.digits + '_'
-
-class graph(object):
- """
- Simple graph structure held in a dictionary.
- """
-
- def __init__(self): self._graph = dict()
-
- def __str__(self): return str(self._graph)
-
- def add_node(self, node_key):
- if self._graph.has_key(node_key): return
- self._graph[node_key] = set()
-
- def remove_node(self, node_key):
- if not self._graph.has_key(node_key): return
- for edges in self._graph.values():
- if node_key in edges: edges.remove(node_key)
- self._graph.pop(node_key)
-
- def add_edge(self, src_node_key, dest_node_key):
- self._graph[src_node_key].add(dest_node_key)
-
- def remove_edge(self, src_node_key, dest_node_key):
- self._graph[src_node_key].remove(dest_node_key)
-
- def get_nodes(self): return self._graph.keys()
-
- def get_edges(self, node_key): return self._graph[node_key]
-
-def expr_split(expr):
- """
- Split up an expression by non alphanumeric characters, including underscore.
- Leave strings in-tact.
- #TODO ignore escaped quotes, use raw strings.
- @param expr an expression string
- @return a list of string tokens that form expr
- """
- toks = list()
- tok = ''
- quote = ''
- for char in expr:
- if quote or char in VAR_CHARS:
- if char == quote: quote = ''
- tok += char
- elif char in ("'", '"'):
- toks.append(tok)
- tok = char
- quote = char
- else:
- toks.append(tok)
- toks.append(char)
- tok = ''
- toks.append(tok)
- return filter(lambda t: t, toks)
-
-def expr_prepend(expr, vars, prepend):
- """
- Search for vars in the expression and add the prepend.
- @param expr an expression string
- @param vars a list of variable names
- @param prepend the prepend string
- @return a new expression with the prepend
- """
- expr_splits = expr_split(expr)
- for i, es in enumerate(expr_splits):
- if es in vars: expr_splits[i] = prepend + es
- return ''.join(expr_splits)
-
-def get_variable_dependencies(expr, vars):
- """
- Return a set of variables used in this expression.
- @param expr an expression string
- @param vars a list of variable names
- @return a subset of vars used in the expression
- """
- expr_toks = expr_split(expr)
- return set(filter(lambda v: v in expr_toks, vars))
-
-def get_graph(exprs):
- """
- Get a graph representing the variable dependencies
- @param exprs a mapping of variable name to expression
- @return a graph of variable deps
- """
- vars = exprs.keys()
- #get dependencies for each expression, load into graph
- var_graph = graph()
- for var in vars: var_graph.add_node(var)
- for var, expr in exprs.iteritems():
- for dep in get_variable_dependencies(expr, vars):
- var_graph.add_edge(dep, var)
- return var_graph
-
-def sort_variables(exprs):
- """
- Get a list of variables in order of dependencies.
- @param exprs a mapping of variable name to expression
- @return a list of variable names
- @throws AssertionError circular dependencies
- """
- var_graph = get_graph(exprs)
- sorted_vars = list()
- #determine dependency order
- while var_graph.get_nodes():
- #get a list of nodes with no edges
- indep_vars = filter(lambda var: not var_graph.get_edges(var), var_graph.get_nodes())
- assert indep_vars
- #add the indep vars to the end of the list
- sorted_vars.extend(sorted(indep_vars))
- #remove each edge-less node from the graph
- for var in indep_vars: var_graph.remove_node(var)
- return reversed(sorted_vars)
-
-if __name__ == '__main__':
- for i in sort_variables({'x':'1', 'y':'x+1', 'a':'x+y', 'b':'y+1', 'c':'a+b+x+y'}): print i
diff --git a/grc/src/platforms/python/utils/extract_docs.py b/grc/src/platforms/python/utils/extract_docs.py
deleted file mode 100644
index 523519f97..000000000
--- a/grc/src/platforms/python/utils/extract_docs.py
+++ /dev/null
@@ -1,92 +0,0 @@
-"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from .. Constants import DOCS_DIR
-from lxml import etree
-import os
-import re
-
-DOXYGEN_NAME_XPATH = '/doxygen/compounddef/compoundname'
-DOXYGEN_BRIEFDESC_GR_XPATH = '/doxygen/compounddef/briefdescription'
-DOXYGEN_DETAILDESC_GR_XPATH = '/doxygen/compounddef/detaileddescription'
-
-def extract_txt(xml):
- """
- Recursivly pull the text out of an xml tree.
- @param xml the xml tree
- @return a string
- """
- text = (xml.text or '').replace('\n', '')
- tail = (xml.tail or '').replace('\n', '')
- if xml.tag == 'para': tail += '\n\n'
- if xml.tag == 'linebreak': text += '\n'
- if xml.tag == 'parametername': text += ': '
- return text + ''.join(
- map(lambda x: extract_txt(x), xml)
- ) + tail
-
-def _extract(key):
- """
- Extract the documentation from the doxygen generated xml files.
- If multiple files match, combine the docs.
- @param key the block key
- @return a string with documentation
- """
- UBUNTU_DOCS_DIR = '/usr/share/doc/gnuradio-doc/xml'
- if os.path.exists(DOCS_DIR): docs_dir = DOCS_DIR
- elif os.path.exists(UBUNTU_DOCS_DIR): docs_dir = UBUNTU_DOCS_DIR
- else: return ''
- #extract matches
- pattern = key.replace('_', '_*').replace('x', '\w')
- prog = re.compile('^class%s\..*$'%pattern)
- matches = filter(lambda f: prog.match(f), os.listdir(docs_dir))
- #combine all matches
- doc_strs = list()
- for match in matches:
- try:
- xml_file = os.path.join(docs_dir, match)
- xml = etree.parse(xml_file)
- #extract descriptions
- comp_name = extract_txt(xml.xpath(DOXYGEN_NAME_XPATH)[0]).strip()
- comp_name = ' --- ' + comp_name + ' --- '
- if re.match('(gr|usrp2|trellis)_.*', key):
- brief_desc = extract_txt(xml.xpath(DOXYGEN_BRIEFDESC_GR_XPATH)[0]).strip()
- detailed_desc = extract_txt(xml.xpath(DOXYGEN_DETAILDESC_GR_XPATH)[0]).strip()
- else:
- brief_desc = ''
- detailed_desc = ''
- #combine
- doc_strs.append('\n\n'.join([comp_name, brief_desc, detailed_desc]).strip())
- except IndexError: pass #bad format
- return '\n\n'.join(doc_strs)
-
-_docs_cache = dict()
-def extract(key):
- """
- Call the private extract and cache the result.
- @param key the block key
- @return a string with documentation
- """
- try: assert _docs_cache.has_key(key)
- except: _docs_cache[key] = _extract(key)
- return _docs_cache[key]
-
-if __name__ == '__main__':
- import sys
- print extract(sys.argv[1])
diff --git a/grc/src/utils/Makefile.am b/grc/src/utils/Makefile.am
deleted file mode 100644
index a48904796..000000000
--- a/grc/src/utils/Makefile.am
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright 2008, 2009 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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, or (at your option)
-# any later version.
-#
-# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-include $(top_srcdir)/grc/Makefile.inc
-
-ourpythondir = $(grc_src_prefix)/utils
-
-ourpython_PYTHON = \
- converter.py \
- odict.py \
- ParseXML.py \
- __init__.py
diff --git a/grc/src/utils/ParseXML.py b/grc/src/utils/ParseXML.py
deleted file mode 100644
index d05b7b8b5..000000000
--- a/grc/src/utils/ParseXML.py
+++ /dev/null
@@ -1,102 +0,0 @@
-"""
-Copyright 2008 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from lxml import etree
-from .. utils import odict
-
-class XMLSyntaxError(Exception):
- def __init__(self, error_log):
- self._error_log = error_log
- def __str__(self):
- return '\n'.join(map(str, self._error_log.filter_from_errors()))
-
-def validate_dtd(xml_file, dtd_file=None):
- """
- Validate an xml file against its dtd.
- @param xml_file the xml file
- @param dtd_file the optional dtd file
- @throws Exception validation fails
- """
- #perform parsing, use dtd validation if dtd file is not specified
- parser = etree.XMLParser(dtd_validation=not dtd_file)
- xml = etree.parse(xml_file, parser=parser)
- if parser.error_log: raise XMLSyntaxError(parser.error_log)
- #perform dtd validation if the dtd file is specified
- if not dtd_file: return
- dtd = etree.DTD(dtd_file)
- if not dtd.validate(xml.getroot()): raise XMLSyntaxError(dtd.error_log)
-
-def from_file(xml_file):
- """
- Create nested data from an xml file using the from xml helper.
- @param xml_file the xml file path
- @return the nested data
- """
- xml = etree.parse(xml_file).getroot()
- return _from_file(xml)
-
-def _from_file(xml):
- """
- Recursivly parse the xml tree into nested data format.
- @param xml the xml tree
- @return the nested data
- """
- tag = xml.tag
- if not len(xml):
- return odict({tag: xml.text or ''}) #store empty tags (text is None) as empty string
- nested_data = odict()
- for elem in xml:
- key, value = _from_file(elem).items()[0]
- if nested_data.has_key(key): nested_data[key].append(value)
- else: nested_data[key] = [value]
- #delistify if the length of values is 1
- for key, values in nested_data.iteritems():
- if len(values) == 1: nested_data[key] = values[0]
- return odict({tag: nested_data})
-
-def to_file(nested_data, xml_file):
- """
- Write an xml file and use the to xml helper method to load it.
- @param nested_data the nested data
- @param xml_file the xml file path
- """
- xml = _to_file(nested_data)[0]
- open(xml_file, 'w').write(etree.tostring(xml, xml_declaration=True, pretty_print=True))
-
-def _to_file(nested_data):
- """
- Recursivly parse the nested data into xml tree format.
- @param nested_data the nested data
- @return the xml tree filled with child nodes
- """
- nodes = list()
- for key, values in nested_data.iteritems():
- #listify the values if not a list
- if not isinstance(values, (list, set, tuple)):
- values = [values]
- for value in values:
- node = etree.Element(key)
- if isinstance(value, (str, unicode)): node.text = value
- else: node.extend(_to_file(value))
- nodes.append(node)
- return nodes
-
-if __name__ == '__main__':
- """Use the main method to test parse xml's functions."""
- pass
diff --git a/grc/src/utils/__init__.py b/grc/src/utils/__init__.py
deleted file mode 100644
index 2682db812..000000000
--- a/grc/src/utils/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-"""
-Copyright 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from odict import odict
diff --git a/grc/src/utils/converter.py b/grc/src/utils/converter.py
deleted file mode 100644
index 34fc438fd..000000000
--- a/grc/src/utils/converter.py
+++ /dev/null
@@ -1,248 +0,0 @@
-"""
-Copyright 2008 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from .. platforms.base.Constants import FLOW_GRAPH_DTD
-import ParseXML
-from .. import utils
-from .. utils import odict
-from lxml import etree
-import difflib
-import os
-
-def _make_param(key, value):
- """
- Make a paramater dict from the key/value pair.
- @param key the key
- @param value the value
- @return a dictionary object
- """
- param = odict()
- param['key'] = key
- param['value'] = value
- return param
-
-def _get_blocks(blocks, tag):
- """
- Get a list of blocks with the tag.
- @param blocks the old block list
- @param tag the tag name
- @retun a list of matching blocks
- """
- return filter(lambda b: b['tag'] == tag, blocks)
-
-def _get_params(block):
- """
- Get a list of params.
- @param block the old block
- @retun a list of params
- """
- params = utils.exists_or_else(block, 'params', {}) or {}
- params = utils.listify(params, 'param')
- return params
-
-def _convert_id(id):
- """
- Convert an old id to a new safe id.
- Replace spaces with underscores.
- Lower case the odl id.
- @return the reformatted id
- """
- return id.lower().replace(' ', '_')
-
-def convert(file_path, platform):
- """
- Convert the flow graph to the new format.
- Make a backup of the old file.
- Save a reformated flow graph to the file path.
- If this is a new format flow graph, do nothing.
- @param file_path the path to the saved flow graph
- @param platform the grc gnuradio platform
- """
- try: #return if file passes validation
- ParseXML.validate_dtd(file_path, FLOW_GRAPH_DTD)
- try:
- changed = False
- #convert instances of gui_coordinate and gui_rotation
- xml = etree.parse(file_path)
- for find, replace in (
- ('gr_add_vxx', 'gr_add_xx'),
- ('gr_multiply_vxx', 'gr_multiply_xx'),
- ):
- keys = xml.xpath('/flow_graph/block[key="%s"]/key'%find)
- for key in keys:
- key.text = replace
- changed = True
- if not changed: return
- #backup after successful conversion
- os.rename(file_path, file_path+'.bak')
- #save new flow graph to file path
- xml.write(file_path, xml_declaration=True, pretty_print=True)
- except Exception, e: print e
- return
- except: pass #convert
- ############################################################
- # extract window size, variables, blocks, and connections
- ############################################################
- old_n = ParseXML.from_file(file_path)['flow_graph']
- try: window_width = min(3*int(old_n['window_width'])/2, 2048)
- except: window_width = 2048
- try: window_height = min(3*int(old_n['window_height'])/2, 2048)
- except: window_height = 2048
- window_size = '%d, %d'%(window_width, window_height)
- variables = utils.exists_or_else(old_n, 'vars', {}) or {}
- variables = utils.listify(variables, 'var')
- blocks = utils.exists_or_else(old_n, 'signal_blocks', {}) or {}
- blocks = utils.listify(blocks, 'signal_block')
- connections = utils.exists_or_else(old_n, 'connections', {}) or {}
- connections = utils.listify(connections, 'connection')
- #initialize new nested data
- new_n = odict()
- new_n['block'] = list()
- new_n['connection'] = list()
- ############################################################
- # conversion - options block
- ############################################################
- #get name
- about_blocks = _get_blocks(blocks, 'About')
- if about_blocks: title = _get_params(about_blocks[0])[0]
- else: title = 'Untitled'
- #get author
- if about_blocks: author = _get_params(about_blocks[0])[1]
- else: author = ''
- #get desc
- note_blocks = _get_blocks(blocks, 'Note')
- if note_blocks: desc = _get_params(note_blocks[0])[0]
- else: desc = ''
- #create options block
- options_block = odict()
- options_block['key'] = 'options'
- options_block['param'] = [
- _make_param('id', 'top_block'),
- _make_param('title', title),
- _make_param('author', author),
- _make_param('description', desc),
- _make_param('window_size', window_size),
- _make_param('_coordinate', '(10, 10)'),
- ]
- #append options block
- new_n['block'].append(options_block)
- ############################################################
- # conversion - variables
- ############################################################
- x = 100
- for variable in variables:
- key = variable['key']
- value = variable['value']
- minimum = utils.exists_or_else(variable, 'min', '')
- maximum = utils.exists_or_else(variable, 'max', '')
- step = utils.exists_or_else(variable, 'step', '')
- x = x + 150
- coor = '(%d, %d)'%(x, 10)
- var_block = odict()
- if minimum and maximum: #slider varible
- #determine num steps
- try: num_steps = str(int((float(maximum) - float(minimum))/float(step)))
- except: num_steps = '100'
- var_block['key'] = 'variable_slider'
- var_block['param'] = [
- _make_param('id', key),
- _make_param('value', value),
- _make_param('min', minimum),
- _make_param('max', maximum),
- _make_param('num_steps', num_steps),
- _make_param('_coordinate', coor),
- ]
- else: #regular variable
- var_block['key'] = 'variable'
- var_block['param'] = [
- _make_param('id', key),
- _make_param('value', value),
- _make_param('_coordinate', coor),
- ]
- #append variable block
- new_n['block'].append(var_block)
- ############################################################
- # conversion - blocks
- ############################################################
- #create name to key map for all blocks in platform
- name_to_key = dict((b.get_name(), b.get_key()) for b in platform.get_blocks())
- for block in blocks:
- #extract info
- tag = block['tag']
- #ignore list
- if tag in ('Note', 'About'): continue
- id = _convert_id(block['id'])
- coor = '(%s, %s + 100)'%(
- utils.exists_or_else(block, 'x_coordinate', '0'),
- utils.exists_or_else(block, 'y_coordinate', '0'),
- )
- rot = utils.exists_or_else(block, 'rotation', '0')
- params = _get_params(block)
- #new block
- new_block = odict()
- matches = difflib.get_close_matches(tag, name_to_key.keys(), 1)
- if not matches: continue
- #match found
- key = name_to_key[matches[0]]
- new_block['key'] = key
- new_block['param'] = [
- _make_param('id', id),
- _make_param('_coordinate', coor),
- _make_param('_rotation', rot),
- ]
- #handle specific blocks
- if key == 'wxgui_fftsink2':
- params = params[0:3] + ['0'] + params[3:4] + ['8'] + params[4:]
- #append params
- for i, param in enumerate(params):
- platform_block = platform.get_block(key)
- try: platform_param = platform_block.get_params()[i+2]
- except IndexError: break
- if platform_param.is_enum():
- try: param_value = platform_param.get_option_keys()[int(param)]
- except: param_value = platform_param.get_option_keys()[0]
- else:
- param_value = param.replace('$', '').replace('^', '**')
- new_block['param'].append(_make_param(platform_param.get_key(), param_value))
- #append block
- new_n['block'].append(new_block)
- ############################################################
- # conversion - connections
- ############################################################
- for connection in connections:
- #extract info
- input_signal_block_id = connection['input_signal_block_id']
- input_socket_index = connection['input_socket_index']
- output_signal_block_id = connection['output_signal_block_id']
- output_socket_index = connection['output_socket_index']
- #new connection
- new_conn = odict()
- new_conn['source_block_id'] = _convert_id(output_signal_block_id)
- new_conn['sink_block_id'] = _convert_id(input_signal_block_id)
- new_conn['source_key'] = output_socket_index
- new_conn['sink_key'] = input_socket_index
- #append connection
- new_n['connection'].append(new_conn)
- ############################################################
- # backup and replace
- ############################################################
- #backup after successful conversion
- os.rename(file_path, file_path+'.bak')
- #save new flow graph to file path
- ParseXML.to_file({'flow_graph': new_n}, file_path)
diff --git a/grc/src/utils/odict.py b/grc/src/utils/odict.py
deleted file mode 100644
index ac3cb2070..000000000
--- a/grc/src/utils/odict.py
+++ /dev/null
@@ -1,93 +0,0 @@
-"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from UserDict import DictMixin
-
-class odict(DictMixin):
-
- def __init__(self, d={}):
- self._keys = list(d.keys())
- self._data = dict(d.copy())
-
- def __setitem__(self, key, value):
- if key not in self._data:
- self._keys.append(key)
- self._data[key] = value
-
- def __getitem__(self, key):
- return self._data[key]
-
- def __delitem__(self, key):
- del self._data[key]
- self._keys.remove(key)
-
- def keys(self):
- return list(self._keys)
-
- def copy(self):
- copy_dict = odict()
- copy_dict._data = self._data.copy()
- copy_dict._keys = list(self._keys)
- return copy_dict
-
- def insert_after(self, pos_key, key, val):
- """
- Insert the new key, value entry after the entry given by the position key.
- If the positional key is None, insert at the end.
- @param pos_key the positional key
- @param key the key for the new entry
- @param val the value for the new entry
- """
- index = (pos_key is None) and len(self._keys) or self._keys.index(pos_key)
- assert key not in self._keys
- self._keys.insert(index+1, key)
- self._data[key] = val
-
- def insert_before(self, pos_key, key, val):
- """
- Insert the new key, value entry before the entry given by the position key.
- If the positional key is None, insert at the begining.
- @param pos_key the positional key
- @param key the key for the new entry
- @param val the value for the new entry
- """
- index = (pos_key is not None) and self._keys.index(pos_key) or 0
- assert key not in self._keys
- self._keys.insert(index, key)
- self._data[key] = val
-
- def find(self, key):
- """
- Get the value for this key if exists.
- @param key the key to search for
- @return the value or None
- """
- if self.has_key(key): return self[key]
- return None
-
- def findall(self, key):
- """
- Get a list of values for this key.
- @param key the key to search for
- @return a list of values or empty list
- """
- obj = self.find(key)
- if obj is None: obj = list()
- if isinstance(obj, list): return obj
- return [obj]