[hamradio-commits] [qsstv] 01/04: New upstream version 9.2.4+repack

Dave Hibberd hibby-guest at moszumanska.debian.org
Sat Jan 21 23:40:25 UTC 2017


This is an automated email from the git hooks/post-receive script.

hibby-guest pushed a commit to branch master
in repository qsstv.

commit 6ef1e552cd9ea0c36f49fcf9c45f73f219c13b86
Author: Hibby <d at vehibberd.com>
Date:   Sat Jan 21 22:06:03 2017 +0000

    New upstream version 9.2.4+repack
---
 qsstv/appglobal.cpp                                |   10 +-
 qsstv/appglobal.h                                  |    5 +
 qsstv/config/configdialog.ui                       |  212 +-
 qsstv/config/cwconfig.ui                           |   19 +-
 qsstv/config/directoriesconfig.ui                  |   15 +
 qsstv/config/drmprofileconfig.ui                   |   74 +-
 qsstv/config/frequencyselectwidget.ui              |   15 +
 qsstv/config/ftpconfig.cpp                         |    4 +-
 qsstv/config/ftpconfig.ui                          |  222 +-
 qsstv/config/guiconfig.cpp                         |    5 +
 qsstv/config/guiconfig.h                           |    1 +
 qsstv/config/guiconfig.ui                          |  399 ++--
 qsstv/config/hybridconfig.cpp                      |   18 +-
 qsstv/config/hybridconfig.h                        |    2 +-
 qsstv/config/hybridconfig.ui                       |   64 +-
 qsstv/config/hybridnotifyconfig.cpp                |   14 +-
 qsstv/config/hybridnotifyconfig.h                  |    2 +-
 qsstv/config/hybridnotifyconfig.ui                 |  123 +-
 qsstv/config/operatorconfig.cpp                    |   24 +-
 qsstv/config/operatorconfig.h                      |    3 +
 qsstv/config/operatorconfig.ui                     |   47 +-
 qsstv/config/repeaterconfig.ui                     |   89 +-
 qsstv/config/rigconfig.ui                          | 2496 +++++---------------
 qsstv/config/soundconfig.ui                        |  125 +-
 qsstv/config/waterfallconfig.cpp                   |   10 +
 qsstv/config/waterfallconfig.h                     |    2 +
 qsstv/config/waterfallconfig.ui                    |  156 +-
 qsstv/dispatch/dispatcher.cpp                      |  648 +++--
 qsstv/dispatch/dispatcher.h                        |   59 +-
 qsstv/dispatch/dispatchevents.h                    |  704 +++---
 qsstv/documentation/manual/images/Gallery_rx.png   |  Bin 991987 -> 581570 bytes
 .../manual/images/Gallery_templates.png            |  Bin 0 -> 98439 bytes
 .../documentation/manual/images/Gallery_txdrm.png  |  Bin 0 -> 184153 bytes
 qsstv/documentation/manual/images/config.png       |  Bin 13929 -> 15212 bytes
 qsstv/documentation/manual/images/config3.png      |  Bin 41811 -> 52566 bytes
 qsstv/documentation/manual/images/config4.png      |  Bin 87050 -> 82043 bytes
 qsstv/documentation/manual/images/config5.png      |  Bin 83564 -> 78350 bytes
 qsstv/documentation/manual/images/config8.png      |  Bin 64012 -> 72980 bytes
 qsstv/documentation/manual/images/receivedrm.png   |  Bin 266130 -> 283367 bytes
 qsstv/documentation/manual/images/transmitdrm.png  |  Bin 347771 -> 295255 bytes
 qsstv/documentation/manual/manual.doxy             |    2 +-
 qsstv/documentation/manual/manual.txt              |   60 +-
 qsstv/documentation/manual/manual/Copying.html     |    6 +-
 qsstv/documentation/manual/manual/Gallery_rx.png   |  Bin 991987 -> 581570 bytes
 .../manual/manual/Gallery_templates.png            |  Bin 0 -> 98439 bytes
 .../documentation/manual/manual/Gallery_txdrm.png  |  Bin 0 -> 184153 bytes
 qsstv/documentation/manual/manual/RXDRM.html       |    6 +-
 qsstv/documentation/manual/manual/RXSSTV.html      |    6 +-
 qsstv/documentation/manual/manual/TXDRM.html       |    6 +-
 qsstv/documentation/manual/manual/TXSSTV.html      |    6 +-
 qsstv/documentation/manual/manual/changelog.html   |   42 +-
 qsstv/documentation/manual/manual/config.png       |  Bin 13929 -> 15212 bytes
 qsstv/documentation/manual/manual/config3.png      |  Bin 41811 -> 52566 bytes
 qsstv/documentation/manual/manual/config4.png      |  Bin 87050 -> 82043 bytes
 qsstv/documentation/manual/manual/config5.png      |  Bin 83564 -> 78350 bytes
 qsstv/documentation/manual/manual/config8.png      |  Bin 64012 -> 72980 bytes
 qsstv/documentation/manual/manual/credits.html     |    9 +-
 qsstv/documentation/manual/manual/editor.html      |    6 +-
 .../documentation/manual/manual/externalprog.html  |    6 +-
 qsstv/documentation/manual/manual/fixdrm.html      |    6 +-
 qsstv/documentation/manual/manual/gallery.html     |   27 +-
 .../manual/manual/gettingstarted.html              |   10 +-
 qsstv/documentation/manual/manual/imagepopup.html  |    6 +-
 qsstv/documentation/manual/manual/index.html       |    8 +-
 .../documentation/manual/manual/installation.html  |    6 +-
 qsstv/documentation/manual/manual/navtreedata.js   |    2 +-
 qsstv/documentation/manual/manual/pages.html       |    4 +-
 qsstv/documentation/manual/manual/receivedrm.png   |  Bin 266130 -> 283367 bytes
 qsstv/documentation/manual/manual/statusbar.html   |    6 +-
 qsstv/documentation/manual/manual/todo1.html       |    6 +-
 qsstv/documentation/manual/manual/transmitdrm.png  |  Bin 347771 -> 295255 bytes
 qsstv/documentation/manual/manual/whatsnew.html    |    8 +-
 qsstv/drmrx/drm.cpp                                |    3 -
 qsstv/drmrx/drm.h                                  |    3 +-
 qsstv/drmrx/drmrx.cpp                              |    1 -
 qsstv/drmrx/drmrx.h                                |    2 -
 qsstv/drmrx/drmstatusframe.ui                      |  399 ++--
 qsstv/drmrx/sourcedecoder.cpp                      |  871 ++++---
 qsstv/drmrx/sourcedecoder.h                        |    8 +-
 qsstv/drmtx/drmtx.cpp                              |  372 ++-
 qsstv/drmtx/drmtx.h                                |   27 +-
 qsstv/dsp/filter.cpp                               |  339 ++-
 qsstv/dsp/filter.h                                 |    3 +-
 qsstv/dsp/filterparam.cpp                          |  140 +-
 qsstv/icons/mgc.raw                                |  Bin 168 -> 0 bytes
 qsstv/icons/mgc2.raw                               |    1 -
 qsstv/mainwidgets/rxfunctions.h                    |    3 -
 qsstv/mainwidgets/rxwidget.cpp                     |   20 +-
 qsstv/mainwidgets/rxwidget.h                       |   10 +-
 qsstv/mainwidgets/rxwidget.ui                      |  814 ++++---
 qsstv/mainwidgets/txfunctions.cpp                  |  225 +-
 qsstv/mainwidgets/txfunctions.h                    |   11 +
 qsstv/mainwidgets/txwidget.cpp                     |  208 +-
 qsstv/mainwidgets/txwidget.h                       |   15 +-
 qsstv/mainwidgets/txwidget.ui                      |  771 +++---
 qsstv/mainwindow.cpp                               |   58 +-
 qsstv/mainwindow.h                                 |    2 +
 qsstv/mainwindow.ui                                |   33 +-
 qsstv/qsstv.pro                                    |    4 +-
 qsstv/qsstv.qrc                                    |    2 -
 qsstv/rig/rigcontrol.cpp                           |    1 -
 qsstv/rig/rigcontrol.h                             |    2 +-
 qsstv/scope/scopeplot.cpp                          |    2 +
 qsstv/sound/soundalsa.cpp                          |   10 +-
 qsstv/sound/wavio.cpp                              |    4 +-
 qsstv/sstv/sstvrx.cpp                              |   19 +-
 qsstv/sstv/sstvrx.h                                |    1 +
 qsstv/sstv/syncprocessor.cpp                       |  129 +-
 qsstv/sstv/syncprocessor.h                         |   10 +-
 qsstv/sstv/visfskid.cpp                            |   23 +-
 qsstv/sstv/visfskid.h                              |    4 +-
 qsstv/utils/ftp.cpp                                |  434 ++--
 qsstv/utils/ftp.h                                  |   16 +-
 qsstv/utils/hybridcrypt.cpp                        |   59 +-
 qsstv/utils/hybridcrypt.h                          |    6 -
 qsstv/utils/jp2io.cpp                              |  501 ++--
 qsstv/utils/logging.h                              |    4 +-
 qsstv/videocapt/cameradialog.cpp                   |   11 +-
 qsstv/widgets/drmsegmentsview.ui                   |   12 +-
 qsstv/widgets/extviewer.cpp                        |    2 +
 qsstv/widgets/fftdisplay.cpp                       |   31 +-
 qsstv/widgets/fftdisplay.h                         |    9 +-
 qsstv/widgets/imageviewer.cpp                      |  846 ++++---
 qsstv/widgets/imageviewer.h                        |   31 +-
 qsstv/widgets/spectrumwidget.cpp                   |    5 +
 qsstv/widgets/spectrumwidget.h                     |    2 +
 qsstv/widgets/vumeter.cpp                          |    1 +
 qsstv_9_1.pro => qsstv_9_2.pro                     |    0
 128 files changed, 6705 insertions(+), 5626 deletions(-)

diff --git a/qsstv/appglobal.cpp b/qsstv/appglobal.cpp
index 7d09e3c..3bfc431 100644
--- a/qsstv/appglobal.cpp
+++ b/qsstv/appglobal.cpp
@@ -5,9 +5,9 @@
 #include <QCursor>
 
 
-const QString MAJORVERSION  = "9.1";
+const QString MAJORVERSION  = "9.2";
 const QString CONFIGVERSION = "9.0";
-const QString MINORVERSION  = ".8";
+const QString MINORVERSION  = ".4";
 const QString LOGVERSION = ("qsstv."+MAJORVERSION+MINORVERSION+".log");
 const QString ORGANIZATION = "ON4QZ";
 const QString APPLICATION  = ("qsstv_" +CONFIGVERSION);
@@ -24,6 +24,12 @@ logFile *logFilePtr;
 configDialog *configDialogPtr;
 
 
+ftpInterface *notifyRXIntf;
+ftpInterface *hybridTxIntf;
+ftpInterface *notifyTXIntf;
+ftpInterface *onlineStatusIntf;
+
+
 
 dispatcher *dispatcherPtr;
 QStatusBar *statusBarPtr;
diff --git a/qsstv/appglobal.h b/qsstv/appglobal.h
index 7ec871e..f11ec08 100644
--- a/qsstv/appglobal.h
+++ b/qsstv/appglobal.h
@@ -15,6 +15,7 @@ class xmlInterface;
 class logBook;
 class dispatcher;
 class fileWatcher;
+class ftpInterface;
 
 enum etransmissionMode {TRXSSTV,TRXDRM,TRXNOMODE};
 
@@ -57,6 +58,10 @@ extern logFile *logFilePtr;
 extern bool useHybrid;
 
 
+extern ftpInterface *notifyRXIntf;
+extern ftpInterface *hybridTxIntf;
+extern ftpInterface *notifyTXIntf;
+extern ftpInterface *onlineStatusIntf;
 
 extern etransmissionMode transmissionModeIndex;  // SSTV , DRM
 
diff --git a/qsstv/config/configdialog.ui b/qsstv/config/configdialog.ui
index c97b795..4e4a02a 100644
--- a/qsstv/config/configdialog.ui
+++ b/qsstv/config/configdialog.ui
@@ -14,16 +14,46 @@
    <string>Configuration</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="spacing">
+    <number>1</number>
+   </property>
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
    <item>
     <widget class="QTabWidget" name="configTabWidget">
      <property name="currentIndex">
-      <number>10</number>
+      <number>2</number>
      </property>
      <widget class="QWidget" name="operatorTab">
       <attribute name="title">
        <string>Operator</string>
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_4">
+       <property name="spacing">
+        <number>1</number>
+       </property>
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
        <item>
         <widget class="operatorConfig" name="operatorWidget" native="true"/>
        </item>
@@ -34,6 +64,21 @@
        <string>Directories</string>
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_3">
+       <property name="spacing">
+        <number>1</number>
+       </property>
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
        <item>
         <widget class="directoriesConfig" name="directoryWidget" native="true"/>
        </item>
@@ -44,6 +89,21 @@
        <string>Gui</string>
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_5">
+       <property name="spacing">
+        <number>1</number>
+       </property>
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
        <item>
         <widget class="guiConfig" name="guiWidget" native="true"/>
        </item>
@@ -54,6 +114,21 @@
        <string>Sound</string>
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_2">
+       <property name="spacing">
+        <number>1</number>
+       </property>
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
        <item>
         <widget class="soundConfig" name="soundWidget" native="true"/>
        </item>
@@ -64,6 +139,21 @@
        <string>CAT</string>
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_6">
+       <property name="spacing">
+        <number>1</number>
+       </property>
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
        <item>
         <widget class="rigConfig" name="catWidget" native="true"/>
        </item>
@@ -74,6 +164,21 @@
        <string>CW</string>
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_7">
+       <property name="spacing">
+        <number>1</number>
+       </property>
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
        <item>
         <widget class="cwConfig" name="cwWidget" native="true"/>
        </item>
@@ -84,6 +189,21 @@
        <string>Repeater</string>
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_8">
+       <property name="spacing">
+        <number>1</number>
+       </property>
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
        <item>
         <widget class="repeaterConfig" name="repeaterWidget" native="true"/>
        </item>
@@ -94,6 +214,21 @@
        <string>FTP</string>
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_9">
+       <property name="spacing">
+        <number>1</number>
+       </property>
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
        <item>
         <widget class="ftpConfig" name="ftpWidget" native="true"/>
        </item>
@@ -104,6 +239,21 @@
        <string>Waterfall</string>
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_10">
+       <property name="spacing">
+        <number>1</number>
+       </property>
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
        <item>
         <widget class="waterfallConfig" name="waterfallWidget" native="true"/>
        </item>
@@ -114,6 +264,21 @@
        <string>Hybrid</string>
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_11">
+       <property name="spacing">
+        <number>1</number>
+       </property>
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
        <item>
         <widget class="hybridConfig" name="hybridWidget" native="true"/>
        </item>
@@ -124,6 +289,21 @@
        <string>Notifications</string>
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_11a">
+       <property name="spacing">
+        <number>1</number>
+       </property>
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
        <item>
         <widget class="hybridNotifyConfig" name="hybridNotifyWidget" native="true"/>
        </item>
@@ -134,6 +314,21 @@
        <string>DRM Profiles</string>
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_12">
+       <property name="spacing">
+        <number>1</number>
+       </property>
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
        <item>
         <widget class="drmProfileConfig" name="drmProfilesWidget" native="true"/>
        </item>
@@ -144,6 +339,21 @@
        <string>Frequencies</string>
       </attribute>
       <layout class="QHBoxLayout" name="horizontalLayout" stretch="0">
+       <property name="spacing">
+        <number>1</number>
+       </property>
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
        <item>
         <widget class="frequencySelectWidget" name="freqSelectWidget" native="true"/>
        </item>
diff --git a/qsstv/config/cwconfig.ui b/qsstv/config/cwconfig.ui
index eca045a..16228a1 100644
--- a/qsstv/config/cwconfig.ui
+++ b/qsstv/config/cwconfig.ui
@@ -6,14 +6,29 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>539</width>
-    <height>357</height>
+    <width>482</width>
+    <height>182</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Dialog</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="spacing">
+    <number>1</number>
+   </property>
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
    <item>
     <layout class="QHBoxLayout" name="_3">
      <property name="spacing">
diff --git a/qsstv/config/directoriesconfig.ui b/qsstv/config/directoriesconfig.ui
index 6b7610e..40a8fc3 100644
--- a/qsstv/config/directoriesconfig.ui
+++ b/qsstv/config/directoriesconfig.ui
@@ -14,6 +14,21 @@
    <string>Dialog</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="spacing">
+    <number>1</number>
+   </property>
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
    <item>
     <layout class="QHBoxLayout" name="_2">
      <property name="spacing">
diff --git a/qsstv/config/drmprofileconfig.ui b/qsstv/config/drmprofileconfig.ui
index c80d6d4..5d8984f 100644
--- a/qsstv/config/drmprofileconfig.ui
+++ b/qsstv/config/drmprofileconfig.ui
@@ -15,21 +15,45 @@
   </property>
   <layout class="QVBoxLayout" name="verticalLayout_2">
    <property name="spacing">
-    <number>2</number>
-   </property>
-   <property name="margin">
     <number>1</number>
    </property>
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
    <item>
     <widget class="QTabWidget" name="tabWidget">
      <property name="currentIndex">
-      <number>0</number>
+      <number>2</number>
      </property>
      <widget class="QWidget" name="Profile1">
       <attribute name="title">
        <string>Profile 1</string>
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_4">
+       <property name="spacing">
+        <number>1</number>
+       </property>
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
        <item>
         <layout class="QHBoxLayout" name="horizontalLayout">
          <item>
@@ -46,6 +70,12 @@
        </item>
        <item>
         <layout class="QGridLayout" name="gridLayout">
+         <property name="horizontalSpacing">
+          <number>6</number>
+         </property>
+         <property name="verticalSpacing">
+          <number>1</number>
+         </property>
          <item row="0" column="0">
           <widget class="QLabel" name="drmModeLabel">
            <property name="minimumSize">
@@ -278,6 +308,21 @@
        <string>Profile 2</string>
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_3">
+       <property name="spacing">
+        <number>1</number>
+       </property>
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
        <item>
         <layout class="QHBoxLayout" name="horizontalLayout_2">
          <item>
@@ -294,6 +339,9 @@
        </item>
        <item>
         <layout class="QGridLayout" name="gridLayout_2">
+         <property name="verticalSpacing">
+          <number>1</number>
+         </property>
          <item row="0" column="0">
           <widget class="QLabel" name="drmModeLabel_2">
            <property name="minimumSize">
@@ -526,6 +574,21 @@
        <string>Profile 3</string>
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout">
+       <property name="spacing">
+        <number>1</number>
+       </property>
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
        <item>
         <layout class="QHBoxLayout" name="horizontalLayout_3">
          <item>
@@ -542,6 +605,9 @@
        </item>
        <item>
         <layout class="QGridLayout" name="gridLayout_3">
+         <property name="verticalSpacing">
+          <number>1</number>
+         </property>
          <item row="0" column="0">
           <widget class="QLabel" name="drmModeLabel_3">
            <property name="minimumSize">
diff --git a/qsstv/config/frequencyselectwidget.ui b/qsstv/config/frequencyselectwidget.ui
index 699a1dd..850555e 100644
--- a/qsstv/config/frequencyselectwidget.ui
+++ b/qsstv/config/frequencyselectwidget.ui
@@ -14,6 +14,21 @@
    <string>Form</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout" stretch="2,0">
+   <property name="spacing">
+    <number>1</number>
+   </property>
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0,0,0">
      <item>
diff --git a/qsstv/config/ftpconfig.cpp b/qsstv/config/ftpconfig.cpp
index 8f23c71..7491310 100644
--- a/qsstv/config/ftpconfig.cpp
+++ b/qsstv/config/ftpconfig.cpp
@@ -137,6 +137,7 @@ void ftpConfig::setParams()
 void ftpConfig::slotTestFTPPushButton()
 {
   QString r1,r2;
+  QApplication::setOverrideCursor(Qt::WaitCursor);
   ftpInterface fInt("TestUploadConnection");
   ui->testFTPPushButton->setDisabled(true);
   getParams();
@@ -145,7 +146,8 @@ void ftpConfig::slotTestFTPPushButton()
   fInt.init();
   fInt.setupConnection(ftpRemoteHost,ftpPort,ftpLogin,ftpPassword,ftpRemoteDRMDirectory);
   r2=fInt.execFTPTest();
+  QApplication::restoreOverrideCursor();
   ui->testFTPPushButton->setDisabled(false);
-  QMessageBox::information(this,"Testing Connection","test",QString("SSTV: %1\nDRM: %2").arg(r1).arg(r2));
+  QMessageBox::information(this,"Testing Connection","",QString("SSTV: %1\nDRM: %2").arg(r1).arg(r2));
 }
 
diff --git a/qsstv/config/ftpconfig.ui b/qsstv/config/ftpconfig.ui
index 5218a9d..d80bef1 100644
--- a/qsstv/config/ftpconfig.ui
+++ b/qsstv/config/ftpconfig.ui
@@ -13,13 +13,37 @@
   <property name="windowTitle">
    <string>Form</string>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
+  <layout class="QVBoxLayout" name="verticalLayout_2">
+   <property name="spacing">
+    <number>1</number>
+   </property>
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
    <item>
     <layout class="QHBoxLayout" name="_2">
      <property name="spacing">
       <number>6</number>
      </property>
-     <property name="margin">
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
       <number>0</number>
      </property>
      <item>
@@ -120,7 +144,16 @@
      <property name="spacing">
       <number>6</number>
      </property>
-     <property name="margin">
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
       <number>0</number>
      </property>
      <item>
@@ -171,7 +204,16 @@
      <property name="spacing">
       <number>6</number>
      </property>
-     <property name="margin">
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
       <number>0</number>
      </property>
      <item>
@@ -222,7 +264,16 @@
      <property name="spacing">
       <number>6</number>
      </property>
-     <property name="margin">
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
       <number>0</number>
      </property>
      <item>
@@ -277,7 +328,16 @@
      <property name="spacing">
       <number>6</number>
      </property>
-     <property name="margin">
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
       <number>0</number>
      </property>
      <item>
@@ -328,7 +388,16 @@
      <property name="spacing">
       <number>6</number>
      </property>
-     <property name="margin">
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
       <number>0</number>
      </property>
      <item>
@@ -375,60 +444,75 @@
     </layout>
    </item>
    <item>
-    <widget class="QGroupBox" name="groupBox">
-     <property name="title">
-      <string>Image store</string>
-     </property>
-     <layout class="QVBoxLayout" name="verticalLayout_2">
-      <item>
-       <layout class="QHBoxLayout" name="horizontalLayout_3">
+    <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <item>
+      <widget class="QGroupBox" name="groupBox">
+       <property name="title">
+        <string>Image store</string>
+       </property>
+       <layout class="QVBoxLayout" name="verticalLayout">
+        <property name="spacing">
+         <number>1</number>
+        </property>
+        <property name="leftMargin">
+         <number>0</number>
+        </property>
+        <property name="topMargin">
+         <number>0</number>
+        </property>
+        <property name="rightMargin">
+         <number>0</number>
+        </property>
+        <property name="bottomMargin">
+         <number>0</number>
+        </property>
         <item>
-         <widget class="QRadioButton" name="imageRadioButton">
-          <property name="text">
-           <string>image1 to image</string>
-          </property>
-         </widget>
+         <layout class="QHBoxLayout" name="horizontalLayout_2">
+          <item>
+           <widget class="QRadioButton" name="imageRadioButton">
+            <property name="text">
+             <string>image1 to image</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QSpinBox" name="ftpNumImagesSpinBox">
+            <property name="minimum">
+             <number>1</number>
+            </property>
+            <property name="maximum">
+             <number>50</number>
+            </property>
+            <property name="value">
+             <number>30</number>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer name="horizontalSpacer">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>40</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+         </layout>
         </item>
         <item>
-         <widget class="QSpinBox" name="ftpNumImagesSpinBox">
-          <property name="minimum">
-           <number>1</number>
-          </property>
-          <property name="maximum">
-           <number>50</number>
-          </property>
-          <property name="value">
-           <number>30</number>
+         <widget class="QRadioButton" name="filenameRadioButton">
+          <property name="text">
+           <string>filename</string>
           </property>
          </widget>
         </item>
-        <item>
-         <spacer name="horizontalSpacer">
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>40</width>
-            <height>20</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
        </layout>
-      </item>
-      <item>
-       <widget class="QRadioButton" name="filenameRadioButton">
-        <property name="text">
-         <string>filename</string>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0">
+      </widget>
+     </item>
      <item>
       <widget class="QLabel" name="label_2">
        <property name="text">
@@ -439,6 +523,23 @@
        </property>
       </widget>
      </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0">
+     <item>
+      <spacer name="horizontalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
      <item>
       <widget class="QPushButton" name="testFTPPushButton">
        <property name="text">
@@ -446,6 +547,19 @@
        </property>
       </widget>
      </item>
+     <item>
+      <spacer name="horizontalSpacer_3">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
     </layout>
    </item>
    <item>
diff --git a/qsstv/config/guiconfig.cpp b/qsstv/config/guiconfig.cpp
index 96cc46b..5ef1abd 100644
--- a/qsstv/config/guiconfig.cpp
+++ b/qsstv/config/guiconfig.cpp
@@ -10,6 +10,7 @@ bool imageStretch;
 QColor backGroundColor;
 QColor imageBackGroundColor;
 bool slowCPU;
+bool lowRes;
 
 guiConfig::guiConfig(QWidget *parent) : baseConfig(parent),  ui(new Ui::guiConfig)
 {
@@ -34,6 +35,7 @@ void guiConfig::readSettings()
   backGroundColor=qSettings.value("backGroundColor",QColor(128,128,128)).value<QColor>();
   imageBackGroundColor=qSettings.value("imageBackGroundColor",QColor(0,0,128)).value<QColor>();
   slowCPU=qSettings.value("slowCPU",false).toBool();
+  lowRes=qSettings.value("lowRes",false).toBool();
   qSettings.endGroup();
   setParams();
 }
@@ -49,6 +51,7 @@ void guiConfig::writeSettings()
   qSettings.setValue("backGroundColor",backGroundColor);
   qSettings.setValue("imageBackGroundColor",imageBackGroundColor);
   qSettings.setValue("slowCPU",slowCPU);
+  qSettings.setValue("lowRes",lowRes);
   qSettings.endGroup();
 }
 
@@ -63,6 +66,7 @@ void guiConfig::getParams()
     changed=true;
   getValue(imageStretch,ui->stretchCheckBox);
   getValue(slowCPU,ui->slowCPUCheckBox);
+  getValue(lowRes,ui->lowResCheckBox);
 }
 
 void guiConfig::setParams()
@@ -73,6 +77,7 @@ void guiConfig::setParams()
   setColorLabel(backGroundColor,false);
   setColorLabel(imageBackGroundColor,true);
   setValue(slowCPU,ui->slowCPUCheckBox);
+  setValue(lowRes,ui->lowResCheckBox);
 }
 
 
diff --git a/qsstv/config/guiconfig.h b/qsstv/config/guiconfig.h
index 41cb178..b0e8971 100644
--- a/qsstv/config/guiconfig.h
+++ b/qsstv/config/guiconfig.h
@@ -11,6 +11,7 @@ extern QString defaultImageFormat;
 extern QColor backGroundColor;
 extern QColor imageBackGroundColor;
 extern bool slowCPU;
+extern bool lowRes;
 
 namespace Ui
 {
diff --git a/qsstv/config/guiconfig.ui b/qsstv/config/guiconfig.ui
index 7de332a..a48b7e3 100644
--- a/qsstv/config/guiconfig.ui
+++ b/qsstv/config/guiconfig.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>578</width>
-    <height>484</height>
+    <width>548</width>
+    <height>446</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -15,182 +15,251 @@
   </property>
   <layout class="QVBoxLayout" name="verticalLayout_5">
    <item>
-    <layout class="QHBoxLayout" name="horizontalLayout_2">
+    <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
-      <layout class="QVBoxLayout" name="verticalLayout_3">
-       <item>
-        <widget class="QGroupBox" name="groupBox_2">
-         <property name="title">
-          <string>Images</string>
-         </property>
-         <layout class="QVBoxLayout" name="verticalLayout_2">
-          <item>
-           <layout class="QGridLayout" name="gridLayout_2">
-            <item row="1" column="0">
-             <widget class="QPushButton" name="backgroundColorPushButton">
-              <property name="text">
-               <string>Background Color</string>
-              </property>
-             </widget>
-            </item>
-            <item row="0" column="0">
-             <widget class="QCheckBox" name="stretchCheckBox">
-              <property name="layoutDirection">
-               <enum>Qt::RightToLeft</enum>
-              </property>
-              <property name="text">
-               <string>Stretch</string>
-              </property>
-             </widget>
-            </item>
-            <item row="2" column="0">
-             <widget class="QPushButton" name="imageBackgroundColorPushButton">
-              <property name="text">
-               <string>Image Background color</string>
-              </property>
-             </widget>
-            </item>
-            <item row="1" column="1">
-             <widget class="QLabel" name="backGroundColorLabel">
-              <property name="minimumSize">
-               <size>
-                <width>60</width>
-                <height>0</height>
-               </size>
-              </property>
-              <property name="autoFillBackground">
-               <bool>true</bool>
-              </property>
-              <property name="frameShape">
-               <enum>QFrame::Box</enum>
-              </property>
-              <property name="frameShadow">
-               <enum>QFrame::Sunken</enum>
-              </property>
-              <property name="lineWidth">
-               <number>3</number>
-              </property>
-              <property name="text">
-               <string/>
-              </property>
-             </widget>
-            </item>
-            <item row="2" column="1">
-             <widget class="QLabel" name="imageBackGroundColorLabel">
-              <property name="minimumSize">
-               <size>
-                <width>60</width>
-                <height>0</height>
-               </size>
-              </property>
-              <property name="autoFillBackground">
-               <bool>true</bool>
-              </property>
-              <property name="frameShape">
-               <enum>QFrame::Box</enum>
-              </property>
-              <property name="frameShadow">
-               <enum>QFrame::Sunken</enum>
-              </property>
-              <property name="lineWidth">
-               <number>3</number>
-              </property>
-              <property name="text">
-               <string/>
-              </property>
-             </widget>
-            </item>
-           </layout>
+      <widget class="QGroupBox" name="groupBox_2">
+       <property name="title">
+        <string>Images</string>
+       </property>
+       <layout class="QVBoxLayout" name="verticalLayout_2">
+        <property name="spacing">
+         <number>1</number>
+        </property>
+        <property name="leftMargin">
+         <number>0</number>
+        </property>
+        <property name="topMargin">
+         <number>0</number>
+        </property>
+        <property name="rightMargin">
+         <number>0</number>
+        </property>
+        <property name="bottomMargin">
+         <number>0</number>
+        </property>
+        <item>
+         <layout class="QGridLayout" name="gridLayout_2">
+          <item row="1" column="0">
+           <widget class="QPushButton" name="backgroundColorPushButton">
+            <property name="text">
+             <string>Background Color</string>
+            </property>
+           </widget>
           </item>
-         </layout>
-        </widget>
-       </item>
-       <item>
-        <widget class="QGroupBox" name="groupBox">
-         <property name="title">
-          <string>Gallery</string>
-         </property>
-         <layout class="QVBoxLayout" name="verticalLayout">
-          <item>
-           <layout class="QGridLayout" name="gridLayout">
-            <item row="0" column="0">
-             <widget class="QLabel" name="label">
-              <property name="text">
-               <string>Rows</string>
-              </property>
-             </widget>
-            </item>
-            <item row="1" column="1">
-             <widget class="QSpinBox" name="columnsSpinBox"/>
-            </item>
-            <item row="0" column="1">
-             <widget class="QSpinBox" name="rowsSpinBox"/>
-            </item>
-            <item row="1" column="0">
-             <widget class="QLabel" name="label_2">
-              <property name="text">
-               <string>Columns</string>
-              </property>
-             </widget>
-            </item>
-           </layout>
+          <item row="0" column="0">
+           <widget class="QCheckBox" name="stretchCheckBox">
+            <property name="layoutDirection">
+             <enum>Qt::RightToLeft</enum>
+            </property>
+            <property name="text">
+             <string>Stretch</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="0">
+           <widget class="QPushButton" name="imageBackgroundColorPushButton">
+            <property name="text">
+             <string>Image Background color</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QLabel" name="backGroundColorLabel">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="autoFillBackground">
+             <bool>true</bool>
+            </property>
+            <property name="frameShape">
+             <enum>QFrame::Box</enum>
+            </property>
+            <property name="frameShadow">
+             <enum>QFrame::Sunken</enum>
+            </property>
+            <property name="lineWidth">
+             <number>3</number>
+            </property>
+            <property name="text">
+             <string/>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="1">
+           <widget class="QLabel" name="imageBackGroundColorLabel">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="autoFillBackground">
+             <bool>true</bool>
+            </property>
+            <property name="frameShape">
+             <enum>QFrame::Box</enum>
+            </property>
+            <property name="frameShadow">
+             <enum>QFrame::Sunken</enum>
+            </property>
+            <property name="lineWidth">
+             <number>3</number>
+            </property>
+            <property name="text">
+             <string/>
+            </property>
+           </widget>
           </item>
          </layout>
-        </widget>
-       </item>
-       <item>
-        <widget class="QGroupBox" name="groupBox_3">
-         <property name="title">
-          <string>Performance</string>
-         </property>
-         <layout class="QVBoxLayout" name="verticalLayout_4">
-          <item>
-           <layout class="QHBoxLayout" name="horizontalLayout">
-            <item>
-             <widget class="QCheckBox" name="slowCPUCheckBox">
-              <property name="layoutDirection">
-               <enum>Qt::RightToLeft</enum>
-              </property>
-              <property name="text">
-               <string>Check if slow CPU</string>
-              </property>
-             </widget>
-            </item>
-            <item>
-             <spacer name="horizontalSpacer_2">
-              <property name="orientation">
-               <enum>Qt::Horizontal</enum>
-              </property>
-              <property name="sizeHint" stdset="0">
-               <size>
-                <width>40</width>
-                <height>20</height>
-               </size>
-              </property>
-             </spacer>
-            </item>
-           </layout>
+        </item>
+       </layout>
+      </widget>
+     </item>
+     <item>
+      <widget class="QGroupBox" name="groupBox">
+       <property name="title">
+        <string>Gallery</string>
+       </property>
+       <layout class="QVBoxLayout" name="verticalLayout">
+        <property name="spacing">
+         <number>1</number>
+        </property>
+        <property name="leftMargin">
+         <number>0</number>
+        </property>
+        <property name="topMargin">
+         <number>0</number>
+        </property>
+        <property name="rightMargin">
+         <number>0</number>
+        </property>
+        <property name="bottomMargin">
+         <number>0</number>
+        </property>
+        <item>
+         <layout class="QGridLayout" name="gridLayout">
+          <item row="0" column="0">
+           <widget class="QLabel" name="label">
+            <property name="text">
+             <string>Rows</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QSpinBox" name="columnsSpinBox"/>
+          </item>
+          <item row="0" column="1">
+           <widget class="QSpinBox" name="rowsSpinBox"/>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLabel" name="label_2">
+            <property name="text">
+             <string>Columns</string>
+            </property>
+           </widget>
           </item>
          </layout>
-        </widget>
-       </item>
-      </layout>
+        </item>
+       </layout>
+      </widget>
      </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QLabel" name="label_3">
+     <property name="text">
+      <string>Exit and restart QSSTV If slow CPU or Low Resolution has changed.</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
      <item>
-      <spacer name="horizontalSpacer">
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+      <widget class="QGroupBox" name="groupBox_3">
+       <property name="title">
+        <string>Performance</string>
        </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>40</width>
-         <height>20</height>
-        </size>
+       <layout class="QVBoxLayout" name="verticalLayout_3">
+        <property name="spacing">
+         <number>1</number>
+        </property>
+        <property name="leftMargin">
+         <number>0</number>
+        </property>
+        <property name="topMargin">
+         <number>0</number>
+        </property>
+        <property name="rightMargin">
+         <number>0</number>
+        </property>
+        <property name="bottomMargin">
+         <number>0</number>
+        </property>
+        <item>
+         <widget class="QCheckBox" name="slowCPUCheckBox">
+          <property name="layoutDirection">
+           <enum>Qt::LeftToRight</enum>
+          </property>
+          <property name="text">
+           <string>Check if slow CPU</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+     </item>
+     <item>
+      <widget class="QGroupBox" name="groupBox_4">
+       <property name="title">
+        <string>Resolution</string>
        </property>
-      </spacer>
+       <layout class="QVBoxLayout" name="verticalLayout_4">
+        <property name="spacing">
+         <number>1</number>
+        </property>
+        <property name="leftMargin">
+         <number>0</number>
+        </property>
+        <property name="topMargin">
+         <number>0</number>
+        </property>
+        <property name="rightMargin">
+         <number>0</number>
+        </property>
+        <property name="bottomMargin">
+         <number>0</number>
+        </property>
+        <item>
+         <widget class="QCheckBox" name="lowResCheckBox">
+          <property name="layoutDirection">
+           <enum>Qt::LeftToRight</enum>
+          </property>
+          <property name="text">
+           <string>Check if Low Screen Resolution</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </widget>
      </item>
     </layout>
    </item>
+   <item>
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>238</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
   </layout>
  </widget>
  <resources/>
diff --git a/qsstv/config/hybridconfig.cpp b/qsstv/config/hybridconfig.cpp
index 34971d2..35e1cc1 100644
--- a/qsstv/config/hybridconfig.cpp
+++ b/qsstv/config/hybridconfig.cpp
@@ -6,7 +6,7 @@
 #include <QMessageBox>
 
 bool enableHybridRx;
-bool enableSpecialServer;
+//bool enableSpecialServer;
 int hybridFtpPort;
 QString hybridFtpRemoteHost;
 QString hybridFtpRemoteDirectory;
@@ -32,7 +32,7 @@ void hybridConfig::readSettings()
     QSettings qSettings;
     qSettings.beginGroup("HYBRID");
     enableHybridRx=qSettings.value("enableHybridRx",true).toBool();
-    enableSpecialServer=qSettings.value("enableSpecialServer",false).toBool();
+//    enableSpecialServer=qSettings.value("enableSpecialServer",false).toBool();
     hybridFtpPort=qSettings.value("hybridFtpPort",21).toInt();
     hybridFtpRemoteHost=qSettings.value("hybridFtpRemoteHost","").toString();
     hybridFtpRemoteDirectory=qSettings.value("hybridFtpRemoteDirectory","").toString();
@@ -50,7 +50,7 @@ void hybridConfig::writeSettings()
     getParams();
     qSettings.beginGroup("HYBRID");
     qSettings.setValue("enableHybridRx",enableHybridRx);
-    qSettings.setValue("enableSpecialServer",enableSpecialServer);
+//    qSettings.setValue("enableSpecialServer",enableSpecialServer);
     qSettings.setValue("hybridFtpPort",hybridFtpPort);
     qSettings.setValue("hybridFtpRemoteHost",hybridFtpRemoteHost);
     qSettings.setValue("hybridFtpRemoteDirectory",hybridFtpRemoteDirectory);
@@ -63,7 +63,7 @@ void hybridConfig::writeSettings()
 void hybridConfig::getParams()
 {
     bool enableHybridRxCopy=enableHybridRx;
-    bool enableSpecialServerCopy=enableSpecialServer;
+//    bool enableSpecialServerCopy=enableSpecialServer;
     int hybridFtpPortCopy=hybridFtpPort;
     QString hybridFtpRemoteHostCopy=hybridFtpRemoteHost;
     QString hybridFtpRemoteDirectoryCopy=hybridFtpRemoteDirectory;
@@ -72,7 +72,7 @@ void hybridConfig::getParams()
 
 
     getValue(enableHybridRx,ui->enableHybridRxCheckBox);
-    getValue(enableSpecialServer,ui->enableSpecialServerCheckBox);
+//    getValue(enableSpecialServer,ui->enableSpecialServerCheckBox);
     getValue(hybridFtpPort,ui->hybridFtpPortSpinBox);
     getValue(hybridFtpRemoteHost,ui->hybridRemoteHostLineEdit);
     getValue(hybridFtpRemoteDirectory,ui->hybridRemoteDirectoryLineEdit);
@@ -81,7 +81,7 @@ void hybridConfig::getParams()
     getValue(hybridFtpHybridFilesDirectory,ui->hybridFilesDirectoryLineEdit);
     changed=false;
     if(  enableHybridRxCopy!=enableHybridRx
-         || enableSpecialServerCopy!=enableSpecialServer
+//         || enableSpecialServerCopy!=enableSpecialServer
          || hybridFtpPortCopy!=hybridFtpPort
          || hybridFtpRemoteHostCopy!=hybridFtpRemoteHost
          || hybridFtpRemoteDirectoryCopy!=hybridFtpRemoteDirectory
@@ -97,7 +97,7 @@ void hybridConfig::getParams()
 void hybridConfig::setParams()
 {
     setValue(enableHybridRx,ui->enableHybridRxCheckBox);
-    setValue(enableSpecialServer,ui->enableSpecialServerCheckBox);
+//    setValue(enableSpecialServer,ui->enableSpecialServerCheckBox);
     setValue(hybridFtpPort,ui->hybridFtpPortSpinBox);
     setValue(hybridFtpRemoteHost,ui->hybridRemoteHostLineEdit);
     setValue(hybridFtpRemoteDirectory,ui->hybridRemoteDirectoryLineEdit);
@@ -113,8 +113,8 @@ void hybridConfig::slotTestHybridPushButton()
     ftpInterface fInt("TestHybridConnection");
     ui->testHybridPushButton->setDisabled(true);
     getParams();
-    hybridCrypt hc;
-    fInt.setupConnection(hc.host(),hc.port(),hc.user(),hc.passwd(),hc.dir()+"/"+hybridFtpHybridFilesDirectory);
+    fInt.setupConnection(hybridFtpRemoteHost,hybridFtpPort,hybridFtpLogin,hybridFtpPassword,hybridFtpRemoteDirectory+"/"+hybridFtpHybridFilesDirectory);
+//    fInt.setupConnection(hc.host(),hc.port(),hc.user(),hc.passwd(),hc.dir()+"/"+hybridFtpHybridFilesDirectory);
     msg=fInt.execFTPTest();
     ui->testHybridPushButton->setDisabled(false);
     QMessageBox::information(this,"Test Connection",msg);
diff --git a/qsstv/config/hybridconfig.h b/qsstv/config/hybridconfig.h
index a287ea4..c80a7c1 100644
--- a/qsstv/config/hybridconfig.h
+++ b/qsstv/config/hybridconfig.h
@@ -4,7 +4,7 @@
 #include "baseconfig.h"
 
 extern bool enableHybridRx;
-extern bool enableSpecialServer;
+//extern bool enableSpecialServer;
 extern int hybridFtpPort;
 extern QString hybridFtpRemoteHost;
 extern QString hybridFtpRemoteDirectory;
diff --git a/qsstv/config/hybridconfig.ui b/qsstv/config/hybridconfig.ui
index 6168911..1885033 100644
--- a/qsstv/config/hybridconfig.ui
+++ b/qsstv/config/hybridconfig.ui
@@ -15,36 +15,11 @@
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
-    <widget class="QCheckBox" name="enableHybridRxCheckBox">
-     <property name="text">
-      <string>Enable Reception in Hybrid Mode </string>
-     </property>
-     <property name="checked">
-      <bool>true</bool>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="_3">
-     <property name="spacing">
-      <number>6</number>
-     </property>
-     <property name="leftMargin">
-      <number>0</number>
-     </property>
-     <property name="topMargin">
-      <number>0</number>
-     </property>
-     <property name="rightMargin">
-      <number>0</number>
-     </property>
-     <property name="bottomMargin">
-      <number>0</number>
-     </property>
+    <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
-      <widget class="QCheckBox" name="enableSpecialServerCheckBox">
+      <widget class="QCheckBox" name="enableHybridRxCheckBox">
        <property name="text">
-        <string>Enable Special Server</string>
+        <string>Enable Reception in Hybrid Mode </string>
        </property>
        <property name="checked">
         <bool>true</bool>
@@ -79,6 +54,9 @@
      </item>
      <item>
       <widget class="QSpinBox" name="hybridFtpPortSpinBox">
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
        <property name="minimum">
         <number>1</number>
        </property>
@@ -413,16 +391,19 @@
     </layout>
    </item>
    <item>
-    <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,0">
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
      <item>
-      <widget class="QLabel" name="label">
-       <property name="text">
-        <string>By default all hybrid files are uploaded to a default server ("Enable Special Server"  not checked). If you wish to use your own server for sending in Hybrid mode then  you need to check "Enable Special Server" and fill in the details. See manual for more information.</string>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
        </property>
-       <property name="wordWrap">
-        <bool>true</bool>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
        </property>
-      </widget>
+      </spacer>
      </item>
      <item>
       <widget class="QPushButton" name="testHybridPushButton">
@@ -431,6 +412,19 @@
        </property>
       </widget>
      </item>
+     <item>
+      <spacer name="horizontalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
     </layout>
    </item>
    <item>
diff --git a/qsstv/config/hybridnotifyconfig.cpp b/qsstv/config/hybridnotifyconfig.cpp
index dc68b6c..67b8c42 100644
--- a/qsstv/config/hybridnotifyconfig.cpp
+++ b/qsstv/config/hybridnotifyconfig.cpp
@@ -5,7 +5,7 @@
 #include <QMessageBox>
 
 bool enableHybridNotify;
-bool enableHybridNotifySpecialServer;
+bool enableHybridNotifySnoop;
 int hybridNotifyPort;
 QString hybridNotifyRemoteHost;
 QString hybridNotifyRemoteDir;
@@ -31,7 +31,7 @@ void hybridNotifyConfig::readSettings()
   QSettings qSettings;
   qSettings.beginGroup("HYBRID_NOTIFY");
   enableHybridNotify=qSettings.value("enableHybridNotify",true).toBool();
-  enableHybridNotifySpecialServer=qSettings.value("enableHybridNotifySpecialServer",false).toBool();
+  enableHybridNotifySnoop=qSettings.value("enableHybridNotifySnoop",true).toBool();
   hybridNotifyPort=qSettings.value("hybridNotifyPort",21).toInt();
   hybridNotifyRemoteHost=qSettings.value("hybridNotifyRemoteHost","").toString();
   hybridNotifyRemoteDir=qSettings.value("hybridNotifyRemoteDir","").toString();
@@ -49,7 +49,7 @@ void hybridNotifyConfig::writeSettings()
   getParams();
   qSettings.beginGroup("HYBRID_NOTIFY");
   qSettings.setValue("enableHybridNotify",enableHybridNotify);
-  qSettings.setValue("enableHybridNotifySpecialServer",enableHybridNotifySpecialServer);
+  qSettings.setValue("enableHybridNotifySnoop",enableHybridNotifySnoop);
   qSettings.setValue("hybridNotifyPort",hybridNotifyPort);
   qSettings.setValue("hybridNotifyRemoteHost",hybridNotifyRemoteHost);
   qSettings.setValue("hybridNotifyRemoteDir",hybridNotifyRemoteDir);
@@ -62,7 +62,7 @@ void hybridNotifyConfig::writeSettings()
 void hybridNotifyConfig::getParams()
 {
   bool enableHybridNotifyCopy=enableHybridNotify;
-  bool enableHybridNotifySpecialServerCopy=enableHybridNotifySpecialServer;
+  bool enableHybridNotifySnoopCopy=enableHybridNotifySnoop;
   int hybridNotifyPortCopy=hybridNotifyPort;
   QString hybridNotifyRemoteHostCopy=hybridNotifyRemoteHost;
   QString hybridNotifyRemoteDirCopy=hybridNotifyRemoteDir;
@@ -72,7 +72,7 @@ void hybridNotifyConfig::getParams()
 
 
   getValue(enableHybridNotify,ui->enableHybridNotifyCheckBox);
-  getValue(enableHybridNotifySpecialServer,ui->enableHybridNotifySpecialServerCheckBox);
+  getValue(enableHybridNotifySnoop,ui->enableHybridNotifySnoopCheckBox);
   getValue(hybridNotifyPort,ui->hybridNotifyPortSpinBox);
   getValue(hybridNotifyRemoteHost,ui->hybridNotifyRemoteHostLineEdit);
   getValue(hybridNotifyRemoteDir,ui->hybridNotifyRemoteDirLineEdit);
@@ -81,7 +81,7 @@ void hybridNotifyConfig::getParams()
   getValue(hybridNotifyDir,ui->hybridNotifyDirLineEdit);
   changed=false;
   if(  enableHybridNotifyCopy!=enableHybridNotify
-       || enableHybridNotifySpecialServerCopy!=enableHybridNotifySpecialServer
+       || enableHybridNotifySnoopCopy!=enableHybridNotifySnoop
        || hybridNotifyPortCopy!=hybridNotifyPort
        || hybridNotifyRemoteHostCopy!=hybridNotifyRemoteHost
        || hybridNotifyRemoteDirCopy!=hybridNotifyRemoteDir
@@ -98,7 +98,7 @@ void hybridNotifyConfig::getParams()
 void hybridNotifyConfig::setParams()
 {
   setValue(enableHybridNotify,ui->enableHybridNotifyCheckBox);
-  setValue(enableHybridNotifySpecialServer,ui->enableHybridNotifySpecialServerCheckBox);
+  setValue(enableHybridNotifySnoop,ui->enableHybridNotifySnoopCheckBox);
   setValue(hybridNotifyPort,ui->hybridNotifyPortSpinBox);
   setValue(hybridNotifyRemoteHost,ui->hybridNotifyRemoteHostLineEdit);
   setValue(hybridNotifyRemoteDir,ui->hybridNotifyRemoteDirLineEdit);
diff --git a/qsstv/config/hybridnotifyconfig.h b/qsstv/config/hybridnotifyconfig.h
index 74b0911..41f42d9 100644
--- a/qsstv/config/hybridnotifyconfig.h
+++ b/qsstv/config/hybridnotifyconfig.h
@@ -4,7 +4,7 @@
 #include "baseconfig.h"
 
 extern bool enableHybridNotify;
-extern bool enableHybridNotifySpecialServer;
+extern bool enableHybridNotifySnoop;
 extern int hybridNotifyPort;
 extern QString hybridNotifyRemoteHost;
 extern QString hybridNotifyRemoteDir;
diff --git a/qsstv/config/hybridnotifyconfig.ui b/qsstv/config/hybridnotifyconfig.ui
index d2df05c..9cfdd7c 100644
--- a/qsstv/config/hybridnotifyconfig.ui
+++ b/qsstv/config/hybridnotifyconfig.ui
@@ -6,45 +6,35 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>730</width>
-    <height>372</height>
+    <width>806</width>
+    <height>388</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="spacing">
+    <number>1</number>
+   </property>
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
    <item>
-    <widget class="QCheckBox" name="enableHybridNotifyCheckBox">
-     <property name="text">
-      <string>Enable Notifications in Hybrid Mode </string>
-     </property>
-     <property name="checked">
-      <bool>true</bool>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="_3">
-     <property name="spacing">
-      <number>6</number>
-     </property>
-     <property name="leftMargin">
-      <number>0</number>
-     </property>
-     <property name="topMargin">
-      <number>0</number>
-     </property>
-     <property name="rightMargin">
-      <number>0</number>
-     </property>
-     <property name="bottomMargin">
-      <number>0</number>
-     </property>
+    <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
-      <widget class="QCheckBox" name="enableHybridNotifySpecialServerCheckBox">
+      <widget class="QCheckBox" name="enableHybridNotifyCheckBox">
        <property name="text">
-        <string>Enable Special Server</string>
+        <string>Send RX Notifications in Hybrid Mode</string>
        </property>
        <property name="checked">
         <bool>true</bool>
@@ -52,6 +42,26 @@
       </widget>
      </item>
      <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QCheckBox" name="enableHybridNotifySnoopCheckBox">
+       <property name="text">
+        <string>Check who else got it</string>
+       </property>
+      </widget>
+     </item>
+     <item>
       <spacer>
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
@@ -61,8 +71,8 @@
        </property>
        <property name="sizeHint" stdset="0">
         <size>
-         <width>20</width>
-         <height>20</height>
+         <width>28</width>
+         <height>24</height>
         </size>
        </property>
       </spacer>
@@ -79,6 +89,9 @@
      </item>
      <item>
       <widget class="QSpinBox" name="hybridNotifyPortSpinBox">
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
        <property name="minimum">
         <number>1</number>
        </property>
@@ -90,22 +103,6 @@
        </property>
       </widget>
      </item>
-     <item>
-      <spacer>
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeType">
-        <enum>QSizePolicy::Preferred</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>20</width>
-         <height>20</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
     </layout>
    </item>
    <item>
@@ -413,16 +410,19 @@
     </layout>
    </item>
    <item>
-    <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,0">
+    <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,0,0">
      <item>
-      <widget class="QLabel" name="label">
-       <property name="text">
-        <string><html><head/><body><p>By default all RxNotification files are uploaded to a default server (&quot;Enable Special Server&quot;  not checked). If you wish to use your own server for RxNotifications in Hybrid mode then  you need to check &quot;Enable Special Server&quot; and fill in the details. See manual for more information.</p></body></html></string>
+      <spacer name="horizontalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
        </property>
-       <property name="wordWrap">
-        <bool>true</bool>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
        </property>
-      </widget>
+      </spacer>
      </item>
      <item>
       <widget class="QPushButton" name="testNotifyPushButton">
@@ -431,6 +431,19 @@
        </property>
       </widget>
      </item>
+     <item>
+      <spacer name="horizontalSpacer_3">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
     </layout>
    </item>
    <item>
diff --git a/qsstv/config/operatorconfig.cpp b/qsstv/config/operatorconfig.cpp
index 702a589..c95d131 100644
--- a/qsstv/config/operatorconfig.cpp
+++ b/qsstv/config/operatorconfig.cpp
@@ -7,6 +7,8 @@ QString myLocator;
 QString myLastname;
 QString myFirstname;
 QString lastReceivedCall;
+bool    onlineStatusEnabled;
+QString onlineStatusText;
 
 operatorConfig::operatorConfig(QWidget *parent) :  baseConfig(parent), ui(new Ui::operatorConfig)
 {
@@ -27,6 +29,8 @@ void operatorConfig::readSettings()
   myLastname=qSettings.value("lastname",QString("NONAME")).toString();
   myFirstname=qSettings.value("firstname",QString("NOFIRSTNAME")).toString();
   myLocator=qSettings.value("locator",QString("NOLOCATOR")).toString();
+  onlineStatusEnabled=qSettings.value("onlinestatusenabled",true).toBool();
+  onlineStatusText=qSettings.value("onlinestatustext",QString("")).toString();
   qSettings.endGroup();
   setParams();
 }
@@ -41,6 +45,8 @@ void operatorConfig::writeSettings()
   qSettings.setValue("locator",myLocator);
   qSettings.setValue("lastname",myLastname);
   qSettings.setValue("firstname",myFirstname);
+  qSettings.setValue("onlinestatusenabled",onlineStatusEnabled);
+  qSettings.setValue("onlinestatustext",onlineStatusText);
   qSettings.endGroup();
 }
 
@@ -51,18 +57,25 @@ void operatorConfig::getParams()
   QString myLocatorCopy= myLocator;
   QString myLastnameCopy=myLastname;
   QString myFirstnameCopy=myFirstname;
+  QString onlineStatusTextCopy=onlineStatusText;
+  bool    onlineStatusEnabledCopy=onlineStatusEnabled;
 
   getValue(myCallsign,ui->callsignLineEdit);
   getValue(myLastname,ui->lastnameLineEdit);
   getValue(myFirstname,ui->firstnameLineEdit);
   getValue(myQth,ui->qthLineEdit);
   getValue(myLocator,ui->locatorLineEdit);
+  getValue(onlineStatusText,ui->onlineStatusText);
+  getValue(onlineStatusEnabled,ui->onlineStatusCheckbox);
+
   changed=false;
   if( myCallsignCopy!=myCallsign
-     || myQthCopy!=myQth
-     || myLocatorCopy!= myLocator
-     || myLastnameCopy!=myLastname
-     || myFirstnameCopy!=myFirstname)
+      || myQthCopy!=myQth
+      || myLocatorCopy!= myLocator
+      || myLastnameCopy!=myLastname
+      || myFirstnameCopy!=myFirstname
+      || onlineStatusEnabledCopy!=onlineStatusEnabled
+      || onlineStatusTextCopy!=onlineStatusText)
     changed=true;
 }
 
@@ -73,5 +86,6 @@ void operatorConfig::setParams()
   setValue(myFirstname,ui->firstnameLineEdit);
   setValue(myQth,ui->qthLineEdit);
   setValue(myLocator,ui->locatorLineEdit);
-
+  setValue(onlineStatusEnabled,ui->onlineStatusCheckbox);
+  setValue(onlineStatusText,ui->onlineStatusText);
 }
diff --git a/qsstv/config/operatorconfig.h b/qsstv/config/operatorconfig.h
index 88acd56..9cfee85 100644
--- a/qsstv/config/operatorconfig.h
+++ b/qsstv/config/operatorconfig.h
@@ -9,6 +9,9 @@ extern QString myLastname;
 extern QString myFirstname;
 extern QString lastReceivedCall;
 
+extern bool    onlineStatusEnabled;
+extern QString onlineStatusText;
+
 
 namespace Ui {
 class operatorConfig;
diff --git a/qsstv/config/operatorconfig.ui b/qsstv/config/operatorconfig.ui
index 0320960..b4ad8df 100644
--- a/qsstv/config/operatorconfig.ui
+++ b/qsstv/config/operatorconfig.ui
@@ -6,14 +6,29 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>588</width>
-    <height>221</height>
+    <width>680</width>
+    <height>272</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="spacing">
+    <number>1</number>
+   </property>
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
    <item>
     <layout class="QHBoxLayout" name="_4">
      <item>
@@ -260,6 +275,34 @@
     </layout>
    </item>
    <item>
+    <widget class="QCheckBox" name="onlineStatusCheckbox">
+     <property name="text">
+      <string>Allow other users to see your online status via the notification server</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="onlineStatusLabel">
+       <property name="text">
+        <string>Online Status Text</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="onlineStatusText">
+       <property name="maxLength">
+        <number>120</number>
+       </property>
+       <property name="placeholderText">
+        <string>antenna, radio, operating freq or other info</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
     <spacer name="spacer">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
diff --git a/qsstv/config/repeaterconfig.ui b/qsstv/config/repeaterconfig.ui
index 3407ac1..bfc3847 100644
--- a/qsstv/config/repeaterconfig.ui
+++ b/qsstv/config/repeaterconfig.ui
@@ -6,20 +6,14 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>599</width>
-    <height>259</height>
+    <width>624</width>
+    <height>474</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
-   <property name="spacing">
-    <number>2</number>
-   </property>
-   <property name="margin">
-    <number>1</number>
-   </property>
    <item>
     <layout class="QHBoxLayout" name="_2">
      <item>
@@ -50,7 +44,16 @@
        <property name="spacing">
         <number>6</number>
        </property>
-       <property name="margin">
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
         <number>0</number>
        </property>
        <item>
@@ -93,7 +96,16 @@
        <property name="spacing">
         <number>6</number>
        </property>
-       <property name="margin">
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
         <number>0</number>
        </property>
        <item>
@@ -118,7 +130,16 @@
      <property name="spacing">
       <number>6</number>
      </property>
-     <property name="margin">
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
       <number>0</number>
      </property>
      <item>
@@ -158,7 +179,16 @@
      <property name="spacing">
       <number>6</number>
      </property>
-     <property name="margin">
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
       <number>0</number>
      </property>
      <item>
@@ -198,7 +228,16 @@
      <property name="spacing">
       <number>6</number>
      </property>
-     <property name="margin">
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
       <number>0</number>
      </property>
      <item>
@@ -238,7 +277,16 @@
      <property name="spacing">
       <number>6</number>
      </property>
-     <property name="margin">
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
       <number>0</number>
      </property>
      <item>
@@ -333,6 +381,19 @@
      </item>
     </layout>
    </item>
+   <item>
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>202</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
   </layout>
  </widget>
  <resources/>
diff --git a/qsstv/config/rigconfig.ui b/qsstv/config/rigconfig.ui
index 6de4aca..07295d4 100644
--- a/qsstv/config/rigconfig.ui
+++ b/qsstv/config/rigconfig.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>658</width>
-    <height>399</height>
+    <width>633</width>
+    <height>426</height>
    </rect>
   </property>
   <property name="font">
@@ -18,1557 +18,537 @@
   <property name="windowTitle">
    <string>Form</string>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout_5">
+  <layout class="QVBoxLayout" name="verticalLayout_2">
    <property name="spacing">
-    <number>2</number>
+    <number>1</number>
    </property>
    <property name="leftMargin">
-    <number>1</number>
+    <number>0</number>
    </property>
    <property name="topMargin">
-    <number>1</number>
+    <number>0</number>
    </property>
    <property name="rightMargin">
-    <number>1</number>
+    <number>0</number>
    </property>
    <property name="bottomMargin">
-    <number>1</number>
+    <number>0</number>
    </property>
    <item>
     <widget class="QGroupBox" name="groupBox_2">
-     <property name="palette">
-      <palette>
-       <active>
-        <colorrole role="WindowText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Button">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Light">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Midlight">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>231</red>
-           <green>231</green>
-           <blue>231</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Dark">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>104</red>
-           <green>104</green>
-           <blue>104</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Mid">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>139</red>
-           <green>139</green>
-           <blue>139</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Text">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="BrightText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ButtonText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Base">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Window">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Shadow">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="AlternateBase">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>231</red>
-           <green>231</green>
-           <blue>231</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ToolTipBase">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>220</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ToolTipText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-       </active>
-       <inactive>
-        <colorrole role="WindowText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Button">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Light">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Midlight">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>231</red>
-           <green>231</green>
-           <blue>231</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Dark">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>104</red>
-           <green>104</green>
-           <blue>104</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Mid">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>139</red>
-           <green>139</green>
-           <blue>139</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Text">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="BrightText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ButtonText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Base">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Window">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Shadow">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="AlternateBase">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>231</red>
-           <green>231</green>
-           <blue>231</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ToolTipBase">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>220</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ToolTipText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-       </inactive>
-       <disabled>
-        <colorrole role="WindowText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>104</red>
-           <green>104</green>
-           <blue>104</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Button">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Light">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Midlight">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>231</red>
-           <green>231</green>
-           <blue>231</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Dark">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>104</red>
-           <green>104</green>
-           <blue>104</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Mid">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>139</red>
-           <green>139</green>
-           <blue>139</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Text">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>104</red>
-           <green>104</green>
-           <blue>104</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="BrightText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ButtonText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>104</red>
-           <green>104</green>
-           <blue>104</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Base">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Window">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Shadow">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="AlternateBase">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ToolTipBase">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>220</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ToolTipText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-       </disabled>
-      </palette>
-     </property>
      <property name="autoFillBackground">
       <bool>true</bool>
      </property>
      <property name="title">
       <string>Special Serial Port</string>
      </property>
-     <layout class="QVBoxLayout" name="verticalLayout_2">
+     <layout class="QHBoxLayout" name="horizontalLayout_7">
       <property name="spacing">
-       <number>2</number>
+       <number>1</number>
       </property>
       <property name="leftMargin">
-       <number>1</number>
+       <number>0</number>
       </property>
       <property name="topMargin">
-       <number>1</number>
+       <number>0</number>
       </property>
       <property name="rightMargin">
-       <number>1</number>
+       <number>0</number>
       </property>
       <property name="bottomMargin">
-       <number>1</number>
+       <number>0</number>
       </property>
       <item>
-       <layout class="QHBoxLayout" name="horizontalLayout_10">
-        <item>
-         <widget class="QCheckBox" name="enablePTTCheckBox">
-          <property name="text">
-           <string>Enable PTT serial Interface</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <spacer name="horizontalSpacer_8">
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>40</width>
-            <height>20</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-        <item>
-         <widget class="QLabel" name="serialInterfaceTextLabel_4">
-          <property name="minimumSize">
-           <size>
-            <width>60</width>
-            <height>0</height>
-           </size>
-          </property>
-          <property name="text">
-           <string>PTT Serial Port</string>
-          </property>
-          <property name="alignment">
-           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-          </property>
-          <property name="wordWrap">
-           <bool>false</bool>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QLineEdit" name="pttSerialPortLineEdit">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <spacer name="horizontalSpacer_15">
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>40</width>
-            <height>20</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-       </layout>
+       <widget class="QCheckBox" name="enablePTTCheckBox">
+        <property name="text">
+         <string>Enable PTT serial Interface</string>
+        </property>
+       </widget>
       </item>
       <item>
-       <layout class="QHBoxLayout" name="horizontalLayout_8"/>
+       <spacer name="horizontalSpacer_8">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>19</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
       </item>
       <item>
-       <layout class="QHBoxLayout" name="horizontalLayout_7">
-        <item>
-         <widget class="QCheckBox" name="RTSCheckBox">
-          <property name="text">
-           <string>+RTS</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QCheckBox" name="DTRCheckBox">
-          <property name="text">
-           <string>+DTR</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QCheckBox" name="nRTSCheckBox">
-          <property name="text">
-           <string>-RTS</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QCheckBox" name="nDTRCheckBox">
-          <property name="text">
-           <string>-DTR</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <spacer name="horizontalSpacer_11">
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>40</width>
-            <height>20</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-       </layout>
+       <widget class="QLabel" name="serialInterfaceTextLabel_4">
+        <property name="minimumSize">
+         <size>
+          <width>60</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="text">
+         <string>PTT Serial Port</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+        </property>
+        <property name="wordWrap">
+         <bool>false</bool>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QLineEdit" name="pttSerialPortLineEdit">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="horizontalSpacer_15">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>20</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QCheckBox" name="RTSCheckBox">
+        <property name="text">
+         <string>+RTS</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QCheckBox" name="DTRCheckBox">
+        <property name="text">
+         <string>+DTR</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QCheckBox" name="nRTSCheckBox">
+        <property name="text">
+         <string>-RTS</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QCheckBox" name="nDTRCheckBox">
+        <property name="text">
+         <string>-DTR</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="horizontalSpacer_11">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>19</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
       </item>
      </layout>
     </widget>
    </item>
    <item>
     <widget class="QGroupBox" name="groupBox">
-     <property name="palette">
-      <palette>
-       <active>
-        <colorrole role="WindowText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Button">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Light">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Midlight">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>231</red>
-           <green>231</green>
-           <blue>231</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Dark">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>104</red>
-           <green>104</green>
-           <blue>104</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Mid">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>139</red>
-           <green>139</green>
-           <blue>139</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Text">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="BrightText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ButtonText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Base">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Window">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Shadow">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="AlternateBase">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>231</red>
-           <green>231</green>
-           <blue>231</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ToolTipBase">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>220</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ToolTipText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-       </active>
-       <inactive>
-        <colorrole role="WindowText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Button">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Light">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Midlight">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>231</red>
-           <green>231</green>
-           <blue>231</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Dark">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>104</red>
-           <green>104</green>
-           <blue>104</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Mid">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>139</red>
-           <green>139</green>
-           <blue>139</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Text">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="BrightText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ButtonText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Base">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Window">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Shadow">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="AlternateBase">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>231</red>
-           <green>231</green>
-           <blue>231</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ToolTipBase">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>220</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ToolTipText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-       </inactive>
-       <disabled>
-        <colorrole role="WindowText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>104</red>
-           <green>104</green>
-           <blue>104</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Button">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Light">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Midlight">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>231</red>
-           <green>231</green>
-           <blue>231</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Dark">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>104</red>
-           <green>104</green>
-           <blue>104</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Mid">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>139</red>
-           <green>139</green>
-           <blue>139</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Text">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>104</red>
-           <green>104</green>
-           <blue>104</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="BrightText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ButtonText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>104</red>
-           <green>104</green>
-           <blue>104</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Base">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Window">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Shadow">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="AlternateBase">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ToolTipBase">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>220</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ToolTipText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-       </disabled>
-      </palette>
-     </property>
      <property name="autoFillBackground">
       <bool>true</bool>
      </property>
      <property name="title">
       <string>Hamlib Control</string>
      </property>
-     <layout class="QVBoxLayout" name="verticalLayout_3">
+     <layout class="QVBoxLayout" name="verticalLayout">
       <property name="spacing">
-       <number>2</number>
+       <number>1</number>
       </property>
       <property name="leftMargin">
-       <number>1</number>
+       <number>0</number>
       </property>
       <property name="topMargin">
-       <number>1</number>
+       <number>0</number>
       </property>
       <property name="rightMargin">
-       <number>1</number>
+       <number>0</number>
       </property>
       <property name="bottomMargin">
-       <number>1</number>
+       <number>0</number>
       </property>
       <item>
-       <layout class="QVBoxLayout" name="verticalLayout">
-        <property name="spacing">
-         <number>2</number>
+       <widget class="QCheckBox" name="enableCATCheckBox">
+        <property name="text">
+         <string>Enable Hamlib Cat Interface</string>
         </property>
+       </widget>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,1">
         <item>
-         <layout class="QHBoxLayout" name="horizontalLayout_9">
-          <item>
-           <widget class="QCheckBox" name="enableCATCheckBox">
+         <layout class="QGridLayout" name="gridLayout_2">
+          <property name="verticalSpacing">
+           <number>1</number>
+          </property>
+          <item row="0" column="0">
+           <widget class="QLabel" name="serialInterfaceTextLabel_2">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
             <property name="text">
-             <string>Enable Hamlib Cat Interface</string>
+             <string>Radio Model</string>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+            </property>
+            <property name="wordWrap">
+             <bool>false</bool>
             </property>
            </widget>
           </item>
-          <item>
-           <spacer name="horizontalSpacer_2">
-            <property name="orientation">
-             <enum>Qt::Horizontal</enum>
+          <item row="0" column="1">
+           <widget class="QComboBox" name="radioModelComboBox">
+            <property name="font">
+             <font>
+              <family>Ubuntu Mono</family>
+              <weight>75</weight>
+              <italic>false</italic>
+              <bold>true</bold>
+              <kerning>false</kerning>
+             </font>
             </property>
-            <property name="sizeHint" stdset="0">
+           </widget>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLabel" name="serialInterfaceTextLabel_3">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="text">
+             <string>CIV Address</string>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+            </property>
+            <property name="wordWrap">
+             <bool>false</bool>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QLineEdit" name="civAddressLineEdit">
+            <property name="maximumSize">
              <size>
-              <width>40</width>
-              <height>20</height>
+              <width>50</width>
+              <height>16777215</height>
              </size>
             </property>
-           </spacer>
+           </widget>
+          </item>
+          <item row="2" column="0">
+           <widget class="QLabel" name="serialInterfaceTextLabel">
+            <property name="minimumSize">
+             <size>
+              <width>108</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="text">
+             <string>Serial Port/Host</string>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+            </property>
+            <property name="wordWrap">
+             <bool>false</bool>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="1">
+           <widget class="QLineEdit" name="serialPortLineEdit">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+           </widget>
           </item>
          </layout>
         </item>
         <item>
-         <layout class="QHBoxLayout" name="horizontalLayout">
-          <item>
-           <layout class="QGridLayout" name="gridLayout_2">
-            <property name="spacing">
-             <number>2</number>
+         <layout class="QGridLayout" name="gridLayout">
+          <property name="verticalSpacing">
+           <number>1</number>
+          </property>
+          <item row="0" column="0">
+           <widget class="QLabel" name="serialInterfaceTextLabel_8">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
             </property>
-            <item row="0" column="0">
-             <widget class="QLabel" name="serialInterfaceTextLabel_2">
-              <property name="minimumSize">
-               <size>
-                <width>60</width>
-                <height>0</height>
-               </size>
-              </property>
-              <property name="text">
-               <string>Radio Model</string>
-              </property>
-              <property name="alignment">
-               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-              </property>
-              <property name="wordWrap">
-               <bool>false</bool>
-              </property>
-             </widget>
+            <property name="text">
+             <string>Parity</string>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+            </property>
+            <property name="wordWrap">
+             <bool>false</bool>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1">
+           <widget class="QComboBox" name="parityComboBox">
+            <property name="maximumSize">
+             <size>
+              <width>70</width>
+              <height>16777215</height>
+             </size>
+            </property>
+            <item>
+             <property name="text">
+              <string>None</string>
+             </property>
             </item>
-            <item row="0" column="1">
-             <widget class="QComboBox" name="radioModelComboBox">
-              <property name="font">
-               <font>
-                <family>Ubuntu Mono</family>
-                <weight>75</weight>
-                <italic>false</italic>
-                <bold>true</bold>
-                <kerning>false</kerning>
-               </font>
-              </property>
-             </widget>
+            <item>
+             <property name="text">
+              <string>Odd</string>
+             </property>
             </item>
-            <item row="1" column="0">
-             <widget class="QLabel" name="serialInterfaceTextLabel_3">
-              <property name="minimumSize">
-               <size>
-                <width>60</width>
-                <height>0</height>
-               </size>
-              </property>
-              <property name="text">
-               <string>CIV Address</string>
-              </property>
-              <property name="alignment">
-               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-              </property>
-              <property name="wordWrap">
-               <bool>false</bool>
-              </property>
-             </widget>
+            <item>
+             <property name="text">
+              <string>Even</string>
+             </property>
             </item>
-            <item row="1" column="1">
-             <layout class="QHBoxLayout" name="horizontalLayout_2">
-              <item>
-               <widget class="QLineEdit" name="civAddressLineEdit">
-                <property name="maximumSize">
-                 <size>
-                  <width>50</width>
-                  <height>16777215</height>
-                 </size>
-                </property>
-               </widget>
-              </item>
-              <item>
-               <spacer name="horizontalSpacer_4">
-                <property name="orientation">
-                 <enum>Qt::Horizontal</enum>
-                </property>
-                <property name="sizeHint" stdset="0">
-                 <size>
-                  <width>40</width>
-                  <height>20</height>
-                 </size>
-                </property>
-               </spacer>
-              </item>
-             </layout>
+           </widget>
+          </item>
+          <item row="0" column="2" colspan="2">
+           <widget class="QLabel" name="serialInterfaceTextLabel_9">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="text">
+             <string>Databits</string>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+            </property>
+            <property name="wordWrap">
+             <bool>false</bool>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="4">
+           <widget class="QComboBox" name="databitsComboBox">
+            <item>
+             <property name="text">
+              <string>7</string>
+             </property>
             </item>
-            <item row="2" column="0">
-             <widget class="QLabel" name="serialInterfaceTextLabel">
-              <property name="minimumSize">
-               <size>
-                <width>108</width>
-                <height>0</height>
-               </size>
-              </property>
-              <property name="text">
-               <string>Serial Port/Host</string>
-              </property>
-              <property name="alignment">
-               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-              </property>
-              <property name="wordWrap">
-               <bool>false</bool>
-              </property>
-             </widget>
+            <item>
+             <property name="text">
+              <string>8</string>
+             </property>
             </item>
-            <item row="2" column="1">
-             <widget class="QLineEdit" name="serialPortLineEdit">
-              <property name="sizePolicy">
-               <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-                <horstretch>0</horstretch>
-                <verstretch>0</verstretch>
-               </sizepolicy>
-              </property>
-             </widget>
+           </widget>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLabel" name="serialPortTextLabel">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="text">
+             <string>Baudrate</string>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+            </property>
+            <property name="wordWrap">
+             <bool>false</bool>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QComboBox" name="baudrateComboBox">
+            <property name="maximumSize">
+             <size>
+              <width>70</width>
+              <height>16777215</height>
+             </size>
+            </property>
+            <property name="currentIndex">
+             <number>5</number>
+            </property>
+            <item>
+             <property name="text">
+              <string>300</string>
+             </property>
             </item>
-            <item row="3" column="0">
-             <widget class="QLabel" name="serialInterfaceTextLabel_6">
-              <property name="minimumSize">
-               <size>
-                <width>60</width>
-                <height>0</height>
-               </size>
-              </property>
-              <property name="text">
-               <string>Handshake</string>
-              </property>
-              <property name="alignment">
-               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-              </property>
-              <property name="wordWrap">
-               <bool>false</bool>
-              </property>
-             </widget>
+            <item>
+             <property name="text">
+              <string>600</string>
+             </property>
             </item>
-            <item row="3" column="1">
-             <layout class="QHBoxLayout" name="horizontalLayout_3" stretch="0,1">
-              <property name="spacing">
-               <number>2</number>
-              </property>
-              <item>
-               <widget class="QComboBox" name="handshakeComboBox">
-                <property name="sizePolicy">
-                 <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-                  <horstretch>0</horstretch>
-                  <verstretch>0</verstretch>
-                 </sizepolicy>
-                </property>
-                <item>
-                 <property name="text">
-                  <string>None</string>
-                 </property>
-                </item>
-                <item>
-                 <property name="text">
-                  <string>Hardware</string>
-                 </property>
-                </item>
-                <item>
-                 <property name="text">
-                  <string>XOn/XOff</string>
-                 </property>
-                </item>
-               </widget>
-              </item>
-              <item>
-               <spacer name="horizontalSpacer_3">
-                <property name="orientation">
-                 <enum>Qt::Horizontal</enum>
-                </property>
-                <property name="sizeHint" stdset="0">
-                 <size>
-                  <width>40</width>
-                  <height>20</height>
-                 </size>
-                </property>
-               </spacer>
-              </item>
-             </layout>
+            <item>
+             <property name="text">
+              <string>1200</string>
+             </property>
             </item>
-           </layout>
-          </item>
-          <item>
-           <layout class="QGridLayout" name="gridLayout">
-            <item row="0" column="0">
-             <widget class="QLabel" name="serialInterfaceTextLabel_8">
-              <property name="minimumSize">
-               <size>
-                <width>60</width>
-                <height>0</height>
-               </size>
-              </property>
-              <property name="text">
-               <string>Parity</string>
-              </property>
-              <property name="alignment">
-               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-              </property>
-              <property name="wordWrap">
-               <bool>false</bool>
-              </property>
-             </widget>
+            <item>
+             <property name="text">
+              <string>2400</string>
+             </property>
             </item>
-            <item row="0" column="1">
-             <widget class="QComboBox" name="parityComboBox">
-              <property name="maximumSize">
-               <size>
-                <width>70</width>
-                <height>16777215</height>
-               </size>
-              </property>
-              <item>
-               <property name="text">
-                <string>None</string>
-               </property>
-              </item>
-              <item>
-               <property name="text">
-                <string>Odd</string>
-               </property>
-              </item>
-              <item>
-               <property name="text">
-                <string>Even</string>
-               </property>
-              </item>
-             </widget>
+            <item>
+             <property name="text">
+              <string>4800</string>
+             </property>
             </item>
-            <item row="0" column="2">
-             <spacer name="horizontalSpacer_7">
-              <property name="orientation">
-               <enum>Qt::Horizontal</enum>
-              </property>
-              <property name="sizeHint" stdset="0">
-               <size>
-                <width>40</width>
-                <height>20</height>
-               </size>
-              </property>
-             </spacer>
+            <item>
+             <property name="text">
+              <string>9600</string>
+             </property>
             </item>
-            <item row="1" column="0">
-             <widget class="QLabel" name="serialInterfaceTextLabel_9">
-              <property name="minimumSize">
-               <size>
-                <width>60</width>
-                <height>0</height>
-               </size>
-              </property>
-              <property name="text">
-               <string>Databits</string>
-              </property>
-              <property name="alignment">
-               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-              </property>
-              <property name="wordWrap">
-               <bool>false</bool>
-              </property>
-             </widget>
+            <item>
+             <property name="text">
+              <string>19200</string>
+             </property>
             </item>
-            <item row="1" column="1" colspan="2">
-             <layout class="QHBoxLayout" name="horizontalLayout_4">
-              <item>
-               <widget class="QComboBox" name="databitsComboBox">
-                <item>
-                 <property name="text">
-                  <string>7</string>
-                 </property>
-                </item>
-                <item>
-                 <property name="text">
-                  <string>8</string>
-                 </property>
-                </item>
-               </widget>
-              </item>
-              <item>
-               <spacer name="horizontalSpacer">
-                <property name="orientation">
-                 <enum>Qt::Horizontal</enum>
-                </property>
-                <property name="sizeHint" stdset="0">
-                 <size>
-                  <width>40</width>
-                  <height>20</height>
-                 </size>
-                </property>
-               </spacer>
-              </item>
-             </layout>
+            <item>
+             <property name="text">
+              <string>38400</string>
+             </property>
             </item>
-            <item row="2" column="0">
-             <widget class="QLabel" name="serialPortTextLabel">
-              <property name="minimumSize">
-               <size>
-                <width>60</width>
-                <height>0</height>
-               </size>
-              </property>
-              <property name="text">
-               <string>Baudrate</string>
-              </property>
-              <property name="alignment">
-               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-              </property>
-              <property name="wordWrap">
-               <bool>false</bool>
-              </property>
-             </widget>
+            <item>
+             <property name="text">
+              <string>57600</string>
+             </property>
             </item>
-            <item row="2" column="1">
-             <widget class="QComboBox" name="baudrateComboBox">
-              <property name="maximumSize">
-               <size>
-                <width>70</width>
-                <height>16777215</height>
-               </size>
-              </property>
-              <property name="currentIndex">
-               <number>5</number>
-              </property>
-              <item>
-               <property name="text">
-                <string>300</string>
-               </property>
-              </item>
-              <item>
-               <property name="text">
-                <string>600</string>
-               </property>
-              </item>
-              <item>
-               <property name="text">
-                <string>1200</string>
-               </property>
-              </item>
-              <item>
-               <property name="text">
-                <string>2400</string>
-               </property>
-              </item>
-              <item>
-               <property name="text">
-                <string>4800</string>
-               </property>
-              </item>
-              <item>
-               <property name="text">
-                <string>9600</string>
-               </property>
-              </item>
-              <item>
-               <property name="text">
-                <string>19200</string>
-               </property>
-              </item>
-              <item>
-               <property name="text">
-                <string>38400</string>
-               </property>
-              </item>
-              <item>
-               <property name="text">
-                <string>57600</string>
-               </property>
-              </item>
-              <item>
-               <property name="text">
-                <string>115200</string>
-               </property>
-              </item>
-              <item>
-               <property name="text">
-                <string>230400</string>
-               </property>
-              </item>
-              <item>
-               <property name="text">
-                <string>460800</string>
-               </property>
-              </item>
-             </widget>
+            <item>
+             <property name="text">
+              <string>115200</string>
+             </property>
             </item>
-            <item row="3" column="0">
-             <widget class="QLabel" name="stopbitsTextLabel">
-              <property name="minimumSize">
-               <size>
-                <width>60</width>
-                <height>0</height>
-               </size>
-              </property>
-              <property name="text">
-               <string>StopBits</string>
-              </property>
-              <property name="alignment">
-               <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-              </property>
-              <property name="wordWrap">
-               <bool>false</bool>
-              </property>
-             </widget>
+            <item>
+             <property name="text">
+              <string>230400</string>
+             </property>
             </item>
-            <item row="3" column="1" colspan="2">
-             <layout class="QHBoxLayout" name="horizontalLayout_5">
-              <item>
-               <widget class="QComboBox" name="stopbitsComboBox">
-                <item>
-                 <property name="text">
-                  <string>1</string>
-                 </property>
-                </item>
-                <item>
-                 <property name="text">
-                  <string>2</string>
-                 </property>
-                </item>
-               </widget>
-              </item>
-              <item>
-               <spacer name="horizontalSpacer_6">
-                <property name="orientation">
-                 <enum>Qt::Horizontal</enum>
-                </property>
-                <property name="sizeHint" stdset="0">
-                 <size>
-                  <width>40</width>
-                  <height>20</height>
-                 </size>
-                </property>
-               </spacer>
-              </item>
-             </layout>
+            <item>
+             <property name="text">
+              <string>460800</string>
+             </property>
             </item>
-           </layout>
-          </item>
-         </layout>
-        </item>
-        <item>
-         <layout class="QHBoxLayout" name="horizontalLayout_11">
-          <item>
-           <widget class="QLabel" name="label">
-            <property name="text">
-             <string>PTT Control via:</string>
-            </property>
            </widget>
           </item>
-          <item>
-           <widget class="QRadioButton" name="catVoiceRadioButton">
-            <property name="enabled">
-             <bool>true</bool>
-            </property>
-            <property name="toolTip">
-             <string extracomment="PTT with voice port as input"/>
+          <item row="1" column="2" colspan="2">
+           <widget class="QLabel" name="stopbitsTextLabel">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
             </property>
             <property name="text">
-             <string>CAT (Voice port)</string>
-            </property>
-            <property name="checked">
-             <bool>true</bool>
-            </property>
-           </widget>
-          </item>
-          <item>
-           <widget class="QRadioButton" name="catDataRadioButton">
-            <property name="enabled">
-             <bool>true</bool>
+             <string>StopBits</string>
             </property>
-            <property name="toolTip">
-             <string/>
+            <property name="alignment">
+             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
             </property>
-            <property name="whatsThis">
-             <string/>
-            </property>
-            <property name="text">
-             <string>CAT (Data port)</string>
+            <property name="wordWrap">
+             <bool>false</bool>
             </property>
            </widget>
           </item>
-          <item>
-           <widget class="QRadioButton" name="rtsRadioButton">
-            <property name="text">
-             <string>RTS</string>
-            </property>
+          <item row="1" column="4">
+           <widget class="QComboBox" name="stopbitsComboBox">
+            <item>
+             <property name="text">
+              <string>1</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>2</string>
+             </property>
+            </item>
            </widget>
           </item>
-          <item>
-           <widget class="QRadioButton" name="dtrRadioButton">
+          <item row="2" column="0" colspan="2">
+           <widget class="QLabel" name="serialInterfaceTextLabel_6">
+            <property name="minimumSize">
+             <size>
+              <width>60</width>
+              <height>0</height>
+             </size>
+            </property>
             <property name="text">
-             <string>DTR</string>
+             <string>Handshake</string>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+            </property>
+            <property name="wordWrap">
+             <bool>false</bool>
             </property>
            </widget>
           </item>
-          <item>
-           <spacer name="horizontalSpacer_12">
-            <property name="orientation">
-             <enum>Qt::Horizontal</enum>
+          <item row="2" column="3" colspan="2">
+           <widget class="QComboBox" name="handshakeComboBox">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
             </property>
-            <property name="sizeHint" stdset="0">
-             <size>
-              <width>40</width>
-              <height>20</height>
-             </size>
-            </property>
-           </spacer>
+            <item>
+             <property name="text">
+              <string>None</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>Hardware</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>XOn/XOff</string>
+             </property>
+            </item>
+           </widget>
           </item>
          </layout>
         </item>
-       </layout>
-      </item>
-      <item>
-       <layout class="QHBoxLayout" name="horizontalLayout_6">
         <item>
-         <spacer name="horizontalSpacer_9">
+         <spacer name="horizontalSpacer">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
@@ -1580,15 +560,65 @@
           </property>
          </spacer>
         </item>
+       </layout>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_11">
         <item>
-         <widget class="QPushButton" name="restartPushButton">
+         <widget class="QLabel" name="label">
           <property name="text">
-           <string>Restart CAT Interface</string>
+           <string>PTT Control via:</string>
           </property>
          </widget>
         </item>
         <item>
-         <spacer name="horizontalSpacer_10">
+         <widget class="QRadioButton" name="catVoiceRadioButton">
+          <property name="enabled">
+           <bool>true</bool>
+          </property>
+          <property name="toolTip">
+           <string extracomment="PTT with voice port as input"/>
+          </property>
+          <property name="text">
+           <string>CAT (Voice port)</string>
+          </property>
+          <property name="checked">
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QRadioButton" name="catDataRadioButton">
+          <property name="enabled">
+           <bool>true</bool>
+          </property>
+          <property name="toolTip">
+           <string/>
+          </property>
+          <property name="whatsThis">
+           <string/>
+          </property>
+          <property name="text">
+           <string>CAT (Data port)</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QRadioButton" name="rtsRadioButton">
+          <property name="text">
+           <string>RTS</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QRadioButton" name="dtrRadioButton">
+          <property name="text">
+           <string>DTR</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_12">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
@@ -1602,459 +632,10 @@
         </item>
        </layout>
       </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QGroupBox" name="groupBox_3">
-     <property name="palette">
-      <palette>
-       <active>
-        <colorrole role="WindowText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Button">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Light">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Midlight">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>231</red>
-           <green>231</green>
-           <blue>231</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Dark">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>104</red>
-           <green>104</green>
-           <blue>104</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Mid">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>139</red>
-           <green>139</green>
-           <blue>139</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Text">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="BrightText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ButtonText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Base">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Window">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Shadow">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="AlternateBase">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>231</red>
-           <green>231</green>
-           <blue>231</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ToolTipBase">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>220</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ToolTipText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-       </active>
-       <inactive>
-        <colorrole role="WindowText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Button">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Light">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Midlight">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>231</red>
-           <green>231</green>
-           <blue>231</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Dark">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>104</red>
-           <green>104</green>
-           <blue>104</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Mid">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>139</red>
-           <green>139</green>
-           <blue>139</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Text">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="BrightText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ButtonText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Base">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Window">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Shadow">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="AlternateBase">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>231</red>
-           <green>231</green>
-           <blue>231</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ToolTipBase">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>220</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ToolTipText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-       </inactive>
-       <disabled>
-        <colorrole role="WindowText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>104</red>
-           <green>104</green>
-           <blue>104</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Button">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Light">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Midlight">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>231</red>
-           <green>231</green>
-           <blue>231</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Dark">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>104</red>
-           <green>104</green>
-           <blue>104</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Mid">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>139</red>
-           <green>139</green>
-           <blue>139</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Text">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>104</red>
-           <green>104</green>
-           <blue>104</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="BrightText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>255</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ButtonText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>104</red>
-           <green>104</green>
-           <blue>104</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Base">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Window">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="Shadow">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="AlternateBase">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>208</red>
-           <green>208</green>
-           <blue>208</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ToolTipBase">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>255</red>
-           <green>255</green>
-           <blue>220</blue>
-          </color>
-         </brush>
-        </colorrole>
-        <colorrole role="ToolTipText">
-         <brush brushstyle="SolidPattern">
-          <color alpha="255">
-           <red>0</red>
-           <green>0</green>
-           <blue>0</blue>
-          </color>
-         </brush>
-        </colorrole>
-       </disabled>
-      </palette>
-     </property>
-     <property name="autoFillBackground">
-      <bool>true</bool>
-     </property>
-     <property name="title">
-      <string>XMLRPC Interface</string>
-     </property>
-     <layout class="QVBoxLayout" name="verticalLayout_4">
-      <property name="spacing">
-       <number>2</number>
-      </property>
-      <property name="leftMargin">
-       <number>1</number>
-      </property>
-      <property name="topMargin">
-       <number>1</number>
-      </property>
-      <property name="rightMargin">
-       <number>1</number>
-      </property>
-      <property name="bottomMargin">
-       <number>1</number>
-      </property>
       <item>
-       <layout class="QHBoxLayout" name="horizontalLayout_13">
-        <item>
-         <widget class="QCheckBox" name="enableXMLRPCCheckBox">
-          <property name="text">
-           <string>Enable XMLRPC Interface</string>
-          </property>
-         </widget>
-        </item>
+       <layout class="QHBoxLayout" name="horizontalLayout_6">
         <item>
-         <spacer name="horizontalSpacer_14">
+         <spacer name="horizontalSpacer_9">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
@@ -2067,36 +648,14 @@
          </spacer>
         </item>
         <item>
-         <widget class="QLabel" name="serialInterfaceTextLabel_5">
-          <property name="minimumSize">
-           <size>
-            <width>60</width>
-            <height>0</height>
-           </size>
-          </property>
+         <widget class="QPushButton" name="restartPushButton">
           <property name="text">
-           <string>Port</string>
-          </property>
-          <property name="alignment">
-           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-          </property>
-          <property name="wordWrap">
-           <bool>false</bool>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QLineEdit" name="XMLRPCPortLineEdit">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
+           <string>Restart CAT Interface</string>
           </property>
          </widget>
         </item>
         <item>
-         <spacer name="horizontalSpacer_5">
+         <spacer name="horizontalSpacer_10">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
@@ -2114,6 +673,95 @@
     </widget>
    </item>
    <item>
+    <widget class="QGroupBox" name="groupBox_3">
+     <property name="autoFillBackground">
+      <bool>true</bool>
+     </property>
+     <property name="title">
+      <string>XMLRPC Interface</string>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout_8">
+      <property name="spacing">
+       <number>1</number>
+      </property>
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+      <item>
+       <widget class="QCheckBox" name="enableXMLRPCCheckBox">
+        <property name="text">
+         <string>Enable XMLRPC Interface</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="horizontalSpacer_14">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>138</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QLabel" name="serialInterfaceTextLabel_5">
+        <property name="minimumSize">
+         <size>
+          <width>60</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="text">
+         <string>Port</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+        </property>
+        <property name="wordWrap">
+         <bool>false</bool>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QLineEdit" name="XMLRPCPortLineEdit">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="horizontalSpacer_5">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>138</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
     <layout class="QHBoxLayout" name="horizontalLayout_12">
      <item>
       <widget class="QLabel" name="serialPortTextLabel_2">
diff --git a/qsstv/config/soundconfig.ui b/qsstv/config/soundconfig.ui
index 1e6c84d..ec488af 100644
--- a/qsstv/config/soundconfig.ui
+++ b/qsstv/config/soundconfig.ui
@@ -6,20 +6,50 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>656</width>
-    <height>451</height>
+    <width>490</width>
+    <height>326</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout_4">
+   <property name="spacing">
+    <number>1</number>
+   </property>
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
    <item>
     <widget class="QGroupBox" name="groupBox_3">
      <property name="title">
       <string>Audio Interface</string>
      </property>
      <layout class="QVBoxLayout" name="verticalLayout_3">
+      <property name="spacing">
+       <number>1</number>
+      </property>
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
       <item>
        <layout class="QHBoxLayout" name="horizontalLayout_4">
         <item>
@@ -31,6 +61,9 @@
         </item>
         <item>
          <layout class="QGridLayout" name="gridLayout_2">
+          <property name="verticalSpacing">
+           <number>1</number>
+          </property>
           <item row="0" column="0">
            <widget class="QLabel" name="inputAudioDeviceLabel">
             <property name="sizePolicy">
@@ -99,53 +132,36 @@
     </widget>
    </item>
    <item>
-    <layout class="QGridLayout" name="gridLayout">
-     <item row="0" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
       <widget class="QLabel" name="inputClockLabel">
        <property name="sizePolicy">
-        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
        <property name="minimumSize">
         <size>
-         <width>145</width>
+         <width>0</width>
          <height>0</height>
         </size>
        </property>
        <property name="text">
-        <string>Input  Clock Frequency</string>
+        <string>Input  Clock Frequency </string>
        </property>
        <property name="wordWrap">
         <bool>false</bool>
        </property>
       </widget>
      </item>
-     <item row="0" column="1">
-      <layout class="QHBoxLayout" name="horizontalLayout_2">
-       <item>
-        <widget class="QLineEdit" name="inputClockLineEdit"/>
-       </item>
-       <item>
-        <spacer name="horizontalSpacer_2">
-         <property name="orientation">
-          <enum>Qt::Horizontal</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>40</width>
-           <height>20</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-      </layout>
+     <item>
+      <widget class="QLineEdit" name="inputClockLineEdit"/>
      </item>
-     <item row="1" column="0">
+     <item>
       <widget class="QLabel" name="outputClockLabel">
        <property name="sizePolicy">
-        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
@@ -153,7 +169,7 @@
        <property name="minimumSize">
         <size>
          <width>0</width>
-         <height>25</height>
+         <height>0</height>
         </size>
        </property>
        <property name="text">
@@ -164,25 +180,8 @@
        </property>
       </widget>
      </item>
-     <item row="1" column="1">
-      <layout class="QHBoxLayout" name="horizontalLayout_3">
-       <item>
-        <widget class="QLineEdit" name="outputClockLineEdit"/>
-       </item>
-       <item>
-        <spacer name="horizontalSpacer">
-         <property name="orientation">
-          <enum>Qt::Horizontal</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>40</width>
-           <height>20</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-      </layout>
+     <item>
+      <widget class="QLineEdit" name="outputClockLineEdit"/>
      </item>
     </layout>
    </item>
@@ -194,6 +193,21 @@
         <string>Sound Input</string>
        </property>
        <layout class="QVBoxLayout" name="verticalLayout">
+        <property name="spacing">
+         <number>1</number>
+        </property>
+        <property name="leftMargin">
+         <number>0</number>
+        </property>
+        <property name="topMargin">
+         <number>0</number>
+        </property>
+        <property name="rightMargin">
+         <number>0</number>
+        </property>
+        <property name="bottomMargin">
+         <number>0</number>
+        </property>
         <item>
          <widget class="QRadioButton" name="inFromCard">
           <property name="text">
@@ -227,6 +241,21 @@
         <string>Sound Output</string>
        </property>
        <layout class="QVBoxLayout" name="verticalLayout_2">
+        <property name="spacing">
+         <number>1</number>
+        </property>
+        <property name="leftMargin">
+         <number>0</number>
+        </property>
+        <property name="topMargin">
+         <number>0</number>
+        </property>
+        <property name="rightMargin">
+         <number>0</number>
+        </property>
+        <property name="bottomMargin">
+         <number>0</number>
+        </property>
         <item>
          <widget class="QRadioButton" name="outToCard">
           <property name="text">
diff --git a/qsstv/config/waterfallconfig.cpp b/qsstv/config/waterfallconfig.cpp
index ce91a59..bbbad9b 100644
--- a/qsstv/config/waterfallconfig.cpp
+++ b/qsstv/config/waterfallconfig.cpp
@@ -7,6 +7,8 @@ QString startPicWF;
 QString endPicWF;
 QString fixWF;
 QString bsrWF;
+QString startBinWF;
+QString endBinWF;
 QString wfFont;
 int wfFontSize;
 bool wfBold;
@@ -34,6 +36,8 @@ void waterfallConfig::readSettings()
   endPicWF=qSettings.value("endPicWF","END PIC").toString();
   fixWF=qSettings.value("fixWF","FIX").toString();
   bsrWF=qSettings.value("bsrWF","BSR").toString();
+  startBinWF=qSettings.value("startBinWF","START BIN").toString();
+  endBinWF=qSettings.value("endBinWF","END BIN").toString();
   wfFont=qSettings.value("wfFont","Arial").toString();
   wfFontSize=qSettings.value("wfFontSize",12).toInt();
   wfBold=qSettings.value("wfBold",false).toBool();
@@ -51,6 +55,8 @@ void waterfallConfig::writeSettings()
   qSettings.setValue("endPicWF",endPicWF);
   qSettings.setValue("fixWF",fixWF);
   qSettings.setValue("bsrWF",bsrWF);
+  qSettings.setValue("startBinWF",startBinWF);
+  qSettings.setValue("endBinWF",endBinWF);
   qSettings.setValue("wfFont",wfFont);
   qSettings.setValue("wfFontSize",wfFontSize);
   qSettings.setValue("wfBold",wfBold);
@@ -65,6 +71,8 @@ void waterfallConfig::getParams()
   getValue(endPicWF,ui->endPicTextEdit);
   getValue(fixWF,ui->fixTextEdit);
   getValue(bsrWF,ui->bsrTextEdit);
+  getValue(startBinWF,ui->startBinTextEdit);
+  getValue(endBinWF,ui->endBinTextEdit);
   getValue(wfFont,ui->fontComboBox);
   getValue(wfFontSize,ui->sizeSpinBox);
   getValue(wfBold,ui->boldCheckBox);
@@ -77,6 +85,8 @@ void waterfallConfig::setParams()
   setValue(endPicWF,ui->endPicTextEdit);
   setValue(fixWF,ui->fixTextEdit);
   setValue(bsrWF,ui->bsrTextEdit);
+  setValue(startBinWF,ui->startBinTextEdit);
+  setValue(endBinWF,ui->endBinTextEdit);
   ui->fontComboBox->blockSignals(true);
   ui->sizeSpinBox->blockSignals(true);
   setValue(sampleString,ui->sampleLineEdit);
diff --git a/qsstv/config/waterfallconfig.h b/qsstv/config/waterfallconfig.h
index a6ec976..73a6693 100644
--- a/qsstv/config/waterfallconfig.h
+++ b/qsstv/config/waterfallconfig.h
@@ -7,6 +7,8 @@ extern QString startPicWF;
 extern QString endPicWF;
 extern QString fixWF;
 extern QString bsrWF;
+extern QString startBinWF;
+extern QString endBinWF;
 extern QString wfFont;
 extern int wfFontSize;
 extern bool wfBold;
diff --git a/qsstv/config/waterfallconfig.ui b/qsstv/config/waterfallconfig.ui
index 44ce1d7..664a2ca 100644
--- a/qsstv/config/waterfallconfig.ui
+++ b/qsstv/config/waterfallconfig.ui
@@ -6,24 +6,56 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>865</width>
-    <height>648</height>
+    <width>683</width>
+    <height>437</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
+  <layout class="QVBoxLayout" name="verticalLayout" stretch="1,0,0">
+   <property name="spacing">
+    <number>1</number>
+   </property>
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
    <item>
-    <layout class="QGridLayout" name="gridLayout">
-     <item row="0" column="0">
-      <widget class="QLabel" name="pictureLabel">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
+    <layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0,0,0" columnstretch="0,1" columnminimumwidth="0,0">
+     <item row="2" column="0">
+      <widget class="QLabel" name="fixLabel">
+       <property name="minimumSize">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>FIX</string>
+       </property>
+       <property name="wordWrap">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="4" column="0">
+      <widget class="QLabel" name="binLabel_1">
+       <property name="text">
+        <string>Start Binary</string>
        </property>
+      </widget>
+     </item>
+     <item row="3" column="0">
+      <widget class="QLabel" name="bsrLabel">
        <property name="minimumSize">
         <size>
          <width>0</width>
@@ -31,37 +63,35 @@
         </size>
        </property>
        <property name="text">
-        <string>Start Picture</string>
+        <string>BSR</string>
        </property>
        <property name="wordWrap">
         <bool>false</bool>
        </property>
       </widget>
      </item>
-     <item row="0" column="1">
-      <widget class="QPlainTextEdit" name="startPicTextEdit">
+     <item row="2" column="1">
+      <widget class="QPlainTextEdit" name="fixTextEdit">
        <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+        <sizepolicy hsizetype="Preferred" vsizetype="Ignored">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
-       <property name="lineWidth">
-        <number>2</number>
-       </property>
-       <property name="midLineWidth">
-        <number>1</number>
-       </property>
       </widget>
      </item>
-     <item row="1" column="0">
-      <widget class="QLabel" name="pictureLabel_2">
+     <item row="1" column="1">
+      <widget class="QPlainTextEdit" name="endPicTextEdit">
        <property name="sizePolicy">
-        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+        <sizepolicy hsizetype="Preferred" vsizetype="Ignored">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="pictureLabel_2">
        <property name="minimumSize">
         <size>
          <width>0</width>
@@ -76,24 +106,30 @@
        </property>
       </widget>
      </item>
-     <item row="1" column="1">
-      <widget class="QPlainTextEdit" name="endPicTextEdit">
+     <item row="0" column="1">
+      <widget class="QPlainTextEdit" name="startPicTextEdit">
        <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+        <sizepolicy hsizetype="Preferred" vsizetype="Ignored">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
+       <property name="maximumSize">
+        <size>
+         <width>16777215</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="lineWidth">
+        <number>2</number>
+       </property>
+       <property name="midLineWidth">
+        <number>1</number>
+       </property>
       </widget>
      </item>
-     <item row="2" column="0">
-      <widget class="QLabel" name="fixLabel">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
+     <item row="0" column="0">
+      <widget class="QLabel" name="pictureLabel">
        <property name="minimumSize">
         <size>
          <width>0</width>
@@ -101,27 +137,27 @@
         </size>
        </property>
        <property name="text">
-        <string>FIX</string>
+        <string>Start Picture</string>
        </property>
        <property name="wordWrap">
         <bool>false</bool>
        </property>
       </widget>
      </item>
-     <item row="2" column="1">
-      <widget class="QPlainTextEdit" name="fixTextEdit">
+     <item row="3" column="1">
+      <widget class="QPlainTextEdit" name="bsrTextEdit">
        <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+        <sizepolicy hsizetype="Preferred" vsizetype="Ignored">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
       </widget>
      </item>
-     <item row="3" column="0">
-      <widget class="QLabel" name="bsrLabel">
+     <item row="4" column="1">
+      <widget class="QPlainTextEdit" name="startBinTextEdit">
        <property name="sizePolicy">
-        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+        <sizepolicy hsizetype="Preferred" vsizetype="Ignored">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
@@ -132,27 +168,47 @@
          <height>0</height>
         </size>
        </property>
+      </widget>
+     </item>
+     <item row="5" column="0">
+      <widget class="QLabel" name="binLabel_2">
        <property name="text">
-        <string>BSR</string>
-       </property>
-       <property name="wordWrap">
-        <bool>false</bool>
+        <string>End Binary</string>
        </property>
       </widget>
      </item>
-     <item row="3" column="1">
-      <widget class="QPlainTextEdit" name="bsrTextEdit">
+     <item row="5" column="1">
+      <widget class="QPlainTextEdit" name="endBinTextEdit">
        <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+        <sizepolicy hsizetype="Preferred" vsizetype="Ignored">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
+       <property name="minimumSize">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
       </widget>
      </item>
     </layout>
    </item>
    <item>
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>3</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
       <widget class="QLabel" name="fontLabel">
@@ -204,6 +260,8 @@
     </layout>
    </item>
   </layout>
+  <zorder>fontLabel</zorder>
+  <zorder>fontLabel</zorder>
  </widget>
  <resources/>
  <connections/>
diff --git a/qsstv/dispatch/dispatcher.cpp b/qsstv/dispatch/dispatcher.cpp
index c245502..107daca 100644
--- a/qsstv/dispatch/dispatcher.cpp
+++ b/qsstv/dispatch/dispatcher.cpp
@@ -26,9 +26,9 @@ It also starts, stops and synchronizes the threads.
 #include "dispatcher.h"
 #include "appglobal.h"
 #include "configparams.h"
-#include "mainwidgets/rxwidget.h"
-#include "mainwidgets/txwidget.h"
-#include "mainwidgets/gallerywidget.h"
+#include "rxwidget.h"
+#include "txwidget.h"
+#include "gallerywidget.h"
 #include "widgets/spectrumwidget.h"
 #include "widgets/vumeter.h"
 #include "rxfunctions.h"
@@ -49,7 +49,6 @@ creates dispatcher instance
 dispatcher::dispatcher()
 {
   mbox=NULL;
-
   progressFTP=NULL;
   lastFileName.clear();
   prTimerIndex=0;
@@ -61,23 +60,41 @@ delete dispatcher instance
 
 dispatcher::~dispatcher()
 {
-
 }
 
 void dispatcher::init()
 {
-  //  if (mbox==NULL)
-  //    {
-  ////      mbox = new QMessageBox(mainWindowPtr);
-  //      mbox = new QMessageBox(0);
-  //    }
   editorActive=false;
   infoTextPtr=new textDisplay(mainWindowPtr);
   mainWindowPtr->spectrumFramePtr->init(RXSTRIPE,1,BASESAMPLERATE/SUBSAMPLINGFACTOR);
   infoTextPtr->hide();
+  setOnlineStatus(true, onlineStatusText);
+  connect(notifyRXIntf, SIGNAL(notification(QString)), this, SLOT(slotRXNotification(QString)));
+  connect(notifyTXIntf, SIGNAL(notification(QString)), this, SLOT(slotTXNotification(QString)));
+  connect(hybridTxIntf, SIGNAL(commandsDone(bool)), this, SLOT(slotHybridTxDone(bool)));
 
 }
 
+void dispatcher::setOnlineStatus(bool online, QString info)
+{
+  txWidgetPtr->functionsPtr()->setOnlineStatus(online, info);
+
+  // TODO: move to rxWidget->functions->?
+  if (!online && enableFTP)
+    {
+      ftpInterface rxftp("RX Image Cleanup");
+      rxftp.setupConnection(ftpRemoteHost,ftpPort,ftpLogin,ftpPassword,ftpRemoteSSTVDirectory);
+      rxftp.uploadToRXServer(""); // mark SSTV offline
+      rxftp.changePath(ftpRemoteDRMDirectory);
+      rxftp.uploadToRXServer(""); // mark DSSTV/DRM offline
+    }
+}
+
+void dispatcher::who()
+{
+  txWidgetPtr->functionsPtr()->who();
+}
+
 
 /*!
   All communication between the threads are passed via this eventhandler.
@@ -86,197 +103,257 @@ void dispatcher::init()
 void dispatcher::customEvent( QEvent * e )
 {
   dispatchEventType type;
+  ftpInterface * iPtr;
   QString fn;
   type=(dispatchEventType)e->type();
   addToLog(((baseEvent*)e)->description,LOGDISPATCH);
   switch(type)
-  {
-  case displayFFT:
-    addToLog("dispatcher: displayFFT",LOGDISPATCH);
-    mainWindowPtr->spectrumFramePtr->realFFT(((displayFFTEvent*)e)->data());
-    rxWidgetPtr->vMeterPtr()->setValue(soundIOPtr->getVolumeDb());
-    //      addToLog(QString::number(soundIOPtr->getVolumeDb()),LOGALL);
+    {
+    case displayFFT:
+      addToLog("dispatcher: displayFFT",LOGDISPATCH);
+      mainWindowPtr->spectrumFramePtr->realFFT(((displayFFTEvent*)e)->data());
+      rxWidgetPtr->vMeterPtr()->setValue(soundIOPtr->getVolumeDb());
+      //      addToLog(QString::number(soundIOPtr->getVolumeDb()),LOGALL);
 
     break;
-  case displaySync:
-    // addToLog("dispatcher: displaySync",LOGDISPATCH);
-    uint s;
-    ((displaySyncEvent*)e)->getInfo(s);
-    rxWidgetPtr->sMeterPtr()->setValue((double)s);
+    case displaySync:
+      // addToLog("dispatcher: displaySync",LOGDISPATCH);
+      uint s;
+      ((displaySyncEvent*)e)->getInfo(s);
+      rxWidgetPtr->sMeterPtr()->setValue((double)s);
     break;
-  case rxSSTVStatus:
-    rxWidgetPtr->setSSTVStatusText(((statusMsgEvent*)e)->getStr());
+    case rxSSTVStatus:
+      rxWidgetPtr->setSSTVStatusText(((rxSSTVStatusEvent*)e)->getStr());
     break;
 
-  case startImageRX:
-    addToLog("dispatcher: clearing RxImage",LOGDISPATCH);
-    //      rxWidgetPtr->getImageViewerPtr()->createImage( ((startImageRXEvent*)e)->getSize(),QColor(0,0,128),imageStretch);
-    rxWidgetPtr->getImageViewerPtr()->createImage( ((startImageRXEvent*)e)->getSize(),imageBackGroundColor,imageStretch);
+    case startImageRX:
+      addToLog("dispatcher: clearing RxImage",LOGDISPATCH);
+      //      rxWidgetPtr->getImageViewerPtr()->createImage( ((startImageRXEvent*)e)->getSize(),QColor(0,0,128),imageStretch);
+      rxWidgetPtr->getImageViewerPtr()->createImage( ((startImageRXEvent*)e)->getSize(),imageBackGroundColor,imageStretch);
+      lastCallsign="";
     break;
 
-  case lineDisplay:
-  {
-    rxWidgetPtr->getImageViewerPtr()->displayImage();
-  }
+    case lineDisplay:
+      {
+        rxWidgetPtr->getImageViewerPtr()->displayImage();
+      }
     break;
-  case endSSTVImageRX:
-    if(autoSave)
-    {
-      addToLog("dispatcher:endImage savingRxImage",LOGDISPATCH);
-      saveRxSSTVImage(((endImageSSTVRXEvent*)e)->getModeName());
-    }
+    case endSSTVImageRX:
+      if(autoSave)
+        {
+          addToLog("dispatcher:endImage savingRxImage",LOGDISPATCH);
+          saveRxSSTVImage(((endImageSSTVRXEvent*)e)->getModeName());
+        }
     break;
 
 
-  case rxDRMStatus:
-    rxWidgetPtr->setDRMStatusText(((statusMsgEvent*)e)->getStr());
+    case rxDRMStatus:
+      rxWidgetPtr->setDRMStatusText(((rxDRMStatusEvent*)e)->getStr());
+
+    break;
 
+    case statusBarMsg:
+      statusBarPtr->showMessage(((statusBarMsgEvent*)e)->getStr());
     break;
-  case callEditor:
-    if(editorActive) break;
-    editorActive=true;
-    ed=new editor();
-    ed->show();
-    iv=((callEditorEvent*)e)->getImageViewer();
-    addToLog (QString(" callEditorEvent imageViewPtr: %1").arg(QString::number((ulong)iv,16)),LOGDISPATCH);
-    addToLog(QString("editor: filename %1").arg(((callEditorEvent*)e)->getFilename()),LOGDISPATCH);
-    ed->openFile(((callEditorEvent*)e)->getFilename());
+    case callEditor:
+      if(editorActive) break;
+      editorActive=true;
+      ed=new editor();
+      ed->show();
+      iv=((callEditorEvent*)e)->getImageViewer();
+      addToLog (QString(" callEditorEvent imageViewPtr: %1").arg(QString::number((ulong)iv,16)),LOGDISPATCH);
+      addToLog(QString("editor: filename %1").arg(((callEditorEvent*)e)->getFilename()),LOGDISPATCH);
+      ed->openFile(((callEditorEvent*)e)->getFilename());
     break;
 
-  case rxDRMNotify:
-    rxWidgetPtr->setDRMNotifyText(((rxDRMNotifyEvent*)e)->getStr());
+    case rxDRMNotify:
+      rxWidgetPtr->setDRMNotifyText(((rxDRMNotifyEvent*)e)->getStr());
+    break;
+    case rxDRMNotifyAppend:
+      rxWidgetPtr->appendDRMNotifyText(((rxDRMNotifyAppendEvent*)e)->getStr());
     break;
-  case rxDRMNotifyAppend:
-    rxWidgetPtr->appendDRMNotifyText(((rxDRMNotifyAppendEvent*)e)->getStr());
+    case txDRMNotify:
+      txWidgetPtr->setDRMNotifyText(((txDRMNotifyEvent*)e)->getStr());
     break;
-  case txDRMNotify:
-    txWidgetPtr->setDRMNotifyText(((txDRMNotifyEvent*)e)->getStr());
+    case txDRMNotifyAppend:
+      txWidgetPtr->appendDRMNotifyText(((txDRMNotifyAppendEvent*)e)->getStr());
     break;
-  case txDRMNotifyAppend:
-    txWidgetPtr->appendDRMNotifyText(((txDRMNotifyAppendEvent*)e)->getStr());
+    case txPrepareComplete:
+      txWidgetPtr->prepareTxComplete(((txPrepareCompleteEvent *)e)->ok());
     break;
 
+    case editorFinished:
+      if(!editorActive) break;
+      if(((editorFinishedEvent*)e)->isOK())
+        {
+          addToLog (QString(" editorFinishedEvent imageViewPtr: %1").arg(QString::number((ulong)iv,16)),LOGDISPATCH);
+          iv->reload();
+        }
+      editorActive=false;
+      delete ed;
+    break;
 
-  case editorFinished:
-    if(!editorActive) break;
-    if(((editorFinishedEvent*)e)->isOK())
-    {
-      addToLog (QString(" editorFinishedEvent imageViewPtr: %1").arg(QString::number((ulong)iv,16)),LOGDISPATCH);
-      iv->reload();
-    }
-    editorActive=false;
-    delete ed;
+    case templatesChanged:
+      galleryWidgetPtr->changedMatrix(imageViewer::TEMPLATETHUMB);
+      txWidgetPtr->setupTemplatesComboBox();
     break;
 
-  case templatesChanged:
-    galleryWidgetPtr->changedMatrix(imageViewer::TEMPLATETHUMB);
-    txWidgetPtr->setupTemplatesComboBox();
+    case progressTX:
+      txTimeCounter=0;
+      addToLog(QString("dispatcher: progress duration=%1").arg(((progressTXEvent*)e)->getInfo()),LOGDISPATCH);
+      prTimerIndex=startTimer(((progressTXEvent*)e)->getInfo()*10); // time in seconds -> times 1000 for msec,divide by 100 for progress
     break;
 
-  case progressTX:
-    txTimeCounter=0;
-    addToLog(QString("dispatcher: progress duration=%1").arg(((progressTXEvent*)e)->getInfo()),LOGDISPATCH);
-    prTimerIndex=startTimer(((progressTXEvent*)e)->getInfo()*10); // time in seconds -> times 1000 for msec,divide by 100 for progress
+    case stoppingTX:
+      addToLog("dispatcher: endTXImage",LOGDISPATCH);
     break;
 
-  case stoppingTX:
-    addToLog("dispatcher: endTXImage",LOGDISPATCH);
+    case endImageTX:
+      //addToLog("dispatcher: endTXImage",LOGDISPATCH);
+      while(soundIOPtr->isPlaying())
+        {
+          qApp->processEvents();
+        }
+      addToLog("dispatcher: endTXImage",LOGDISPATCH);
+      startRX();
     break;
 
-  case endImageTX:
-    //addToLog("dispatcher: endTXImage",LOGDISPATCH);
-    while(soundIOPtr->isPlaying())
-    {
-      qApp->processEvents();
-    }
-    addToLog("dispatcher: endTXImage",LOGDISPATCH);
-    startRX();
+    case displayDRMInfo:
+      if(!slowCPU)
+        {
+          rxWidgetPtr->mscWdg()->setConstellation(MSC);
+          rxWidgetPtr->facWdg()->setConstellation(FAC);
+        }
+      rxWidgetPtr->statusWdg()->setStatus();
     break;
 
-  case displayDRMInfo:
-    if(!slowCPU)
-    {
-      rxWidgetPtr->mscWdg()->setConstellation(MSC);
-      rxWidgetPtr->facWdg()->setConstellation(FAC);
-    }
-    rxWidgetPtr->statusWdg()->setStatus();
+    case displayDRMStat:
+      DSPFLOAT s1;
+      ((displayDRMStatEvent*)e)->getInfo(s1);
+      rxWidgetPtr->sMeterPtr()->setValue(s1);
     break;
 
-  case displayDRMStat:
-    DSPFLOAT s1;
-    ((displayDRMStatEvent*)e)->getInfo(s1);
-    rxWidgetPtr->sMeterPtr()->setValue(s1);
+    case loadRXImage:
+      {
+        QString fn=((loadRXImageEvent *)e)->getFilename();
+        rxWidgetPtr->getImageViewerPtr()->openImage(fn,false,false,false);
+      }
+    break;
+    case moveToTx:
+      {
+        txWidgetPtr->setImage(((moveToTxEvent *)e)->getFilename());
+      }
+    break;
+    case saveDRMImage:
+      {
+        QString info;
+        ((saveDRMImageEvent*)e)->getFilename(fn);
+        ((saveDRMImageEvent*)e)->getInfo(info);
+        if(!rxWidgetPtr->getImageViewerPtr()->openImage(fn,false,false,false))
+          {
+            if(mbox==NULL) delete mbox;
+            mbox = new QMessageBox(mainWindowPtr);
+            mbox->setWindowTitle("Received file");
+            mbox->setText(QString("Saved file %1").arg(fn));
+            mbox->show();
+            QTimer::singleShot(4000, mbox, SLOT(hide()));
+            break;
+          }
+        saveImage(fn, info);
+      }
     break;
 
-  case loadRXImage:
-  {
-    QString fn=((loadRXImageEvent *)e)->getFilename();
-    rxWidgetPtr->getImageViewerPtr()->openImage(fn,false,false,false);
-  }
+    case prepareFix:
+      addToLog("prepareFix",LOGDISPATCH);
+      startDRMFIXTx( ((prepareFixEvent*)e)->getData());
     break;
-  case moveToTx:
-  {
-    txWidgetPtr->setImage(((moveToTxEvent *)e)->getFilename());
-  }
+    case displayText:
+      infoTextPtr->clear();
+      infoTextPtr->setWindowTitle(QString("Received from %1").arg(drmCallsign));
+      infoTextPtr->append(((displayTextEvent*)e)->getStr());
+      infoTextPtr->show();
     break;
-  case saveDRMImage:
-  {
-    ((saveDRMImageEvent*)e)->getFilename(fn);
-    if(!rxWidgetPtr->getImageViewerPtr()->openImage(fn,false,false,false))
-    {
+
+    case displayMBox:
       if(mbox==NULL) delete mbox;
       mbox = new QMessageBox(mainWindowPtr);
-      mbox->setWindowTitle("Received file");
-      mbox->setText(QString("Saved file %1").arg(fn));
+      mbox->setWindowTitle(((displayMBoxEvent*)e)->getTitle());
+      mbox->setText(((displayMBoxEvent*)e)->getStr());
       mbox->show();
       QTimer::singleShot(4000, mbox, SLOT(hide()));
-      break;
-    }
-    saveImage(fn);
-  }
     break;
 
-  case prepareFix:
-    addToLog("prepareFix",LOGDISPATCH);
-    startDRMFIXTx( ((prepareFixEvent*)e)->getData());
+    case displayProgressFTP:
+      {
+        if(((displayProgressFTPEvent*)e)->getTotal()==0)
+          {
+            delete progressFTP;
+            progressFTP=NULL;
+            break;
+          }
+        if(progressFTP==NULL)
+          {
+            progressFTP=new QProgressDialog("FTP Transfer","Cancel",0,0,mainWindowPtr);
+          }
+        progressFTP->show();
+        progressFTP->setMaximum(((displayProgressFTPEvent*)e)->getTotal());
+        progressFTP->setValue(((displayProgressFTPEvent*)e)->getBytes());
+      }
     break;
-  case displayText:
-    infoTextPtr->clear();
-    infoTextPtr->setWindowTitle(QString("Received from %1").arg(drmCallsign));
-    infoTextPtr->append(((displayTextEvent*)e)->getStr());
-    infoTextPtr->show();
+    case  ftpSetup:
+
+      iPtr=((ftpSetupEvent*)e)->getFtpIntfPtr();
+      if(iPtr==notifyRXIntf)
+        {
+          notifyRXDone=DFTPWAITING;
+        }
+      else if(iPtr==hybridTxIntf)
+        {
+          hybridTxDone=DFTPWAITING;
+        }
+      else if(iPtr==notifyTXIntf)
+        {
+          notifyTxDone=DFTPWAITING;
+        }
+        iPtr->setupConnection(
+            ((ftpSetupEvent*)e)->getHost(),
+            ((ftpSetupEvent*)e)->getPort(),
+            ((ftpSetupEvent*)e)->getUser(),
+            ((ftpSetupEvent*)e)->getPassword(),
+            ((ftpSetupEvent*)e)->getDir());
     break;
 
-  case displayMBox:
-    if(mbox==NULL) delete mbox;
-    mbox = new QMessageBox(mainWindowPtr);
-    mbox->setWindowTitle(((displayMBoxEvent*)e)->getTitle());
-    mbox->setText(((displayMBoxEvent*)e)->getStr());
-    mbox->show();
-    QTimer::singleShot(4000, mbox, SLOT(hide()));
+    case ftpUploadFile:
+
+      ((ftpUploadFileEvent*)e)->getFtpIntfPtr()->uploadFile(
+            ((ftpUploadFileEvent*)e)->getSrcFn(),
+            ((ftpUploadFileEvent*)e)->getDstFn(),
+            ((ftpUploadFileEvent*)e)->getReconnect()
+            );
     break;
 
-  case displayProgressFTP:
-  {
-    if(((displayProgressFTPEvent*)e)->getTotal()==0)
-    {
-      delete progressFTP;
-      progressFTP=NULL;
-      break;
-    }
-    if(progressFTP==NULL)
-    {
-      progressFTP=new QProgressDialog("FTP Transfer","Cancel",0,0,mainWindowPtr);
-    }
-    progressFTP->show();
-    progressFTP->setMaximum(((displayProgressFTPEvent*)e)->getTotal());
-    progressFTP->setValue(((displayProgressFTPEvent*)e)->getBytes());
-  }
+
+    case notifyAction:
+      notifyRXIntf->mremove(((notifyActionEvent*)e)->getToRemove());
+      notifyRXIntf->uploadData(((notifyActionEvent*)e)->getMsg().toLatin1(), ((notifyActionEvent*)e)->getFilename());
     break;
-  default:
-    addToLog(QString("unsupported event: %1").arg(((baseEvent*)e)->description), LOGALL);
+
+    case notifyCheck:
+
+
+      iPtr=((ftpSetupEvent*)e)->getFtpIntfPtr();
+
+      iPtr->startNotifyCheck(
+            ((notifyCheckEvent*)e)->getFilename(),
+            ((notifyCheckEvent*)e)->getInterval(),
+            ((notifyCheckEvent*)e)->getRepeats(),
+            ((notifyCheckEvent*)e)->getToRemove()
+            );
     break;
-  }
+    default:
+      addToLog(QString("unsupported event: %1").arg(((baseEvent*)e)->description), LOGALL);
+    break;
+    }
   ((baseEvent *)e)->setDone();
 }
 
@@ -284,11 +361,11 @@ void dispatcher::customEvent( QEvent * e )
 void dispatcher::idleAll()
 {
   if(prTimerIndex>=0)
-  {
-    killTimer(prTimerIndex);
-    prTimerIndex=-1;
-    txWidgetPtr->setProgress(0);
-  }
+    {
+      killTimer(prTimerIndex);
+      prTimerIndex=-1;
+      txWidgetPtr->setProgress(0);
+    }
   rigControllerPtr->activatePTT(false);
   rxWidgetPtr->functionsPtr()->stopAndWait();
   txWidgetPtr->functionsPtr()->stopAndWait();
@@ -310,6 +387,11 @@ void dispatcher::startTX(txFunctions::etxState state)
   txWidgetPtr->functionsPtr()->startTX(state);
 }
 
+void dispatcher::prepareTX(txFunctions::etxState state)
+{
+  txWidgetPtr->functionsPtr()->prepareTX(state);
+}
+
 void dispatcher::startDRMFIXTx(QByteArray ba)
 {
   if(!txWidgetPtr->functionsPtr()->prepareFIX(ba)) return;
@@ -318,11 +400,38 @@ void dispatcher::startDRMFIXTx(QByteArray ba)
 
 void dispatcher::startDRMTxBinary()
 {
+  //TODO: this whole thing should probably live in txWidget::slotBinary
+  QFileInfo finfo;
+  int txtime=0;
+  QMessageBox mbox(mainWindowPtr);
+  QPushButton *sendButton;
+
   dirDialog d((QWidget *)mainWindowPtr,"Binary File");
   QString filename=d.openFileName("","*");
   if(filename.isEmpty()) return;
   if(!txWidgetPtr->functionsPtr()->prepareBinary(filename)) return;
-  startTX(txFunctions::TXSENDDRMBINARY);
+
+  txtime = txWidgetPtr->functionsPtr()->calcTxTime(true,0);
+  finfo.setFile(filename);
+
+  if (txtime > (3*60))
+    mbox.setIcon(QMessageBox::Warning);
+
+  mbox.setWindowTitle("TX Binary File");
+  mbox.setText(QString("'%1'").arg(filename));
+  mbox.setInformativeText(QString("The file is %1Kb and will take %2 seconds on air to send").
+                          arg(finfo.size()/1000.0,0,'f',0).arg(txtime));
+
+  if (useHybrid)
+    sendButton = mbox.addButton(tr("Upload ready to transmit"), QMessageBox::AcceptRole);
+  else
+    sendButton = mbox.addButton(tr("Start Transmitting"), QMessageBox::AcceptRole);
+  mbox.setStandardButtons(QMessageBox::Cancel);
+
+  mbox.exec();
+  if (mbox.clickedButton() == sendButton) {
+      txWidgetPtr->functionsPtr()->prepareTX(txFunctions::TXPREPAREDRMBINARY);
+    }
 }
 
 
@@ -330,98 +439,171 @@ void dispatcher::startDRMTxBinary()
 void dispatcher::logSSTV(QString call,bool fromFSKID)
 {
   if(lastFileName.isEmpty())
-  {
-    return;
-  }
+    {
+      return;
+    }
   if(fromFSKID)
-  {
-    QDateTime dt(QDateTime::currentDateTime().toUTC());
-    int diffsec=saveTimeStamp.secsTo(dt);
-    if(diffsec<2)
     {
-      logBookPtr->logQSO(call,"SSTV",lastFileName);
+      QDateTime dt(QDateTime::currentDateTime().toUTC());
+      int diffsec=saveTimeStamp.secsTo(dt);
+      if(diffsec<2)
+        {
+          logBookPtr->logQSO(call,"SSTV",lastFileName);
+        }
+      lastCallsign=call;
     }
-  }
   else
-  {
-    logBookPtr->logQSO(call,"SSTV","");
-  }
+    {
+      logBookPtr->logQSO(call,"SSTV","");
+    }
 
 }
 
 
 void dispatcher::saveRxSSTVImage(QString shortModeName)
 {
-  QString s,fileName;
+  QString info,s,fileName;
+  int m;
   QDateTime dt(QDateTime::currentDateTime().toUTC()); //this is compatible with QT 4.6
   dt.setTimeSpec(Qt::UTC);
   if (shortModeName.isEmpty())
-  {
-    lastFileName.clear();
-    return;
-  }
+    {
+      lastFileName.clear();
+      return;
+    }
   if(!autoSave)
-  {
-    lastFileName=shortModeName;
-  }
+    {
+      lastFileName=shortModeName;
+    }
   else
-  {
-    fileName=QString("%1/%2_%3.%4").arg(rxSSTVImagesPath).arg(shortModeName).arg(dt.toString("yyyyMMdd_HHmmss")).arg(defaultImageFormat);
-    addToLog(QString("dispatcher: saveRxImage():%1 ").arg(fileName),LOGDISPATCH);
-    rxWidgetPtr->getImageViewerPtr()->save(fileName,defaultImageFormat,true,false);
-    saveImage(fileName);
-    lastFileName=QString("%1_%2.%3").arg(shortModeName).arg(dt.toString("yyyyMMdd_HHmmss")).arg(defaultImageFormat);
-    saveTimeStamp= dt;
-  }
+    {
+      fileName=QString("%1/%2_%3.%4").arg(rxSSTVImagesPath).arg(shortModeName).arg(dt.toString("yyyyMMdd_HHmmss")).arg(defaultImageFormat);
+      addToLog(QString("dispatcher: saveRxImage():%1 ").arg(fileName),LOGDISPATCH);
+      rxWidgetPtr->getImageViewerPtr()->save(fileName,defaultImageFormat,true,false);
+
+      info="";
+      m=0;
+      while (m<=NUMSSTVMODES && shortModeName!=SSTVTable[m].shortName) m++;
+      if (m<=NUMSSTVMODES)
+        info += SSTVTable[m].name;
+      else
+        info += shortModeName;
+
+      if (!lastCallsign.isEmpty())
+        info += " de "+lastCallsign;
+
+      saveImage(fileName, info);
+      lastFileName=QString("%1_%2.%3").arg(shortModeName).arg(dt.toString("yyyyMMdd_HHmmss")).arg(defaultImageFormat);
+      saveTimeStamp= dt;
+    }
 }
 
-void dispatcher::saveImage(QString fileName)
+void dispatcher::saveImage(QString fileName, QString infotext)
 {
   QFileInfo info(fileName);
-  eftpError ftpResult;
-  displayMBoxEvent *stmb=0;
   QString fn="/tmp/"+info.baseName()+"."+ftpDefaultImageFormat;
   galleryWidgetPtr->putRxImage(fileName);
   txWidgetPtr->setPreviewWidget(fileName);
   if(enableFTP)
-  {
-    ftpInterface ftpIntf("Save RX Image");
-
-    if(transmissionModeIndex==TRXSSTV)
     {
-      rxWidgetPtr->getImageViewerPtr()->save(fn,ftpDefaultImageFormat,true,false);
-      ftpIntf.setupConnection(ftpRemoteHost,ftpPort,ftpLogin,ftpPassword,ftpRemoteSSTVDirectory);
+      QImage *imp = rxWidgetPtr->getImageViewerPtr()->getImagePtr();
+      QImage im;
+
+      if (imp && imp->width()) {
+          // the original source image is available, possibly in higher quality
+          // than the displayed image. Only for DRM Images.
+          im = QImage(imp->convertToFormat(QImage::Format_RGB32));
+        }
+      else {
+          // Uses the displayed image in whatever quality is displayed.
+          // Applies to SSTV images.
+          rxWidgetPtr->getImageViewerPtr()->save(fn,ftpDefaultImageFormat,true,false);
+          im = QImage(fn);
+        }
+      QString text, remoteDir;
+      QPainter p;
+      double freq=0;
+      int pixelSize, height, width;
+
+      rigControllerPtr->getFrequency(freq);
+
+      text = QString("%1 UTC %2 kHz ").
+          arg(QDateTime::currentDateTime().toUTC().toString("hh:mm ddd MMM d, yyyy")).
+          arg(freq/1000,1,'f',0);
+
+      if (transmissionModeIndex==TRXSSTV) {
+          remoteDir = ftpRemoteSSTVDirectory;
+        }
+      else {
+          remoteDir = ftpRemoteDRMDirectory;
+        }
+
+      if (!infotext.isEmpty()) text += " "+infotext;
+
+      // Limit uploaded size
+      if ((im.width() > 960) || (im.height() > 768)) {
+          im = im.scaled(960,768, Qt::KeepAspectRatio);
+        }
+
+      // Stamp text over the top left of the image
+      // and keep it the same portion, unless the
+      // font would be unreadable
+      QFont font("Arial");
+      pixelSize = 9 * im.width()/320;
+      if (pixelSize<8) pixelSize=8;
+      font.setPixelSize(pixelSize);
+      QFontMetrics fontm(font);
+
+      width = fontm.width(text) + 6;
+      height= fontm.height() + 2;
+
+      p.begin(&im);
+      p.setPen(Qt::black);
+      p.fillRect(0,0,width,height, Qt::black);
+      p.setPen(Qt::white);
+      p.setBrush(Qt::white);
+      p.setFont(font);
+      p.drawText(2,height-fontm.descent()-1, text);
+
+      im.save(fn, ftpDefaultImageFormat.toUpper().toLatin1().data());
+      p.end();
+
+      uploadToRXServer(remoteDir, fn);
+      QFile::remove(fn);
     }
-    else
-    {
-      rxWidgetPtr->getImageViewerPtr()->save(fn,ftpDefaultImageFormat,true,true);
-      ftpIntf.setupConnection(ftpRemoteHost,ftpPort,ftpLogin,ftpPassword,ftpRemoteDRMDirectory); // TO CHECK JOMA
-    }
-    ftpResult=ftpIntf.uploadToRXServer(fn);
-    switch(ftpResult)
+}
+
+void dispatcher::uploadToRXServer(QString remoteDir, QString fn)
+{
+  displayMBoxEvent *stmb=0;
+  eftpError ftpResult;
+
+  ftpInterface ftpIntf("Save RX Image");
+
+  ftpIntf.setupConnection(ftpRemoteHost,ftpPort,ftpLogin,ftpPassword,remoteDir);
+
+  ftpResult=ftpIntf.uploadToRXServer(fn);
+  switch(ftpResult)
     {
     case FTPOK:
-      break;
+    break;
     case FTPERROR:
       stmb= new displayMBoxEvent("FTP Error",QString("Host: %1: %2").arg(ftpRemoteHost).arg(ftpIntf.getLastError()));
-      break;
+    break;
     case FTPNAMEERROR:
       stmb= new displayMBoxEvent("FTP Error",QString("Host: %1, Error in filename").arg(ftpRemoteHost));
-      break;
+    break;
     case FTPCANCELED:
       stmb= new displayMBoxEvent("FTP Error",QString("Connection to %1 Canceled").arg(ftpRemoteHost));
-      break;
+    break;
     case FTPTIMEOUT:
       stmb= new displayMBoxEvent("FTP Error",QString("Connection to %1 timed out").arg(ftpRemoteHost));
-      break;
+    break;
     }
-    if(ftpResult!=FTPOK)
+  if(ftpResult!=FTPOK)
     {
       QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
-      return;
     }
-
-  }
 }
 
 
@@ -429,17 +611,49 @@ void dispatcher::saveImage(QString fileName)
 void dispatcher::timerEvent(QTimerEvent *event)
 {
   if(event->timerId()==prTimerIndex)
-  {
-    txWidgetPtr->setProgress(++txTimeCounter);
-    if(txTimeCounter>=100)
     {
-      if(prTimerIndex>=0)
-      {
-        killTimer(prTimerIndex);
-        prTimerIndex=-1;
-        txWidgetPtr->setProgress(0);
-      }
+      txWidgetPtr->setProgress(++txTimeCounter);
+      if(txTimeCounter>=100)
+        {
+          if(prTimerIndex>=0)
+            {
+              killTimer(prTimerIndex);
+              prTimerIndex=-1;
+              txWidgetPtr->setProgress(0);
+            }
+        }
+      txWidgetPtr->setProgress(txTimeCounter);
+    }
+}
+
+void dispatcher::slotRXNotification(QString info)
+{
+  if (info != "")
+    {
+      rxWidgetPtr->appendDRMNotifyText(info);
+    }
+}
+
+void dispatcher::slotTXNotification(QString info)
+{
+  if (info != "")
+    {
+      txWidgetPtr->appendDRMNotifyText(info);
     }
-    txWidgetPtr->setProgress(txTimeCounter);
-  }
 }
+
+
+void dispatcher::slotHybridTxDone(bool error)
+{
+  if(error)
+    {
+      hybridTxDone=DFTPERROR;
+    }
+  else
+    {
+      hybridTxDone=DFTPOK;
+    }
+
+}
+
+
diff --git a/qsstv/dispatch/dispatcher.h b/qsstv/dispatch/dispatcher.h
index b89d16f..d35d18b 100644
--- a/qsstv/dispatch/dispatcher.h
+++ b/qsstv/dispatch/dispatcher.h
@@ -29,47 +29,64 @@ class editor;
 class imageViewer;
 #include <QProgressDialog>
 
+enum eftpResult {DFTPWAITING,DFTPOK,DFTPERROR};
 
 /**
 @author Johan Maes
 */
 class dispatcher : public QObject
 {
-	Q_OBJECT
+  Q_OBJECT
 
 public:
 
-	dispatcher();
-	~dispatcher();
-	void init();
+  dispatcher();
+  ~dispatcher();
+  void init();
   void idleAll();
   void startRX();
   void startTX(txFunctions::etxState state);
+  void prepareTX(txFunctions::etxState state);
   void readSettings();
   void writeSettings();
   void customEvent( QEvent * e );
   void startDRMFIXTx(QByteArray ba);
   void startDRMTxBinary();
-//  void startDRMHybridTx(QString fn);
-//  void startDRMHybridText(QString txt);
-//  void sendSweepTone(double duration,double lowerFreq,double upperFreq);
-  void saveImage(QString fileName);
+  //  void startDRMHybridTx(QString fn);
+  //  void startDRMHybridText(QString txt);
+  //  void sendSweepTone(double duration,double lowerFreq,double upperFreq);
+  void saveImage(QString fileName, QString infotext);
+  void uploadToRXServer(QString remoteDir, QString fn);
   void logSSTV(QString call, bool fromFSKID);
+  void setOnlineStatus(bool online, QString info="");
+  void who();
+  eftpResult notifyRXDone;
+  eftpResult hybridTxDone;
+  eftpResult notifyTxDone;
+
+
+private slots:
+  void slotRXNotification(QString info);
+  void slotTXNotification(QString);
+//  void slotWhoResult();
+  void slotHybridTxDone(bool error);
+
 
 private:
-    void saveRxSSTVImage(QString shortModeName);
-    void timerEvent(QTimerEvent *event);
-    bool editorActive;
-    editor *ed;
-    imageViewer *iv;
-    int txTimeCounter;
-    int prTimerIndex;
-    int logTimerIndex;
-    textDisplay *infoTextPtr;
-    QMessageBox *mbox;
-    QProgressDialog *progressFTP;
-    QString lastFileName;
-    QDateTime saveTimeStamp;
+  void saveRxSSTVImage(QString shortModeName);
+  void timerEvent(QTimerEvent *event);
+  bool editorActive;
+  editor *ed;
+  imageViewer *iv;
+  int txTimeCounter;
+  int prTimerIndex;
+  int logTimerIndex;
+  textDisplay *infoTextPtr;
+  QMessageBox *mbox;
+  QProgressDialog *progressFTP;
+  QString lastFileName;
+  QString lastCallsign;
+  QDateTime saveTimeStamp;
 };
 #endif
 
diff --git a/qsstv/dispatch/dispatchevents.h b/qsstv/dispatch/dispatchevents.h
index 37d8037..bcd82cd 100644
--- a/qsstv/dispatch/dispatchevents.h
+++ b/qsstv/dispatch/dispatchevents.h
@@ -25,64 +25,72 @@
 #include "appdefs.h"
 #include <unistd.h>
 
+class ftpInterface;
+
 
 /** dispatch events are used to communicate with the different threads */
 enum dispatchEventType
 {
-    info = QEvent::User, //!< send when dsp stops running
-    soundcardIdle, //!< send when soundcard stops running
-    displayFFT,
-    displaySync,
-    displayDRMStat,
-    displayDRMInfo,
-    syncDisp,				//!< synchro display event
-    lineDisplay,				//!< display 1 line
-    eraseDisp,
-    createMode,
-    startImageRX,
-    endSSTVImageRX,
-    endImageTX,
-    stoppingTX,
-    progressTX,
-    //  verticalRetrace,
-    //  syncLost,
-    outOfSync,
-    statusMsg,  	//!<  display status message
-    rxSSTVStatus,     //! shows message in sstv tab
-    rxDRMStatus,     //! shows message in drm tab
-    rxDRMNotify,	//! shows text in rx notifications box
-    rxDRMNotifyAppend,
-    txDRMNotify,  //! shows text in tx notifications box
-    txDRMNotifyAppend,
-    closeWindows,
-    callEditor,
-    templatesChanged,
-    editorFinished,
-    changeRXFilter,
-    startAutoRepeater,
-    startRepeater,
-    stopRxTx,
-    loadRXImage,
-    saveDRMImage,
-    prepareFix,
-    displayText,
-    displayMBox,
-    displayProgressFTP,
-    moveToTx
+  info = QEvent::User, //!< send when dsp stops running
+  soundcardIdle, //!< send when soundcard stops running
+  displayFFT,
+  displaySync,
+  displayDRMStat,
+  displayDRMInfo,
+  syncDisp,				//!< synchro display event
+  lineDisplay,				//!< display 1 line
+  eraseDisp,
+  createMode,
+  startImageRX,
+  endSSTVImageRX,
+  endImageTX,
+  stoppingTX,
+  progressTX,
+  //  verticalRetrace,
+  //  syncLost,
+  outOfSync,
+//  statusMsg,  	//!<  display status message
+  rxSSTVStatus,     //! shows message in sstv tab
+  rxDRMStatus,     //! shows message in drm tab
+  rxDRMNotify,	//! shows text in rx notifications box
+  rxDRMNotifyAppend,
+  txDRMNotify,  //! shows text in tx notifications box
+  txDRMNotifyAppend,
+  txPrepareComplete, //!< tx preparations (uploading etc) complete
+  closeWindows,
+  callEditor,
+  templatesChanged,
+  editorFinished,
+  changeRXFilter,
+  startAutoRepeater,
+  startRepeater,
+  stopRxTx,
+  loadRXImage,
+  saveDRMImage,
+  prepareFix,
+  displayText,
+  displayMBox,
+  displayProgressFTP,
+  moveToTx,
+  notifyAction,
+  ftpSetup,
+  notifyCheck,
+  ftpUploadFile,
+  statusBarMsg
 };
 
 class baseEvent: public QEvent
 {
 public:
-    baseEvent(QEvent::Type t):QEvent(t) {doneIt=NULL;}
-    void waitFor(bool *d) {doneIt=d;}
-    void setDone()
-    {
-        if(doneIt!=NULL) *doneIt=true;
-    }
-    QString description;
+  baseEvent(QEvent::Type t):QEvent(t) {doneIt=NULL;}
+  void waitFor(bool *d) {doneIt=d;}
+  void setDone()
+  {
+    if(doneIt!=NULL) *doneIt=true;
+  }
+  QString description;
 private:
-    bool *doneIt;
+  bool *doneIt;
 
 };
 
@@ -92,15 +100,15 @@ private:
 class infoEvent : public  baseEvent
 {
 public:
-    /** create event */
-    infoEvent(QString t):baseEvent( (QEvent::Type) info ), str(t)
-    {
-        description="infoEvent";
-    }
-    /** returns info string from the event */
-    QString getStr() const { return str; }
+  /** create event */
+  infoEvent(QString t):baseEvent( (QEvent::Type) info ), str(t)
+  {
+    description="infoEvent";
+  }
+  /** returns info string from the event */
+  QString getStr() const { return str; }
 private:
-    QString str;
+  QString str;
 };
 
 /**
@@ -109,76 +117,153 @@ private:
 class soundcardIdleEvent : public baseEvent
 {
 public:
-    /** create event */
-    soundcardIdleEvent():baseEvent( (QEvent::Type) soundcardIdle )
+  /** create event */
+  soundcardIdleEvent():baseEvent( (QEvent::Type) soundcardIdle )
+  {
     {
-        {
-            description=" soudcardIdleEvent";
-        }
+      description=" soudcardIdleEvent";
     }
+  }
 };
 
 
-//class rxDataAvailableEvent : public baseEvent
-//{
-//public:
-//	/** create event */
-//	rxDataAvailableEvent(uint idx,uint numSamples):baseEvent( (QEvent::Type)rxData ), index(idx),len(numSamples) {}
-//	/** returns length and pointer  from the event */
-//  uint getIndex(uint &idx) const { idx=index; return len;}
-
-//private:
-//  uint index;
-//	uint len;
-//};
-
-
 /**
   this event is send with teh sync quality info and the signal volume
 */
 class displaySyncEvent : public baseEvent
 {
 public:
-    /** create event */
-    displaySyncEvent(uint s):baseEvent( (QEvent::Type) displaySync), sync(s)
-    {
-        description=" displaySyncEvent";
-    }
-    /** returns int sync value */
-    void getInfo(uint &s)  {s=sync;}
+  /** create event */
+  displaySyncEvent(uint s):baseEvent( (QEvent::Type) displaySync), sync(s)
+  {
+    description=" displaySyncEvent";
+  }
+  /** returns int sync value */
+  void getInfo(uint &s)  {s=sync;}
 
 private:
-    uint sync;
-    DSPFLOAT vol;
+  uint sync;
+  DSPFLOAT vol;
 };
 
 class displayDRMStatEvent  : public baseEvent
 {
 public:
-    /** create event */
-    displayDRMStatEvent(uint s):baseEvent( (QEvent::Type) displayDRMStat), snr(s)
-    {
-        description=" displayDRMStatEvent";
-    }
-    /** returns length and pointer  from the event */
-    void getInfo(DSPFLOAT &s)  {s=snr;}
+  /** create event */
+  displayDRMStatEvent(uint s):baseEvent( (QEvent::Type) displayDRMStat), snr(s)
+  {
+    description=" displayDRMStatEvent";
+  }
+  /** returns length and pointer  from the event */
+  void getInfo(DSPFLOAT &s)  {s=snr;}
 
 private:
-    DSPFLOAT snr;
+  DSPFLOAT snr;
 };
 
-class statusMsgEvent : public baseEvent
+//class statusMsgEvent : public baseEvent
+//{
+//public:
+//  /** create event */
+//  statusMsgEvent(QString t):baseEvent( (QEvent::Type)statusMsg ), str(t)
+//  {
+//    description="statusMsgEvent";
+//  }
+//  /** returns info string from the event */
+//  QString getStr() const { return str; }
+//private:
+//  QString str;
+//};
+
+class ftpSetupEvent : public baseEvent
 {
 public:
-    /** create event */
-    statusMsgEvent(QString t):baseEvent( (QEvent::Type)statusMsg ), str(t)
-    {
-        description="statusMsgEvent";
-    }
-    /** returns info string from the event */
-    QString getStr() const { return str; }
+  /** create event */
+  ftpSetupEvent(ftpInterface * ftpIntf,QString h,int p,QString u,QString pwd,QString d)
+    :baseEvent( (QEvent::Type)ftpSetup ),ftpIntfPtr(ftpIntf), host(h),port(p),user(u),password(pwd),dir(d)
+  {
+    description="ftpSetupEvent";
+  }
+  /** returns settings from the event */
+  ftpInterface *getFtpIntfPtr() const { return ftpIntfPtr; }
+  QString getHost() const { return host; }
+  int getPort() const { return port; }
+  QString getUser() const { return user; }
+  QString getPassword() const { return password; }
+  QString getDir() const { return dir; }
+private:
+  ftpInterface *ftpIntfPtr;
+  QString host;
+  int port;
+  QString user;
+  QString password;
+  QString dir;
+};
+
+class ftpUploadFileEvent : public baseEvent
+{
+public:
+  /** create event */
+  ftpUploadFileEvent(ftpInterface * ftpIntf,QString srcFn,QString dstFn,bool recon)
+    :baseEvent( (QEvent::Type)ftpUploadFile ),ftpIntfPtr(ftpIntf),sourceFilename(srcFn), destFilename(dstFn),reconnect(recon)
+  {
+    description="ftpUploadFileEvent";
+  }
+  /** returns settings from the event */
+  ftpInterface *getFtpIntfPtr() const { return ftpIntfPtr; }
+  QString getSrcFn() const { return sourceFilename; }
+  QString getDstFn() const { return destFilename; }
+  bool   getReconnect() const { return reconnect; }
+private:
+  ftpInterface *ftpIntfPtr;
+  QString sourceFilename;
+  QString destFilename;
+  bool reconnect;
+};
+
+
+
+class notifyActionEvent : public baseEvent
+{
+public:
+  /** create event */
+  notifyActionEvent(QString toRem,QString message,QString fn)
+    :baseEvent( (QEvent::Type)notifyAction ), toRemove(toRem),msg(message),filename(fn)
+  {
+    description="notifyActionEvent";
+  }
+  /** returns settings from the event */
+  QString getToRemove() const { return toRemove; }
+  QString getMsg() const { return msg; }
+  QString getFilename() const { return filename; }
+private:
+  QString toRemove;
+  QString msg;
+  QString filename;
+};
+
+
+class notifyCheckEvent : public baseEvent
+{
+public:
+  /** create event */
+  notifyCheckEvent(ftpInterface * ftpIntf,QString fn,int intv, int rp, bool rm)
+    :baseEvent( (QEvent::Type)notifyCheck),ftpIntfPtr(ftpIntf), filename(fn),interval(intv),repeats(rp),remove(rm)
+  {
+    description="notifyCheckEvent";
+  }
+  /** returns settings from the event */
+  ftpInterface *getFtpIntfPtr() const { return ftpIntfPtr; }
+  QString getFilename() const { return filename; }
+  int getInterval() const { return interval; }
+  int getRepeats() const { return repeats; }
+  bool getToRemove() const { return remove; }
 private:
-    QString str;
+  ftpInterface *ftpIntfPtr;
+  QString filename;
+  int interval;
+  int repeats;
+  bool remove;
 };
 
 
@@ -186,29 +271,29 @@ private:
 class rxSSTVStatusEvent : public baseEvent
 {
 public:
-    /** create event */
-    rxSSTVStatusEvent(QString t):baseEvent( (QEvent::Type)rxSSTVStatus ), str(t)
-    {
-        description="rxSSTVStatusEvent";
-    }
-    /** returns info string from the event */
-    QString getStr() const { return str; }
+  /** create event */
+  rxSSTVStatusEvent(QString t):baseEvent( (QEvent::Type)rxSSTVStatus ), str(t)
+  {
+    description="rxSSTVStatusEvent";
+  }
+  /** returns info string from the event */
+  QString getStr() const { return str; }
 private:
-    QString str;
+  QString str;
 };
 
 class rxDRMStatusEvent : public baseEvent
 {
 public:
-    /** create event */
-    rxDRMStatusEvent(QString t):baseEvent( (QEvent::Type)rxDRMStatus ), str(t)
-    {
-        description="rxDRMStatusEvent";
-    }
-    /** returns info string from the event */
-    QString getStr() const { return str; }
+  /** create event */
+  rxDRMStatusEvent(QString t):baseEvent( (QEvent::Type)rxDRMStatus ), str(t)
+  {
+    description="rxDRMStatusEvent";
+  }
+  /** returns info string from the event */
+  QString getStr() const { return str; }
 private:
-    QString str;
+  QString str;
 };
 
 class rxDRMNotifyEvent : public baseEvent
@@ -263,34 +348,47 @@ public:
   }
   /** returns info string from the event */
   QString getStr() const { return str; }
- private:
-   QString str;
- };
+private:
+  QString str;
+};
 
+class txPrepareCompleteEvent : public baseEvent
+{
+public:
+  /** create event */
+  txPrepareCompleteEvent(bool tok):baseEvent( (QEvent::Type)txPrepareComplete ), _ok(tok)
+  {
+    description="txPrepareCompleteEvent";
+  }
+  /** returns info string from the event */
+  bool ok() const { return _ok; }
+private:
+  bool _ok;
+};
 
 class lineDisplayEvent : public baseEvent
 {
 public:
-    /** create event */
-    lineDisplayEvent(uint lineNbr):baseEvent( (QEvent::Type)lineDisplay ), lineNumber(lineNbr)
-    {
-        description="lineDisplayEvent";
-    }
-    /** returns length and pointer  from the event */
-    void getInfo(uint &lineNbr) const { lineNbr=lineNumber;}
+  /** create event */
+  lineDisplayEvent(uint lineNbr):baseEvent( (QEvent::Type)lineDisplay ), lineNumber(lineNbr)
+  {
+    description="lineDisplayEvent";
+  }
+  /** returns length and pointer  from the event */
+  void getInfo(uint &lineNbr) const { lineNbr=lineNumber;}
 
 private:
-    uint lineNumber;
+  uint lineNumber;
 };
 
 class eraseDisplayEvent : public baseEvent
 {
 public:
-    /** create event */
-    eraseDisplayEvent():baseEvent( (QEvent::Type)eraseDisp )
-    {
-        description="eraseDisplayEvent";
-    }
+  /** create event */
+  eraseDisplayEvent():baseEvent( (QEvent::Type)eraseDisp )
+  {
+    description="eraseDisplayEvent";
+  }
 };
 
 
@@ -298,72 +396,72 @@ public:
 class displayDRMInfoEvent : public baseEvent
 {
 public:
-    /** create event */
-    displayDRMInfoEvent():baseEvent( (QEvent::Type)displayDRMInfo)
-    {
-        description="displayDRMInfo";
-    }
+  /** create event */
+  displayDRMInfoEvent():baseEvent( (QEvent::Type)displayDRMInfo)
+  {
+    description="displayDRMInfo";
+  }
 };
 
 class startAutoRepeaterEvent: public baseEvent
 {
 public:
-    /** create event */
-    startAutoRepeaterEvent():baseEvent( (QEvent::Type)startAutoRepeater )
-    {
-        description="startAutoRepeaterEvent";
-    }
+  /** create event */
+  startAutoRepeaterEvent():baseEvent( (QEvent::Type)startAutoRepeater )
+  {
+    description="startAutoRepeaterEvent";
+  }
 };
 
 class startRepeaterEvent: public baseEvent
 {
 public:
-    /** create event */
-    startRepeaterEvent():baseEvent( (QEvent::Type)startRepeater )
-    {
-        description="startRepeaterEvent";
-    }
+  /** create event */
+  startRepeaterEvent():baseEvent( (QEvent::Type)startRepeater )
+  {
+    description="startRepeaterEvent";
+  }
 };
 
 
 class createModeEvent : public baseEvent
 {
 public:
-    /** create event */
-    createModeEvent(uint m,QString t):baseEvent( (QEvent::Type)createMode ), mode(m) ,str(t)
-    {
-        description="createModeEvent";
-    }
-    /** returns info string from the event */
-    void getMode(uint &m,QString &s) const { m=mode;s=str; }
+  /** create event */
+  createModeEvent(uint m,QString t):baseEvent( (QEvent::Type)createMode ), mode(m) ,str(t)
+  {
+    description="createModeEvent";
+  }
+  /** returns info string from the event */
+  void getMode(uint &m,QString &s) const { m=mode;s=str; }
 private:
-    uint mode;
-    QString str;
+  uint mode;
+  QString str;
 };
 
 class loadRXImageEvent : public baseEvent
 {
 public:
-    loadRXImageEvent(QString fn):baseEvent( (QEvent::Type)loadRXImage),fileName(fn)
-    {
-        description="loadRXImageEvent";
-    }
-    QString getFilename() {return fileName;}
+  loadRXImageEvent(QString fn):baseEvent( (QEvent::Type)loadRXImage),fileName(fn)
+  {
+    description="loadRXImageEvent";
+  }
+  QString getFilename() {return fileName;}
 private:
-    QString fileName;
+  QString fileName;
 };
 
 
 class moveToTxEvent : public baseEvent
 {
 public:
-    moveToTxEvent(QString fn):baseEvent( (QEvent::Type)moveToTx),fileName(fn)
-    {
-        description="moveToTxEvent";
-    }
-    QString getFilename() {return fileName;}
+  moveToTxEvent(QString fn):baseEvent( (QEvent::Type)moveToTx),fileName(fn)
+  {
+    description="moveToTxEvent";
+  }
+  QString getFilename() {return fileName;}
 private:
-    QString fileName;
+  QString fileName;
 };
 
 
@@ -371,13 +469,15 @@ private:
 class saveDRMImageEvent : public baseEvent
 {
 public:
-    saveDRMImageEvent(QString fn):baseEvent( (QEvent::Type)saveDRMImage),fileName(fn)
-    {
-        description="saveDRMImageEvent";
-    }
-    void getFilename(QString &fn) {fn=fileName;}
+  saveDRMImageEvent(QString fn,QString i):baseEvent( (QEvent::Type)saveDRMImage),fileName(fn),info(i)
+  {
+    description="saveDRMImageEvent";
+  }
+  void getFilename(QString &fn) {fn=fileName;}
+  void getInfo(QString &i) {i=info;}
 private:
-    QString fileName;
+  QString fileName;
+  QString info;
 };
 
 
@@ -385,49 +485,49 @@ private:
 class startImageRXEvent : public baseEvent
 {
 public:
-    /** create event */
-    startImageRXEvent(QSize ims):baseEvent( (QEvent::Type)startImageRX ),imSize(ims)
-    {
-        description="startImageRXEvent";
-    }
-    QSize getSize()  {return imSize;}
+  /** create event */
+  startImageRXEvent(QSize ims):baseEvent( (QEvent::Type)startImageRX ),imSize(ims)
+  {
+    description="startImageRXEvent";
+  }
+  QSize getSize()  {return imSize;}
 private:
-    QSize imSize;
+  QSize imSize;
 
 };
 
 class endImageSSTVRXEvent : public baseEvent
 {
 public:
-    /** create event */
-    endImageSSTVRXEvent(QString mn):baseEvent( (QEvent::Type)endSSTVImageRX ),modeName(mn)
-    {
-        description="endImageSSTVRXEvent";
-    }
-    QString getModeName() {return modeName;}
+  /** create event */
+  endImageSSTVRXEvent(QString mn):baseEvent( (QEvent::Type)endSSTVImageRX ),modeName(mn)
+  {
+    description="endImageSSTVRXEvent";
+  }
+  QString getModeName() {return modeName;}
 private:
-    QString modeName;
+  QString modeName;
 };
 
 class endImageTXEvent : public baseEvent
 {
 public:
-    /** create event */
-    endImageTXEvent():baseEvent( (QEvent::Type)endImageTX )
-    {
-        description="endImageTXEvent";
-    }
+  /** create event */
+  endImageTXEvent():baseEvent( (QEvent::Type)endImageTX )
+  {
+    description="endImageTXEvent";
+  }
 };
 
 
 class stopTXEvent : public baseEvent
 {
 public:
-    /** create event */
-    stopTXEvent():baseEvent( (QEvent::Type)stoppingTX )
-    {
-        description="stopTXEvent";
-    }
+  /** create event */
+  stopTXEvent():baseEvent( (QEvent::Type)stoppingTX )
+  {
+    description="stopTXEvent";
+  }
 };
 
 //class verticalRetraceEvent : public baseEvent
@@ -455,11 +555,11 @@ public:
 class outOfSyncEvent : public baseEvent
 {
 public:
-    /** create event */
-    outOfSyncEvent():baseEvent( (QEvent::Type)outOfSync )
-    {
-        description="outOfSyncEvent";
-    }
+  /** create event */
+  outOfSyncEvent():baseEvent( (QEvent::Type)outOfSync )
+  {
+    description="outOfSyncEvent";
+  }
 };
 
 
@@ -467,27 +567,27 @@ public:
 class progressTXEvent : public baseEvent
 {
 public:
-    /** create event */
-    progressTXEvent(double tim):baseEvent( (QEvent::Type)progressTX ), txTime(tim)
-    {
-        description="progressTXEvent";
-    }
-    /** returns length and pointer  from the event */
-    double getInfo() { return txTime;}
+  /** create event */
+  progressTXEvent(double tim):baseEvent( (QEvent::Type)progressTX ), txTime(tim)
+  {
+    description="progressTXEvent";
+  }
+  /** returns length and pointer  from the event */
+  double getInfo() { return txTime;}
 
 private:
-    double txTime;
+  double txTime;
 };
 
 class closeWindowsEvent : public baseEvent
 {
 public:
-    /** create event */
-    closeWindowsEvent():baseEvent( (QEvent::Type)closeWindows)
-    {
-        description="closeWindowEvent";
-    }
-    /** returns length and pointer  from the event */
+  /** create event */
+  closeWindowsEvent():baseEvent( (QEvent::Type)closeWindows)
+  {
+    description="closeWindowEvent";
+  }
+  /** returns length and pointer  from the event */
 };
 
 
@@ -495,44 +595,44 @@ public:
 class callEditorEvent : public baseEvent
 {
 public:
-    /** create event */
-    callEditorEvent(imageViewer *iv,QString fn):baseEvent( (QEvent::Type) callEditor ), filename(fn),imviewer(iv)
-    {
-        description="callEditorEvent";
-    }
-    /** returns info string from the event */
-    QString getFilename() const { return filename; }
-    imageViewer *getImageViewer() { return imviewer; }
+  /** create event */
+  callEditorEvent(imageViewer *iv,QString fn):baseEvent( (QEvent::Type) callEditor ), filename(fn),imviewer(iv)
+  {
+    description="callEditorEvent";
+  }
+  /** returns info string from the event */
+  QString getFilename() const { return filename; }
+  imageViewer *getImageViewer() { return imviewer; }
 private:
-    QString filename;
-    imageViewer *imviewer;
+  QString filename;
+  imageViewer *imviewer;
 };
 
 
 class templatesChangedEvent : public baseEvent
 {
 public:
-    /** create event */
-    templatesChangedEvent():baseEvent( (QEvent::Type) templatesChanged )
-    {
-        description="templateChangeEvent";
-    }
+  /** create event */
+  templatesChangedEvent():baseEvent( (QEvent::Type) templatesChanged )
+  {
+    description="templateChangeEvent";
+  }
 };
 
 class editorFinishedEvent : public baseEvent
 {
 public:
-    /** create event */
-    editorFinishedEvent(bool b,QString fn):baseEvent( (QEvent::Type)editorFinished),ok(b),filename(fn)
-    {
-        description="editorFinishedEvent";
-    }
-    bool isOK() { return ok;}
-    QString getFilename() const { return filename; }
+  /** create event */
+  editorFinishedEvent(bool b,QString fn):baseEvent( (QEvent::Type)editorFinished),ok(b),filename(fn)
+  {
+    description="editorFinishedEvent";
+  }
+  bool isOK() { return ok;}
+  QString getFilename() const { return filename; }
 
 private:
-    bool ok;
-    QString filename;
+  bool ok;
+  QString filename;
 
 };
 
@@ -540,51 +640,51 @@ private:
 class displayFFTEvent : public baseEvent
 {
 public:
-    /** create event */
-    displayFFTEvent(DSPFLOAT *buf):baseEvent( (QEvent::Type)displayFFT),buffer(buf)
-    {
-        description="displayFFTEvent";
-    }
-    DSPFLOAT *data() { return buffer;}
+  /** create event */
+  displayFFTEvent(DSPFLOAT *buf):baseEvent( (QEvent::Type)displayFFT),buffer(buf)
+  {
+    description="displayFFTEvent";
+  }
+  DSPFLOAT *data() { return buffer;}
 private:
-    DSPFLOAT *buffer;
+  DSPFLOAT *buffer;
 
 };
 
 class filterRXChangedEvent: public baseEvent
 {
 public:
-    /** create event */
-    filterRXChangedEvent(int fIndex):baseEvent( (QEvent::Type)changeRXFilter),filterIndex(fIndex)
-    {
-        description="filterChangedEvent";
-    }
-    int index() { return filterIndex;}
+  /** create event */
+  filterRXChangedEvent(int fIndex):baseEvent( (QEvent::Type)changeRXFilter),filterIndex(fIndex)
+  {
+    description="filterChangedEvent";
+  }
+  int index() { return filterIndex;}
 private:
-    int filterIndex;
+  int filterIndex;
 };
 
 class stopRxTxEvent : public baseEvent
 {
 public:
-    /** create event */
-    stopRxTxEvent():baseEvent( (QEvent::Type)stopRxTx)
-    {
-        description="stopRxTxEvent";
-    }
+  /** create event */
+  stopRxTxEvent():baseEvent( (QEvent::Type)stopRxTx)
+  {
+    description="stopRxTxEvent";
+  }
 };
 
 
 class prepareFixEvent: public baseEvent
 {
 public:
-    prepareFixEvent(QByteArray ba):baseEvent( (QEvent::Type)prepareFix),data(ba)
-    {
-        description="filterChangedEvent";
-    }
-    QByteArray &getData() {return data;}
+  prepareFixEvent(QByteArray ba):baseEvent( (QEvent::Type)prepareFix),data(ba)
+  {
+    description="filterChangedEvent";
+  }
+  QByteArray &getData() {return data;}
 private:
-    QByteArray data;
+  QByteArray data;
 };
 
 
@@ -594,51 +694,65 @@ private:
 class displayTextEvent : public  baseEvent
 {
 public:
-    /** create event */
-    displayTextEvent(QString t):baseEvent( (QEvent::Type) displayText ), str(t)
-    {
-        description="displayTextEvent";
-    }
-    /** returns info string from the event */
-    QString getStr() const { return str; }
+  /** create event */
+  displayTextEvent(QString t):baseEvent( (QEvent::Type) displayText ), str(t)
+  {
+    description="displayTextEvent";
+  }
+  /** returns info string from the event */
+  QString getStr() const { return str; }
 private:
-    QString str;
+  QString str;
 };
 
 class displayMBoxEvent : public  baseEvent
 {
 public:
-    /** create event */
-    displayMBoxEvent(QString title,QString text):baseEvent( (QEvent::Type) displayMBox ), str(text), title(title)
-    {
-        description="displayMBoxEvent";
-    }
-    /** returns info string from the event */
-    QString getStr() const { return str; }
-    QString getTitle() const { return title; }
+  /** create event */
+  displayMBoxEvent(QString title,QString text):baseEvent( (QEvent::Type) displayMBox ), str(text), title(title)
+  {
+    description="displayMBoxEvent";
+  }
+  /** returns info string from the event */
+  QString getStr() const { return str; }
+  QString getTitle() const { return title; }
 
 private:
-    QString str;
-    QString title;
+  QString str;
+  QString title;
 };
 
 
 class displayProgressFTPEvent : public  baseEvent
 {
 public:
-    /** create event */
-    displayProgressFTPEvent(quint64 byts,quint64 tot):baseEvent( (QEvent::Type) displayProgressFTP ),  bytes(byts),total(tot)
-    {
-        description="displayMBoxEvent";
-    }
-    /** returns info string from the event */
-    quint64 getTotal() const { return total; }
-    quint64 getBytes() const { return bytes; }
+  /** create event */
+  displayProgressFTPEvent(quint64 byts,quint64 tot):baseEvent( (QEvent::Type) displayProgressFTP ),  bytes(byts),total(tot)
+  {
+    description="displayMBoxEvent";
+  }
+  /** returns info string from the event */
+  quint64 getTotal() const { return total; }
+  quint64 getBytes() const { return bytes; }
 
 private:
-    quint64 bytes;
-    quint64 total;
+  quint64 bytes;
+  quint64 total;
 
 };
 
+class statusBarMsgEvent : public baseEvent
+{
+public:
+  /** create event */
+  statusBarMsgEvent(QString t):baseEvent( (QEvent::Type)statusBarMsg ), str(t)
+  {
+    description="statusBarMsgEvent";
+  }
+  /** returns info string from the event */
+  QString getStr() const { return str; }
+private:
+  QString str;
+};
+
 #endif
diff --git a/qsstv/documentation/manual/images/Gallery_rx.png b/qsstv/documentation/manual/images/Gallery_rx.png
index c7ed4f1..3de5831 100644
Binary files a/qsstv/documentation/manual/images/Gallery_rx.png and b/qsstv/documentation/manual/images/Gallery_rx.png differ
diff --git a/qsstv/documentation/manual/images/Gallery_templates.png b/qsstv/documentation/manual/images/Gallery_templates.png
new file mode 100644
index 0000000..ff922fb
Binary files /dev/null and b/qsstv/documentation/manual/images/Gallery_templates.png differ
diff --git a/qsstv/documentation/manual/images/Gallery_txdrm.png b/qsstv/documentation/manual/images/Gallery_txdrm.png
new file mode 100644
index 0000000..fd5e4c1
Binary files /dev/null and b/qsstv/documentation/manual/images/Gallery_txdrm.png differ
diff --git a/qsstv/documentation/manual/images/config.png b/qsstv/documentation/manual/images/config.png
index 39bce23..cb13e09 100644
Binary files a/qsstv/documentation/manual/images/config.png and b/qsstv/documentation/manual/images/config.png differ
diff --git a/qsstv/documentation/manual/images/config3.png b/qsstv/documentation/manual/images/config3.png
index eaf589f..80c64b4 100644
Binary files a/qsstv/documentation/manual/images/config3.png and b/qsstv/documentation/manual/images/config3.png differ
diff --git a/qsstv/documentation/manual/images/config4.png b/qsstv/documentation/manual/images/config4.png
index 887ae2b..be24342 100644
Binary files a/qsstv/documentation/manual/images/config4.png and b/qsstv/documentation/manual/images/config4.png differ
diff --git a/qsstv/documentation/manual/images/config5.png b/qsstv/documentation/manual/images/config5.png
index 709b761..1816297 100644
Binary files a/qsstv/documentation/manual/images/config5.png and b/qsstv/documentation/manual/images/config5.png differ
diff --git a/qsstv/documentation/manual/images/config8.png b/qsstv/documentation/manual/images/config8.png
index 44001f9..9a052c3 100644
Binary files a/qsstv/documentation/manual/images/config8.png and b/qsstv/documentation/manual/images/config8.png differ
diff --git a/qsstv/documentation/manual/images/receivedrm.png b/qsstv/documentation/manual/images/receivedrm.png
index 7945ee2..d20660a 100644
Binary files a/qsstv/documentation/manual/images/receivedrm.png and b/qsstv/documentation/manual/images/receivedrm.png differ
diff --git a/qsstv/documentation/manual/images/transmitdrm.png b/qsstv/documentation/manual/images/transmitdrm.png
index e329d32..c3b029a 100644
Binary files a/qsstv/documentation/manual/images/transmitdrm.png and b/qsstv/documentation/manual/images/transmitdrm.png differ
diff --git a/qsstv/documentation/manual/manual.doxy b/qsstv/documentation/manual/manual.doxy
index c5d3b5c..ee00246 100644
--- a/qsstv/documentation/manual/manual.doxy
+++ b/qsstv/documentation/manual/manual.doxy
@@ -32,7 +32,7 @@ PROJECT_NAME           = QSSTV
 # This could be handy for archiving the generated documentation or
 # if some version control system is used.
 
-PROJECT_NUMBER         = 9.1
+PROJECT_NUMBER         = 9.2
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer
diff --git a/qsstv/documentation/manual/manual.txt b/qsstv/documentation/manual/manual.txt
index 22676b3..76a1b76 100644
--- a/qsstv/documentation/manual/manual.txt
+++ b/qsstv/documentation/manual/manual.txt
@@ -22,7 +22,7 @@ n/***************************************************************************
 /** \file */
 
 // Documentation
-/*! \mainpage QSSTV 9.1
+/*! \mainpage QSSTV 9.2
 \author Johan Maes ON4QZ
 
 \section intro_sec Introduction
@@ -56,7 +56,7 @@ Johan ON4QZ
 
 
 \page whatsnew What's New
-QSSTV 9.1.x has the following new features compared to QSSTV 8.2.x
+QSSTV 9.2.x has the following new features compared to QSSTV 8.2.x
 
 - Build on top QT 5.x ( and also compatible with Qt 4.8)
 - Better synchronization in SSTV mode
@@ -76,8 +76,34 @@ QSSTV 9.1.x has the following new features compared to QSSTV 8.2.x
 
 \page changelog Change log
 
+\li 20161022 QSSTV 9.2.4
+- some minor bugfixing
+- eliminated online status setting in Config Notication tab (doubled with setting in Operator settings)
+- bug fix: incremental counter on filename wih hybrid mode
+- added filename to statusbar when sending DRM image
+
+\li 20161021 QSSTV 9.2.3
+- bug fix: memory leak in tx DRM when loading/resizing images
+- faster compression of tx images
+- bug-fix: hybrid mode saved images with wrong file extension. Receivers tried downloading wrong file.
+- Added all the patches (more then 20) from Mike, VK6M: rx/tx notifications and a large number of patches for image handling
+- Added new features (such a save waterfall image) implmented by Mike, VK6M
+- Todo: update the documentation !
+
+
+
+\li 20160929 QSSTV 9.2.2
+- added CTRL_F keyboard shortcut to switch to and from full screen. This is mainly used on low resolution screens where the top and/or
+bottom taskbars are masking part of the QSSTV window.
+
+\li 20160929 QSSTV 9.2.1
+- added low Resolution mode
+- changed SSTV sync detection
+- some minor bug fixes
+
+
 \li 20160703 QSSTV 9.1.8
- - The program uses jp2 files for sending images in DRM mode. The file extensions where not correct. ->fixed
+ - The program uses jp2 files for sending images in DRM mode. The file extensions were not correct. ->fixed
  - changes of the configuration do not need a restart of the program anymore (adding templates, stock images, DRM Profiles)
  - images in the gallery are now resized.
  - added menu option To Tx in Gallery Images RX and TX.
@@ -261,6 +287,10 @@ The following tabs are available
 Push the push button to select the colour selector.
 - Gallery: Rows and columns: set-up the number of rows and columns to be used in the Gallery tab. If you're running on a slow CPU (like on a Raspberry Pi) select row=1 and columns=1.
 - Slow CPU: Select this option if you're running on a slow CPU (e.g. Rapsberry Pi)
+- Low Resolution: Select this option if your display is for example 800x480. This options sets the maximum vertical resolution of QSSTV to less than 480 lines. It therefore removes some features
+from the receive window (Rx Notification Window in DRM) and the transmit window (Image replay Preview and TX Notifications in DRM mode).
+You can toggle to and from full screen by using the CTRL_F key combination.
+
 
 <br><br>
 
@@ -394,8 +424,7 @@ You will either see a pop-up with "Connection OK" or an error message showing th
 \image html config10.png
 <br><br>
 - Enable Reception in Hybrid Mode: allows reception of hamDRM in hybrid mode. If this is not enabled, hybrid mode files will not be shown or stored.
-- Enable Special server: Activate only if you want to use a different server than the preprogrammed default one of VK4AES
-- FTP Port: default 21
+- FTP Port: default 21 (cannot be modified at this moment for compatibility with EasyPal)
 - Remote Hostname: hostname of your ftp server
 - Remote directory:the ftp server directory where the stored images are
 - FTP Login name: the login name on the server
@@ -737,15 +766,17 @@ The Gallery contains six tabs. The directories where the different images are st
 <br>
 \image html Gallery_rx.png
 <br>
--RX SSTV: SSTV images are stored on disk and shown here if the Auto-save is enabled in the receive window and the minimum percentage is reached
--RX DRM:  All images received in DRM mode are stored on disk and shown here.
--TX SSTV: When sending an image in SSTV mode then the resulting images is stored on disk and shown here (this includes the template overlay).
--TX DRM:  When sending an image in SSTV mode then the resulting images is stored on disk and shown here (this includes the template overlay).
--TX Stock: Contains your selection of "Stock" images you want to use for transmission.
--Templates <br> <br>
-\image html Gallery_tx.png
--Templates: template images to be used as overlay on tx images
-\image html Gallery_template.png
+- RX SSTV: SSTV images are stored on disk and shown here if the Auto-save is enabled in the receive window and the minimum percentage is reached
+- RX DRM:  All images received in DRM mode are stored on disk and shown here.
+- TX SSTV: When sending an image in SSTV mode then the resulting images is stored on disk and shown here (this includes the template overlay).
+- TX DRM:  When sending an image in SSTV mode then the resulting images is stored on disk and shown here (this includes the template overlay).
+- TX Stock: Contains your selection of "Stock" images you want to use for transmission.
+- Templates: template images to be used as overlay on tx images
+<br> <br>
+Some examles
+\image html Gallery_txdrm.png
+<br>
+\image html Gallery_templates.png
 
 
 
@@ -875,7 +906,6 @@ Easypal was used extensively to test my program. <br>
 Erik is now silent key as of 14th march 2015.     We will miss him.
 <br>
 I hope there will be other OM's that take up the maintenance,enhancements  and development of EasyPal so that people running Windows will continue to enjoy his software.
-<br>reference: http://vk4aes.com/
 
 \page externalprog External Programs
 
diff --git a/qsstv/documentation/manual/manual/Copying.html b/qsstv/documentation/manual/manual/Copying.html
index 8d8ba81..a02f06c 100644
--- a/qsstv/documentation/manual/manual/Copying.html
+++ b/qsstv/documentation/manual/manual/Copying.html
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -67,8 +67,8 @@ $(document).ready(function(){initNavTree('Copying.html','');});
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.2</a></li>
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/documentation/manual/manual/Gallery_rx.png b/qsstv/documentation/manual/manual/Gallery_rx.png
index c7ed4f1..3de5831 100644
Binary files a/qsstv/documentation/manual/manual/Gallery_rx.png and b/qsstv/documentation/manual/manual/Gallery_rx.png differ
diff --git a/qsstv/documentation/manual/manual/Gallery_templates.png b/qsstv/documentation/manual/manual/Gallery_templates.png
new file mode 100644
index 0000000..ff922fb
Binary files /dev/null and b/qsstv/documentation/manual/manual/Gallery_templates.png differ
diff --git a/qsstv/documentation/manual/manual/Gallery_txdrm.png b/qsstv/documentation/manual/manual/Gallery_txdrm.png
new file mode 100644
index 0000000..fd5e4c1
Binary files /dev/null and b/qsstv/documentation/manual/manual/Gallery_txdrm.png differ
diff --git a/qsstv/documentation/manual/manual/RXDRM.html b/qsstv/documentation/manual/manual/RXDRM.html
index 095e8fd..2e07b0c 100644
--- a/qsstv/documentation/manual/manual/RXDRM.html
+++ b/qsstv/documentation/manual/manual/RXDRM.html
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -128,8 +128,8 @@ $(document).ready(function(){initNavTree('RXDRM.html','');});
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.2</a></li>
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/documentation/manual/manual/RXSSTV.html b/qsstv/documentation/manual/manual/RXSSTV.html
index 7a3872b..6c354aa 100644
--- a/qsstv/documentation/manual/manual/RXSSTV.html
+++ b/qsstv/documentation/manual/manual/RXSSTV.html
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -111,8 +111,8 @@ $(document).ready(function(){initNavTree('RXSSTV.html','');});
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.2</a></li>
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/documentation/manual/manual/TXDRM.html b/qsstv/documentation/manual/manual/TXDRM.html
index fba95bf..b332e1f 100644
--- a/qsstv/documentation/manual/manual/TXDRM.html
+++ b/qsstv/documentation/manual/manual/TXDRM.html
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -114,8 +114,8 @@ Avoid to send huge images (especially if you're not in hybrid mode).<br />
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.2</a></li>
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/documentation/manual/manual/TXSSTV.html b/qsstv/documentation/manual/manual/TXSSTV.html
index 10ea526..ad7d66d 100644
--- a/qsstv/documentation/manual/manual/TXSSTV.html
+++ b/qsstv/documentation/manual/manual/TXSSTV.html
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -139,8 +139,8 @@ $(document).ready(function(){initNavTree('TXSSTV.html','');});
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.2</a></li>
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/documentation/manual/manual/changelog.html b/qsstv/documentation/manual/manual/changelog.html
index 5f80d03..2319f93 100644
--- a/qsstv/documentation/manual/manual/changelog.html
+++ b/qsstv/documentation/manual/manual/changelog.html
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -62,8 +62,42 @@ $(document).ready(function(){initNavTree('changelog.html','');});
 </div><!--header-->
 <div class="contents">
 <div class="textblock"><ul>
+<li>20161022 QSSTV 9.2.4<ul>
+<li>some minor bugfixing</li>
+<li>eliminated online status setting in Config Notication tab (doubled with setting in Operator settings)</li>
+<li>bug fix: incremental counter on filename wih hybrid mode</li>
+<li>added filename to statusbar when sending DRM image</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>20161021 QSSTV 9.2.3<ul>
+<li>bug fix: memory leak in tx DRM when loading/resizing images</li>
+<li>faster compression of tx images</li>
+<li>bug-fix: hybrid mode saved images with wrong file extension. Receivers tried downloading wrong file.</li>
+<li>Added all the patches (more then 20) from Mike, VK6M: rx/tx notifications and a large number of patches for image handling</li>
+<li>Added new features (such a save waterfall image) implmented by Mike, VK6M</li>
+<li>Todo: update the documentation !</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>20160929 QSSTV 9.2.2<ul>
+<li>added CTRL_F keyboard shortcut to switch to and from full screen. This is mainly used on low resolution screens where the top and/or bottom taskbars are masking part of the QSSTV window.</li>
+</ul>
+</li>
+</ul>
+<ul>
+<li>20160929 QSSTV 9.2.1<ul>
+<li>added low Resolution mode</li>
+<li>changed SSTV sync detection</li>
+<li>some minor bug fixes</li>
+</ul>
+</li>
+</ul>
+<ul>
 <li>20160703 QSSTV 9.1.8<ul>
-<li>The program uses jp2 files for sending images in DRM mode. The file extensions where not correct. ->fixed</li>
+<li>The program uses jp2 files for sending images in DRM mode. The file extensions were not correct. ->fixed</li>
 <li>changes of the configuration do not need a restart of the program anymore (adding templates, stock images, DRM Profiles)</li>
 <li>images in the gallery are now resized.</li>
 <li>added menu option To Tx in Gallery Images RX and TX.</li>
@@ -179,8 +213,8 @@ $(document).ready(function(){initNavTree('changelog.html','');});
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.2</a></li>
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/documentation/manual/manual/config.png b/qsstv/documentation/manual/manual/config.png
index 39bce23..cb13e09 100644
Binary files a/qsstv/documentation/manual/manual/config.png and b/qsstv/documentation/manual/manual/config.png differ
diff --git a/qsstv/documentation/manual/manual/config3.png b/qsstv/documentation/manual/manual/config3.png
index eaf589f..80c64b4 100644
Binary files a/qsstv/documentation/manual/manual/config3.png and b/qsstv/documentation/manual/manual/config3.png differ
diff --git a/qsstv/documentation/manual/manual/config4.png b/qsstv/documentation/manual/manual/config4.png
index 887ae2b..be24342 100644
Binary files a/qsstv/documentation/manual/manual/config4.png and b/qsstv/documentation/manual/manual/config4.png differ
diff --git a/qsstv/documentation/manual/manual/config5.png b/qsstv/documentation/manual/manual/config5.png
index 709b761..1816297 100644
Binary files a/qsstv/documentation/manual/manual/config5.png and b/qsstv/documentation/manual/manual/config5.png differ
diff --git a/qsstv/documentation/manual/manual/config8.png b/qsstv/documentation/manual/manual/config8.png
index 44001f9..9a052c3 100644
Binary files a/qsstv/documentation/manual/manual/config8.png and b/qsstv/documentation/manual/manual/config8.png differ
diff --git a/qsstv/documentation/manual/manual/credits.html b/qsstv/documentation/manual/manual/credits.html
index c3c17e9..3f163bb 100644
--- a/qsstv/documentation/manual/manual/credits.html
+++ b/qsstv/documentation/manual/manual/credits.html
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -81,15 +81,14 @@ and adapted by PA0MBO. For more information , see the manual of txrxamadrm.</li>
 <br />
 </p>
 <p>Erik is now silent key as of 14th march 2015. We will miss him. <br />
- I hope there will be other OM's that take up the maintenance,enhancements and development of EasyPal so that people running Windows will continue to enjoy his software. <br />
-reference: <a href="http://vk4aes.com/">http://vk4aes.com/</a> </p>
+ I hope there will be other OM's that take up the maintenance,enhancements and development of EasyPal so that people running Windows will continue to enjoy his software. </p>
 </div></div><!-- contents -->
 </div><!-- doc-content -->
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.2</a></li>
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/documentation/manual/manual/editor.html b/qsstv/documentation/manual/manual/editor.html
index 1122384..8caa955 100644
--- a/qsstv/documentation/manual/manual/editor.html
+++ b/qsstv/documentation/manual/manual/editor.html
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -193,8 +193,8 @@ You can enter multiple lines of text. Click OK, the window will be hidden and yo
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.2</a></li>
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/documentation/manual/manual/externalprog.html b/qsstv/documentation/manual/manual/externalprog.html
index 42c7f73..ee43d4c 100644
--- a/qsstv/documentation/manual/manual/externalprog.html
+++ b/qsstv/documentation/manual/manual/externalprog.html
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -103,8 +103,8 @@ $(document).ready(function(){initNavTree('externalprog.html','');});
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.2</a></li>
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/documentation/manual/manual/fixdrm.html b/qsstv/documentation/manual/manual/fixdrm.html
index 8e6f1bd..4f4e21c 100644
--- a/qsstv/documentation/manual/manual/fixdrm.html
+++ b/qsstv/documentation/manual/manual/fixdrm.html
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -73,8 +73,8 @@ $(document).ready(function(){initNavTree('fixdrm.html','');});
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.2</a></li>
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/documentation/manual/manual/gallery.html b/qsstv/documentation/manual/manual/gallery.html
index 36774d6..e4f9383 100644
--- a/qsstv/documentation/manual/manual/gallery.html
+++ b/qsstv/documentation/manual/manual/gallery.html
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -66,21 +66,30 @@ $(document).ready(function(){initNavTree('gallery.html','');});
 <img src="Gallery_rx.png" alt="Gallery_rx.png"/>
 </div>
 <p> <br />
- -RX SSTV: SSTV images are stored on disk and shown here if the Auto-save is enabled in the receive window and the minimum percentage is reached -RX DRM: All images received in DRM mode are stored on disk and shown here. -TX SSTV: When sending an image in SSTV mode then the resulting images is stored on disk and shown here (this includes the template overlay). -TX DRM: When sending an image in SSTV mode then the resulting images is stored on disk and shown here (this includes the templat [...]
+</p><ul>
+<li>RX SSTV: SSTV images are stored on disk and shown here if the Auto-save is enabled in the receive window and the minimum percentage is reached</li>
+<li>RX DRM: All images received in DRM mode are stored on disk and shown here.</li>
+<li>TX SSTV: When sending an image in SSTV mode then the resulting images is stored on disk and shown here (this includes the template overlay).</li>
+<li>TX DRM: When sending an image in SSTV mode then the resulting images is stored on disk and shown here (this includes the template overlay).</li>
+<li>TX Stock: Contains your selection of "Stock" images you want to use for transmission.</li>
+<li>Templates: template images to be used as overlay on tx images <br />
  <br />
- </p><div class="image">
-<img src="Gallery_tx.png" alt="Gallery_tx.png"/>
+ Some examles <div class="image">
+<img src="Gallery_txdrm.png" alt="Gallery_txdrm.png"/>
 </div>
-<p> -Templates: template images to be used as overlay on tx images </p><div class="image">
-<img src="Gallery_template.png" alt="Gallery_template.png"/>
+ <br />
+ <div class="image">
+<img src="Gallery_templates.png" alt="Gallery_templates.png"/>
 </div>
- </div></div><!-- contents -->
+ </li>
+</ul>
+</div></div><!-- contents -->
 </div><!-- doc-content -->
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.2</a></li>
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/documentation/manual/manual/gettingstarted.html b/qsstv/documentation/manual/manual/gettingstarted.html
index 7ecb832..4e83eb7 100644
--- a/qsstv/documentation/manual/manual/gettingstarted.html
+++ b/qsstv/documentation/manual/manual/gettingstarted.html
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -127,6 +127,7 @@ This information can also be used in templates (see also <a class="el" href="edi
 <li>Image Background Colour: Default image background Push the push button to select the colour selector.</li>
 <li>Gallery: Rows and columns: set-up the number of rows and columns to be used in the Gallery tab. If you're running on a slow CPU (like on a Raspberry Pi) select row=1 and columns=1.</li>
 <li>Slow CPU: Select this option if you're running on a slow CPU (e.g. Rapsberry Pi)</li>
+<li>Low Resolution: Select this option if your display is for example 800x480. This options sets the maximum vertical resolution of QSSTV to less than 480 lines. It therefore removes some features from the receive window (Rx Notification Window in DRM) and the transmit window (Image replay Preview and TX Notifications in DRM mode). You can toggle to and from full screen by using the CTRL_F key combination.</li>
 </ul>
 </li>
 </ul>
@@ -297,8 +298,7 @@ Note: <b> Most distributions use Pulse Audio interface.. You can select the audi
 <br />
 <ul>
 <li>Enable Reception in Hybrid Mode: allows reception of hamDRM in hybrid mode. If this is not enabled, hybrid mode files will not be shown or stored.</li>
-<li>Enable Special server: Activate only if you want to use a different server than the preprogrammed default one of VK4AES</li>
-<li>FTP Port: default 21</li>
+<li>FTP Port: default 21 (cannot be modified at this moment for compatibility with EasyPal)</li>
 <li>Remote Hostname: hostname of your ftp server</li>
 <li>Remote directory:the ftp server directory where the stored images are</li>
 <li>FTP Login name: the login name on the server</li>
@@ -369,8 +369,8 @@ remote           local      st poll reach  delay   offset    disp
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.2</a></li>
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/documentation/manual/manual/imagepopup.html b/qsstv/documentation/manual/manual/imagepopup.html
index 166de00..2042a66 100644
--- a/qsstv/documentation/manual/manual/imagepopup.html
+++ b/qsstv/documentation/manual/manual/imagepopup.html
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -83,8 +83,8 @@ $(document).ready(function(){initNavTree('imagepopup.html','');});
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.2</a></li>
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/documentation/manual/manual/index.html b/qsstv/documentation/manual/manual/index.html
index a97a019..a2ec081 100644
--- a/qsstv/documentation/manual/manual/index.html
+++ b/qsstv/documentation/manual/manual/index.html
@@ -4,7 +4,7 @@
 <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
 <meta http-equiv="X-UA-Compatible" content="IE=9"/>
 <meta name="generator" content="Doxygen 1.8.11"/>
-<title>QSSTV: QSSTV 9.1</title>
+<title>QSSTV: QSSTV 9.2</title>
 <link href="tabs.css" rel="stylesheet" type="text/css"/>
 <script type="text/javascript" src="jquery.js"></script>
 <script type="text/javascript" src="dynsections.js"></script>
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -58,7 +58,7 @@ $(document).ready(function(){initNavTree('index.html','');});
 <div id="doc-content">
 <div class="header">
   <div class="headertitle">
-<div class="title">QSSTV 9.1 </div>  </div>
+<div class="title">QSSTV 9.2 </div>  </div>
 </div><!--header-->
 <div class="contents">
 <div class="textblock"><dl class="section author"><dt>Author</dt><dd>Johan Maes ON4QZ</dd></dl>
@@ -92,7 +92,7 @@ Introduction</h1>
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/documentation/manual/manual/installation.html b/qsstv/documentation/manual/manual/installation.html
index eddde14..fd46f17 100644
--- a/qsstv/documentation/manual/manual/installation.html
+++ b/qsstv/documentation/manual/manual/installation.html
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -104,8 +104,8 @@ Step 4: Run QSSTV</h1>
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.2</a></li>
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/documentation/manual/manual/navtreedata.js b/qsstv/documentation/manual/manual/navtreedata.js
index 944f507..d5d2af5 100644
--- a/qsstv/documentation/manual/manual/navtreedata.js
+++ b/qsstv/documentation/manual/manual/navtreedata.js
@@ -1,7 +1,7 @@
 var NAVTREE =
 [
   [ "QSSTV", "index.html", [
-    [ "QSSTV 9.1", "index.html", "index" ]
+    [ "QSSTV 9.2", "index.html", "index" ]
   ] ]
 ];
 
diff --git a/qsstv/documentation/manual/manual/pages.html b/qsstv/documentation/manual/manual/pages.html
index b8658fa..d4ba8cb 100644
--- a/qsstv/documentation/manual/manual/pages.html
+++ b/qsstv/documentation/manual/manual/pages.html
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -70,7 +70,7 @@ $(document).ready(function(){initNavTree('pages.html','');});
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/documentation/manual/manual/receivedrm.png b/qsstv/documentation/manual/manual/receivedrm.png
index 7945ee2..d20660a 100644
Binary files a/qsstv/documentation/manual/manual/receivedrm.png and b/qsstv/documentation/manual/manual/receivedrm.png differ
diff --git a/qsstv/documentation/manual/manual/statusbar.html b/qsstv/documentation/manual/manual/statusbar.html
index 7d30148..ad05b5e 100644
--- a/qsstv/documentation/manual/manual/statusbar.html
+++ b/qsstv/documentation/manual/manual/statusbar.html
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -96,8 +96,8 @@ Note: BSR is greyed out in SSTV. <br />
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.2</a></li>
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/documentation/manual/manual/todo1.html b/qsstv/documentation/manual/manual/todo1.html
index eee863b..46480ae 100644
--- a/qsstv/documentation/manual/manual/todo1.html
+++ b/qsstv/documentation/manual/manual/todo1.html
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -71,8 +71,8 @@ $(document).ready(function(){initNavTree('todo1.html','');});
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.2</a></li>
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/documentation/manual/manual/transmitdrm.png b/qsstv/documentation/manual/manual/transmitdrm.png
index e329d32..c3b029a 100644
Binary files a/qsstv/documentation/manual/manual/transmitdrm.png and b/qsstv/documentation/manual/manual/transmitdrm.png differ
diff --git a/qsstv/documentation/manual/manual/whatsnew.html b/qsstv/documentation/manual/manual/whatsnew.html
index c49e769..8e5b9a6 100644
--- a/qsstv/documentation/manual/manual/whatsnew.html
+++ b/qsstv/documentation/manual/manual/whatsnew.html
@@ -26,7 +26,7 @@
  <tr style="height: 56px;">
   <td id="projectalign" style="padding-left: 0.5em;">
    <div id="projectname">QSSTV
-    <span id="projectnumber">9.1</span>
+    <span id="projectnumber">9.2</span>
    </div>
   </td>
  </tr>
@@ -61,7 +61,7 @@ $(document).ready(function(){initNavTree('whatsnew.html','');});
 <div class="title">What's New </div>  </div>
 </div><!--header-->
 <div class="contents">
-<div class="textblock"><p>QSSTV 9.1.x has the following new features compared to QSSTV 8.2.x</p>
+<div class="textblock"><p>QSSTV 9.2.x has the following new features compared to QSSTV 8.2.x</p>
 <ul>
 <li>Build on top QT 5.x ( and also compatible with Qt 4.8)</li>
 <li>Better synchronization in SSTV mode</li>
@@ -81,8 +81,8 @@ $(document).ready(function(){initNavTree('whatsnew.html','');});
 <!-- start footer part -->
 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
   <ul>
-    <li class="navelem"><a class="el" href="index.html">QSSTV 9.1</a></li>
-    <li class="footer">Generated on Fri Jul 22 2016 14:16:33 for QSSTV by
+    <li class="navelem"><a class="el" href="index.html">QSSTV 9.2</a></li>
+    <li class="footer">Generated on Sat Oct 22 2016 16:05:51 for QSSTV by
     <a href="http://www.doxygen.org/index.html">
     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.11 </li>
   </ul>
diff --git a/qsstv/drmrx/drm.cpp b/qsstv/drmrx/drm.cpp
index 00a2b1f..66a0146 100644
--- a/qsstv/drmrx/drm.cpp
+++ b/qsstv/drmrx/drm.cpp
@@ -156,6 +156,3 @@ float lastAvgSNR;
 bool avgSNRAvailable;
 QString drmCallsign;
 
-
-
-
diff --git a/qsstv/drmrx/drm.h b/qsstv/drmrx/drm.h
index ca02719..4006b4a 100644
--- a/qsstv/drmrx/drm.h
+++ b/qsstv/drmrx/drm.h
@@ -33,6 +33,7 @@
 
 class demodulator;
 class sourceDecoder;
+class ftpInterface;
 
 extern int input_samples_buffer_request;
 extern int symbols_per_frame_list[4];
@@ -125,8 +126,6 @@ extern sourceDecoder *srcDecoder;
 extern QString drmCallsign;
 
 
-
-
 #endif
 
 
diff --git a/qsstv/drmrx/drmrx.cpp b/qsstv/drmrx/drmrx.cpp
index 1207e58..901f4cf 100644
--- a/qsstv/drmrx/drmrx.cpp
+++ b/qsstv/drmrx/drmrx.cpp
@@ -71,6 +71,5 @@ void drmRx::run(DSPFLOAT *dataPtr)
   ce2->waitFor(&done);
   QApplication::postEvent(dispatcherPtr, ce2);
   while(!done) { usleep(10);}
-
 }
 
diff --git a/qsstv/drmrx/drmrx.h b/qsstv/drmrx/drmrx.h
index 98493da..c66e623 100644
--- a/qsstv/drmrx/drmrx.h
+++ b/qsstv/drmrx/drmrx.h
@@ -25,8 +25,6 @@ public slots:
   float rRation;
   float resamp_signal[2 * DRMBUFSIZE];
   drmHilbertFilter iqFilter;
-
-
 };
 
 #endif // DRMRX_H
diff --git a/qsstv/drmrx/drmstatusframe.ui b/qsstv/drmrx/drmstatusframe.ui
index fe9db29..d94f3d5 100644
--- a/qsstv/drmrx/drmstatusframe.ui
+++ b/qsstv/drmrx/drmstatusframe.ui
@@ -6,10 +6,27 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>410</width>
-    <height>581</height>
+    <width>387</width>
+    <height>225</height>
    </rect>
   </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>0</width>
+    <height>0</height>
+   </size>
+  </property>
+  <property name="font">
+   <font>
+    <pointsize>8</pointsize>
+   </font>
+  </property>
   <property name="windowTitle">
    <string>Frame</string>
   </property>
@@ -19,7 +36,7 @@
   <property name="frameShadow">
    <enum>QFrame::Raised</enum>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
+  <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,0,1">
    <property name="spacing">
     <number>1</number>
    </property>
@@ -36,198 +53,249 @@
     <number>0</number>
    </property>
    <item>
-    <layout class="QGridLayout" name="gridLayout">
-     <property name="spacing">
+    <layout class="QGridLayout" name="gridLayout" rowminimumheight="1,1,1,1">
+     <property name="verticalSpacing">
       <number>1</number>
      </property>
-     <item row="1" column="0">
-      <widget class="QLabel" name="bandwidthLabel">
-       <property name="text">
-        <string>Bandwidth</string>
+     <item row="0" column="0">
+      <widget class="QLabel" name="modeLabel">
+       <property name="minimumSize">
+        <size>
+         <width>0</width>
+         <height>15</height>
+        </size>
        </property>
-      </widget>
-     </item>
-     <item row="3" column="0">
-      <widget class="QLabel" name="protectionLabel">
        <property name="text">
-        <string>Protection</string>
+        <string>Mode</string>
        </property>
       </widget>
      </item>
-     <item row="2" column="0">
-      <widget class="QLabel" name="interleaveLabel">
+     <item row="0" column="1">
+      <widget class="QLabel" name="modeEdit">
+       <property name="minimumSize">
+        <size>
+         <width>40</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="frameShape">
+        <enum>QFrame::Box</enum>
+       </property>
        <property name="text">
-        <string>InterLeave</string>
+        <string/>
        </property>
       </widget>
      </item>
-     <item row="4" column="0">
-      <widget class="QLabel" name="qamLabel">
+     <item row="0" column="2">
+      <widget class="QLabel" name="bandwidthLabel">
        <property name="text">
-        <string>QAM</string>
+        <string>Bandwidth</string>
        </property>
       </widget>
      </item>
-     <item row="8" column="1">
-      <widget class="QLabel" name="rxSegmentsEdit">
+     <item row="0" column="3">
+      <widget class="QLabel" name="bandwidthEdit">
        <property name="minimumSize">
         <size>
          <width>40</width>
          <height>0</height>
         </size>
        </property>
+       <property name="frameShape">
+        <enum>QFrame::Box</enum>
+       </property>
        <property name="text">
         <string/>
        </property>
       </widget>
      </item>
-     <item row="8" column="0">
-      <widget class="QLabel" name="rxSegmentsLabel">
+     <item row="0" column="4">
+      <widget class="QLabel" name="qamLabel">
        <property name="text">
-        <string>RX  Sgmnts</string>
+        <string>QAM</string>
        </property>
       </widget>
      </item>
-     <item row="1" column="1">
-      <widget class="QLabel" name="bandwidthEdit">
+     <item row="0" column="5">
+      <widget class="QLabel" name="qamEdit">
        <property name="minimumSize">
         <size>
          <width>40</width>
          <height>0</height>
         </size>
        </property>
+       <property name="frameShape">
+        <enum>QFrame::Box</enum>
+       </property>
        <property name="text">
         <string/>
        </property>
       </widget>
      </item>
-     <item row="6" column="0">
-      <widget class="QLabel" name="offsetLabel">
-       <property name="text">
-        <string>Offset</string>
+     <item row="1" column="0">
+      <widget class="QLabel" name="interleaveLabel">
+       <property name="minimumSize">
+        <size>
+         <width>0</width>
+         <height>15</height>
+        </size>
        </property>
-      </widget>
-     </item>
-     <item row="0" column="0">
-      <widget class="QLabel" name="modeLabel">
        <property name="text">
-        <string>Mode</string>
+        <string>InterLeave</string>
        </property>
       </widget>
      </item>
-     <item row="0" column="1">
-      <widget class="QLabel" name="modeEdit">
+     <item row="1" column="1">
+      <widget class="QLabel" name="interleaveEdit">
        <property name="minimumSize">
         <size>
          <width>40</width>
          <height>0</height>
         </size>
        </property>
+       <property name="frameShape">
+        <enum>QFrame::Box</enum>
+       </property>
        <property name="text">
         <string/>
        </property>
       </widget>
      </item>
-     <item row="5" column="1">
-      <widget class="QLabel" name="snrEdit">
+     <item row="1" column="2">
+      <widget class="QLabel" name="protectionLabel">
+       <property name="text">
+        <string>Protection</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="3">
+      <widget class="QLabel" name="protectionEdit">
        <property name="minimumSize">
         <size>
          <width>40</width>
          <height>0</height>
         </size>
        </property>
+       <property name="frameShape">
+        <enum>QFrame::Box</enum>
+       </property>
        <property name="text">
         <string/>
        </property>
       </widget>
      </item>
-     <item row="4" column="1">
-      <widget class="QLabel" name="qamEdit">
+     <item row="1" column="4">
+      <widget class="QLabel" name="transportIDLabel">
+       <property name="text">
+        <string>Transp. ID</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="5">
+      <widget class="QLabel" name="transportIDEdit">
        <property name="minimumSize">
         <size>
          <width>40</width>
          <height>0</height>
         </size>
        </property>
+       <property name="frameShape">
+        <enum>QFrame::Box</enum>
+       </property>
        <property name="text">
         <string/>
        </property>
       </widget>
      </item>
-     <item row="5" column="0">
-      <widget class="QLabel" name="snrLabel">
+     <item row="2" column="0">
+      <widget class="QLabel" name="offsetLabel">
+       <property name="minimumSize">
+        <size>
+         <width>0</width>
+         <height>15</height>
+        </size>
+       </property>
        <property name="text">
-        <string>SNR</string>
+        <string>Offset</string>
        </property>
       </widget>
      </item>
-     <item row="3" column="1">
-      <widget class="QLabel" name="protectionEdit">
+     <item row="2" column="1">
+      <widget class="QLabel" name="offsetEdit">
        <property name="minimumSize">
         <size>
          <width>40</width>
          <height>0</height>
         </size>
        </property>
+       <property name="frameShape">
+        <enum>QFrame::Box</enum>
+       </property>
        <property name="text">
         <string/>
        </property>
       </widget>
      </item>
-     <item row="7" column="0">
-      <widget class="QLabel" name="totalSegmentsLabel">
+     <item row="2" column="2">
+      <widget class="QLabel" name="snrLabel">
        <property name="text">
-        <string>Total Segm.</string>
+        <string>SNR</string>
        </property>
       </widget>
      </item>
-     <item row="2" column="1">
-      <widget class="QLabel" name="interleaveEdit">
+     <item row="2" column="3">
+      <widget class="QLabel" name="snrEdit">
        <property name="minimumSize">
         <size>
          <width>40</width>
          <height>0</height>
         </size>
        </property>
+       <property name="frameShape">
+        <enum>QFrame::Box</enum>
+       </property>
        <property name="text">
         <string/>
        </property>
       </widget>
      </item>
-     <item row="7" column="1">
-      <widget class="QLabel" name="totalSegmentsEdit">
+     <item row="3" column="0">
+      <widget class="QLabel" name="rxSegmentsLabel">
        <property name="minimumSize">
         <size>
-         <width>40</width>
-         <height>0</height>
+         <width>0</width>
+         <height>15</height>
         </size>
        </property>
        <property name="text">
-        <string/>
+        <string>RX  Sgmnts</string>
        </property>
       </widget>
      </item>
-     <item row="6" column="1">
-      <widget class="QLabel" name="offsetEdit">
+     <item row="3" column="1">
+      <widget class="QLabel" name="rxSegmentsEdit">
        <property name="minimumSize">
         <size>
          <width>40</width>
          <height>0</height>
         </size>
        </property>
+       <property name="frameShape">
+        <enum>QFrame::Box</enum>
+       </property>
        <property name="text">
         <string/>
        </property>
       </widget>
      </item>
-     <item row="9" column="0">
+     <item row="3" column="2">
       <widget class="QLabel" name="curSegmentLabel">
        <property name="text">
         <string>Cur. Sgmnt</string>
        </property>
       </widget>
      </item>
-     <item row="9" column="1">
+     <item row="3" column="3">
       <widget class="QLabel" name="currentSegmentEdit">
        <property name="minimumSize">
         <size>
@@ -235,39 +303,49 @@
          <height>0</height>
         </size>
        </property>
+       <property name="frameShape">
+        <enum>QFrame::Box</enum>
+       </property>
        <property name="text">
         <string/>
        </property>
       </widget>
      </item>
-     <item row="10" column="1">
-      <widget class="QLabel" name="transportIDEdit">
+     <item row="3" column="4">
+      <widget class="QLabel" name="totalSegmentsLabel">
+       <property name="text">
+        <string>Total Segm.</string>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="5">
+      <widget class="QLabel" name="totalSegmentsEdit">
        <property name="minimumSize">
         <size>
          <width>40</width>
          <height>0</height>
         </size>
        </property>
-       <property name="text">
-        <string/>
+       <property name="frameShape">
+        <enum>QFrame::Box</enum>
        </property>
-      </widget>
-     </item>
-     <item row="10" column="0">
-      <widget class="QLabel" name="transportIDLabel">
        <property name="text">
-        <string>Transp. ID</string>
+        <string/>
        </property>
       </widget>
      </item>
-     <item row="11" column="0">
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
       <widget class="QLabel" name="callsignLabel">
        <property name="text">
         <string>Callsign</string>
        </property>
       </widget>
      </item>
-     <item row="11" column="1">
+     <item>
       <widget class="QLabel" name="callEdit">
        <property name="font">
         <font>
@@ -276,6 +354,9 @@
          <bold>true</bold>
         </font>
        </property>
+       <property name="frameShape">
+        <enum>QFrame::Box</enum>
+       </property>
        <property name="text">
         <string/>
        </property>
@@ -288,6 +369,18 @@
    </item>
    <item>
     <widget class="drmSegmentsView" name="blocksReceivedLabel">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>17</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>17</height>
+      </size>
+     </property>
      <property name="autoFillBackground">
       <bool>false</bool>
      </property>
@@ -306,80 +399,6 @@
        <property name="spacing">
         <number>1</number>
        </property>
-       <item row="0" column="0">
-        <widget class="QLabel" name="timeLEDLabel">
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-           <weight>75</weight>
-           <bold>true</bold>
-          </font>
-         </property>
-         <property name="text">
-          <string>TIME</string>
-         </property>
-         <property name="alignment">
-          <set>Qt::AlignCenter</set>
-         </property>
-        </widget>
-       </item>
-       <item row="0" column="1">
-        <widget class="QLabel" name="frameLedLabel">
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-           <weight>75</weight>
-           <bold>true</bold>
-          </font>
-         </property>
-         <property name="text">
-          <string>FRAME</string>
-         </property>
-         <property name="alignment">
-          <set>Qt::AlignCenter</set>
-         </property>
-        </widget>
-       </item>
-       <item row="0" column="2">
-        <widget class="QLabel" name="facLEDLabel">
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-           <weight>75</weight>
-           <bold>true</bold>
-          </font>
-         </property>
-         <property name="text">
-          <string>FAC</string>
-         </property>
-         <property name="alignment">
-          <set>Qt::AlignCenter</set>
-         </property>
-        </widget>
-       </item>
-       <item row="0" column="3">
-        <widget class="QLabel" name="mscLEDLabel">
-         <property name="minimumSize">
-          <size>
-           <width>40</width>
-           <height>0</height>
-          </size>
-         </property>
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-           <weight>75</weight>
-           <bold>true</bold>
-          </font>
-         </property>
-         <property name="text">
-          <string>MSC</string>
-         </property>
-         <property name="alignment">
-          <set>Qt::AlignCenter</set>
-         </property>
-        </widget>
-       </item>
        <item row="1" column="0">
         <widget class="QLabel" name="timeLED">
          <property name="minimumSize">
@@ -567,8 +586,25 @@
          </property>
         </widget>
        </item>
-       <item row="1" column="1">
-        <widget class="QLabel" name="frameLED">
+       <item row="0" column="1">
+        <widget class="QLabel" name="frameLedLabel">
+         <property name="font">
+          <font>
+           <pointsize>8</pointsize>
+           <weight>75</weight>
+           <bold>true</bold>
+          </font>
+         </property>
+         <property name="text">
+          <string>FRAME</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="2">
+        <widget class="QLabel" name="facLED">
          <property name="minimumSize">
           <size>
            <width>50</width>
@@ -754,8 +790,8 @@
          </property>
         </widget>
        </item>
-       <item row="1" column="2">
-        <widget class="QLabel" name="facLED">
+       <item row="1" column="3">
+        <widget class="QLabel" name="mscLED">
          <property name="minimumSize">
           <size>
            <width>50</width>
@@ -941,8 +977,65 @@
          </property>
         </widget>
        </item>
-       <item row="1" column="3">
-        <widget class="QLabel" name="mscLED">
+       <item row="0" column="0">
+        <widget class="QLabel" name="timeLEDLabel">
+         <property name="font">
+          <font>
+           <pointsize>8</pointsize>
+           <weight>75</weight>
+           <bold>true</bold>
+          </font>
+         </property>
+         <property name="text">
+          <string>TIME</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="2">
+        <widget class="QLabel" name="facLEDLabel">
+         <property name="font">
+          <font>
+           <pointsize>8</pointsize>
+           <weight>75</weight>
+           <bold>true</bold>
+          </font>
+         </property>
+         <property name="text">
+          <string>FAC</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="3">
+        <widget class="QLabel" name="mscLEDLabel">
+         <property name="minimumSize">
+          <size>
+           <width>40</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="font">
+          <font>
+           <pointsize>8</pointsize>
+           <weight>75</weight>
+           <bold>true</bold>
+          </font>
+         </property>
+         <property name="text">
+          <string>MSC</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="1">
+        <widget class="QLabel" name="frameLED">
          <property name="minimumSize">
           <size>
            <width>50</width>
@@ -1140,7 +1233,7 @@
      <property name="sizeHint" stdset="0">
       <size>
        <width>20</width>
-       <height>0</height>
+       <height>40</height>
       </size>
      </property>
     </spacer>
diff --git a/qsstv/drmrx/sourcedecoder.cpp b/qsstv/drmrx/sourcedecoder.cpp
index 6c9ab1f..a6a5635 100644
--- a/qsstv/drmrx/sourcedecoder.cpp
+++ b/qsstv/drmrx/sourcedecoder.cpp
@@ -2,46 +2,31 @@
 #include "drm.h"
 #include "appglobal.h"
 #include "drmproto.h"
-#include <math.h>
-#include <float.h>
 #include "configparams.h"
 #include "dispatch/dispatcher.h"
-#include <QApplication>
-#include <QFileInfo>
-#include "utils/reedsolomoncoder.h"
-#include <QFile>
-#include "drmrx/demodulator.h"
-#include "utils/ftp.h"
+#include "reedsolomoncoder.h"
+#include "demodulator.h"
+#include "ftp.h"
 #include "configparams.h"
-
 #include "logbook/logbook.h"
-#include "drmrx/drmstatusframe.h"
+#include "drmstatusframe.h"
+
+
 #include <QThread>
+#include <QApplication>
+#include <QFileInfo>
+#include <QFile>
+#include <math.h>
+#include <float.h>
 
 sourceDecoder::sourceDecoder(QObject *parent) : QObject(parent)
 {
-//  QThread *thr;
   transportBlockPtrList.clear();
- notifyIntf=NULL;
-//  thr=QThread::currentThread();
-//  qDebug() << "thread" << thr->currentThreadId() <<thr->objectName();
 
 }
 
 void sourceDecoder::init()
 {
-//  QThread *thr=QThread::currentThread();
-//  qDebug() << "source dec init" << thr->currentThreadId() <<thr->objectName();
-  if (notifyIntf==NULL)
-  {
-    notifyIntf = new ftpInterface("RX Notification FTP");
-    connect(notifyIntf, SIGNAL(notification(QString)), this, SLOT(rxNotification(QString)));
-  }
-  else
-  {
-    notifyIntf->dumpState();
-  }
-
   lastTransportBlockPtr=NULL;
   bodyTotalSegments=0;
   checkIt=false;
@@ -69,40 +54,40 @@ bool sourceDecoder::decode()
 
   if (channel_decoded_data_buffer_data_valid != 1)  return false;
   if (audio_data_flag == 0)
-  {
-    addToLog("audio decoding not implemented in qsstv !\n",LOGDRMSRC); return false;
-  }
+    {
+      addToLog("audio decoding not implemented in qsstv !\n",LOGDRMSRC); return false;
+    }
   addToLog("Datapacket received",LOGPERFORM);
   N_partB = (int) (length_decoded_data/ 8);
   addToLog(QString("N-partB lenght=%1").arg(N_partB),LOGDRMSRC);
   if(N_partB>PACKETBUFFERLEN)
-  {
-    addToLog(QString("packet buffer length exceeded: lenght=%1").arg(N_partB),LOGDRMMOT);
-  }
+    {
+      addToLog(QString("packet buffer length exceeded: lenght=%1").arg(N_partB),LOGDRMMOT);
+    }
   bits2bytes (channel_decoded_data_buffer, N_partB * 8, packetBuffer);
   crc16_bytewise(&checksum, packetBuffer,N_partB);
   if(fabs (checksum) <= DBL_EPSILON)
-  {
-    if(!setupDataBlock(packetBuffer,true,N_partB))
+    {
+      if(!setupDataBlock(packetBuffer,true,N_partB))
+        {
+          msc_valid=INVALID;
+          return false;
+        }
+    }
+  else
     {
       msc_valid=INVALID;
       return false;
     }
-  }
-  else
-  {
-    msc_valid=INVALID;
-    return false;
-  }
   // at this point we have a dataPacket we now check header / data and buils a transport stream
   switch(currentDataPacket.dataGroupType)
-  {
-  case MOTDATA:  addToLog("Datasegment",LOGDRMSRC);   addDataSegment(); break;
-  case MOTHEAD:  addToLog("Headersegment",LOGDRMSRC); addHeaderSegment(); break;
-  default:
+    {
+    case MOTDATA:  addToLog("Datasegment",LOGDRMSRC);   addDataSegment(); break;
+    case MOTHEAD:  addToLog("Headersegment",LOGDRMSRC); addHeaderSegment(); break;
+    default:
     return false;
     break;
-  }
+    }
   return true;
 }
 
@@ -123,39 +108,39 @@ bool sourceDecoder::setupDataBlock(unsigned char *buffer,bool crcIsOK,int len)
   currentDataBlock.continuityIndex = (header & 0x7);
   currentDataBlock.log();
   if ((currentDataBlock.PPI != 0) && (crcIsOK))
-  {
-    availableBytes=buffer[1];
-    bufPtr=(const char *)&buffer[2];
-  }
-  else
-  {
-    availableBytes=len-3;
-    bufPtr=(const char *)&buffer[1];
-  }
-  if(currentDataBlock.firstFlag)
-  {
-    holdingBuffer.clear();
-    lastContinuityIndex=currentDataBlock.continuityIndex;
-  }
+    {
+      availableBytes=buffer[1];
+      bufPtr=(const char *)&buffer[2];
+    }
   else
-  {
-    if(lastContinuityIndex<0)
     {
-      return false;
+      availableBytes=len-3;
+      bufPtr=(const char *)&buffer[1];
     }
-    lastContinuityIndex=(lastContinuityIndex+1)%8;
-    if(currentDataBlock.continuityIndex!=lastContinuityIndex)
+  if(currentDataBlock.firstFlag)
     {
-      lastContinuityIndex=-1;
-      return false;
+      holdingBuffer.clear();
+      lastContinuityIndex=currentDataBlock.continuityIndex;
     }
+  else
+    {
+      if(lastContinuityIndex<0)
+        {
+          return false;
+        }
+      lastContinuityIndex=(lastContinuityIndex+1)%8;
+      if(currentDataBlock.continuityIndex!=lastContinuityIndex)
+        {
+          lastContinuityIndex=-1;
+          return false;
+        }
 
-  }
+    }
   holdingBuffer.append(bufPtr,availableBytes);
   if(currentDataBlock.lastFlag)
-  {
-    return setupDataPacket(holdingBuffer);
-  }
+    {
+      return setupDataPacket(holdingBuffer);
+    }
   return false;
 }
 
@@ -228,44 +213,44 @@ bool sourceDecoder::setupDataPacket(QByteArray ba)
   if(header&0x20) currentDataPacket.sessionFlag=true;
 
   if(header&0x40)
-  {
-    currentDataPacket.crcFlag=true;
-    crc16_bytewise (&checksum,(unsigned char *)currentDataPacket.ba.data(),currentDataPacket.ba.count());
-    if (fabs (checksum) <= DBL_EPSILON)
     {
-      currentDataPacket.crcOK=true;
-    }
-    else
-    {
-      currentDataPacket.crcOK=false;
-      msc_valid=INVALID;
-      return false;
+      currentDataPacket.crcFlag=true;
+      crc16_bytewise (&checksum,(unsigned char *)currentDataPacket.ba.data(),currentDataPacket.ba.count());
+      if (fabs (checksum) <= DBL_EPSILON)
+        {
+          currentDataPacket.crcOK=true;
+        }
+      else
+        {
+          currentDataPacket.crcOK=false;
+          msc_valid=INVALID;
+          return false;
+        }
+      currentDataPacket.chop(2); // drop crc
     }
-    currentDataPacket.chop(2); // drop crc
-  }
   currentDataPacket.advance(2); //skip header and continuity bits
   if(currentDataPacket.extFlag) currentDataPacket.advance(2); // just skip the extension bytes
 
   if(currentDataPacket.sessionFlag)
-  {
-    currentDataPacket.segmentNumber = (((unsigned char)(currentDataPacket.ba.at(0)) & 0x7F))*256+ ((unsigned char)currentDataPacket.ba.at(1))  ;
-    if(currentDataPacket.ba.at(0)&0x80)
     {
-      currentDataPacket.lastSegment=true;
+      currentDataPacket.segmentNumber = (((unsigned char)(currentDataPacket.ba.at(0)) & 0x7F))*256+ ((unsigned char)currentDataPacket.ba.at(1))  ;
+      if(currentDataPacket.ba.at(0)&0x80)
+        {
+          currentDataPacket.lastSegment=true;
+        }
+      currentSegmentNumber=currentDataPacket.segmentNumber;
+      currentDataPacket.advance(2);
     }
-    currentSegmentNumber=currentDataPacket.segmentNumber;
-    currentDataPacket.advance(2);
-  }
 
   if (currentDataPacket.userFlag)
-  {
-    currentDataPacket.userAccessField = (unsigned char)(currentDataPacket.ba.at(0));
-    currentDataPacket.advance(1);
-    lengthIndicator = (currentDataPacket.userAccessField& 0xF);
-
-    if((currentDataPacket.userAccessField & 0x10) && (lengthIndicator>=2)) currentDataPacket.transportID = (((unsigned char)(currentDataPacket.ba.at(0))))*256+ ((unsigned char)currentDataPacket.ba.at(1))  ;
-    currentDataPacket.advance(lengthIndicator);
-  }
+    {
+      currentDataPacket.userAccessField = (unsigned char)(currentDataPacket.ba.at(0));
+      currentDataPacket.advance(1);
+      lengthIndicator = (currentDataPacket.userAccessField& 0xF);
+
+      if((currentDataPacket.userAccessField & 0x10) && (lengthIndicator>=2)) currentDataPacket.transportID = (((unsigned char)(currentDataPacket.ba.at(0))))*256+ ((unsigned char)currentDataPacket.ba.at(1))  ;
+      currentDataPacket.advance(lengthIndicator);
+    }
   currentDataPacket.segmentSize=(((unsigned char)(currentDataPacket.ba.at(0)) & 0x1F))*256+ ((unsigned char)currentDataPacket.ba.at(1));
   currentDataPacket.advance(2);
   currentDataPacket.lenght=currentDataPacket.ba.count();
@@ -292,22 +277,22 @@ bool sourceDecoder::addHeaderSegment()
   tbPtr=getTransporPtr(currentDataPacket.transportID,true);
   if(!tbPtr->alreadyReceived) msc_valid=VALID;
   else
-  {
-    msc_valid=ALREADYRECEIVED;
-    if(!alreadyDisplayed)
     {
-      alreadyDisplayed=true;
-      // redisplay
-      stce= new loadRXImageEvent(QString("%1").arg(tbPtr->newFileName));
-      QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
-      stmb= new displayMBoxEvent("DRM Receive",QString("File %1 already received").arg(tbPtr->newFileName));
-      QApplication::postEvent( dispatcherPtr, stmb );
-    }
+      msc_valid=ALREADYRECEIVED;
+      if(!alreadyDisplayed)
+        {
+          alreadyDisplayed=true;
+          // redisplay
+          stce= new loadRXImageEvent(QString("%1").arg(tbPtr->newFileName));
+          QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
+          stmb= new displayMBoxEvent("DRM Receive",QString("File %1 already received").arg(tbPtr->newFileName));
+          QApplication::postEvent( dispatcherPtr, stmb );
+        }
 
 
 
-    return true;
-  }
+      return true;
+    }
 
   tbPtr->headerReceived=true;
   unsigned char *dataPtr=(unsigned char *)currentDataPacket.ba.data();
@@ -333,39 +318,39 @@ bool sourceDecoder::addHeaderSegment()
   // the first byte of every parameter block contains a 2-bits PLI (B7 and B6) indicating the type of parameter block.
 
   while(currentDataPacket.ba.count())  // todo
-  {
-    PLI=dataPtr[0]>>6;
-    paramID=dataPtr[0]&0x3F;
-    switch (PLI)
     {
-    case 0:
-      currentDataPacket.advance(1);
-      break;
-    case 1:
-      loadParams(tbPtr,paramID,1);
-      currentDataPacket.advance(2);
-      break;
-    case 2:
-      loadParams(tbPtr,paramID,4);
-      currentDataPacket.advance(5);
-      break;
-    case 3:
-      extBit=dataPtr[0]&0x80;
-      if(extBit)
-      {
-        dataFieldLength=256*(dataPtr[0]&0x7F)+dataPtr[1];
-        currentDataPacket.advance(2);
-      }
-      else
-      {
-        dataFieldLength=dataPtr[0]&0x7F;
-        currentDataPacket.advance(1);
-      }
-      loadParams(tbPtr,paramID,dataFieldLength);
-      currentDataPacket.advance(dataFieldLength);
-      break;
-    }
-  }
+      PLI=dataPtr[0]>>6;
+      paramID=dataPtr[0]&0x3F;
+      switch (PLI)
+        {
+        case 0:
+          currentDataPacket.advance(1);
+        break;
+        case 1:
+          loadParams(tbPtr,paramID,1);
+          currentDataPacket.advance(2);
+        break;
+        case 2:
+          loadParams(tbPtr,paramID,4);
+          currentDataPacket.advance(5);
+        break;
+        case 3:
+          extBit=dataPtr[0]&0x80;
+          if(extBit)
+            {
+              dataFieldLength=256*(dataPtr[0]&0x7F)+dataPtr[1];
+              currentDataPacket.advance(2);
+            }
+          else
+            {
+              dataFieldLength=dataPtr[0]&0x7F;
+              currentDataPacket.advance(1);
+            }
+          loadParams(tbPtr,paramID,dataFieldLength);
+          currentDataPacket.advance(dataFieldLength);
+        break;
+        }
+    }
   return true;
 
 }
@@ -378,19 +363,19 @@ void sourceDecoder::loadParams(transportBlock *tbPtr,unsigned char paramID,int l
   rxDRMStatusEvent *stce;
   QString tmp,t;
   switch(paramID)
-  {
-  case 5: // expiration
+    {
+    case 5: // expiration
     break;
-  case 6:
+    case 6:
     break;
-  case 12:
-    tbPtr->fileName=QString::fromLatin1(currentDataPacket.ba.data()+1).left(len-1);
-    stce= new rxDRMStatusEvent(QString("%1").arg(tbPtr->fileName));
-    QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
+    case 12:
+      tbPtr->fileName=QString::fromLatin1(currentDataPacket.ba.data()+1).left(len-1);
+      stce= new rxDRMStatusEvent(QString("%1").arg(tbPtr->fileName));
+      QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
     break;
-  default:
+    default:
     break;
-  }
+    }
 }
 
 
@@ -406,37 +391,37 @@ void sourceDecoder::addDataSegment()
 
   if(!tbPtr->alreadyReceived) msc_valid=VALID;
   else
-  {
-    msc_valid=ALREADYRECEIVED;
-    //      return;
-  }
+    {
+      msc_valid=ALREADYRECEIVED;
+      //      return;
+    }
   if(currentDataPacket.lastSegment)
-  {
-    tbPtr->totalSegments=currentDataPacket.segmentNumber+1;
-    tbPtr->lastSegmentReceived=true;
-  }
+    {
+      tbPtr->totalSegments=currentDataPacket.segmentNumber+1;
+      tbPtr->lastSegmentReceived=true;
+    }
   else
-  {
-    tbPtr->defaultSegmentSize=currentDataPacket.segmentSize;
-  }
+    {
+      tbPtr->defaultSegmentSize=currentDataPacket.segmentSize;
+    }
   for(i=tbPtr->dataSegmentPtrList.count();i<=currentDataPacket.segmentNumber;i++)
-  {
-    tbPtr->dataSegmentPtrList.append(new dataSegment(tbPtr->defaultSegmentSize));
-  }
+    {
+      tbPtr->dataSegmentPtrList.append(new dataSegment(tbPtr->defaultSegmentSize));
+    }
 
   if(!tbPtr->dataSegmentPtrList.at(currentDataPacket.segmentNumber)->hasData())
-  {
-    checkIt=true;
-  }
+    {
+      checkIt=true;
+    }
   else
-  {
-    msc_valid=ALREADYRECEIVED;
-  }
+    {
+      msc_valid=ALREADYRECEIVED;
+    }
   if(tbPtr->alreadyReceived)
-  {
-    msc_valid=ALREADYRECEIVED;
-    checkIt=false;
-  }
+    {
+      msc_valid=ALREADYRECEIVED;
+      checkIt=false;
+    }
   if(tbPtr->totalSegments<currentDataPacket.segmentNumber+1) tbPtr->totalSegments=currentDataPacket.segmentNumber+1;
   bodyTotalSegments=tbPtr->totalSegments;
   rxSegments=tbPtr->segmentsReceived;
@@ -459,28 +444,28 @@ void sourceDecoder::writeData(transportBlock *tbPtr)
   erasureList.append(tbPtr->totalSegments);
   erasureList.append(tbPtr->defaultSegmentSize);
   for(i=0;i<tbPtr->dataSegmentPtrList.count();i++)
-  {
-    if(!tbPtr->dataSegmentPtrList.at(i)->hasData())
     {
-      erasureList.append(i);
-      ba.append(QByteArray(tbPtr->defaultSegmentSize,0x00));
-    }
-    else
-    {
-      ba.append(tbPtr->dataSegmentPtrList.at(i)->data);
+      if(!tbPtr->dataSegmentPtrList.at(i)->hasData())
+        {
+          erasureList.append(i);
+          ba.append(QByteArray(tbPtr->defaultSegmentSize,0x00));
+        }
+      else
+        {
+          ba.append(tbPtr->dataSegmentPtrList.at(i)->data);
+        }
+      length+=tbPtr->dataSegmentPtrList.at(i)->data.size();
     }
-    length+=tbPtr->dataSegmentPtrList.at(i)->data.size();
-  }
   tbPtr->segmentsReceived=0;
   drmBlockList.clear();
   for(i=0;i<tbPtr->dataSegmentPtrList.count();i++)
-  {
-    if(tbPtr->dataSegmentPtrList.at(i)->hasData())
     {
-      drmBlockList.append(i);
-      tbPtr->segmentsReceived++;
+      if(tbPtr->dataSegmentPtrList.at(i)->hasData())
+        {
+          drmBlockList.append(i);
+          tbPtr->segmentsReceived++;
+        }
     }
-  }
   if(tbPtr->isAlmostComplete()<63) return ;
 
   if(!tbPtr->lastSegmentReceived) return;
@@ -497,6 +482,9 @@ void sourceDecoder::saveImage(transportBlock *tbPtr)
   QImage test;
   displayTextEvent *stce;
   displayMBoxEvent *stmb=0;
+  notifyActionEvent *na;
+
+
   rxDRMNotifyEvent *rxne;
   QString t;
 
@@ -506,9 +494,9 @@ void sourceDecoder::saveImage(transportBlock *tbPtr)
   bool   saveOK=false;
   alreadyDisplayed=true;
   if(tbPtr->alreadyReceived)
-  {
-    return ;
-  }
+    {
+      return ;
+    }
   if(tbPtr->fileName.isEmpty()) return ;
   if(tbPtr->retrieveTries==0) lastAvgSNR=avgSNR;
 
@@ -517,169 +505,166 @@ void sourceDecoder::saveImage(transportBlock *tbPtr)
 
   isHybrid=false;
   if((tbPtr->fileName.left(3)==".de") || (tbPtr->fileName.left(3)=="de_"))
-  {
-    isHybrid=true;
-    ftpInterface ftpIntf("Save Image FTP");
-    if((enableHybridRx) && (soundRoutingInput!=soundBase::SNDINFROMFILE))
-    {
-      addToLog(QString("Hybrid filename %1, attempt %2").arg(tbPtr->fileName).arg(tbPtr->retrieveTries+1),LOGALL);
-      downloadF=rxDRMImagesPath+"/"+tbPtr->fileName;
-      for(i=0;i<tbPtr->dataSegmentPtrList.count();i++)
-      {
-        hybridBa+=tbPtr->dataSegmentPtrList.at(i)->data;
-      }
-      if(hc.deCrypt(&hybridBa))
-      {
-        if ((tbPtr->retrieveTries==0) && enableHybridNotify)
-        {
-          RxOkF = "Dummy"+tbPtr->fileName+"+++."+myCallsign+QString("  -%1dB SNR").arg(lastAvgSNR,0,'f',0);
-          notifyIntf->mremove("*+++."+myCallsign+"*");
-          notifyIntf->uploadData(QByteArray("Dummy\r\n"), RxOkF);
-          rxNotifyCheck(tbPtr->fileName,&hc);
-        }
-        tbPtr->retrieveTries++;
-        ftpIntf.setupConnection(hc.host(),hc.port(),hc.user(),hc.passwd(),hc.dir()+"/"+hybridFtpHybridFilesDirectory);
-        ftpResult=ftpIntf.downloadFile(tbPtr->fileName.toLatin1(),downloadF);
-        switch(ftpResult)
+    {
+      isHybrid=true;
+      ftpInterface ftpIntf("Save Image FTP");
+      if((enableHybridRx) && (soundRoutingInput!=soundBase::SNDINFROMFILE))
         {
-        case FTPOK:
-          break;
-        case FTPERROR:
-          stmb= new displayMBoxEvent("FTP Error",QString("Host: %1: %2").arg(ftpRemoteHost).arg(ftpIntf.getLastError()));
-          errorOut() << "ftp error" << ftpRemoteHost << ftpIntf.getLastError();
-          break;
-        case FTPNAMEERROR:
-          stmb= new displayMBoxEvent("FTP Error",QString("Host: %1, Error in filename").arg(ftpRemoteHost));
-          errorOut() << "ftp filename error" << ftpRemoteHost << ftpIntf.getLastError();
-          break;
-        case FTPCANCELED:
-          stmb= new displayMBoxEvent("FTP Error",QString("Connection to %1 Canceled").arg(ftpRemoteHost));
-          errorOut() << "ftp connection error" << ftpRemoteHost << ftpIntf.getLastError();
-          break;
-        case FTPTIMEOUT:
-          stmb= new displayMBoxEvent("FTP Error",QString("Connection to %1 timed out").arg(ftpRemoteHost));
-          errorOut() << "ftp connection timeout error" << ftpRemoteHost << ftpIntf.getLastError();
-          break;
+          addToLog(QString("Hybrid filename %1, attempt %2").arg(tbPtr->fileName).arg(tbPtr->retrieveTries+1),LOGALL);
+          downloadF=rxDRMImagesPath+"/"+tbPtr->fileName;
+          for(i=0;i<tbPtr->dataSegmentPtrList.count();i++)
+            {
+              hybridBa+=tbPtr->dataSegmentPtrList.at(i)->data;
+            }
+          if(hc.deCrypt(&hybridBa))
+            {
+              if ((tbPtr->retrieveTries==0) && rxNotifySetup())
+                {
+                  RxOkF = "Dummy"+tbPtr->fileName+"+++."+myCallsign+QString("  %1dB SNR").arg(lastAvgSNR,0,'f',0);
+
+                  if (enableHybridNotify)
+                    {
+                      na=new notifyActionEvent("*+++."+myCallsign+"*","Dummy\r\n", RxOkF);
+                      QApplication::postEvent( dispatcherPtr, na);  // Qt will delete it when done
+
+
+                    }
+                  if (enableHybridNotifySnoop)
+                    {
+                      rxNotifyCheck(tbPtr->fileName);
+                    }
+                }
+              tbPtr->retrieveTries++;
+
+              ftpIntf.setupConnection(hc.host(),hc.port(),hc.user(),hc.passwd(),hc.dir()+"/"+hybridFtpHybridFilesDirectory);
+              ftpResult=ftpIntf.downloadFile(tbPtr->fileName.toLatin1(),downloadF);
+              switch(ftpResult)
+                {
+                case FTPOK:
+                break;
+                case FTPERROR:
+                  stmb= new displayMBoxEvent("FTP Error",QString("Host: %1: %2").arg(ftpRemoteHost).arg(ftpIntf.getLastError()));
+                  errorOut() << "ftp error" << ftpRemoteHost << ftpIntf.getLastError();
+                break;
+                case FTPNAMEERROR:
+                  stmb= new displayMBoxEvent("FTP Error",QString("Host: %1, Error in filename").arg(ftpRemoteHost));
+                  errorOut() << "ftp filename error" << ftpRemoteHost << ftpIntf.getLastError();
+                break;
+                case FTPCANCELED:
+                  stmb= new displayMBoxEvent("FTP Error",QString("Connection to %1 Canceled").arg(ftpRemoteHost));
+                  errorOut() << "ftp connection error" << ftpRemoteHost << ftpIntf.getLastError();
+                break;
+                case FTPTIMEOUT:
+                  stmb= new displayMBoxEvent("FTP Error",QString("Connection to %1 timed out").arg(ftpRemoteHost));
+                  errorOut() << "ftp connection timeout error" << ftpRemoteHost << ftpIntf.getLastError();
+                break;
+                }
+              if(ftpResult!=FTPOK)
+                {
+                  if ((ftpResult!=FTPTIMEOUT) || (tbPtr->retrieveTries>1)) {
+                      QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
+                      tbPtr->setAlreadyReceived(true);
+                    }
+                  return;
+                }
+
+            }
+          else
+            {
+              if (tbPtr->retrieveTries==0)
+                {
+                  stmb= new displayMBoxEvent("Hybrid Error","No file downloaded");
+                  QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
+                  return;
+                }
+            }
         }
-        if(ftpResult!=FTPOK)
+      else
         {
-          if ((ftpResult!=FTPTIMEOUT) || (tbPtr->retrieveTries>1)) {
-            QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
-            tbPtr->setAlreadyReceived(true);
-          }
-          return;
+          downloadF.clear();
         }
 
-      }
-      else
-      {
-        stmb= new displayMBoxEvent("Hybrid Error","No file downloaded");
-        QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
-        return;
-      }
-    }
-    else
-    {
-      downloadF.clear();
-    }
-
-    tbPtr->newFileName=downloadF;
+      tbPtr->newFileName=downloadF;
 
-  }
+    }
 
   if(tbPtr->newFileName.isEmpty()) return ;
-  //  test=readJP2Image(tbPtr->newFileName);
   if(!test.load(tbPtr->newFileName))
-  {
-
-    // maybe text
-    QFileInfo finfo(tbPtr->newFileName);
-    if((finfo.suffix()=="txt") || (finfo.suffix()=="chat") )
     {
-      QFile fi(tbPtr->newFileName);
-      if(!fi.open(QIODevice::ReadOnly)) return;
-      t=fi.readAll();
-      stce= new displayTextEvent(t);
-      QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
-      textMode=true;
+      // maybe text
+      QFileInfo finfo(tbPtr->newFileName);
+      if((finfo.suffix()=="txt") || (finfo.suffix()=="chat") )
+        {
+          QFile fi(tbPtr->newFileName);
+          if(!fi.open(QIODevice::ReadOnly)) return;
+          t=fi.readAll();
+          stce= new displayTextEvent(t);
+          QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
+          textMode=true;
+        }
+      saveOK=true;
     }
-    saveOK=true;
-  }
   else
-  {
-    saveOK=true;
-  }
+    {
+      saveOK=true;
+    }
   if(saveOK)
-  {
-    QFileInfo tfi(tbPtr->newFileName);
+    {
+      QFileInfo tfi(tbPtr->newFileName);
 
-    QString modestr(tfi.fileName());
-    modestr+=QString(" %1dB ").arg(lastAvgSNR,0,'f',0);
-    if(isHybrid) modestr+="Hybrid ";
-    modestr+=compactModeToString(tbPtr->modeCode);
-    logBookPtr->logQSO(tbPtr->callsign,"DSSTV",modestr);
+      QString modestr(tfi.fileName());
+      modestr+=QString(" %1dB ").arg(lastAvgSNR,0,'f',0);
+      if(isHybrid) modestr+="Hybrid ";
+      modestr+=compactModeToString(tbPtr->modeCode);
+      logBookPtr->logQSO(tbPtr->callsign,"DSSTV",modestr);
 
-  }
+    }
   tbPtr->setAlreadyReceived(true);
   if(!textMode)
-  {
-    saveDRMImageEvent *ce = new saveDRMImageEvent(tbPtr->newFileName);
-    ce->waitFor(&done);
-    QApplication::postEvent(dispatcherPtr, ce);
-    while(!done)
     {
-      usleep(10);
-    }
-    checkIt=false;
-  }
-}
+      QString info="";
+      if (isHybrid) info+="Hybrid";
+      else       info+=compactModeToString(tbPtr->modeCode);
 
+      info+=QString(" %2dB de %3").arg(lastAvgSNR,0,'f',0).arg(tbPtr->callsign);
 
-bool sourceDecoder::rxNotifyCheck(QString fn, hybridCrypt *c)
+      //    slotRXNotification("*** "+info);
+      saveDRMImageEvent *ce = new saveDRMImageEvent(tbPtr->newFileName,info);
+      ce->waitFor(&done);
+      QApplication::postEvent(dispatcherPtr, ce);
+      while(!done)
+        {
+          usleep(10);
+        }
+      checkIt=false;
+    }
+}
+bool sourceDecoder::rxNotifySetup()
 {
-  rxDRMNotifyEvent *rxne;
-  if (!enableHybridNotify) return false;
-
-  if (enableHybridNotifySpecialServer)
-  {
-    addToLog(QString("using special server host:%1, port:%2, user:%3, pwd:%4").arg(c->host()).arg(c->port()).arg(c->user()).arg(c->passwd()),LOGNOTIFY);
-
-    notifyIntf->setupConnection(hybridNotifyRemoteHost, hybridNotifyPort,
-                                hybridNotifyLogin, hybridNotifyPassword,
-                                hybridNotifyRemoteDir+"/"+hybridNotifyDir);
-  }
-  else if (c)
-  {
-    // notification to image server
-    addToLog(QString("notification to image server host:%1, port:%2, user:%3, pwd:%4").arg(c->host()).arg(c->port()).arg(c->user()).arg(c->passwd()),LOGNOTIFY);
-    notifyIntf->setupConnection(c->host(),c->port(),c->user(),c->passwd(),c->dir()+"/RxOkNotifications1");
-  }
-  else
-  {
-    // notification to vk4aes.com (EasyPal compatible)
-    addToLog("notification to image server",LOGNOTIFY);
-    notifyIntf->setupConnection("vk4aes.com",21,"vk4aes","10mar1936","/RxOkNotifications1");
+  ftpSetupEvent *se;
+  if (!(enableHybridNotify || enableHybridNotifySnoop)) return false;
 
-    // or to default server (from hc object)
-    //notifyIntf->setupConnection(hc->host(),hc->port(),hc->user(),hc->passwd(),hc->dir()+"/RxOkNotifications1");
-  }
+  se=new ftpSetupEvent (notifyRXIntf,hybridNotifyRemoteHost,hybridNotifyPort,hybridNotifyLogin,hybridNotifyPassword,hybridNotifyRemoteDir+"/RxOkNotifications1");
 
-  rxne = new rxDRMNotifyEvent("");
-  QApplication::postEvent( dispatcherPtr, rxne );
-//   QThread *thr;
-//   thr=QThread::currentThread();
-//  qDebug() << "thread not" << thr->currentThreadId() <<thr->objectName();
-  notifyIntf->startNotifyCheck(fn, 5, 45/5, false);
+  QApplication::postEvent( dispatcherPtr, se);  // Qt will delete it when done
   return true;
 }
 
-void sourceDecoder::rxNotification(QString info)
+
+
+
+bool sourceDecoder::rxNotifyCheck(QString fn)
 {
-  if (info != "")
-  {
-    rxDRMNotifyAppendEvent *rxne = new rxDRMNotifyAppendEvent(info);
-    QApplication::postEvent( dispatcherPtr, rxne );  // Qt will delete it when done
-  }
+  rxDRMNotifyEvent *rxne;
+  notifyCheckEvent *se;
+  rxne = new rxDRMNotifyEvent("");
+  QApplication::postEvent( dispatcherPtr, rxne );
+
+  if (!enableHybridNotifySnoop) return false;
+  se=new  notifyCheckEvent(notifyRXIntf,fn, 5, 45/5, false);
+  QApplication::postEvent( dispatcherPtr,se );
+
+  return true;
 }
 
 bool sourceDecoder::checkSaveImage(QByteArray ba,transportBlock *tbPtr)
@@ -698,38 +683,38 @@ bool sourceDecoder::checkSaveImage(QByteArray ba,transportBlock *tbPtr)
   QFileInfo qfinf(fileName);
   extension=qfinf.suffix().toLower();
   if((extension=="rs1") || (extension=="rs2") ||(extension=="rs3")||(extension=="rs4"))
-  {
-    // try to decode
-    if(tbPtr->alreadyReceived) return false;
-    if(!rsd.decode(ba,fileName,tbPtr->newFileName,baFile,extension,erasureList)) return false;
-    baFilePtr=&baFile;
-  }
+    {
+      // try to decode
+      if(tbPtr->alreadyReceived) return false;
+      if(!rsd.decode(ba,fileName,tbPtr->newFileName,baFile,extension,erasureList)) return false;
+      baFilePtr=&baFile;
+    }
   else
-  {
-    if(!tbPtr->isComplete()) return false;
-    tbPtr->newFileName=fileName;
-    if((tbPtr->fileName=="bsr.bin")&&(!tbPtr->alreadyReceived))
-    {
-      tbPtr->setAlreadyReceived(true);
-      pe = new prepareFixEvent(ba);
-      QApplication::postEvent(dispatcherPtr, pe);
-      return false;
+    {
+      if(!tbPtr->isComplete()) return false;
+      tbPtr->newFileName=fileName;
+      if((tbPtr->fileName=="bsr.bin")&&(!tbPtr->alreadyReceived))
+        {
+          tbPtr->setAlreadyReceived(true);
+          pe = new prepareFixEvent(ba);
+          QApplication::postEvent(dispatcherPtr, pe);
+          return false;
+        }
+      baFilePtr=&ba;
     }
-    baFilePtr=&ba;
-  }
   if(!tbPtr->alreadyReceived)
-  {
-    outFile.setFileName(tbPtr->newFileName);
-    if(outFile.open(QIODevice::WriteOnly)<=0)
     {
+      outFile.setFileName(tbPtr->newFileName);
+      if(outFile.open(QIODevice::WriteOnly)<=0)
+        {
+          outFile.close();
+          return false;
+        }
+      outFile.write(*baFilePtr);
       outFile.close();
-      return false;
+      erasureList.clear();
+      saveImage(tbPtr);
     }
-    outFile.write(*baFilePtr);
-    outFile.close();
-    erasureList.clear();
-    saveImage(tbPtr);
-  }
   return false;
 }
 
@@ -740,12 +725,12 @@ QList <bsrBlock> *sourceDecoder::getBSR()
   bsrList.clear();
 
   for(i=0;i<transportBlockPtrList.count();i++)
-  {
-    tbPtr=transportBlockPtrList.at(i);
-    if(tbPtr->alreadyReceived) continue;
-    if(tbPtr->fileName=="bsr.bin") continue;
-    bsrList.append(bsrBlock(tbPtr));
-  }
+    {
+      tbPtr=transportBlockPtrList.at(i);
+      if(tbPtr->alreadyReceived) continue;
+      if(tbPtr->fileName=="bsr.bin") continue;
+      bsrList.append(bsrBlock(tbPtr));
+    }
   return &bsrList;
 }
 
@@ -759,12 +744,12 @@ bool sourceDecoder::storeBSR(transportBlock *tb, bool compat)
   erasureList.append(tb->totalSegments);
   erasureList.append(tb->defaultSegmentSize);
   for(i=0;i<tb->dataSegmentPtrList.count();i++)
-  {
-    if(!tb->dataSegmentPtrList.at(i)->hasData())
     {
-      erasureList.append(i);
+      if(!tb->dataSegmentPtrList.at(i)->hasData())
+        {
+          erasureList.append(i);
+        }
     }
-  }
   tb->baBSR.clear();
   if(erasureList.count()<3) return false; //erasurelist has already totalSegments and defaultSegmentSize
   tb->baBSR.append(QString::number(tb->transportID).toLatin1().data());
@@ -778,41 +763,41 @@ bool sourceDecoder::storeBSR(transportBlock *tb, bool compat)
   prevErasure=erasureList.at(2);
   needsFiller=false;
   for(i=3;i<erasureList.count();i++) //skip
-  {
-    if(((prevErasure+1)==erasureList.at(i))&&(compat))
     {
-      needsFiller=true;
+      if(((prevErasure+1)==erasureList.at(i))&&(compat))
+        {
+          needsFiller=true;
+        }
+      else
+        {
+          if(needsFiller)
+            {
+              tb->baBSR.append(QString::number(-1).toLatin1().data());
+              tb->baBSR.append("\n");
+              needsFiller=false;
+            }
+          tb->baBSR.append(QString::number(erasureList.at(i)).toLatin1().data());
+          tb->baBSR.append("\n");
+        }
+      prevErasure=erasureList.at(i);
     }
-    else
+  if(needsFiller)
     {
-      if(needsFiller)
-      {
-        tb->baBSR.append(QString::number(-1).toLatin1().data());
-        tb->baBSR.append("\n");
-        needsFiller=false;
-      }
-      tb->baBSR.append(QString::number(erasureList.at(i)).toLatin1().data());
+      tb->baBSR.append(QString::number(-1).toLatin1().data());
+      tb->baBSR.append("\n");
+      needsFiller=false;
+      tb->baBSR.append(QString::number(erasureList.at(erasureList.count()-1)).toLatin1().data());
       tb->baBSR.append("\n");
     }
-    prevErasure=erasureList.at(i);
-  }
-  if(needsFiller)
-  {
-    tb->baBSR.append(QString::number(-1).toLatin1().data());
-    tb->baBSR.append("\n");
-    needsFiller=false;
-    tb->baBSR.append(QString::number(erasureList.at(erasureList.count()-1)).toLatin1().data());
-    tb->baBSR.append("\n");
-  }
   tb->baBSR.append("-99\n");
   if(!compat)
-  {
-    QString temp;
-    tb->baBSR.append(tb->fileName+"\n");
-    temp=QString::number(tb->modeCode);
-    while(temp.length()<5) temp.prepend("0");
-    tb->baBSR.append(temp);
-  }
+    {
+      QString temp;
+      tb->baBSR.append(tb->fileName+"\n");
+      temp=QString::number(tb->modeCode);
+      while(temp.length()<5) temp.prepend("0");
+      tb->baBSR.append(temp);
+    }
   return true;
 }
 
@@ -823,53 +808,53 @@ transportBlock *sourceDecoder::getTransporPtr(unsigned short tId,bool create)
   rxDRMStatusEvent *stce;
   bool found=false;
   for(i=0;i<transportBlockPtrList.count();i++)
-  {
-    if(transportBlockPtrList.at(i)->transportID==tId)
     {
-      found=true;
-      break;
+      if(transportBlockPtrList.at(i)->transportID==tId)
+        {
+          found=true;
+          break;
+        }
     }
-  }
   if(found) lastTransportBlockPtr=transportBlockPtrList.at(i);
   else if (create)
-  {
-    callsignValid=false;
-    bodyTotalSegments=0;
-    drmBlockList.clear();
-    stce= new rxDRMStatusEvent("");
-    QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
-    if(transportBlockPtrList.count()>=MAXTRANSPORTLISTS)
-    {
-      //delete the oldest
-      transportBlockPtrList.removeFirst();
-    }
-    for(i=0;i<transportBlockPtrList.count();)
-    {
-      if(transportBlockPtrList.at(i)->fileName=="bsr.bin")
-      {
-        transportBlockPtrList.takeAt(i);
-      }
-      else i++;
-    }
-    transportBlockPtrList.append(new transportBlock(tId));
-    lastTransportBlockPtr=transportBlockPtrList.last();
-    lastTransportBlockPtr->robMode=robustness_mode;
-    lastTransportBlockPtr->interLeaver=interleaver_depth_new;
-    lastTransportBlockPtr->mscMode=msc_mode_new; // qam
-    lastTransportBlockPtr->mpx=multiplex_description.PL_PartB;
-    lastTransportBlockPtr->spectrum=spectrum_occupancy_new;
-    // remap msc_new to modeCode
-    int mCode=1;    //default QAM16
-    if(msc_mode_new==3) mCode=0;
-    if(msc_mode_new==0) mCode=2;
-    int protection=0;
-    if(multiplex_description.PL_PartB==1) protection=1;
-    lastTransportBlockPtr->modeCode=robustness_mode*10000+spectrum_occupancy_new*1000+protection*100+mCode*10+interleaver_depth_new;
-  }
+    {
+      callsignValid=false;
+      bodyTotalSegments=0;
+      drmBlockList.clear();
+      stce= new rxDRMStatusEvent("");
+      QApplication::postEvent( dispatcherPtr, stce );  // Qt will delete it when done
+      if(transportBlockPtrList.count()>=MAXTRANSPORTLISTS)
+        {
+          //delete the oldest
+          transportBlockPtrList.removeFirst();
+        }
+      for(i=0;i<transportBlockPtrList.count();)
+        {
+          if(transportBlockPtrList.at(i)->fileName=="bsr.bin")
+            {
+              transportBlockPtrList.takeAt(i);
+            }
+          else i++;
+        }
+      transportBlockPtrList.append(new transportBlock(tId));
+      lastTransportBlockPtr=transportBlockPtrList.last();
+      lastTransportBlockPtr->robMode=robustness_mode;
+      lastTransportBlockPtr->interLeaver=interleaver_depth_new;
+      lastTransportBlockPtr->mscMode=msc_mode_new; // qam
+      lastTransportBlockPtr->mpx=multiplex_description.PL_PartB;
+      lastTransportBlockPtr->spectrum=spectrum_occupancy_new;
+      // remap msc_new to modeCode
+      int mCode=1;    //default QAM16
+      if(msc_mode_new==3) mCode=0;
+      if(msc_mode_new==0) mCode=2;
+      int protection=0;
+      if(multiplex_description.PL_PartB==1) protection=1;
+      lastTransportBlockPtr->modeCode=robustness_mode*10000+spectrum_occupancy_new*1000+protection*100+mCode*10+interleaver_depth_new;
+    }
   else
-  {
-    return NULL;
-  }
+    {
+      return NULL;
+    }
   return lastTransportBlockPtr;
 }
 
@@ -877,17 +862,11 @@ void sourceDecoder::removeTransporPtr(transportBlock * ptr)
 {
   int i;
   for(i=0;i<transportBlockPtrList.count();i++)
-  {
-    if(transportBlockPtrList.at(i)==ptr)
     {
-      transportBlockPtrList.takeAt(i);
-      break;
+      if(transportBlockPtrList.at(i)==ptr)
+        {
+          transportBlockPtrList.takeAt(i);
+          break;
+        }
     }
-  }
 }
-
-
-
-
-
-
diff --git a/qsstv/drmrx/sourcedecoder.h b/qsstv/drmrx/sourcedecoder.h
index a6acdeb..da1a098 100644
--- a/qsstv/drmrx/sourcedecoder.h
+++ b/qsstv/drmrx/sourcedecoder.h
@@ -193,9 +193,9 @@ public:
   bool checkSaveImage(QByteArray ba, transportBlock *tbPtr);
   void saveImage(transportBlock *tbPtr);
   bool storeBSR(transportBlock *tb,bool compat);
-  bool rxNotifyCheck(QString fn, hybridCrypt *hc);
-private slots:
-  void rxNotification(QString info);
+  bool rxNotifySetup();
+  bool rxNotifyCheck(QString fn);
+
 private:
   bool setupDataBlock(unsigned char *buffer,bool crcIsOK,int len);
   bool setupDataPacket(QByteArray ba);
@@ -218,6 +218,6 @@ private:
   bool isHybrid;
   hybridCrypt hc;
   bool alreadyDisplayed;
-  ftpInterface *notifyIntf;
+//  ftpInterface *notifyIntf;
 };
 #endif // SOURCEDECODER_H
diff --git a/qsstv/drmtx/drmtx.cpp b/qsstv/drmtx/drmtx.cpp
index 5810e86..77bfdf4 100644
--- a/qsstv/drmtx/drmtx.cpp
+++ b/qsstv/drmtx/drmtx.cpp
@@ -11,213 +11,339 @@
 #include "ftp.h"
 #include "hybridcrypt.h"
 
-#include <QFileInfo>
-
-
-
 
 drmTx::drmTx(QObject *parent) :
   QObject(parent)
 {
   txDRM=new drmTransmitter;
   txList.clear();
-  notifyIntf=NULL;
 
+  hybridTxCount=1;
 }
 
 drmTx::~drmTx()
 {
   delete txDRM;
+
 }
 
 void drmTx::init()
 {
-  if(notifyIntf==NULL)
-  {
-      notifyIntf = new ftpInterface("HybridTXNotify");
-      connect(notifyIntf, SIGNAL(notification(QString)), this, SLOT(rxNotification(QString)));
-  }
+  connect(onlineStatusIntf, SIGNAL(listingComplete()), this, SLOT(slotWhoResult()));
 }
 
 void drmTx::start()
 {
+  statusBarMsgEvent *statBar;
+  statBar=new statusBarMsgEvent("Sending "+drmTxFileName.fileName());
+  QApplication::postEvent(dispatcherPtr,statBar);
   txDRM->start(true);
-}
 
 
+}
 
-bool drmTx::initDRMImage(bool binary,QString fileName)
+void drmTx::forgetTxFileName()
 {
-  eRSType rsType;
-  reedSolomonCoder rsd;
-  QString fn;
-  QString ext;
+  drmTxStamp="";
+}
+
+QString drmTx::getTxFileName(QString fileName)
+{
+  QString prefix;
   QFileInfo finf;
-  QFile inf;
-  hybridCrypt hc;
-  init();
-  setTxParams(drmParams);
-  // we need to save it as a jpg file
-  if(binary)
+
+  if(useHybrid)
     {
-      finf.setFile(fileName);
+      prefix=QString("de_"+myCallsign+"-%1-").arg(hybridTxCount);
     }
-  else
-    {
-      finf.setFile(txWidgetPtr->getImageViewerPtr()->getFilename());
+  else {
+      // Once allocated, keep the same TX name...
+      // cleared by applyTemplate() or forgetTxFileName()
+      if (drmTxStamp.isEmpty())
+        drmTxStamp=QDateTime::currentDateTime().toUTC().toString("yyyyMMddHHmmss");
+      prefix = drmTxStamp+"-";
     }
-  if(useHybrid)
+
+  if(fileName.isEmpty())
     {
-      fn="de_"+myCallsign+"-1-"+finf.baseName();
+      finf.setFile(txWidgetPtr->getImageViewerPtr()->getCompressedFilename());
     }
   else
     {
-      fn=QDateTime::currentDateTime().toUTC().toString("yyyyMMddHHmmss");
-      fn+="-"+finf.baseName();
+      finf.setFile(fileName);
     }
-  ext=finf.suffix();
-  fixBlockList.clear();
-  if(txList.count()>5) txList.removeFirst();
-  txList.append(txSession());
-  txList.last().filename=fn;
-  txList.last().extension=ext;
+
+  drmTxFileName.setFile(prefix + finf.fileName());
+  return drmTxFileName.fileName();
+}
+
+bool drmTx::initDRMImage(bool binary,QString fileName)
+{
+  eRSType rsType;
+  reedSolomonCoder rsd;
+  QFile inf;
+  setTxParams(drmParams);
+
+  if (binary && fileName.isEmpty()) return false;
+  if (!binary && !txWidgetPtr->getImageViewerPtr()->hasValidImage()) return false;
+
+  addToLog(QString("bin=%1, fileName=%2").arg(binary).arg(fileName),LOGDRMTX);
+
+  // make sure drmTxFileName is up to date
+  getTxFileName(fileName);
+
   if(!useHybrid)
     {
-      txList.last().drmParams=drmTxParameters;
       if(binary)
         {
           inf.setFileName(fileName);
           if(!inf.open(QIODevice::ReadOnly))
             {
+              addToLog(QString("Unable to open '%1' for read").arg(fileName),LOGDRMTX);
               return false;
             }
-          txList.last().ba=inf.readAll();
-
+          baDRM=inf.readAll();
         }
       else
         {
-          if(!txWidgetPtr->getImageViewerPtr()->copyToBuffer(&(txList.last().ba)))
-          {
+          if(!txWidgetPtr->getImageViewerPtr()->copyToBuffer(&baDRM))
+            {
+              addToLog(QString("Unable to copy image from txWidget->viewer"),LOGDRMTX);
               return false;
-          }
-          txList.last().extension="jp2";
+            }
+          drmTxFileName.setFile(drmTxFileName.completeBaseName()+".jp2");
         }
 
-      rsType=(eRSType)txList.last().drmParams.reedSolomon;
-      baDRM=txList.last().ba;
+      rsType=(eRSType)drmTxParameters.reedSolomon;
       if(rsType!=RSTNONE)
         {
-          rsd.encode(baDRM,txList.last().extension,rsType);
-          txDRM->init(&baDRM,txList.last().filename,rsTypeStr[rsType],txList.last().drmParams);
+          rsd.encode(baDRM,drmTxFileName.suffix(),rsType);
+          txDRM->init(&baDRM,drmTxFileName.baseName(),rsTypeStr[rsType],drmTxParameters);
         }
       else
         {
-          txDRM->init(&baDRM,txList.last().filename,txList.last().extension,txList.last().drmParams);
+          txDRM->init(&baDRM,drmTxFileName.baseName(),drmTxFileName.suffix(),drmTxParameters);
         }
     }
   else
     {
-      txList.last().drmParams.bandwith=1; // bw 2.2
-      txList.last().drmParams.robMode=2;  // mode E
-      txList.last().drmParams.interleaver=0; // long
-      txList.last().drmParams.protection=0; // high
-      txList.last().drmParams.qam=0; // 4bit QAM
-      txList.last().drmParams.callsign=myCallsign;
+      hybridCrypt hc;
+
+      drmTxHybridParameters.bandwith=1; // bw 2.2
+      drmTxHybridParameters.robMode=2;  // mode E
+      drmTxHybridParameters.interleaver=0; // long
+      drmTxHybridParameters.protection=0; // high
+      drmTxHybridParameters.qam=0; // 4bit QAM
+      drmTxHybridParameters.callsign=myCallsign;
 
       // we have to fill in the body
-      txList.last().ba.clear();
-      hc.enCrypt(&txList.last().ba);
-      txDRM->init(&txList.last().ba,txList.last().filename,txList.last().extension,txList.last().drmParams);
-      if(!ftpDRMHybrid(txList.last().filename+"."+finf.suffix()))
-      {
-        return false;
-      }
-      ftpDRMHybridNotifyCheck(txList.last().filename+"."+finf.suffix());
+      baDRM.clear();
+      hc.enCrypt(&baDRM);
+      txDRM->init(&baDRM,drmTxFileName.baseName(),drmTxFileName.suffix(),drmTxHybridParameters);
+      hybridTxCount++;
+    }
+  return true;
+}
+
+void drmTx::updateTxList()
+{
+  fixBlockList.clear();
+  if ((txList.count()>0) && (txList.last().transportID == txTransportID)) return;
+
+  if(txList.count()>5) txList.removeFirst();
+
+  txList.append(txSession());
+  txList.last().filename=drmTxFileName.baseName();
+  txList.last().extension=drmTxFileName.suffix();
+  txList.last().ba=baDRM;
+
+  if (useHybrid) {
+      txList.last().drmParams=drmTxHybridParameters;
+      ftpDRMHybridNotifyCheck(txList.last().filename+"."+txList.last().extension);
     }
+  else {
+      txList.last().drmParams=drmTxParameters;
+    }
+
   // transportID is set
   txList.last().transportID=txTransportID;
-  return true;
 }
 
-bool drmTx::ftpDRMHybrid(QString fn)
+bool drmTx::ftpDRMHybrid(QString fileName, QString destName)
 {
-//  char *data;
-//  unsigned int ct;
-  eftpError ftpResult;
-  QByteArray testBA;
   QByteArray ba;
-  QTemporaryFile ftmp;
-  QFileInfo finf;
-  finf.setFile(fn);
-  QString changedFn;
-  ftpInterface ftpIntf("HybridTX");
-  hybridCrypt hc;
-  ftpIntf.setupConnection(hc.host(),hc.port(),hc.user(),hc.passwd(),hc.dir()+"/"+hybridFtpHybridFilesDirectory);
-  if(!txWidgetPtr->getImageViewerPtr()->copyToBuffer(&ba))
+
+  QString ftpErrorStr;
+  ftpSetupEvent *ftpSetup;
+  ftpUploadFileEvent *ftpUpload;
+
+  addToLog(QString("destName='%1' last='%2'").arg(destName).arg(lastHybridUpload),LOGFTP);
+
+  if (destName == lastHybridUpload)
     {
-      return false;
+      addToLog(QString("%1 already uploaded").arg(destName), LOGFTP);
+      return true;
+    }
+  ftpSetup=new ftpSetupEvent(hybridTxIntf,hybridFtpRemoteHost,hybridFtpPort,hybridFtpLogin,hybridFtpPassword,hybridFtpRemoteDirectory+"/"+hybridFtpHybridFilesDirectory);
+
+  QApplication::postEvent(dispatcherPtr,ftpSetup);
+
+  //  hybridTxIntf->setupConnection(hybridFtpRemoteHost,hybridFtpPort,hybridFtpLogin,hybridFtpPassword,hybridFtpRemoteDirectory+"/"+hybridFtpHybridFilesDirectory);
+    hybridTxIntf->closeWhenDone();
+
+  if (fileName.isEmpty())
+    {
+      txWidgetPtr->getImageViewerPtr()->copyToBuffer(&ba);
+      if(!ftmp.open()) return false;
+      ftmp.write(ba);
+      ftmp.close();
+      ftpUpload=new ftpUploadFileEvent(hybridTxIntf,ftmp.fileName(),destName,true);
+    }
+  else
+    {
+      ftpUpload=new ftpUploadFileEvent(hybridTxIntf,fileName,destName,true);
+    }
+  QApplication::postEvent(dispatcherPtr,ftpUpload);
+  while(dispatcherPtr->hybridTxDone==DFTPWAITING)
+    {
+      qApp->processEvents();
     }
-  if(!ftmp.open()) return false;
-  ftmp.write(ba);
-  ftmp.close();
-  changedFn=finf.completeBaseName()+".jp2";
 
-  ftpResult=ftpIntf.uploadFile(ftmp.fileName(),changedFn,true);
-  switch(ftpResult)
+
+  if(dispatcherPtr->hybridTxDone!=DFTPOK)
     {
-    case FTPCANCELED:
-      ftpErrorStr="Connection Canceled";
-    break;
-    case FTPOK:
-      break;
-    case FTPERROR:
-      ftpErrorStr=ftpIntf.getLastError();
-      break;
-    case FTPNAMEERROR:
-      ftpErrorStr="Error in filename";
-      break;
-    case FTPTIMEOUT:
-      ftpErrorStr="FTP timed out";
-      break;
+      ftpErrorStr=hybridTxIntf->getLastError();
+      addToLog(QString("ftpDRMHybrid Upload Error: %1").arg(ftpErrorStr),LOGDRMTX);
+      displayMBoxEvent *mbe = new displayMBoxEvent("Upload Error",ftpErrorStr);
+      QApplication::postEvent( dispatcherPtr, mbe );
+      return false;
     }
-  addToLog("sendDRMHybrid",LOGDRMTX);
-  return ftpResult==FTPOK;
+  lastHybridUpload=destName;
+
+  addToLog(QString("hybridTxCount updated to %1").arg(hybridTxCount),LOGDRMTX);
+  return true;
 }
 
+void drmTx::clearLastHybridUpload()
+{
+  addToLog(QString("Clearing lasHybridUpload, was: %1").arg(lastHybridUpload),LOGFTP);
+  lastHybridUpload = "";
+}
 
 bool drmTx::ftpDRMHybridNotifyCheck(QString fn)
 {
   txDRMNotifyEvent *txne;
+  ftpSetupEvent *ftpSetup;
+  notifyCheckEvent *ce;
   if (!enableHybridNotify) return false;
   
-  if (enableHybridNotifySpecialServer) {
-     notifyIntf->setupConnection(hybridNotifyRemoteHost, hybridNotifyPort,
-              hybridNotifyLogin, hybridNotifyPassword,
-              hybridNotifyRemoteDir+"/"+hybridNotifyDir);
-     }
-  else {
-     // notification to vk4aes.com (EasyPal compatible)
-     notifyIntf->setupConnection("vk4aes.com",21,"vk4aes","10mar1936","/RxOkNotifications1");
-                    
-     // or notification to image server
-     //notifyIntf->setupConnection(hc.host(),hc.port(),hc.user(),hc.passwd(),hc.dir()+"/RxOkNotifications1");
-     }
-     
+//  notifyTXIntf->setupConnection(hybridFtpRemoteHost, hybridFtpPort,
+//                                hybridFtpLogin, hybridFtpPassword,
+//                                hybridFtpRemoteDirectory+"/"+hybridFtpHybridFilesDirectory);
+  ftpSetup=new ftpSetupEvent(notifyTXIntf,hybridNotifyRemoteHost,hybridNotifyPort,hybridNotifyLogin,hybridNotifyPassword,hybridNotifyRemoteDir+"/RxOkNotifications1");
+  QApplication::postEvent(dispatcherPtr,ftpSetup);
+  //    }
+  //  else
+  //    // NOT CORRECT !!!  there is no default;
+  //    {
+  //      hybridCrypt hc;
+  //      // notification to last RX Hybrid Image server or custom server if selected
+  //      notifyTXIntf->setupConnection(hc.host(),hc.port(),hc.user(),hc.passwd(),hc.dir()+"/RxOkNotifications1");
+  //    }
+
   txne = new txDRMNotifyEvent("");
   QApplication::postEvent( dispatcherPtr, txne );
-  
-  notifyIntf->startNotifyCheck(fn, 15, 60/15, true);
+  ce=new notifyCheckEvent(notifyTXIntf,fn, 15, 60/15, true);
+  QApplication::postEvent( dispatcherPtr, ce );
+
+//  notifyTXIntf->startNotifyCheck(fn, 15, 60/15, true);
   return true;
 }
 
-void drmTx::rxNotification(QString info)
+//void drmTx::rxNotification(QString info)
+//{
+//  if (info != "") {
+//      txDRMNotifyAppendEvent *txne = new txDRMNotifyAppendEvent(info);
+//      QApplication::postEvent( dispatcherPtr, txne );
+//    }
+//}
+
+
+void drmTx::setupStatusIntf()
 {
-  if (info != "") {
-     txDRMNotifyAppendEvent *txne = new txDRMNotifyAppendEvent(info);
-     QApplication::postEvent( dispatcherPtr, txne );
-  }
+  if (!hybridNotifyRemoteHost.isEmpty())
+    {
+      onlineStatusIntf->setupConnection(hybridNotifyRemoteHost, hybridNotifyPort,
+                                        hybridNotifyLogin, hybridNotifyPassword,
+                                        hybridNotifyRemoteDir+"/OnlineCallsigns1");
+
+      onlineStatusIntf->closeWhenDone();
+      onlineStatusIntf->hideProgress();
+    }
 }
 
+void drmTx::who()
+{
+  // get a list of online callsigns
+  setupStatusIntf();
+  onlineStatusIntf->getListing("*");
+
+  rxDRMNotifyEvent *rxne = new rxDRMNotifyEvent("Retrieving List...");
+  QApplication::postEvent( dispatcherPtr, rxne );
+
+  // slotWhoResult is called when we have the info
+}
+
+void drmTx::slotWhoResult()
+{
+  int i;
+  QString info="Online User List\n";
+
+  QList <QUrlInfo> users = onlineStatusIntf->getListingResults();
+  onlineStatusIntf->clearListingResults();
+
+  for (i=0; i<users.count(); i++) {
+      info += users.at(i).name()+"\n";
+    }
+
+  // put it in the RX widget notifications box
+  rxDRMNotifyEvent *rxne = new rxDRMNotifyEvent(info);
+  QApplication::postEvent( dispatcherPtr, rxne );
+}
+
+
+void drmTx::setOnlineStatus(bool online, QString info)
+{
+  // we can use onlineStatusInt directly because this function is only used from the main thread
+
+  addToLog(QString("Call:%1 online:%2, info:%3").arg(myCallsign).arg(online).arg(info),LOGFTP);
+
+  if (onlineStatusEnabled) {
+      setupStatusIntf();
+      if (online)
+        {
+          onlineStatusIntf->uploadData(QByteArray("Dummy\r\n"), myCallsign+"."+info);
+        }
+      else
+        {
+          onlineStatusIntf->mremove(myCallsign+".*");
+        }
+    }
+
+  if (enableHybridRx && !online)
+    {
+      hybridCrypt hc;
+      hybridTxIntf->setupConnection(hc.host(),hc.port(),hc.user(),hc.passwd(),hc.dir()+"/"+hybridFtpHybridFilesDirectory);
+      hybridTxIntf->mremove("de_"+myCallsign+"-*"); // Delete hybrid images sent
+      hybridTxIntf->closeWhenDone();
+    }
+
+  if (!online) {
+      onlineStatusIntf->wait(-1);
+      hybridTxIntf->wait(-1);
+      notifyTXIntf->wait(-1);
+    }
+}
 
 double  drmTx::calcTxTime(int overheadTime)
 {
@@ -232,7 +358,7 @@ int drmTx::processFIX(QByteArray bsrByteArray)
 {
   int i,j;
   bool inSeries;
-//  bool extended; // todo check use of extended
+  //  bool extended; // todo check use of extended
   bool done;
   int block;
   int trID,lastBlock;
@@ -253,7 +379,7 @@ int drmTx::processFIX(QByteArray bsrByteArray)
   fixBlockList.append(lastBlock++);
   inSeries=false;
   done=false;
-//  extended=false;
+  //  extended=false;
   for(i=4;(!done)&&i<sl.count();i++)
     {
       block=sl.at(i).toInt();
@@ -278,7 +404,7 @@ int drmTx::processFIX(QByteArray bsrByteArray)
   // check if we have a filename beyond -99
   if((i+1)<sl.count()) // we need an additional 2 entries (filename and mode)
     {
-//      extended=true;
+      //      extended=true;
       //      fileName=sl.at(i++); // not used at this moment
     }
   return trID;
@@ -335,5 +461,7 @@ txSession *drmTx::getSessionPtr(uint transportID)
 
 void drmTx::applyTemplate(QString templateFilename, bool useTemplate, imageViewer *ivPtr)
 {
+  clearLastHybridUpload();
+  forgetTxFileName();
   ivPtr->setParam(templateFilename,useTemplate);
 }
diff --git a/qsstv/drmtx/drmtx.h b/qsstv/drmtx/drmtx.h
index c535c42..8d70d73 100644
--- a/qsstv/drmtx/drmtx.h
+++ b/qsstv/drmtx/drmtx.h
@@ -3,7 +3,11 @@
 
 
 #include <QObject>
+#include <QFileInfo>
+#include <QTemporaryFile>
 
+
+#include "hybridcrypt.h"
 #include "drmtransmitter.h"
 #include "reedsolomoncoder.h"
 #include "ftp.h"
@@ -31,8 +35,13 @@ public:
   ~drmTx();
   void init();
   void start();
+  void forgetTxFileName();
+  QString getTxFileName(QString fileName);
+  bool ftpDRMHybrid(QString fileName, QString destName);
   bool initDRMImage(bool binary, QString fileName);
-  bool ftpDRMHybridNotifyCheck(QString fn);
+  void updateTxList();
+  void who();
+  void setOnlineStatus(bool online, QString info="");
   
   void sendBSR(QByteArray *p,drmTxParams dp);
   int processFIX(QByteArray bsrByteArray);
@@ -48,21 +57,29 @@ public:
     drmTxParameters=params;
   }
  double calcTxTime(int overheadTime);
+ void clearLastHybridUpload();
 
 signals:
 
 private slots:
-  void rxNotification(QString info);
+//  void rxNotification(QString info);
+  void slotWhoResult();
 
 private:
     void runRx();
-    bool ftpDRMHybrid(QString fn);
+    bool ftpDRMHybridNotifyCheck(QString fn);
+    void setupStatusIntf();
     drmTransmitter *txDRM;
     QList <txSession> txList;
     drmTxParams drmTxParameters;
+    drmTxParams drmTxHybridParameters;
+    QFileInfo   drmTxFileName;
+    QString	drmTxStamp;
+    int		hybridTxCount;
     QByteArray baDRM;
-    QString ftpErrorStr;
-    ftpInterface *notifyIntf;
+    QString lastHybridUpload;
+    QTemporaryFile ftmp;
+
 };
 
 #endif // DRMTX_H
diff --git a/qsstv/dsp/filter.cpp b/qsstv/dsp/filter.cpp
index 311509e..05de072 100644
--- a/qsstv/dsp/filter.cpp
+++ b/qsstv/dsp/filter.cpp
@@ -27,6 +27,8 @@ void filter::init()
   prevTemp=0;
   angleToFc=SAMPLERATE/(2*M_PI);
   frCenter=0;
+  fltrIndex=0;
+  coefIndex=0;
 }
 
 void filter::resetPointers()
@@ -88,80 +90,232 @@ void filter::allocate()
     {
       nco.init(frCenter/SAMPLERATE);
     }
+  fltrIndex=nZeroes;
+  coefIndex = nZeroes+1;
 }
 
 
 void filter::processFIR(FILTERPARAMTYPE *dataPtr, double *dataOutputPtr)
 {
-  FILTERPARAMTYPE resI=0;
-  FILTERPARAMTYPE *fp1;
+  //  FILTERPARAMTYPE resI;
+  //  FILTERPARAMTYPE *fp1;
+  //  const FILTERPARAMTYPE *cf1;
+  //  unsigned int i,k;
+  //  for (k=0;k<dataLen;k++)
+  //    {
+  //      resI=0;
+  //      cf1 = coefZPtr;
+  //      fp1 = sampleBufferIPtr;
+  //      memmove(sampleBufferIPtr+1, sampleBufferIPtr, bufSize);
+  //      sampleBufferIPtr[0]=dataPtr[k];
+  //      for(i=0;i<=nZeroes;i++,fp1++,cf1++)
+  //        {
+  //          resI+=(*fp1)*(*cf1);
+  //        };
+  //      dataOutputPtr[k]=resI/gain;
+
+  //      //      double vol=sqrt(resI*resI);
+  //      //      if (vol>avgVolume) avgVolume=avgVolume*(1-volumeAttackIntegrator)+(volumeAttackIntegrator)*vol;
+  //      //      else if (vol<avgVolume) avgVolume=avgVolume*(1-volumeDecayIntegrator)+(volumeDecayIntegrator)*vol;
+  //      //      volumePtr[i]=avgVolume;
+  //    }
+
+
+  FILTERPARAMTYPE resI;
   const FILTERPARAMTYPE *cf1;
   unsigned int i,k;
+  int fi;
   for (k=0;k<dataLen;k++)
     {
+      sampleBufferIPtr[fltrIndex]=dataPtr[k];
+      fi=fltrIndex--;
+      if(fltrIndex<0)
+        fltrIndex=nZeroes;
       resI=0;
       cf1 = coefZPtr;
-      fp1 = sampleBufferIPtr;
-      memmove(sampleBufferIPtr+1, sampleBufferIPtr, bufSize);
-      sampleBufferIPtr[0]=dataPtr[k];
-      for(i=0;i<=nZeroes;i++,fp1++,cf1++)
+      for(i=0;i<=nZeroes;i++,cf1++)
         {
-          resI+=(*fp1)*(*cf1);
-        };
-      dataOutputPtr[k]=resI/gain;
+          if ((fi+i) >nZeroes)
+            {
+              fi -=(nZeroes+1);
+            }
+
+          resI+=sampleBufferIPtr[fi+i]*(*cf1);
+        }
 
-      //      double vol=sqrt(resI*resI);
-      //      if (vol>avgVolume) avgVolume=avgVolume*(1-volumeAttackIntegrator)+(volumeAttackIntegrator)*vol;
-      //      else if (vol<avgVolume) avgVolume=avgVolume*(1-volumeDecayIntegrator)+(volumeDecayIntegrator)*vol;
-      //      volumePtr[i]=avgVolume;
+      dataOutputPtr[k]=resI/gain;
     }
+
+
+//  FILTERPARAMTYPE resI;
+//  FILTERPARAMTYPE *fp1;
+//  const FILTERPARAMTYPE *cf1;
+//  unsigned int i,k;
+//  for (k=0;k<dataLen;k++)
+//    {
+//      sampleBufferIPtr[fltrIndex]=dataPtr[k];
+//      fp1 = &sampleBufferIPtr[nZeroes];
+//      resI=0;
+//      cf1=&coefZPtr[coefIndex];
+//      for(i=0;i<=nZeroes;i++,fp1--,cf1--)
+//        {
+//          resI+=(*fp1)*(*cf1);
+//        }
+//      fltrIndex--;
+//      if(fltrIndex<0)
+//        {
+//          fltrIndex=nZeroes;
+//          coefIndex =nZeroes+1;
+//        }
+//      else
+//        {
+//          coefIndex++;
+//        }
+//      dataOutputPtr[k]=resI/gain;
+//    }
 }
 
 void filter::processFIRInt(FILTERPARAMTYPE *dataPtr, quint16 *dataOutputPtr)
 {
+  //  FILTERPARAMTYPE resI=0;
+  //  FILTERPARAMTYPE *fp1;
+  //  const FILTERPARAMTYPE *cf1;
+  //  unsigned int i,k;
+  //  for (k=0;k<dataLen;k++)
+  //    {
+  //      resI=0;
+  //      cf1 = coefZPtr;
+  //      fp1 = sampleBufferIPtr;
+  //      memmove(sampleBufferIPtr+1, sampleBufferIPtr, bufSize);
+  //      sampleBufferIPtr[0]=dataPtr[k];
+  //      for(i=0;i<=nZeroes;i++,fp1++,cf1++)
+  //        {
+  //          resI+=(*fp1)*(*cf1);
+  //        };
+  //      dataOutputPtr[k]=(quint16)rint(resI/gain);
+  //    }
+
   FILTERPARAMTYPE resI=0;
-  FILTERPARAMTYPE *fp1;
   const FILTERPARAMTYPE *cf1;
   unsigned int i,k;
+  int fi;
   for (k=0;k<dataLen;k++)
     {
+      sampleBufferIPtr[fltrIndex]=dataPtr[k];
+      fi=fltrIndex--;
+      if(fltrIndex<0)
+        fltrIndex=nZeroes;
       resI=0;
       cf1 = coefZPtr;
-      fp1 = sampleBufferIPtr;
-      memmove(sampleBufferIPtr+1, sampleBufferIPtr, bufSize);
-      sampleBufferIPtr[0]=dataPtr[k];
-      for(i=0;i<=nZeroes;i++,fp1++,cf1++)
+      for(i=0;i<=nZeroes;i++,cf1++)
         {
-          resI+=(*fp1)*(*cf1);
-        };
+          if ((fi+i) >nZeroes)
+            {
+              fi -=(nZeroes+1);
+            }
+
+          resI+=sampleBufferIPtr[fi+i]*(*cf1);
+        }
       dataOutputPtr[k]=(quint16)rint(resI/gain);
     }
+
+
+//  FILTERPARAMTYPE resI;
+//  FILTERPARAMTYPE *fp1;
+//  const FILTERPARAMTYPE *cf1;
+//  unsigned int i,k;
+//  for (k=0;k<dataLen;k++)
+//    {
+//      sampleBufferIPtr[fltrIndex]=dataPtr[k];
+//      fp1 = &sampleBufferIPtr[nZeroes];
+//      resI=0;
+//      cf1=&coefZPtr[coefIndex];
+//      for(i=0;i<=nZeroes;i++,fp1--,cf1--)
+//        {
+//          resI+=(*fp1)*(*cf1);
+//        }
+//      fltrIndex--;
+//      if(fltrIndex<0)
+//        {
+//          fltrIndex=nZeroes;
+//          coefIndex =nZeroes+1;
+//        }
+//      else
+//        {
+//          coefIndex++;
+//        }
+//      dataOutputPtr[k]=(quint16)rint(resI/gain);
+//    }
 }
 
 
 void filter::processFIRDemod(FILTERPARAMTYPE *dataPtr,FILTERPARAMTYPE *dataOutputPtr)
 {
-  FILTERPARAMTYPE  temp;
-  unsigned int i,k;
-  FILTERPARAMTYPE resI=0, resQ=0;
-  FILTERPARAMTYPE *fp1, *fp2;
+//  FILTERPARAMTYPE  temp;
+//  unsigned int i,k;
+//  FILTERPARAMTYPE resI=0, resQ=0;
+//  FILTERPARAMTYPE *fp1, *fp2;
+//  const FILTERPARAMTYPE *cf1;
+//  FILTERPARAMTYPE discRe,discIm;
+
+//  for (k=0;k<dataLen;k++)
+//    {
+//      resI=0;
+//      resQ=0;
+//      cf1 = coefZPtr;
+//      fp1 = sampleBufferIPtr;
+//      fp2 = sampleBufferQPtr;
+//      memmove(sampleBufferIPtr, sampleBufferIPtr+1, bufSize);
+//      memmove(sampleBufferQPtr, sampleBufferQPtr+1, bufSize);
+//      nco.multiply(sampleBufferIPtr[nZeroes],sampleBufferQPtr[nZeroes],dataPtr[k]);
+//      for(i=0;i<=nZeroes;i++,fp1++,fp2++,cf1++)
+//        {
+//          resI+=(*fp1)*(*cf1);
+//          resQ+=(*fp2)*(*cf1);
+//        }
+//      resI/=gain;
+//      resQ/=gain;
+//      discRe=resI*resIprev+resQ*resQprev;
+//      discIm=-resQ*resIprev+resQprev*resI;
+//      resIprev=resI;
+//      resQprev=resQ;
+//      if(discRe==0) discRe=0.0001;
+//      temp=frCenter-atan2(discIm,discRe)*angleToFc;
+//      if(temp<500) temp=prevTemp;
+//      if(temp>2600) temp=prevTemp;
+//      prevTemp=temp;
+//      dataOutputPtr[k]=temp;
+//      double vol=sqrt(resI*resI+resQ*resQ);
+//      if (vol>avgVolume) avgVolume=avgVolume*(1-volumeAttackIntegrator)+(volumeAttackIntegrator)*vol;
+//      else if (vol<avgVolume) avgVolume=avgVolume*(1-volumeDecayIntegrator)+(volumeDecayIntegrator)*vol;
+//      volumePtr[i]=avgVolume;
+//    }
+
+
+  FILTERPARAMTYPE resI,resQ;
   const FILTERPARAMTYPE *cf1;
   FILTERPARAMTYPE discRe,discIm;
-
+  FILTERPARAMTYPE  temp;
+  unsigned int i,k;
+  int fi;
   for (k=0;k<dataLen;k++)
     {
+      nco.multiply(sampleBufferIPtr[fltrIndex],sampleBufferQPtr[fltrIndex],dataPtr[k]);
+      fi=fltrIndex--;
+      if(fltrIndex<0)
+        fltrIndex=nZeroes;
       resI=0;
       resQ=0;
       cf1 = coefZPtr;
-      fp1 = sampleBufferIPtr;
-      fp2 = sampleBufferQPtr;
-      memmove(sampleBufferIPtr, sampleBufferIPtr+1, bufSize);
-      memmove(sampleBufferQPtr, sampleBufferQPtr+1, bufSize);
-      nco.multiply(sampleBufferIPtr[nZeroes],sampleBufferQPtr[nZeroes],dataPtr[k]);
-      for(i=0;i<=nZeroes;i++,fp1++,fp2++,cf1++)
+      for(i=0;i<=nZeroes;i++,cf1++)
         {
-          resI+=(*fp1)*(*cf1);
-          resQ+=(*fp2)*(*cf1);
+          if ((fi+i) >nZeroes)
+            {
+              fi -=(nZeroes+1);
+            }
+
+          resI+=sampleBufferIPtr[fi+i]*(*cf1);
+          resQ+=sampleBufferQPtr[fi+i]*(*cf1);
         }
       resI/=gain;
       resQ/=gain;
@@ -180,6 +334,58 @@ void filter::processFIRDemod(FILTERPARAMTYPE *dataPtr,FILTERPARAMTYPE *dataOutpu
       else if (vol<avgVolume) avgVolume=avgVolume*(1-volumeDecayIntegrator)+(volumeDecayIntegrator)*vol;
       volumePtr[i]=avgVolume;
     }
+
+
+//  FILTERPARAMTYPE resI,resQ;
+//  FILTERPARAMTYPE *fp1,*fp2;
+//  const FILTERPARAMTYPE *cf1;
+//  FILTERPARAMTYPE discRe,discIm;
+//  FILTERPARAMTYPE  temp;
+
+//  unsigned int i,k;
+//  for (k=0;k<dataLen;k++)
+//    {
+//      nco.multiply(sampleBufferIPtr[fltrIndex],sampleBufferQPtr[fltrIndex],dataPtr[k]);
+//      fp1 = &sampleBufferIPtr[nZeroes];
+//      fp2 = &sampleBufferQPtr[nZeroes];
+//      resI=0;
+//      resQ=0;
+//      cf1=&coefZPtr[coefIndex];
+//      for(i=0;i<=nZeroes;i++,fp1--,fp2--,cf1--)
+//        {
+//          resI+=(*fp1)*(*cf1);
+//          resQ+=(*fp2)*(*cf1);
+//        }
+//      fltrIndex--;
+//      if(fltrIndex<0)
+//        {
+//          fltrIndex=nZeroes;
+//          coefIndex =nZeroes+1;
+//        }
+//      else
+//        {
+//          coefIndex++;
+//        }
+//      resI/=gain;
+//      resQ/=gain;
+//      discRe=resI*resIprev+resQ*resQprev;
+//      discIm=-resQ*resIprev+resQprev*resI;
+//      resIprev=resI;
+//      resQprev=resQ;
+//      if(discRe==0) discRe=0.0001;
+//      temp=frCenter-atan2(discIm,discRe)*angleToFc;
+//      if(temp<500) temp=prevTemp;
+//      if(temp>2600) temp=prevTemp;
+//      prevTemp=temp;
+//      dataOutputPtr[k]=temp;
+//      double vol=sqrt(resI*resI+resQ*resQ);
+//      if (vol>avgVolume) avgVolume=avgVolume*(1-volumeAttackIntegrator)+(volumeAttackIntegrator)*vol;
+//      else if (vol<avgVolume) avgVolume=avgVolume*(1-volumeDecayIntegrator)+(volumeDecayIntegrator)*vol;
+//      volumePtr[i]=avgVolume;
+
+//    }
+
+
 }
 
 
@@ -210,46 +416,6 @@ void filter::processHILBVolume(FILTERPARAMTYPE *dataPtr)
     }
 }
 
-//void filter::processHILBDemod(FILTERPARAMTYPE *dataPtr)
-//{
-//  int  temp;
-//  uint i,k;
-//  FILTERPARAMTYPE resI;
-//  FILTERPARAMTYPE resQ;
-//  FILTERPARAMTYPE discRe;
-//  FILTERPARAMTYPE discIm;
-//  const FILTERPARAMTYPE *cf1;
-//  FILTERPARAMTYPE *fp1;
-
-//  for (k=0;k<dataLen;k++)
-//    {
-//      resQ=0;
-//      cf1 = coefZPtr+1;
-//      fp1 = sampleBufferIPtr+1;
-//      memmove(sampleBufferIPtr+1, sampleBufferIPtr, bufSize);
-//      sampleBufferIPtr[0]=dataPtr[k];
-//      for(i=1;i<=nZeroes;i+=2,fp1+=2,cf1+=2)
-//        {
-//          resQ+=(*fp1)*(*cf1);
-//        };
-//      resQ/=gain;
-//      resI=sampleBufferIPtr[nZeroes/2];
-//      discRe=resI*resIprev+resQ*resQprev;
-//      discIm=-resQ*resIprev+resQprev*resI;
-//      resIprev=resI;
-//      resQprev=resQ;
-//      if(discRe==0) discRe=0.0001;
-//      temp=(int)round(frCenter-atan2(discIm,discRe)*angleToFc);
-//      if(temp<500) temp=prevTemp;
-//      if(temp>2600) temp=prevTemp;
-//      prevTemp=temp;
-//      demodPtr[k]=temp;
-//      double vol=sqrt(resI*resI+resQ*resQ);
-//      if (vol>avgVolume) avgVolume=avgVolume*(1-volumeAttackIntegrator)+(volumeAttackIntegrator)*vol;
-//      else if (vol<avgVolume) avgVolume=avgVolume*(1-volumeDecayIntegrator)+(volumeDecayIntegrator)*vol;
-//      volumePtr[i]=avgVolume;
-//    }
-//}
 
 
 void filter::processIIR(double *dataPtr)
@@ -281,6 +447,33 @@ void filter::processIIR(double *dataPtr)
 
 void filter::processIQ(FILTERPARAMTYPE *dataPtr, float *dataOutputPtr)
 {
+
+//  FILTERPARAMTYPE resQ;
+//  const FILTERPARAMTYPE *cf1;
+//  unsigned int i,k;
+//  int fi;
+//  for (k=0;k<dataLen;k++)
+//    {
+//      sampleBufferIPtr[fltrIndex]=dataPtr[k];
+//      fi=fltrIndex--;
+//      if(fltrIndex<0)
+//        fltrIndex=nZeroes;
+//      resQ=0;
+//      cf1 = coefZPtr;
+//      for(i=0;i<=nZeroes;i++,cf1++)
+//        {
+//          if ((fi+i) >nZeroes)
+//            {
+//              fi -=(nZeroes+1);
+//            }
+
+//          resQ+=sampleBufferIPtr[fi+i]*(*cf1);
+//        }
+//      dataOutputPtr[2*k+1]=sampleBufferIPtr[(nZeroes+1)/2]; // just delay
+//      dataOutputPtr[2*k]=resQ/gain;
+//    }
+
+
   FILTERPARAMTYPE resQ=0;
   const FILTERPARAMTYPE *cf1;
   FILTERPARAMTYPE *fp1;
diff --git a/qsstv/dsp/filter.h b/qsstv/dsp/filter.h
index 78bfc77..dffe139 100644
--- a/qsstv/dsp/filter.h
+++ b/qsstv/dsp/filter.h
@@ -17,7 +17,6 @@ public:
   void processFIRDemod(FILTERPARAMTYPE *dataPtr, FILTERPARAMTYPE *dataOutputPtr);
   void processIIR(FILTERPARAMTYPE *dataPtr);
   void processHILBVolume(FILTERPARAMTYPE *dataPtr);
-//  void processHILBDemod(FILTERPARAMTYPE *dataPtr);
   void processIQ(FILTERPARAMTYPE *dataPtr,float *dataOutputPtr);
   void setupMatchedFilter(FILTERPARAMTYPE freq, uint numTaps);
   void allocate();
@@ -33,6 +32,8 @@ public:
   uint nZeroes;
   uint nPoles;
   uint dataLen;
+  int fltrIndex;
+  unsigned int coefIndex;
 
 private:
 
diff --git a/qsstv/dsp/filterparam.cpp b/qsstv/dsp/filterparam.cpp
index e0e75b7..b86ffee 100644
--- a/qsstv/dsp/filterparam.cpp
+++ b/qsstv/dsp/filterparam.cpp
@@ -21,82 +21,82 @@
 #include "filterparam.h"
 
 
-// blIIR  Chebyshev , Bandpass
-// localSamplingrate = 12000.000000
-// order = 4
-// Gain = 103035.237413
-// corner 1 frequency = 1050.000000
-// corner 2 frequency = 1350.000000
-//Ripple = -1.000000
-//
-// Coefficients - Zeroes:
+//// blIIR  Chebyshev , Bandpass
+//// localSamplingrate = 12000.000000
+//// order = 4
+//// Gain = 103035.237413
+//// corner 1 frequency = 1050.000000
+//// corner 2 frequency = 1350.000000
+////Ripple = -1.000000
+////
+//// Coefficients - Zeroes:
 
-const double z_sync_bp[SYNCBPNUMZEROES+1]=
-{
-   1,
-   0,
-   -4,
-   0,
-   6,
-   0,
-   -4,
-   0,
-   1
-};
+//const double z_sync_bp[SYNCBPNUMZEROES+1]=
+//{
+//   1,
+//   0,
+//   -4,
+//   0,
+//   6,
+//   0,
+//   -4,
+//   0,
+//   1
+//};
 
-// Coefficients - Poles:
-const double p_sync_bp[SYNCBPNUMPOLES]=
-{
-   -0.861024987351637,
-   5.67674544613512,
-   -17.6022837176932,
-   33.0747979391828,
-   -41.0238598189095,
-   34.3363117528713,
-   -18.970571207451,
-   6.35126296063036
-};
+//// Coefficients - Poles:
+//const double p_sync_bp[SYNCBPNUMPOLES]=
+//{
+//   -0.861024987351637,
+//   5.67674544613512,
+//   -17.6022837176932,
+//   33.0747979391828,
+//   -41.0238598189095,
+//   34.3363117528713,
+//   -18.970571207451,
+//   6.35126296063036
+//};
 
 
-//==================================================================================
+////==================================================================================
 
-// blIIR  Chebyshev , Bandpass
-// localSamplingrate = 12000.000000
-// order = 4
-// Gain = 2284.945151
-// corner 1 frequency = 1500.000000
-// corner 2 frequency = 2300.000000
-//Ripple = -1.000000
-//
-// Coefficients - Zeroes:
-#define VIDEOBPNUMZEROES 8
-#define VIDEOBPNUMPOLES 8
-#define VIDEOBPGAIN 2284.945151
-const double z_video_bp[VIDEOBPNUMZEROES+1]=
-{
-   1,
-   0,
-   -4,
-   0,
-   6,
-   0,
-   -4,
-   0,
-   1
-};
+//// blIIR  Chebyshev , Bandpass
+//// localSamplingrate = 12000.000000
+//// order = 4
+//// Gain = 2284.945151
+//// corner 1 frequency = 1500.000000
+//// corner 2 frequency = 2300.000000
+////Ripple = -1.000000
+////
+//// Coefficients - Zeroes:
+//#define VIDEOBPNUMZEROES 8
+//#define VIDEOBPNUMPOLES 8
+//#define VIDEOBPGAIN 2284.945151
+//const double z_video_bp[VIDEOBPNUMZEROES+1]=
+//{
+//   1,
+//   0,
+//   -4,
+//   0,
+//   6,
+//   0,
+//   -4,
+//   0,
+//   1
+//};
 
-// Coefficients - Poles:
-const double p_video_bp[VIDEOBPNUMPOLES]=
-{
-   -0.671359159217638,
-   3.06934557661143,
-   -8.13204301860416,
-   13.9576511061334,
-   -17.3434093144714,
-   15.4193178643578,
-   -9.92569527488599,
-   4.14238390732604
-};
+//// Coefficients - Poles:
+//const double p_video_bp[VIDEOBPNUMPOLES]=
+//{
+//   -0.671359159217638,
+//   3.06934557661143,
+//   -8.13204301860416,
+//   13.9576511061334,
+//   -17.3434093144714,
+//   15.4193178643578,
+//   -9.92569527488599,
+//   4.14238390732604
+//};
 
 //==============================================================================
 
diff --git a/qsstv/icons/mgc.raw b/qsstv/icons/mgc.raw
deleted file mode 100644
index a56a08a..0000000
Binary files a/qsstv/icons/mgc.raw and /dev/null differ
diff --git a/qsstv/icons/mgc2.raw b/qsstv/icons/mgc2.raw
deleted file mode 100644
index 751ab07..0000000
--- a/qsstv/icons/mgc2.raw
+++ /dev/null
@@ -1 +0,0 @@
-s`�dF512[8#0:E/?�r
/#0�bAFKC/?83�pVI&,
/M6�_
/?4�_12*1�_T7[8#0�e
diff --git a/qsstv/mainwidgets/rxfunctions.h b/qsstv/mainwidgets/rxfunctions.h
index 3a33510..0d10a6a 100644
--- a/qsstv/mainwidgets/rxfunctions.h
+++ b/qsstv/mainwidgets/rxfunctions.h
@@ -33,9 +33,6 @@ public:
   sstvRx  *sstvRxPtr;
   void stopThread();
 
-
-
-
 #ifndef QT_NO_DEBUG
   unsigned int setOffset(unsigned int offset,bool ask);
 #endif
diff --git a/qsstv/mainwidgets/rxwidget.cpp b/qsstv/mainwidgets/rxwidget.cpp
index abd132e..3ccb388 100644
--- a/qsstv/mainwidgets/rxwidget.cpp
+++ b/qsstv/mainwidgets/rxwidget.cpp
@@ -13,7 +13,7 @@
 #include "guiconfig.h"
 #include "mainwindow.h"
 #include "configparams.h"
-
+#include "ftp.h"
 
 
 rxWidget::rxWidget(QWidget *parent):QWidget(parent),ui(new Ui::rxWidget)
@@ -42,6 +42,9 @@ rxWidget::rxWidget(QWidget *parent):QWidget(parent),ui(new Ui::rxWidget)
   connect(&rxFunctionsPtr->sstvRxPtr->syncWideProc,SIGNAL(callReceived(QString)),SLOT(slotNewCall(QString)));
   connect(rxFunctionsPtr->sstvRxPtr,SIGNAL(resetCall()),SLOT(slotResetCall()));
   connect(ui->logPushButton,SIGNAL(clicked()),SLOT(slotLogCall()));
+  connect(ui->whoPushButton,SIGNAL(clicked()),SLOT(slotWho()));
+  notifyRXIntf = new ftpInterface("RX Notification FTP");
+
 }
 
 rxWidget::~rxWidget()
@@ -49,6 +52,7 @@ rxWidget::~rxWidget()
   writeSettings();
   rxFunctionsPtr->terminate();
   delete rxFunctionsPtr;
+  delete notifyRXIntf;
 }
 
 void rxWidget::init()
@@ -82,6 +86,12 @@ void rxWidget::init()
       ui->drmMSCWidget->hide();
       ui->drmFACWidget->hide();
     }
+  if(slowCPU || lowRes)
+    {
+      ui->rxNotificationList->hide();
+      ui->whoPushButton->hide();
+//      ui->whoSpacer->hide();
+    }
 }
 
 void rxWidget::readSettings()
@@ -219,6 +229,7 @@ void rxWidget::slotSave()
 {
   QDateTime dt(QDateTime::currentDateTime().toUTC()); //this is compatible with QT 4.6
   QString path;
+  QString info;
   dirDialog d(this);
   if(transmissionModeIndex==TRXSSTV)
   {
@@ -231,12 +242,17 @@ void rxWidget::slotSave()
     return;
   }
 
+  info="";
   QString fileName=d.saveFileName(path,"*","png");
   if (fileName==QString::null) return ;
   getImageViewerPtr()->save(fileName,defaultImageFormat,true,false);
-  dispatcherPtr->saveImage(fileName);
+  dispatcherPtr->saveImage(fileName,info);
 }
 
+void rxWidget::slotWho()
+{
+  dispatcherPtr->who();
+}
 
 void rxWidget::setSettingsTab()
 {
diff --git a/qsstv/mainwidgets/rxwidget.h b/qsstv/mainwidgets/rxwidget.h
index 932031b..bc35b03 100644
--- a/qsstv/mainwidgets/rxwidget.h
+++ b/qsstv/mainwidgets/rxwidget.h
@@ -28,12 +28,13 @@ public:
   void startRX(bool st);
   rxFunctions *functionsPtr() {return rxFunctionsPtr;}
   imageViewer *getImageViewerPtr(){ return imageViewerPtr;}
-//  spectrumWidget *fftDisplayPtr() ;
+  //  spectrumWidget *fftDisplayPtr() ;
   vuMeter *vMeterPtr();
   vuMeter *sMeterPtr();
   drmConstellationFrame *mscWdg() {return ui->drmMSCWidget;}
   drmConstellationFrame *facWdg() {return ui->drmFACWidget;}
-  void setDRMStatusText(QString txt) {
+  void setDRMStatusText(QString txt)
+  {
     ui->drmStatusLineEdit->clear();
     ui->drmStatusLineEdit->appendPlainText(txt);
   }
@@ -44,9 +45,9 @@ public:
   void appendDRMNotifyText(QString txt) {
     ui->rxNotificationList->appendPlainText(txt);
   }
-//  drmPSDFrame *psdWdg() {return ui->drmPSDWidget;}
+  //  drmPSDFrame *psdWdg() {return ui->drmPSDWidget;}
   drmStatusFrame *statusWdg() {return ui->drmStatusWidget;}
-//  int getFilterIndex();
+  //  int getFilterIndex();
   void init();
   void setSSTVStatusText(QString txt);
   void setSettingsTab();
@@ -63,6 +64,7 @@ private slots:
   void slotLogCall();
   void slotErase();
   void slotSave();
+  void slotWho();
 
 signals:
   void modeSwitch(int);
diff --git a/qsstv/mainwidgets/rxwidget.ui b/qsstv/mainwidgets/rxwidget.ui
index 39322e7..099608c 100644
--- a/qsstv/mainwidgets/rxwidget.ui
+++ b/qsstv/mainwidgets/rxwidget.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>926</width>
-    <height>862</height>
+    <width>1004</width>
+    <height>660</height>
    </rect>
   </property>
   <property name="sizePolicy">
@@ -173,7 +173,7 @@
            <height>16777215</height>
           </size>
          </property>
-        </widget>
+         </widget>
        </item>
       </layout>
      </item>
@@ -448,9 +448,9 @@
         <attribute name="title">
          <string>DRM</string>
         </attribute>
-        <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,0,0">
+        <layout class="QVBoxLayout" name="verticalLayout_6" stretch="1,0,1,0,0,0">
          <property name="spacing">
-          <number>0</number>
+          <number>1</number>
          </property>
          <property name="leftMargin">
           <number>0</number>
@@ -461,35 +461,43 @@
          <property name="rightMargin">
           <number>0</number>
          </property>
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
          <item>
-          <layout class="QVBoxLayout" name="drmLayout1" stretch="1">
-           <property name="spacing">
-            <number>1</number>
+          <widget class="drmStatusFrame" name="drmStatusWidget">
+           <property name="minimumSize">
+            <size>
+             <width>0</width>
+             <height>120</height>
+            </size>
            </property>
-           <item>
-            <widget class="drmStatusFrame" name="drmStatusWidget">
-             <property name="frameShape">
-              <enum>QFrame::StyledPanel</enum>
-             </property>
-             <property name="frameShadow">
-              <enum>QFrame::Raised</enum>
-             </property>
-            </widget>
-           </item>
-          </layout>
+           <property name="frameShape">
+            <enum>QFrame::StyledPanel</enum>
+           </property>
+           <property name="frameShadow">
+            <enum>QFrame::Raised</enum>
+           </property>
+          </widget>
          </item>
          <item>
           <widget class="QPlainTextEdit" name="drmStatusLineEdit">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
            <property name="minimumSize">
             <size>
              <width>0</width>
-             <height>55</height>
+             <height>0</height>
             </size>
            </property>
            <property name="maximumSize">
             <size>
              <width>16777215</width>
-             <height>50</height>
+             <height>40</height>
             </size>
            </property>
            <property name="readOnly">
@@ -498,393 +506,421 @@
           </widget>
          </item>
          <item>
-          <layout class="QVBoxLayout" name="drmLayout4" stretch="0,1">
-           <property name="spacing">
-            <number>1</number>
-           </property>
+          <layout class="QHBoxLayout" name="horizontalLayout_5">
            <item>
-            <widget class="QLabel" name="drmFACLabel">
-             <property name="text">
-              <string>FAC</string>
-             </property>
-             <property name="alignment">
-              <set>Qt::AlignCenter</set>
+            <layout class="QVBoxLayout" name="drmLayout4" stretch="0,1">
+             <property name="spacing">
+              <number>1</number>
              </property>
-            </widget>
+             <item>
+              <widget class="QLabel" name="drmFACLabel">
+               <property name="text">
+                <string>FAC</string>
+               </property>
+               <property name="alignment">
+                <set>Qt::AlignCenter</set>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="drmConstellationFrame" name="drmFACWidget">
+               <property name="minimumSize">
+                <size>
+                 <width>0</width>
+                 <height>55</height>
+                </size>
+               </property>
+               <property name="maximumSize">
+                <size>
+                 <width>16777215</width>
+                 <height>120</height>
+                </size>
+               </property>
+               <property name="palette">
+                <palette>
+                 <active>
+                  <colorrole role="WindowText">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>76</red>
+                     <green>76</green>
+                     <blue>76</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="Light">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>197</red>
+                     <green>197</green>
+                     <blue>197</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="Dark">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>0</red>
+                     <green>0</green>
+                     <blue>0</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="Text">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>60</red>
+                     <green>60</green>
+                     <blue>60</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="ButtonText">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>76</red>
+                     <green>76</green>
+                     <blue>76</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                 </active>
+                 <inactive>
+                  <colorrole role="WindowText">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>76</red>
+                     <green>76</green>
+                     <blue>76</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="Light">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>197</red>
+                     <green>197</green>
+                     <blue>197</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="Dark">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>0</red>
+                     <green>0</green>
+                     <blue>0</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="Text">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>60</red>
+                     <green>60</green>
+                     <blue>60</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="ButtonText">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>76</red>
+                     <green>76</green>
+                     <blue>76</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                 </inactive>
+                 <disabled>
+                  <colorrole role="WindowText">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>0</red>
+                     <green>0</green>
+                     <blue>0</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="Light">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>197</red>
+                     <green>197</green>
+                     <blue>197</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="Dark">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>0</red>
+                     <green>0</green>
+                     <blue>0</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="Text">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>0</red>
+                     <green>0</green>
+                     <blue>0</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="ButtonText">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>0</red>
+                     <green>0</green>
+                     <blue>0</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                 </disabled>
+                </palette>
+               </property>
+               <property name="frameShape">
+                <enum>QFrame::Panel</enum>
+               </property>
+               <property name="frameShadow">
+                <enum>QFrame::Sunken</enum>
+               </property>
+               <property name="lineWidth">
+                <number>3</number>
+               </property>
+              </widget>
+             </item>
+            </layout>
            </item>
            <item>
-            <widget class="drmConstellationFrame" name="drmFACWidget">
-             <property name="minimumSize">
-              <size>
-               <width>0</width>
-               <height>80</height>
-              </size>
-             </property>
-             <property name="maximumSize">
-              <size>
-               <width>16777215</width>
-               <height>120</height>
-              </size>
-             </property>
-             <property name="palette">
-              <palette>
-               <active>
-                <colorrole role="WindowText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>76</red>
-                   <green>76</green>
-                   <blue>76</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Light">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>197</red>
-                   <green>197</green>
-                   <blue>197</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Dark">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Text">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>60</red>
-                   <green>60</green>
-                   <blue>60</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="ButtonText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>76</red>
-                   <green>76</green>
-                   <blue>76</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-               </active>
-               <inactive>
-                <colorrole role="WindowText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>76</red>
-                   <green>76</green>
-                   <blue>76</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Light">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>197</red>
-                   <green>197</green>
-                   <blue>197</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Dark">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Text">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>60</red>
-                   <green>60</green>
-                   <blue>60</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="ButtonText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>76</red>
-                   <green>76</green>
-                   <blue>76</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-               </inactive>
-               <disabled>
-                <colorrole role="WindowText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Light">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>197</red>
-                   <green>197</green>
-                   <blue>197</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Dark">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Text">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="ButtonText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-               </disabled>
-              </palette>
+            <layout class="QVBoxLayout" name="verticalLayout" stretch="0,1">
+             <property name="spacing">
+              <number>1</number>
              </property>
-             <property name="frameShape">
-              <enum>QFrame::Panel</enum>
-             </property>
-             <property name="frameShadow">
-              <enum>QFrame::Sunken</enum>
-             </property>
-             <property name="lineWidth">
-              <number>3</number>
-             </property>
-            </widget>
+             <item>
+              <widget class="QLabel" name="drmMSCLabel">
+               <property name="text">
+                <string>MSC</string>
+               </property>
+               <property name="alignment">
+                <set>Qt::AlignCenter</set>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="drmConstellationFrame" name="drmMSCWidget">
+               <property name="minimumSize">
+                <size>
+                 <width>0</width>
+                 <height>55</height>
+                </size>
+               </property>
+               <property name="maximumSize">
+                <size>
+                 <width>16777215</width>
+                 <height>120</height>
+                </size>
+               </property>
+               <property name="palette">
+                <palette>
+                 <active>
+                  <colorrole role="WindowText">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>76</red>
+                     <green>76</green>
+                     <blue>76</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="Light">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>197</red>
+                     <green>197</green>
+                     <blue>197</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="Dark">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>0</red>
+                     <green>0</green>
+                     <blue>0</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="Text">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>60</red>
+                     <green>60</green>
+                     <blue>60</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="ButtonText">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>76</red>
+                     <green>76</green>
+                     <blue>76</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                 </active>
+                 <inactive>
+                  <colorrole role="WindowText">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>76</red>
+                     <green>76</green>
+                     <blue>76</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="Light">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>197</red>
+                     <green>197</green>
+                     <blue>197</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="Dark">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>0</red>
+                     <green>0</green>
+                     <blue>0</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="Text">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>60</red>
+                     <green>60</green>
+                     <blue>60</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="ButtonText">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>76</red>
+                     <green>76</green>
+                     <blue>76</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                 </inactive>
+                 <disabled>
+                  <colorrole role="WindowText">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>0</red>
+                     <green>0</green>
+                     <blue>0</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="Light">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>197</red>
+                     <green>197</green>
+                     <blue>197</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="Dark">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>0</red>
+                     <green>0</green>
+                     <blue>0</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="Text">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>0</red>
+                     <green>0</green>
+                     <blue>0</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                  <colorrole role="ButtonText">
+                   <brush brushstyle="SolidPattern">
+                    <color alpha="255">
+                     <red>0</red>
+                     <green>0</green>
+                     <blue>0</blue>
+                    </color>
+                   </brush>
+                  </colorrole>
+                 </disabled>
+                </palette>
+               </property>
+               <property name="frameShape">
+                <enum>QFrame::Panel</enum>
+               </property>
+               <property name="frameShadow">
+                <enum>QFrame::Sunken</enum>
+               </property>
+               <property name="lineWidth">
+                <number>3</number>
+               </property>
+              </widget>
+             </item>
+            </layout>
            </item>
           </layout>
          </item>
          <item>
-          <layout class="QVBoxLayout" name="drmLayout3" stretch="0,1,0">
-           <property name="spacing">
-            <number>1</number>
+          <spacer name="verticalSpacer_2">
+           <property name="orientation">
+            <enum>Qt::Vertical</enum>
            </property>
+           <property name="sizeType">
+            <enum>QSizePolicy::Expanding</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>20</width>
+             <height>95</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <layout class="QHBoxLayout" name="horizontalLayout_2">
            <item>
-            <widget class="QLabel" name="drmMSCLabel">
-             <property name="text">
-              <string>MSC</string>
-             </property>
-             <property name="alignment">
-              <set>Qt::AlignCenter</set>
-             </property>
-            </widget>
-           </item>
-           <item>
-            <widget class="drmConstellationFrame" name="drmMSCWidget">
-             <property name="minimumSize">
-              <size>
-               <width>0</width>
-               <height>80</height>
-              </size>
-             </property>
-             <property name="maximumSize">
-              <size>
-               <width>16777215</width>
-               <height>120</height>
-              </size>
-             </property>
-             <property name="palette">
-              <palette>
-               <active>
-                <colorrole role="WindowText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>76</red>
-                   <green>76</green>
-                   <blue>76</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Light">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>197</red>
-                   <green>197</green>
-                   <blue>197</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Dark">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Text">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>60</red>
-                   <green>60</green>
-                   <blue>60</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="ButtonText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>76</red>
-                   <green>76</green>
-                   <blue>76</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-               </active>
-               <inactive>
-                <colorrole role="WindowText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>76</red>
-                   <green>76</green>
-                   <blue>76</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Light">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>197</red>
-                   <green>197</green>
-                   <blue>197</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Dark">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Text">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>60</red>
-                   <green>60</green>
-                   <blue>60</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="ButtonText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>76</red>
-                   <green>76</green>
-                   <blue>76</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-               </inactive>
-               <disabled>
-                <colorrole role="WindowText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Light">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>197</red>
-                   <green>197</green>
-                   <blue>197</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Dark">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="Text">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-                <colorrole role="ButtonText">
-                 <brush brushstyle="SolidPattern">
-                  <color alpha="255">
-                   <red>0</red>
-                   <green>0</green>
-                   <blue>0</blue>
-                  </color>
-                 </brush>
-                </colorrole>
-               </disabled>
-              </palette>
-             </property>
-             <property name="frameShape">
-              <enum>QFrame::Panel</enum>
-             </property>
-             <property name="frameShadow">
-              <enum>QFrame::Sunken</enum>
-             </property>
-             <property name="lineWidth">
-              <number>3</number>
-             </property>
-            </widget>
-           </item>
-           <item>
-            <spacer name="verticalSpacer_2">
+            <spacer name="horizontalSpacer_2">
              <property name="orientation">
-              <enum>Qt::Vertical</enum>
-             </property>
-             <property name="sizeType">
-              <enum>QSizePolicy::Expanding</enum>
+              <enum>Qt::Horizontal</enum>
              </property>
              <property name="sizeHint" stdset="0">
               <size>
-               <width>20</width>
-               <height>40</height>
+               <width>40</width>
+               <height>20</height>
               </size>
              </property>
             </spacer>
            </item>
+           <item>
+            <widget class="QPushButton" name="whoPushButton">
+             <property name="text">
+              <string>Who is on?</string>
+             </property>
+            </widget>
+           </item>
           </layout>
          </item>
          <item>
diff --git a/qsstv/mainwidgets/txfunctions.cpp b/qsstv/mainwidgets/txfunctions.cpp
index abf31c5..03742a5 100644
--- a/qsstv/mainwidgets/txfunctions.cpp
+++ b/qsstv/mainwidgets/txfunctions.cpp
@@ -59,11 +59,17 @@ const QString txStateStr[txFunctions::TXTEST+1]=
   "SENDTONE",
   "SENDID",
   "SENDDRM",
+  "SENDDRMPIC",
+  "SENDDRMBINARY",
   "SENDDRMBSR",
   "SENDDRMFIX",
   "SENDDRMTXT",
   "SSTVIMAGE",
   "SSTVPOST",
+  "RESTART",
+  "PREPARESSTV",
+  "PREPAREDRM",
+  "PREPAREDRMBINARY",
   "TXTEST"
 };
 
@@ -91,12 +97,16 @@ void txFunctions::init()
   synthesPtr=new synthesizer(txClock);
   switchTxState(TXIDLE);
   addToLog("txFunc: Init",LOGTXFUNC);
+  drmTxPtr->init();
 
 }
 
 void txFunctions::run()
 {
   double waterfallTime;
+  QString startWFTxt,endWFTxt;
+
+
   abort=false;
   init();
   while(!abort)
@@ -121,89 +131,79 @@ void txFunctions::run()
           switchTxState(TXIDLE);
         break;
 
-        case TXSENDDRMBINARY:
-          waitTxOn();
-          waterfallTime=waterfallPtr->getDuration("START BIN");
-          waterfallTime+=waterfallPtr->getDuration("END BIN");
-          if(!drmTxPtr->initDRMImage(true,binaryFilename))
-            {
-              waitEnd();
-              switchTxState(TXIDLE);
-            }
-          startProgress(drmTxPtr->calcTxTime(waterfallTime));
-          addToLog("start of wf",LOGTXFUNC);
-          if(useVOX) synthesPtr->sendTone(1.,1700.,0,false);
-          waterfallPtr->setText("START BIN");
-          synthesPtr->sendWFText();
-          addToLog("start of txDrm",LOGTXFUNC);
-          drmTxPtr->start();
+        case TXPREPAREDRMBINARY:
+          {
+            bool ok=true;
+            if (useHybrid)
+              ok=drmTxPtr->ftpDRMHybrid(binaryFilename, drmTxPtr->getTxFileName(binaryFilename));
+            switchTxState(TXIDLE);
+            prepareTXComplete(ok);
+          }
+        break;
+        case TXPREPAREDRMPIC:
+          {
+            bool ok=true;
+            if (useHybrid)
+              ok=drmTxPtr->ftpDRMHybrid("", drmTxPtr->getTxFileName(""));
+            switchTxState(TXIDLE);
+            prepareTXComplete(ok);
+          }
+        break;
 
-          addToLog("end of txDrm",LOGTXFUNC);
-          if(txState==TXSENDDRM) // abort if txState is idle
+        case TXSENDDRMPIC:
+          startWFTxt = startPicWF;
+          endWFTxt   = endPicWF;
+          if (drmTxPtr->initDRMImage(false,""))
             {
-              waterfallPtr->setText("END BIN");
-              synthesPtr->sendWFText();
-              addToLog("end of wf",LOGTXFUNC);
-              addToLog("txFunc: TXSENDDRM waiting for end",LOGTXFUNC);
-              waitEnd();
+              drmTxPtr->updateTxList();
+              switchTxState(TXSENDDRM);
             }
-          switchTxState(TXIDLE);
+          else
+            switchTxState(TXIDLE);
         break;
-        case TXSENDDRM:
-          waitTxOn();
-          waterfallTime=waterfallPtr->getDuration(endPicWF);
-          waterfallTime+=waterfallPtr->getDuration(startPicWF);
-          if(!drmTxPtr->initDRMImage(false,""))
-            {
-              waitEnd();
-              switchTxState(TXIDLE);
-              break;
-            }
-          startProgress(drmTxPtr->calcTxTime(waterfallTime));
-          if(useVOX) synthesPtr->sendTone(1.,1700.,0,false);
-          addToLog("start of wf",LOGTXFUNC);
-          waterfallPtr->setText(startPicWF);
-          synthesPtr->sendWFText();
-          addToLog("start of txDrm",LOGTXFUNC);
-          drmTxPtr->start();
 
-          addToLog("end of txDrm",LOGTXFUNC);
-          if(txState==TXSENDDRM) // abort if txState is idle
+        case TXSENDDRMBINARY:
+          startWFTxt = startBinWF;
+          endWFTxt   = endBinWF;
+          if (drmTxPtr->initDRMImage(true,binaryFilename))
             {
-              waterfallPtr->setText(endPicWF);
-              synthesPtr->sendWFText();
-              addToLog("end of wf",LOGTXFUNC);
-              addToLog("txFunc: TXSENDDRM waiting for end",LOGTXFUNC);
-              waitEnd();
+              drmTxPtr->updateTxList();
+              switchTxState(TXSENDDRM);
             }
-          switchTxState(TXIDLE);
+          else
+            switchTxState(TXIDLE);
         break;
 
-
-
         case TXSENDDRMBSR:
-          waitTxOn();
-          waterfallTime=waterfallPtr->getDuration(bsrWF);
-          if(useVOX) synthesPtr->sendTone(1.,1700.,0,false);
-          startProgress(drmTxPtr->calcTxTime(waterfallTime));
-          synthesPtr->sendWFText();
-          drmTxPtr->start();
-          addToLog("txFunc: TXSENDDRMBSR waiting for end",LOGTXFUNC);
-          waitEnd();
-          switchTxState(TXIDLE);
+          startWFTxt = bsrWF;
+          endWFTxt   = "";
+          switchTxState(TXSENDDRM);
         break;
 
         case TXSENDDRMFIX:
+          startWFTxt = fixWF;
+          endWFTxt   = "";
+          switchTxState(TXSENDDRM);
+        break;
+
+        case TXSENDDRM:
           waitTxOn();
-          waterfallTime=waterfallPtr->getDuration(fixWF);
-          if(useVOX) synthesPtr->sendTone(1.,1700.,0,false);
+          waterfallTime=waterfallPtr->getDuration(endWFTxt);
+          waterfallTime+=waterfallPtr->getDuration(startWFTxt);
+
+
           startProgress(drmTxPtr->calcTxTime(waterfallTime));
+          addToLog("start of wf",LOGTXFUNC);
+          if(useVOX) synthesPtr->sendTone(1.,1700.,0,false);
+          waterfallPtr->setText(startWFTxt);
           synthesPtr->sendWFText();
+          addToLog("start of txDrm",LOGTXFUNC);
           drmTxPtr->start();
-          addToLog("txFunc: TXSENDDRMFIX waiting for end",LOGTXFUNC);
-          if(txState==TXSENDDRMFIX) // abort if txState is idle
+
+          addToLog("end of txDrm",LOGTXFUNC);
+          if(txState==TXSENDDRM) // abort if txState is idle
             {
-              waterfallPtr->setText(endPicWF);
+              waterfallPtr->setText(endWFTxt);
               synthesPtr->sendWFText();
               addToLog("end of wf",LOGTXFUNC);
               addToLog("txFunc: TXSENDDRM waiting for end",LOGTXFUNC);
@@ -211,9 +211,11 @@ void txFunctions::run()
             }
           switchTxState(TXIDLE);
         break;
+
         case TXSENDDRMTXT:
           waitTxOn();
         break;
+
         case TXSENDWFID:
           addToLog("Entered TXSENDID",LOGTXFUNC);
           waitTxOn();
@@ -228,11 +230,16 @@ void txFunctions::run()
         break;
 
         case TXSENDCWID:
-           waitTxOn();
-           if(useVOX) synthesPtr->sendTone(1.,1700.,0,false);
-           sendCW();
-           waitEnd();
-           switchTxState(TXIDLE);
+          waitTxOn();
+          if(useVOX) synthesPtr->sendTone(1.,1700.,0,false);
+          sendCW();
+          waitEnd();
+          switchTxState(TXIDLE);
+        break;
+
+        case TXPREPARESSTV:
+          switchTxState(TXIDLE);
+          prepareTXComplete(true);
         break;
 
         case TXSSTVIMAGE:
@@ -264,7 +271,7 @@ void txFunctions::run()
         break;
         case TXRESTART:
           switchTxState(TXIDLE);
-          break;
+        break;
         case TXTEST:
           sendTestPattern();
         break;
@@ -277,6 +284,31 @@ void txFunctions::run()
   txState=TXIDLE;
 }
 
+void txFunctions::setOnlineStatus(bool online, QString info)
+{
+  drmTxPtr->setOnlineStatus(online, info);
+}
+
+void txFunctions::who()
+{
+  drmTxPtr->who();
+}
+
+int txFunctions::calcTxTime(bool binary, int overhead)
+{
+  bool ok=false;
+  int txTime=0;
+  if (binary) {
+      ok=drmTxPtr->initDRMImage(true, binaryFilename);
+    }
+  else {
+      ok=drmTxPtr->initDRMImage(false, "");
+    }
+  if (ok) txTime = drmTxPtr->calcTxTime(overhead);
+  addToLog(QString("ok=%1, time=%2").arg(ok).arg(txTime), LOGTXFUNC);
+  return txTime;
+}
+
 void txFunctions::setDRMTxParams(drmTxParams params)
 {
   drmTxPtr->setTxParams(params);
@@ -293,18 +325,59 @@ void txFunctions::startProgress(double duration)
 void txFunctions::stopThread()
 {
   abort=true;
- if(!isRunning()) return;
+  if(!isRunning()) return;
   while(abort && isRunning())
-  {
+    {
       qApp->processEvents();
     }
 }
 
+bool txFunctions::txBusy()
+{
+  if(isRunning() && txState!=TXIDLE)
+    {
+      return true;
+    }
+  return false;
+}
+
 void txFunctions::startTX(etxState state)
 {
   switchTxState(state);
 }
 
+void txFunctions::prepareTXComplete(bool ok)
+{
+  txPrepareCompleteEvent *ce;
+  ce=new txPrepareCompleteEvent(ok);
+  QApplication::postEvent( dispatcherPtr, ce );  // Qt will delete it when done
+}
+
+void txFunctions::prepareTX(etxState state)
+{
+  if (txState != TXIDLE) {
+      addToLog("txState is not TXIDLE",LOGTXFUNC);
+      return;
+    }
+
+  switch (state) {
+    case TXPREPARESSTV:
+    case TXSSTVIMAGE:    switchTxState(TXPREPARESSTV);
+    break;
+
+    case TXPREPAREDRMPIC:
+    case TXSENDDRMPIC:   switchTxState(TXPREPAREDRMPIC);
+    break;
+
+    case TXPREPAREDRMBINARY:
+    case TXSENDDRMBINARY:switchTxState(TXPREPAREDRMBINARY);
+    break;
+
+    default:
+      addToLog(QString("Invalid prepareTX state:%1").arg(state),LOGTXFUNC);
+    }
+}
+
 void txFunctions::waitTxOn()
 {
   double txDelay;
@@ -416,7 +489,7 @@ void txFunctions:: sendFSKID()
 
   l=myCallsign.size();
   idx=0;
-  Checksum=0;
+
   // synthesPtr->sendTone(2.0,00,0,false);
   synthesPtr->sendTone(0.3,1500.,0,false);
   synthesPtr->sendTone(0.1,2100.,0,true);
@@ -511,6 +584,10 @@ void txFunctions::applyTemplate(imageViewer *ivPtr,QString templateFilename)
     }
 }
 
+void txFunctions::forgetTxFileName()
+{
+  drmTxPtr->forgetTxFileName();
+}
 
 void txFunctions::switchTxState(etxState newState)
 {
diff --git a/qsstv/mainwidgets/txfunctions.h b/qsstv/mainwidgets/txfunctions.h
index e8b9c17..4a96262 100644
--- a/qsstv/mainwidgets/txfunctions.h
+++ b/qsstv/mainwidgets/txfunctions.h
@@ -31,6 +31,7 @@ public:
     TXSENDWFID,
     TXSENDCWID,
     TXSENDDRM,
+    TXSENDDRMPIC,
     TXSENDDRMBINARY,
     TXSENDDRMBSR,
     TXSENDDRMFIX,
@@ -38,6 +39,9 @@ public:
     TXSSTVIMAGE,
     TXSSTVPOST,
     TXRESTART,
+    TXPREPARESSTV,
+    TXPREPAREDRMPIC,
+    TXPREPAREDRMBINARY,
     TXTEST
 
   };
@@ -47,6 +51,7 @@ public:
   void run();
   void stopThread();
   void startTX(etxState state);
+  void prepareTX(etxState state);
   void stopAndWait();
   void setToneParam(double duration,double lowerFreq,double upperFreq=0)
   {
@@ -58,10 +63,15 @@ public:
   bool prepareBinary(QString fileName);
   void sendBSR(QByteArray *p,drmTxParams dp);
   void applyTemplate(imageViewer *ivPtr,QString templateFilename);
+  void forgetTxFileName();
   etxState getTXState() { return txState;}
   void setDRMTxParams(drmTxParams params);
+  void setOnlineStatus(bool online, QString info="");
+  void who();
   //  bool initDRMFIX(txSession *sessionPtr);
+  int calcTxTime(bool binary, int overhead);
   void txTestPattern(imageViewer *ivPtr, etpSelect sel);
+  bool txBusy();
 
 
 private:
@@ -74,6 +84,7 @@ private:
   void sendFSKChar(int IDChar);
   void switchTxState(etxState newState);
   void startProgress(double duration);
+  void prepareTXComplete(bool ok);
   etxState txState;
   bool started;
   bool abort;
diff --git a/qsstv/mainwidgets/txwidget.cpp b/qsstv/mainwidgets/txwidget.cpp
index 724b541..c3d90b6 100644
--- a/qsstv/mainwidgets/txwidget.cpp
+++ b/qsstv/mainwidgets/txwidget.cpp
@@ -27,6 +27,9 @@
 
 
 
+
+
+
 txWidget::txWidget(QWidget *parent) :  QWidget(parent), ui(new Ui::txWidget)
 {
   int i;
@@ -42,15 +45,25 @@ txWidget::txWidget(QWidget *parent) :  QWidget(parent), ui(new Ui::txWidget)
       ui->sstvModeComboBox->addItem(getSSTVModeNameLong((esstvMode)i));
     }
 
+  ui->sstvResizeComboBox->addItem("Stretch");
+  ui->sstvResizeComboBox->addItem("Crop");
+  ui->sstvResizeComboBox->addItem("Fit");
 
   connect(ui->sstvModeComboBox,SIGNAL(activated(int)),SLOT(slotModeChanged(int )));
+  connect(ui->sstvResizeComboBox,SIGNAL(activated(int)),SLOT(slotResizeChanged(int)));
 
+  connect(ui->drmTxBandwidthComboBox,SIGNAL(activated(int)),SLOT(slotGetTXParams()));
+  connect(ui->drmTxInterleaveComboBox,SIGNAL(activated(int)),SLOT(slotGetTXParams()));
+  connect(ui->drmTxProtectionComboBox,SIGNAL(activated(int)),SLOT(slotGetTXParams()));
+  connect(ui->drmTxQAMComboBox,SIGNAL(activated(int)),SLOT(slotGetTXParams()));
+  connect(ui->drmTxModeComboBox,SIGNAL(activated(int)),SLOT(slotGetTXParams()));
+  connect(ui->drmTxReedSolomonComboBox,SIGNAL(activated(int)),SLOT(slotGetTXParams()));
 
   connect(ui->templatesComboBox,SIGNAL(currentIndexChanged(int)),SLOT(slotGetParams()));
   connect(ui->templateCheckBox,SIGNAL(toggled(bool)),SLOT(slotGetParams()));
   connect(ui->refreshPushButton,SIGNAL(clicked()),SLOT(slotGetParams()));
-  connect(ui->cwCheckBox,SIGNAL(toggled(bool)),SLOT(slotGetParams()));
-  connect(ui->voxCheckBox,SIGNAL(toggled(bool)),SLOT(slotGetParams()));
+  connect(ui->cwCheckBox,SIGNAL(toggled(bool)),SLOT(slotGetTXParams()));
+  connect(ui->voxCheckBox,SIGNAL(toggled(bool)),SLOT(slotGetTXParams()));
   connect(ui->toCallLineEdit,SIGNAL(editingFinished ()),SLOT(slotGetParams()));
   connect(ui->operatorLineEdit,SIGNAL(editingFinished ()),SLOT(slotGetParams()));
   connect(ui->rsvLineEdit,SIGNAL(editingFinished ()),SLOT(slotGetParams()));
@@ -63,6 +76,9 @@ txWidget::txWidget(QWidget *parent) :  QWidget(parent), ui(new Ui::txWidget)
   connect(ui->stopToolButton, SIGNAL(clicked()), this, SLOT(slotStop()));
   connect(ui->drmProfileComboBox,SIGNAL(activated(int)),SLOT(slotProfileChanged(int )));
 
+  connect(ui->hybridCheckBox,SIGNAL(toggled(bool)),SLOT(slotHybridToggled()));
+  connect(ui->uploadToolButton, SIGNAL(clicked()), this, SLOT(slotUpload()));
+
   connect(ui->generateToneToolButton, SIGNAL(clicked()), this, SLOT(slotGenerateSignal()));
   connect(ui->sweepToneToolButton, SIGNAL(clicked()), this, SLOT(slotSweepSignal()));
   connect(ui->repeaterToneToolButton, SIGNAL(clicked()), this, SLOT(slotGenerateRepeaterTone()));
@@ -77,13 +93,22 @@ txWidget::txWidget(QWidget *parent) :  QWidget(parent), ui(new Ui::txWidget)
   connect(ui->templatesComboBox,SIGNAL(currentIndexChanged(int)),SLOT(slotImageChanged()));
 
   sizeRatio=-1;
+
+  hybridTxIntf = new ftpInterface("HybridTX");
+  notifyTXIntf   = new ftpInterface("HybridTXNotify");
+  onlineStatusIntf = new ftpInterface("HybridOnlineStatus");
+
 }
 
 txWidget::~txWidget()
 {
   writeSettings();
+  delete hybridTxIntf;
+  delete notifyTXIntf;
+  delete onlineStatusIntf;
   txFunctionsPtr->terminate();
   delete txFunctionsPtr;
+
   delete ui;
 }
 
@@ -109,6 +134,12 @@ void txWidget::init()
   changeTransmissionMode(transmissionModeIndex);
   //  setSettingsTab();
   slotProfileChanged(0);
+  if(lowRes)
+    {
+      ui->txNotificationList->hide();
+      ui->refreshPushButton->hide();
+      ui->previewWidget->hide();
+    }
 }
 
 void txWidget::readSettings()
@@ -159,15 +190,31 @@ void txWidget::writeSettings()
   qSettings.endGroup();
 }
 
-void txWidget::slotGetParams()
+void txWidget::slotGetTXParams()
 {
+  // get only the params that don't require re-applying the template
+  // used by prepareTX() and slotGetParams()
   int temp=sstvModeIndexTx;
   getIndex(temp,ui->sstvModeComboBox);
   sstvModeIndexTx=esstvMode(temp);
-  getIndex(templateIndex,ui->templatesComboBox);
-  getValue(useTemplate,ui->templateCheckBox);
   getValue(useVOX,ui->voxCheckBox);
   getValue(useCW,ui->cwCheckBox);
+  getIndex(drmParams.bandwith,ui->drmTxBandwidthComboBox);
+  getIndex(drmParams.interleaver,ui->drmTxInterleaveComboBox);
+  getIndex(drmParams.protection,ui->drmTxProtectionComboBox);
+  getIndex(drmParams.qam,ui->drmTxQAMComboBox);
+  getIndex(drmParams.robMode,ui->drmTxModeComboBox);
+  getIndex(drmParams.reedSolomon,ui->drmTxReedSolomonComboBox);
+  drmParams.callsign=myCallsign;
+  updateTxTime();
+  txFunctionsPtr->forgetTxFileName();
+}
+
+
+void txWidget::slotGetParams()
+{
+  getIndex(templateIndex,ui->templatesComboBox);
+  getValue(useTemplate,ui->templateCheckBox);
   getValue(useHybrid,ui->hybridCheckBox);
   getValue(imageViewerPtr->toCall,ui->toCallLineEdit);
   getValue(imageViewerPtr->toOperator,ui->operatorLineEdit);
@@ -175,14 +222,9 @@ void txWidget::slotGetParams()
   getValue(imageViewerPtr->comment1,ui->xPlainTextEdit);
   getValue(imageViewerPtr->comment2,ui->yPlainTextEdit);
   getValue(imageViewerPtr->comment3,ui->zPlainTextEdit);
-  getIndex(drmParams.bandwith,ui->drmTxBandwidthComboBox);
-  getIndex(drmParams.interleaver,ui->drmTxInterleaveComboBox);
-  getIndex(drmParams.protection,ui->drmTxProtectionComboBox);
-  getIndex(drmParams.qam,ui->drmTxQAMComboBox);
-  getIndex(drmParams.robMode,ui->drmTxModeComboBox);
-  getIndex(drmParams.reedSolomon,ui->drmTxReedSolomonComboBox);
+  slotGetTXParams();
   getValue(sizeRatio,ui->sizeSlider);
-  drmParams.callsign=myCallsign;
+  ui->uploadToolButton->setEnabled(useHybrid && (transmissionModeIndex!=TRXSSTV));
   if(txFunctionsPtr->getTXState()==txFunctions::TXIDLE)
     {
       applyTemplate();
@@ -208,6 +250,8 @@ void txWidget::setParams()
   setIndex(drmParams.robMode,ui->drmTxModeComboBox);
   setIndex(drmParams.reedSolomon,ui->drmTxReedSolomonComboBox);
   setValue(sizeRatio,ui->sizeSlider);
+  ui->uploadToolButton->setEnabled(useHybrid && (transmissionModeIndex!=TRXSSTV));
+  updateTxTime();
 }
 
 void txWidget::copyProfile(drmTxParams d)
@@ -259,7 +303,7 @@ void txWidget::startTX(bool st,bool check)
 {
   if(st)
     {
-      slotGetParams();
+      //slotGetParams();
       if(check)
         {
           if(!imageViewerPtr->hasValidImage())
@@ -278,12 +322,82 @@ void txWidget::startTX(bool st,bool check)
 
 void txWidget::slotStart()
 {
+  if(imageViewerPtr->hasValidImage()) {
+      doTx=1;
+      prepareTx();
+    }
+}
+
+void txWidget::slotUpload()
+{
+  if(imageViewerPtr->hasValidImage()) {
+      doTx=0;
+      prepareTx();
+    }
+}
+
+void txWidget::prepareTx()
+{
+  addToLog(QString("doTx=%1").arg(doTx),LOGTXMAIN);
+  ui->uploadToolButton->setEnabled(false);
+  ui->startToolButton->setEnabled(false);
+
+  switch (transmissionModeIndex)
+    {
+    case TRXSSTV: dispatcherPtr->prepareTX(txFunctions::TXPREPARESSTV);
+    break;
+    case TRXDRM:  dispatcherPtr->prepareTX(txFunctions::TXPREPAREDRMPIC);
+    break;
+    case TRXNOMODE:
+    break;
+    }
+}
+
+void txWidget::prepareTxComplete(bool ok)
+{
+  addToLog(QString("ok=%1, doTx=%2").arg(ok).arg(doTx),LOGTXMAIN);
+  if (!ok) {
+      addToLog("Upload/prepare failed",LOGTXMAIN);
+      ui->uploadToolButton->setEnabled(useHybrid && (transmissionModeIndex!=TRXSSTV));
+    }
+  ui->startToolButton->setEnabled(true);
+  if (ok && doTx) {
+      if (doTx==2) {
+          if (useHybrid)
+            {
+              QMessageBox mbox(mainWindowPtr);
+              QPushButton *sendButton;
+              mbox.setWindowTitle("TX Binary File");
+              mbox.setText("The file has been uploaded ready for transmission");
+
+              sendButton = mbox.addButton(tr("Start Transmitting"), QMessageBox::AcceptRole);
+              mbox.setStandardButtons(QMessageBox::Cancel);
+
+              mbox.exec();
+              if (mbox.clickedButton() == sendButton) {
+                  dispatcherPtr->startTX(txFunctions::TXSENDDRMBINARY);
+                }
+            }
+          else
+            {
+              dispatcherPtr->startTX(txFunctions::TXSENDDRMBINARY);
+            }
+        }
+      else
+        {
+          startTxImage();
+        }
+    }
+}
+
+void txWidget::startTxImage()
+{
   QDateTime dt(QDateTime::currentDateTime().toUTC()); //this is compatible with QT 4.6
   dt.setTimeSpec(Qt::UTC);
   if(!imageViewerPtr->hasValidImage()) return;
   QFileInfo finf=imageViewerPtr->getFilename();
   QString fn;
-  slotGetParams();
+
   switch(transmissionModeIndex)
     {
     case TRXSSTV:
@@ -294,7 +408,7 @@ void txWidget::slotStart()
           galleryWidgetPtr->txImageChanged();
         }
       dispatcherPtr->startTX(txFunctions::TXSSTVIMAGE);
-      break;
+    break;
     case TRXDRM:
       if(saveTXimages)
         {
@@ -302,12 +416,12 @@ void txWidget::slotStart()
           imageViewerPtr->save(fn,defaultImageFormat,true,false);
           galleryWidgetPtr->txImageChanged();
         }
-      dispatcherPtr->startTX(txFunctions::TXSENDDRM);
-      break;
+      dispatcherPtr->startTX(txFunctions::TXSENDDRMPIC);
+    break;
       //    case FAX:
       //    break;
     case TRXNOMODE:
-      break;
+    break;
     }
 }
 
@@ -352,13 +466,14 @@ void txWidget::sendWfText()
 void txWidget::slotStop()
 {
   dispatcherPtr->startRX();
+  ui->startToolButton->setEnabled(true);
 }
 
 
-void txWidget::slotDisplayStatusMessage(QString s)
-{
-  statusBarPtr->showMessage(s);
-}
+//void txWidget::slotDisplayStatusMessage(QString s)
+//{
+//  statusBarPtr->showMessage(s);
+//}
 
 
 //void txWidget::slotReplay()
@@ -437,7 +552,7 @@ void txWidget::slotEdit()
 {
   if (ed!=NULL) delete ed;
   ed=new editor(this);
-  if(txFunctionsPtr->isRunning())
+  if(txFunctionsPtr->txBusy())
     {
       QMessageBox::warning(this,"Editor","Transmission busy, editor not available");
       return;
@@ -454,6 +569,14 @@ void txWidget::slotEdit()
 void txWidget::applyTemplate()
 {
   txFunctionsPtr->applyTemplate(imageViewerPtr,galleryWidgetPtr->getTemplateFileName(ui->templatesComboBox->currentIndex()));
+  ui->uploadToolButton->setEnabled(useHybrid && (transmissionModeIndex!=TRXSSTV));
+  updateTxTime();
+}
+
+void txWidget::updateTxTime()
+{
+  int s=txFunctionsPtr->calcTxTime(false,0);
+  ui->sizeDurationLabel->setText( QString::number(s)+"s");
 }
 
 
@@ -478,6 +601,21 @@ void txWidget::slotModeChanged(int m)
     }
 }
 
+void txWidget::slotResizeChanged(int i)
+{
+  switch (i) {
+    case 0: // Stretch
+      imageViewerPtr->setAspectMode(Qt::IgnoreAspectRatio);
+    break;
+    case 1: // Crop
+      imageViewerPtr->setAspectMode(Qt::KeepAspectRatioByExpanding);
+    break;
+    case 2: // Fit
+      imageViewerPtr->setAspectMode(Qt::KeepAspectRatio);
+    break;
+    }
+  applyTemplate();
+}
 
 /** \todo implement repeater */
 
@@ -510,19 +648,19 @@ void txWidget::slotRepeaterTimer()
         {
         case 0:
           fn=repeaterImage1;
-          break;
+        break;
         case 1:
           fn=repeaterImage2;
-          break;
+        break;
         case 2:
           fn=repeaterImage3;
-          break;
+        break;
         case 3:
           fn=repeaterImage4;
-          break;
+        break;
         default:
           fn=repeaterImage1;
-          break;
+        break;
         }
       fi.setFileName(fn);
       if (fi.exists())
@@ -568,19 +706,24 @@ void txWidget::setSettingsTab()
     if(transmissionModeIndex==TRXDRM)
       {
         ui->hybridCheckBox->setEnabled(true);
+        ui->uploadToolButton->setEnabled(useHybrid && (transmissionModeIndex!=TRXSSTV));
         ui->binaryPushButton->setEnabled(true);
         ui->sizeLabel->setEnabled(true);
         ui->sizeSlider->setEnabled(true);
         ui->sizeKbLabel->setEnabled(true);
+        ui->sizeDurationLabel->setEnabled(true);
         mainWindowPtr->setSSTVDRMPushButton(true);
       }
     else
       {
         ui->hybridCheckBox->setEnabled(false);
+        ui->uploadToolButton->setEnabled(false);
         ui->binaryPushButton->setEnabled(false);
         ui->sizeLabel->setEnabled(false);
         ui->sizeSlider->setEnabled(false);
         ui->sizeKbLabel->setEnabled(false);
+        ui->sizeDurationLabel->setEnabled(false);
+        ui->sizeDurationLabel->setText("-");
         mainWindowPtr->setSSTVDRMPushButton(false);
       }
   }
@@ -608,7 +751,7 @@ void txWidget::slotSizeApply()
   fileSize=imageViewerPtr->setSizeRatio(sizeRatio,transmissionModeIndex==TRXDRM);
   imageViewerPtr->displayImage();
   ui->sizeKbLabel->setText( QString::number(fileSize/1000)+ "kB");
-  applyTemplate();
+  //  applyTemplate();
   QApplication::restoreOverrideCursor();
 }
 
@@ -678,9 +821,16 @@ void txWidget::slotImageChanged()
 void txWidget::slotBinary()
 {
   slotGetParams();
+  doTx=2;
   dispatcherPtr->startDRMTxBinary();
 }
 
+void txWidget::slotHybridToggled()
+{
+  getValue(useHybrid,ui->hybridCheckBox);
+  ui->uploadToolButton->setEnabled(useHybrid && (transmissionModeIndex!=TRXSSTV));
+  updateTxTime();
+}
 
 void txWidget::txTestPattern(etpSelect sel)
 {
diff --git a/qsstv/mainwidgets/txwidget.h b/qsstv/mainwidgets/txwidget.h
index ed247bf..3996c3a 100644
--- a/qsstv/mainwidgets/txwidget.h
+++ b/qsstv/mainwidgets/txwidget.h
@@ -10,6 +10,9 @@
 
 #include <QWidget>
 
+
+
+
 class drmTransmitter;
 namespace Ui {
 class txWidget;
@@ -24,6 +27,8 @@ public:
   ~txWidget();
   void init();
   void startTX(bool st, bool check=true);
+  void prepareTx();
+  void prepareTxComplete(bool ok);
   void writeSettings();
   void readSettings();
   imageViewer *getImagePtr();
@@ -63,10 +68,12 @@ public:
   void sendCWID();
 
 public slots:
+  void slotGetTXParams();
   void slotGetParams();
   void slotStart();
+  void slotUpload();
   void slotStop();
-  void slotDisplayStatusMessage(QString);
+//  void slotDisplayStatusMessage(QString);
 
   void slotGenerateSignal();
   void slotSweepSignal();
@@ -83,7 +90,9 @@ public slots:
   void slotProfileChanged(int );
   void slotImageChanged();
   void slotModeChanged(int);
+  void slotResizeChanged(int);
   void slotBinary();
+  void slotHybridToggled();
 
 signals:
   void modeSwitch(int);
@@ -100,12 +109,16 @@ private:
   QImage origImage;
   QImage resultImage;
   void applyTemplate();
+  void updateTxTime();
   imageViewer *imageViewerPtr;
   etransmissionMode currentTXMode;
   int sizeRatio;
   bool sizeRatioChanged;
   int drmProfileIdx;
   QString previewFilename;
+  int doTx;
+
+  void startTxImage();
 };
 
 #endif // TXWIDGET_H
diff --git a/qsstv/mainwidgets/txwidget.ui b/qsstv/mainwidgets/txwidget.ui
index 98569e8..c0779a3 100644
--- a/qsstv/mainwidgets/txwidget.ui
+++ b/qsstv/mainwidgets/txwidget.ui
@@ -19,13 +19,28 @@
    <string>Form</string>
   </property>
   <layout class="QHBoxLayout" name="horizontalLayout_9" stretch="1,0">
+   <property name="spacing">
+    <number>1</number>
+   </property>
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
    <item>
     <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1,0">
      <property name="spacing">
-      <number>2</number>
+      <number>1</number>
      </property>
      <item>
-      <layout class="QHBoxLayout" name="horizontalLayout_5" stretch="0,0,0,0,0,0,0,1,0,3,0,0">
+      <layout class="QHBoxLayout" name="horizontalLayout_5" stretch="0,0,0,0,0,0,0,1,0,0,3,0,0">
        <property name="spacing">
         <number>2</number>
        </property>
@@ -160,6 +175,23 @@
         </widget>
        </item>
        <item>
+        <widget class="QToolButton" name="uploadToolButton">
+         <property name="toolTip">
+          <string>Upload Now</string>
+         </property>
+         <property name="statusTip">
+          <string>Upload Now</string>
+         </property>
+         <property name="text">
+          <string>Upload</string>
+         </property>
+         <property name="icon">
+          <iconset resource="../qsstv.qrc">
+           <normaloff>:/icons/up.png</normaloff>:/icons/up.png</iconset>
+         </property>
+        </widget>
+       </item>
+       <item>
         <spacer name="horizontalSpacer">
          <property name="orientation">
           <enum>Qt::Horizontal</enum>
@@ -239,7 +271,7 @@
           <number>1</number>
          </property>
          <property name="maximum">
-          <number>200</number>
+          <number>1000</number>
          </property>
          <property name="pageStep">
           <number>10</number>
@@ -254,10 +286,10 @@
           <enum>Qt::Horizontal</enum>
          </property>
          <property name="invertedAppearance">
-          <bool>false</bool>
+          <bool>true</bool>
          </property>
          <property name="invertedControls">
-          <bool>false</bool>
+          <bool>true</bool>
          </property>
          <property name="tickPosition">
           <enum>QSlider::TicksBelow</enum>
@@ -298,6 +330,19 @@
          </property>
         </widget>
        </item>
+       <item>
+        <widget class="QLabel" name="sizeDurationLabel">
+         <property name="minimumSize">
+          <size>
+           <width>50</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="text">
+          <string>TextLabel</string>
+         </property>
+        </widget>
+       </item>
       </layout>
      </item>
     </layout>
@@ -305,7 +350,7 @@
    <item>
     <layout class="QVBoxLayout" name="verticalLayout">
      <property name="spacing">
-      <number>2</number>
+      <number>1</number>
      </property>
      <item>
       <widget class="QTabWidget" name="settingsTableWidget">
@@ -770,81 +815,24 @@
         <attribute name="title">
          <string>SSTV</string>
         </attribute>
-        <layout class="QVBoxLayout" name="verticalLayout_6">
+        <layout class="QVBoxLayout" name="verticalLayout_3">
          <item>
-          <layout class="QVBoxLayout" name="verticalLayout_5">
-           <item>
-            <layout class="QHBoxLayout" name="horizontalLayout_4">
-             <item>
-              <spacer name="horizontalSpacer_6">
-               <property name="orientation">
-                <enum>Qt::Horizontal</enum>
-               </property>
-               <property name="sizeHint" stdset="0">
-                <size>
-                 <width>40</width>
-                 <height>20</height>
-                </size>
-               </property>
-              </spacer>
-             </item>
-             <item>
-              <widget class="QLabel" name="modeLabel">
-               <property name="text">
-                <string>Mode</string>
-               </property>
-               <property name="alignment">
-                <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-               </property>
-               <property name="wordWrap">
-                <bool>false</bool>
-               </property>
-              </widget>
-             </item>
-             <item>
-              <widget class="QComboBox" name="sstvModeComboBox">
-               <property name="toolTip">
-                <string>Transmit mode</string>
-               </property>
-               <property name="statusTip">
-                <string>Transmit mode</string>
-               </property>
-              </widget>
-             </item>
-            </layout>
-           </item>
+          <layout class="QHBoxLayout" name="horizontalLayout_4">
            <item>
-            <spacer name="verticalSpacer_2">
+            <spacer name="horizontalSpacer_6">
              <property name="orientation">
-              <enum>Qt::Vertical</enum>
+              <enum>Qt::Horizontal</enum>
              </property>
              <property name="sizeHint" stdset="0">
               <size>
-               <width>20</width>
-               <height>40</height>
+               <width>40</width>
+               <height>20</height>
               </size>
              </property>
             </spacer>
            </item>
-          </layout>
-         </item>
-        </layout>
-       </widget>
-       <widget class="QWidget" name="drmTXTab">
-        <attribute name="title">
-         <string>DRM</string>
-        </attribute>
-        <layout class="QVBoxLayout" name="verticalLayout_3">
-         <item>
-          <layout class="QGridLayout" name="gridLayout_2">
-           <item row="0" column="0">
-            <widget class="QLabel" name="drmModeLabel">
-             <property name="minimumSize">
-              <size>
-               <width>30</width>
-               <height>0</height>
-              </size>
-             </property>
+           <item>
+            <widget class="QLabel" name="modeLabel">
              <property name="text">
               <string>Mode</string>
              </property>
@@ -856,224 +844,378 @@
              </property>
             </widget>
            </item>
-           <item row="0" column="1">
-            <widget class="QComboBox" name="drmTxModeComboBox">
-             <item>
-              <property name="text">
-               <string>A</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>B</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>E</string>
-              </property>
-             </item>
-            </widget>
-           </item>
-           <item row="0" column="2">
-            <widget class="QLabel" name="drmQAMLabel">
-             <property name="minimumSize">
-              <size>
-               <width>30</width>
-               <height>0</height>
-              </size>
-             </property>
-             <property name="text">
-              <string>QAM</string>
-             </property>
-             <property name="alignment">
-              <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+           <item>
+            <widget class="QComboBox" name="sstvModeComboBox">
+             <property name="toolTip">
+              <string>Transmit mode</string>
              </property>
-             <property name="wordWrap">
-              <bool>false</bool>
+             <property name="statusTip">
+              <string>Transmit mode</string>
              </property>
             </widget>
            </item>
-           <item row="0" column="3">
-            <widget class="QComboBox" name="drmTxQAMComboBox">
-             <item>
-              <property name="text">
-               <string>4</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>16</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>64</string>
-              </property>
-             </item>
-            </widget>
-           </item>
-           <item row="1" column="0">
-            <widget class="QLabel" name="drmProtectionLabel">
-             <property name="minimumSize">
+          </layout>
+         </item>
+         <item>
+          <spacer name="verticalSpacer_2">
+           <property name="orientation">
+            <enum>Qt::Vertical</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>20</width>
+             <height>19</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <layout class="QHBoxLayout" name="horizontalLayout_10">
+           <item>
+            <spacer name="horizontalSpacer_2">
+             <property name="orientation">
+              <enum>Qt::Horizontal</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
               <size>
-               <width>30</width>
-               <height>0</height>
+               <width>40</width>
+               <height>20</height>
               </size>
              </property>
-             <property name="text">
-              <string>Prot.</string>
-             </property>
-             <property name="alignment">
-              <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-             </property>
-             <property name="wordWrap">
-              <bool>false</bool>
-             </property>
-            </widget>
+            </spacer>
            </item>
-           <item row="1" column="1">
-            <widget class="QComboBox" name="drmTxProtectionComboBox">
-             <item>
-              <property name="text">
-               <string>High</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>Low</string>
-              </property>
-             </item>
-            </widget>
+           <item>
+            <widget class="QComboBox" name="sstvResizeComboBox"/>
            </item>
-           <item row="1" column="2">
-            <widget class="QLabel" name="drmBandwidthLabel">
-             <property name="minimumSize">
-              <size>
-               <width>30</width>
-               <height>0</height>
-              </size>
-             </property>
-             <property name="text">
-              <string>BW</string>
-             </property>
-             <property name="alignment">
-              <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-             </property>
-             <property name="wordWrap">
-              <bool>false</bool>
-             </property>
-            </widget>
+          </layout>
+         </item>
+        </layout>
+       </widget>
+       <widget class="QWidget" name="drmTXTab">
+        <attribute name="title">
+         <string>DRM</string>
+        </attribute>
+        <layout class="QGridLayout" name="gridLayout_2">
+         <property name="leftMargin">
+          <number>0</number>
+         </property>
+         <property name="topMargin">
+          <number>0</number>
+         </property>
+         <property name="rightMargin">
+          <number>0</number>
+         </property>
+         <property name="bottomMargin">
+          <number>0</number>
+         </property>
+         <property name="horizontalSpacing">
+          <number>1</number>
+         </property>
+         <property name="verticalSpacing">
+          <number>0</number>
+         </property>
+         <item row="0" column="0">
+          <widget class="QLabel" name="drmModeLabel">
+           <property name="minimumSize">
+            <size>
+             <width>30</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Mode</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+           </property>
+           <property name="wordWrap">
+            <bool>false</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1">
+          <widget class="QComboBox" name="drmTxModeComboBox">
+           <property name="minimumSize">
+            <size>
+             <width>40</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>40</width>
+             <height>25</height>
+            </size>
+           </property>
+           <item>
+            <property name="text">
+             <string>A</string>
+            </property>
            </item>
-           <item row="1" column="3">
-            <widget class="QComboBox" name="drmTxBandwidthComboBox">
-             <item>
-              <property name="text">
-               <string>2.2 KHz</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>2.5 KHz</string>
-              </property>
-             </item>
-            </widget>
+           <item>
+            <property name="text">
+             <string>B</string>
+            </property>
            </item>
-           <item row="2" column="0">
-            <widget class="QLabel" name="drmInterleavelabel">
-             <property name="minimumSize">
-              <size>
-               <width>30</width>
-               <height>0</height>
-              </size>
-             </property>
-             <property name="text">
-              <string>Interleave</string>
-             </property>
-             <property name="alignment">
-              <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-             </property>
-             <property name="wordWrap">
-              <bool>false</bool>
-             </property>
-            </widget>
+           <item>
+            <property name="text">
+             <string>E</string>
+            </property>
            </item>
-           <item row="2" column="1">
-            <widget class="QComboBox" name="drmTxInterleaveComboBox">
-             <item>
-              <property name="text">
-               <string>Short</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>Long</string>
-              </property>
-             </item>
-            </widget>
+          </widget>
+         </item>
+         <item row="0" column="2">
+          <widget class="QLabel" name="drmQAMLabel">
+           <property name="minimumSize">
+            <size>
+             <width>30</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>QAM</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+           </property>
+           <property name="wordWrap">
+            <bool>false</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="3">
+          <widget class="QComboBox" name="drmTxQAMComboBox">
+           <property name="minimumSize">
+            <size>
+             <width>45</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>45</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <item>
+            <property name="text">
+             <string>4</string>
+            </property>
            </item>
-           <item row="2" column="2">
-            <widget class="QLabel" name="drmReadSolomonLabel">
-             <property name="minimumSize">
-              <size>
-               <width>30</width>
-               <height>0</height>
-              </size>
-             </property>
-             <property name="text">
-              <string>Rs</string>
-             </property>
-             <property name="alignment">
-              <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-             </property>
-             <property name="wordWrap">
-              <bool>false</bool>
-             </property>
-            </widget>
+           <item>
+            <property name="text">
+             <string>16</string>
+            </property>
            </item>
-           <item row="2" column="3">
-            <widget class="QComboBox" name="drmTxReedSolomonComboBox">
-             <item>
-              <property name="text">
-               <string>None</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>RS1</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>RS2</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>RS3</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>RS4</string>
-              </property>
-             </item>
-            </widget>
+           <item>
+            <property name="text">
+             <string>64</string>
+            </property>
            </item>
-           <item row="3" column="0">
-            <widget class="QLabel" name="drmProfileLabel">
-             <property name="text">
-              <string>Profile</string>
-             </property>
-             <property name="alignment">
-              <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-             </property>
-            </widget>
+          </widget>
+         </item>
+         <item row="0" column="4">
+          <widget class="QLabel" name="drmBandwidthLabel">
+           <property name="minimumSize">
+            <size>
+             <width>30</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>BW</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+           </property>
+           <property name="wordWrap">
+            <bool>false</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="5">
+          <widget class="QComboBox" name="drmTxBandwidthComboBox">
+           <property name="minimumSize">
+            <size>
+             <width>70</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>70</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <item>
+            <property name="text">
+             <string>2.2 KHz</string>
+            </property>
            </item>
-           <item row="3" column="1" colspan="3">
-            <widget class="QComboBox" name="drmProfileComboBox"/>
+           <item>
+            <property name="text">
+             <string>2.5 KHz</string>
+            </property>
            </item>
-          </layout>
+          </widget>
+         </item>
+         <item row="1" column="0">
+          <widget class="QLabel" name="drmInterleavelabel">
+           <property name="minimumSize">
+            <size>
+             <width>30</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Interl.</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+           </property>
+           <property name="wordWrap">
+            <bool>false</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1" colspan="2">
+          <widget class="QComboBox" name="drmTxInterleaveComboBox">
+           <item>
+            <property name="text">
+             <string>Short</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>Long</string>
+            </property>
+           </item>
+          </widget>
+         </item>
+         <item row="1" column="4">
+          <widget class="QLabel" name="drmProtectionLabel">
+           <property name="minimumSize">
+            <size>
+             <width>30</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Prot.</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+           </property>
+           <property name="wordWrap">
+            <bool>false</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="5">
+          <widget class="QComboBox" name="drmTxProtectionComboBox">
+           <property name="minimumSize">
+            <size>
+             <width>65</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>65</width>
+             <height>25</height>
+            </size>
+           </property>
+           <item>
+            <property name="text">
+             <string>High</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>Low</string>
+            </property>
+           </item>
+          </widget>
+         </item>
+         <item row="2" column="0">
+          <widget class="QLabel" name="drmProfileLabel">
+           <property name="text">
+            <string>Profile</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="1" colspan="3">
+          <widget class="QComboBox" name="drmProfileComboBox">
+           <property name="maximumSize">
+            <size>
+             <width>16777215</width>
+             <height>25</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="4">
+          <widget class="QLabel" name="drmReadSolomonLabel">
+           <property name="minimumSize">
+            <size>
+             <width>30</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Rs</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+           </property>
+           <property name="wordWrap">
+            <bool>false</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="5">
+          <widget class="QComboBox" name="drmTxReedSolomonComboBox">
+           <property name="minimumSize">
+            <size>
+             <width>65</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>65</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <item>
+            <property name="text">
+             <string>None</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>RS1</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>RS2</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>RS3</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>RS4</string>
+            </property>
+           </item>
+          </widget>
          </item>
         </layout>
        </widget>
@@ -1081,9 +1223,6 @@
      </item>
      <item>
       <layout class="QHBoxLayout" name="horizontalLayout">
-       <property name="spacing">
-        <number>2</number>
-       </property>
        <item>
         <widget class="QLabel" name="progressLabel">
          <property name="text">
@@ -1114,16 +1253,13 @@
        <property name="verticalSpacing">
         <number>0</number>
        </property>
-       <item row="0" column="0">
-        <widget class="QCheckBox" name="voxCheckBox">
+       <item row="1" column="1">
+        <widget class="QComboBox" name="templatesComboBox">
          <property name="toolTip">
-          <string>Send leading tone</string>
+          <string>Select template</string>
          </property>
          <property name="statusTip">
-          <string>Send leading tone</string>
-         </property>
-         <property name="text">
-          <string>VOX</string>
+          <string>Select template</string>
          </property>
         </widget>
        </item>
@@ -1147,13 +1283,16 @@
          </property>
         </widget>
        </item>
-       <item row="1" column="1">
-        <widget class="QComboBox" name="templatesComboBox">
+       <item row="0" column="0">
+        <widget class="QCheckBox" name="voxCheckBox">
          <property name="toolTip">
-          <string>Select template</string>
+          <string>Send leading tone</string>
          </property>
          <property name="statusTip">
-          <string>Select template</string>
+          <string>Send leading tone</string>
+         </property>
+         <property name="text">
+          <string>VOX</string>
          </property>
         </widget>
        </item>
@@ -1161,8 +1300,11 @@
      </item>
      <item>
       <layout class="QGridLayout" name="gridLayout">
-       <property name="spacing">
-        <number>2</number>
+       <property name="horizontalSpacing">
+        <number>1</number>
+       </property>
+       <property name="verticalSpacing">
+        <number>0</number>
        </property>
        <item row="0" column="0">
         <widget class="QLabel" name="toCallLabel">
@@ -1282,6 +1424,9 @@
      </item>
      <item>
       <layout class="QHBoxLayout" name="horizontalLayout_8">
+       <property name="spacing">
+        <number>1</number>
+       </property>
        <item>
         <widget class="QLabel" name="rstLabel_4">
          <property name="minimumSize">
@@ -1300,6 +1445,18 @@
        </item>
        <item>
         <widget class="xyzPlainTextEdit" name="xPlainTextEdit">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Expanding" vsizetype="Ignored">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>0</width>
+           <height>32</height>
+          </size>
+         </property>
          <property name="maximumSize">
           <size>
            <width>16777215</width>
@@ -1312,6 +1469,9 @@
      </item>
      <item>
       <layout class="QHBoxLayout" name="horizontalLayout_3">
+       <property name="spacing">
+        <number>1</number>
+       </property>
        <item>
         <widget class="QLabel" name="rstLabel_5">
          <property name="minimumSize">
@@ -1330,6 +1490,18 @@
        </item>
        <item>
         <widget class="xyzPlainTextEdit" name="yPlainTextEdit">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Expanding" vsizetype="Ignored">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>0</width>
+           <height>32</height>
+          </size>
+         </property>
          <property name="maximumSize">
           <size>
            <width>16777215</width>
@@ -1342,6 +1514,9 @@
      </item>
      <item>
       <layout class="QHBoxLayout" name="horizontalLayout_7">
+       <property name="spacing">
+        <number>1</number>
+       </property>
        <item>
         <widget class="QLabel" name="rstLabel_6">
          <property name="minimumSize">
@@ -1360,10 +1535,22 @@
        </item>
        <item>
         <widget class="xyzPlainTextEdit" name="zPlainTextEdit">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Expanding" vsizetype="Ignored">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>0</width>
+           <height>32</height>
+          </size>
+         </property>
          <property name="maximumSize">
           <size>
            <width>16777215</width>
-           <height>50</height>
+           <height>16777215</height>
           </size>
          </property>
         </widget>
@@ -1409,6 +1596,12 @@
      </item>
      <item>
       <widget class="QPlainTextEdit" name="txNotificationList">
+       <property name="minimumSize">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
        <property name="acceptDrops">
         <bool>false</bool>
        </property>
diff --git a/qsstv/mainwindow.cpp b/qsstv/mainwindow.cpp
index 9441e75..5c6280d 100644
--- a/qsstv/mainwindow.cpp
+++ b/qsstv/mainwindow.cpp
@@ -120,6 +120,7 @@ mainWindow::mainWindow(QWidget *parent) : QMainWindow(parent),  ui(new Ui::MainW
 
   // setup connections
 
+  connect(ui->actionSaveWaterfallImage,SIGNAL(triggered()),this, SLOT(slotSaveWaterfallImage()));
   connect(ui->actionExit,SIGNAL(triggered()),this, SLOT(slotExit()));
   connect(ui->actionConfigure,SIGNAL(triggered()),this, SLOT(slotConfigure()));
   connect(ui->actionCalibrate,SIGNAL(triggered()),this, SLOT(slotCalibrate()));
@@ -134,6 +135,11 @@ mainWindow::mainWindow(QWidget *parent) : QMainWindow(parent),  ui(new Ui::MainW
   connect(rxWidgetPtr,SIGNAL(modeSwitch(int)),this, SLOT(slotModeChange(int)));
   connect(txWidgetPtr,SIGNAL(modeSwitch(int)),this, SLOT(slotModeChange(int)));
 
+  QAction *fs = new QAction(this);
+  fs->setShortcut(Qt::Key_F | Qt::CTRL);
+  connect(fs, SIGNAL(triggered()), this, SLOT(slotFullScreen()));
+  this->addAction(fs);
+
 #ifdef ENABLELOGGING
   connect(ui->actionLogSettings, SIGNAL(triggered()),SLOT(slotLogSettings()));
   connect(ui->actionResetLog, SIGNAL(triggered()),SLOT(slotResetLog()));
@@ -151,8 +157,6 @@ mainWindow::mainWindow(QWidget *parent) : QMainWindow(parent),  ui(new Ui::MainW
   connect(ui->actionDumpSamplesPerLine,SIGNAL(triggered()),this, SLOT(slotDumpSamplesPerLine()));
   connect(ui->actionTxTestPattern,SIGNAL(triggered()),this, SLOT(slotTxTestPattern()));
 
-
-
 #else
   ui->menuOptions->removeAction(ui->actionDumpSamplesPerLine);
   ui->menuScope->removeAction(ui->actionShowDataScope);
@@ -295,13 +299,49 @@ void mainWindow::setNewFont()
   //  txMW->setFont(fnt);
 }
 
+void mainWindow::slotSaveWaterfallImage()
+{
+  QImage *wf = ui->spectrumFrame->getImage();
+  if (wf) {
+     double freq=0;
+     QDateTime now=QDateTime::currentDateTime();
+     QString fn="waterfall-"+now.toString("yyyyMMddhhmmss")+".jpg";
+
+     QImage im(wf->width()+2, wf->height()+22, QImage::Format_RGB32);
+     QPainter p(&im);
+
+     im.fill(Qt::black);
+     p.setPen(Qt::lightGray);
+     p.drawImage(2,20,*wf);
+     p.drawRect(0,0,wf->width()+1,wf->height()+21);
+
+     //TODO: rig frequency etc
+     rigControllerPtr->getFrequency(freq);
+     if (freq>0)
+        p.drawText(1,15, QString("%1 MHz").arg(freq/1000000.0,1,'f',6));
+     else
+        p.drawText(1,15, "no freq");
+
+     if (im.save(fn, "jpg"))
+       {
+        statusBarPtr->showMessage("Saved "+fn);
+        }
+     else {
+        statusBarPtr->showMessage("Error saving image");
+        }
+     delete wf;
+     }
+}
+
 void mainWindow::slotExit()
 {
   int exit;
   exit=QMessageBox::information(this, tr("Quit..."),tr("Do you really want to quit QSSTV?"), QMessageBox::Ok, QMessageBox::Cancel);
   if(exit==QMessageBox::Ok)
     {
+      statusBarPtr->showMessage("Cleaning up...");
       dispatcherPtr->idleAll();
+      dispatcherPtr->setOnlineStatus(false);
       rxWidgetPtr->functionsPtr()->stopThread();
       txWidgetPtr->functionsPtr()->stopThread();
       if(soundIOPtr) soundIOPtr->stopSoundThread();
@@ -501,6 +541,19 @@ void mainWindow::cleanUpCache(QString dirPath)
     }
 }
 
+void mainWindow::slotFullScreen()
+{
+  if(isFullScreen())
+    {
+      this->setWindowState(Qt::WindowMaximized);
+    }
+  else
+    {
+      this->setWindowState(Qt::WindowFullScreen);
+    }
+}
+
+
 
 #ifndef QT_NO_DEBUG
 void mainWindow::slotShowDataScope()
@@ -546,5 +599,4 @@ void mainWindow::slotTxTestPattern()
       txWidgetPtr->txTestPattern(sel);
     }
 }
-
 #endif
diff --git a/qsstv/mainwindow.h b/qsstv/mainwindow.h
index 75c2405..2c3a07e 100644
--- a/qsstv/mainwindow.h
+++ b/qsstv/mainwindow.h
@@ -29,11 +29,13 @@ public:
 
 private slots:
   void slotConfigure();
+  void slotSaveWaterfallImage();
   void slotExit();
   void slotResetLog();
   void slotLogSettings();
   void slotAboutQt();
   void slotAboutQSSTV();
+  void slotFullScreen();
   void slotDocumentation();
   void slotCalibrate();
   void slotModeChange(int);
diff --git a/qsstv/mainwindow.ui b/qsstv/mainwindow.ui
index 2153cc4..597d0b5 100644
--- a/qsstv/mainwindow.ui
+++ b/qsstv/mainwindow.ui
@@ -27,19 +27,19 @@
   <widget class="QWidget" name="centralwidget">
    <layout class="QHBoxLayout" name="horizontalLayout">
     <property name="spacing">
-     <number>1</number>
+     <number>0</number>
     </property>
     <property name="leftMargin">
-     <number>1</number>
+     <number>0</number>
     </property>
     <property name="topMargin">
-     <number>1</number>
+     <number>0</number>
     </property>
     <property name="rightMargin">
-     <number>1</number>
+     <number>0</number>
     </property>
     <property name="bottomMargin">
-     <number>1</number>
+     <number>0</number>
     </property>
     <item>
      <widget class="QTabWidget" name="maintabWidget">
@@ -175,7 +175,7 @@
      <x>0</x>
      <y>0</y>
      <width>831</width>
-     <height>19</height>
+     <height>20</height>
     </rect>
    </property>
    <property name="font">
@@ -188,6 +188,8 @@
     <property name="title">
      <string>File</string>
     </property>
+    <addaction name="actionSaveWaterfallImage"/>
+    <addaction name="separator"/>
     <addaction name="actionExit"/>
     <addaction name="actionTxTestPattern"/>
    </widget>
@@ -314,6 +316,25 @@
     <string>Clear</string>
    </property>
   </action>
+  <action name="actionFullScreen">
+   <property name="enabled">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>&Full Screen</string>
+   </property>
+   <property name="shortcutContext">
+    <enum>Qt::WidgetShortcut</enum>
+   </property>
+   <property name="autoRepeat">
+    <bool>false</bool>
+   </property>
+  </action>
+  <action name="actionSaveWaterfallImage">
+   <property name="text">
+    <string>Save Waterfall Image</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>
diff --git a/qsstv/qsstv.pro b/qsstv/qsstv.pro
index fb7ddf9..870d89d 100644
--- a/qsstv/qsstv.pro
+++ b/qsstv/qsstv.pro
@@ -496,7 +496,9 @@ OTHER_FILES += \
     documentation/manual/images/entertext.png \
     ../COPYING \
     ../README.txt \
-    documentation/manual/images/editor_image_size.png
+    documentation/manual/images/editor_image_size.png \
+    documentation/manual/images/Gallery_templates.png \
+    documentation/manual/images/Gallery_txdrm.png
 
 CONFIG(debug ,debug|release){
         message(added debugging)
diff --git a/qsstv/qsstv.qrc b/qsstv/qsstv.qrc
index 18443d6..d88d4f3 100644
--- a/qsstv/qsstv.qrc
+++ b/qsstv/qsstv.qrc
@@ -24,8 +24,6 @@
         <file>icons/eraser.png</file>
         <file>icons/filenew.png</file>
         <file>icons/gradient.png</file>
-        <file>icons/mgc.raw</file>
-        <file>icons/mgc2.raw</file>
         <file>icons/colorline.png</file>
         <file>icons/left.png</file>
         <file>icons/doubleleft.png</file>
diff --git a/qsstv/rig/rigcontrol.cpp b/qsstv/rig/rigcontrol.cpp
index 13f19c9..c6b1991 100644
--- a/qsstv/rig/rigcontrol.cpp
+++ b/qsstv/rig/rigcontrol.cpp
@@ -68,7 +68,6 @@ bool rigControl::init()
     int retcode;
     if(!catParams.enableCAT) return false;
 
-    addToLog(QString("rigcontrol:init myport pathname: %1").arg(myport.pathname),LOGRIGCTRL);
     catParams.radioModelNumber=getModelNumber(getRadioModelIndex());
     my_rig = rig_init(catParams.radioModelNumber);
     if(!my_rig)
diff --git a/qsstv/rig/rigcontrol.h b/qsstv/rig/rigcontrol.h
index 3ae16b8..0aa3661 100644
--- a/qsstv/rig/rigcontrol.h
+++ b/qsstv/rig/rigcontrol.h
@@ -62,7 +62,7 @@ public:
   QString initError;
 
 private:
-  hamlib_port_t myport;
+
   RIG *my_rig;            // handle to rig (nstance)
   freq_t freq;            // frequency
   rmode_t rmode;          // radio mode of operation
diff --git a/qsstv/scope/scopeplot.cpp b/qsstv/scope/scopeplot.cpp
index 7bdb6f7..73edb3c 100644
--- a/qsstv/scope/scopeplot.cpp
+++ b/qsstv/scope/scopeplot.cpp
@@ -18,6 +18,7 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 #include "scopeplot.h"
+#include "appglobal.h"
 #include "qwt_plot.h"
 #include "qwt_plot_curve.h"
 #include "qwt_plot_grid.h"
@@ -57,6 +58,7 @@ scopePlot::scopePlot(QString title, QWidget *parent) : QMainWindow(parent)
   showCrv2=true;
   showCrv3=true;
   showCrv4=true;
+  setWindowTitle("Scope " +qsstvVersion);
   init(title);
 }
 
diff --git a/qsstv/sound/soundalsa.cpp b/qsstv/sound/soundalsa.cpp
index f78bf35..5f40a76 100644
--- a/qsstv/sound/soundalsa.cpp
+++ b/qsstv/sound/soundalsa.cpp
@@ -207,7 +207,7 @@ void soundAlsa::flushPlayback()
 
 bool soundAlsa::setupSoundParams(bool isCapture)
 {
-  int err;
+  int err=0;
   int dir=0;
   snd_pcm_t *handle;
   isStereo=false;
@@ -239,16 +239,16 @@ bool soundAlsa::setupSoundParams(bool isCapture)
   /* Set the count of channels */
   if(isCapture)
   {
-    err=snd_pcm_hw_params_get_channels_min(hwparams,&minChannelsCapture);
-    err=snd_pcm_hw_params_get_channels_max(hwparams,&maxChannelsCapture);
+    snd_pcm_hw_params_get_channels_min(hwparams,&minChannelsCapture);
+    snd_pcm_hw_params_get_channels_max(hwparams,&maxChannelsCapture);
     err = snd_pcm_hw_params_set_channels ( handle, hwparams, minChannelsCapture);
     if(!alsaErrorHandler(err,"Channels count not correct; " )) return false;
   }
   else
   {
 
-    err=snd_pcm_hw_params_get_channels_min(hwparams,&minChannelsPlayback);
-    err=snd_pcm_hw_params_get_channels_max(hwparams,&maxChannelsPlayback);
+    snd_pcm_hw_params_get_channels_min(hwparams,&minChannelsPlayback);
+    snd_pcm_hw_params_get_channels_max(hwparams,&maxChannelsPlayback);
     err = snd_pcm_hw_params_set_channels ( handle, hwparams, 2); //allways stereo output
     if(!alsaErrorHandler(err,"Channels count not correct; " ))
     {
diff --git a/qsstv/sound/wavio.cpp b/qsstv/sound/wavio.cpp
index ab34701..aa2aa4c 100644
--- a/qsstv/sound/wavio.cpp
+++ b/qsstv/sound/wavio.cpp
@@ -248,12 +248,12 @@ bool  wavIO::write(quint16 *dPtr, uint numSamples, bool isStereo)
   {
     addToLog("wavio write error",LOGALL);
     closeFile();
-    if(tempBufPtr) delete tempBufPtr;
+    if(tempBufPtr) delete []tempBufPtr;
     return false;
   }
   numberOfSamples+=numSamples;
   addToLog(QString("wavio write:%1 total samples=%2").arg(numSamples).arg(numberOfSamples),LOGWAVIO);
-  if(tempBufPtr) delete tempBufPtr;
+  if(tempBufPtr) delete []tempBufPtr;
   return true;
 }
 
diff --git a/qsstv/sstv/sstvrx.cpp b/qsstv/sstv/sstvrx.cpp
index 283a897..a050913 100644
--- a/qsstv/sstv/sstvrx.cpp
+++ b/qsstv/sstv/sstvrx.cpp
@@ -16,6 +16,8 @@
 QString defaultImageFormat;
 int minCompletion;
 
+#define DECAY 0.9956
+
 const QString stateStr[sstvRx::END+1]=
 {
   "Hunting",
@@ -62,6 +64,7 @@ void sstvRx::resetParams(bool bufferReset)
   bufferCounter=0;
   if(bufferReset)
     {
+      agcVolume=0;
       bufferVideoDemod.reset();
       bufferSync1200Vol.reset();
       bufferSync1900Vol.reset();
@@ -95,12 +98,22 @@ void sstvRx::setFilters()
 
 void sstvRx::run(DSPFLOAT *dataPtr, unsigned int *inputVolumePtr)
 {
+  int i;
   bufferCounter++;
   if(videoFilterPtr==NULL)
     {
       errorOut() << "videoFltr NULL";
       return;
     }
+  // run AGC
+  for(i=0;i<RXSTRIPE;i++)
+    {
+      DSPFLOAT tmp=sqrt(dataPtr[i]*dataPtr[i]);
+      if(tmp>agcVolume) agcVolume=tmp;
+      else agcVolume*=DECAY;
+      if(agcVolume<1000) agcVolume=1000;  //maximum gain is 8
+      dataPtr[i]=dataPtr[i]*8000/agcVolume;
+    }
   videoFilterPtr->process(dataPtr);
   bufferVideoDemod.putNoCheck(videoFilterPtr->demodPtr,RXSTRIPE);
   syncFilterPtr->process(dataPtr);
@@ -117,8 +130,8 @@ void sstvRx::run(DSPFLOAT *dataPtr, unsigned int *inputVolumePtr)
       syncNarrowProc.freqPtr=bufferVideoDemod.readPointer();
       syncWideProc.syncVolumePtr =bufferSync1200Vol.readPointer();
       syncNarrowProc.syncVolumePtr =bufferSync1900Vol.readPointer();
-      syncWideProc.inputVolumePtr=bufferInputVol.readPointer();
-      syncNarrowProc.inputVolumePtr=bufferInputVol.readPointer();
+//      syncWideProc.inputVolumePtr=bufferInputVol.readPointer();
+//      syncNarrowProc.inputVolumePtr=bufferInputVol.readPointer();
 
       displaySyncEvent* ce;
       if(syncProcPtr)
@@ -415,7 +428,7 @@ void sstvRx::eraseImage()
 #ifndef QT_NO_DEBUG
 unsigned int sstvRx::setOffset(unsigned int offset,bool ask)
 {
-  unsigned int xOffset;
+  unsigned int xOffset=0;
   if(ask)
     {
       scopeOffset so;
diff --git a/qsstv/sstv/sstvrx.h b/qsstv/sstv/sstvrx.h
index d88cc9e..dda9462 100644
--- a/qsstv/sstv/sstvrx.h
+++ b/qsstv/sstv/sstvrx.h
@@ -70,6 +70,7 @@ private:
   unsigned int currentIdx;
   bool usingWide;
   syncProcessor *syncProcPtr;
+  DSPFLOAT agcVolume;
 };
 
 #endif // SSTVRX_H
diff --git a/qsstv/sstv/syncprocessor.cpp b/qsstv/sstv/syncprocessor.cpp
index cc56feb..d3dbdbf 100644
--- a/qsstv/sstv/syncprocessor.cpp
+++ b/qsstv/sstv/syncprocessor.cpp
@@ -23,19 +23,27 @@
 ssenitivity sensitivityArray[2]=
 {
   // minMatchedLines maxLineDistanceModeDetect maxLineDistanceInSync onVolume offVolume  startToMax;
-  {         6,                2,                       7,              1.7,     0.9 ,      1.5},
-  {         6,                2,                       7 ,             1.7,     0.9 ,      1.5}
+  {         6,                2,                       7,              3000,    2500 ,      1.5},
+  {         6,                2,                       7 ,             2000,    1800 ,      1.5}
 };
 
 
+//const QString syncStateStr[syncProcessor::SYNCVALID+1]=
+//{
+//  "SYNCOFF",
+//  "SYNCUP",
+//  "SYNCSTART",
+//  "SYNCON",
+//  "SYNCDOWN",
+//  "SYNCEND",
+//  "SYNCVALID"
+//};
+
+
 const QString syncStateStr[syncProcessor::SYNCVALID+1]=
 {
   "SYNCOFF",
   "SYNCUP",
-  "SYNCSTART",
-  "SYNCON",
-  "SYNCDOWN",
-  "SYNCEND",
   "SYNCVALID"
 };
 
@@ -183,14 +191,14 @@ void syncProcessor::process()
   if(detectNarrow)
     {
       scopeViewerSyncNarrow->addData(SCDATA1,syncVolumePtr,sampleCounter,RXSTRIPE);
-      scopeViewerSyncNarrow->addData(SCDATA2,inputVolumePtr,sampleCounter,RXSTRIPE);
+//      scopeViewerSyncNarrow->addData(SCDATA2,inputVolumePtr,sampleCounter,RXSTRIPE);
       scopeViewerSyncNarrow->addData(SCDATA3,syncStateBuffer,sampleCounter,RXSTRIPE);
       scopeViewerSyncNarrow->addData(SCDATA4,freqPtr,sampleCounter,RXSTRIPE);
     }
   else
     {
       scopeViewerSyncWide->addData(SCDATA1,syncVolumePtr,sampleCounter,RXSTRIPE);
-      scopeViewerSyncWide->addData(SCDATA2,inputVolumePtr,sampleCounter,RXSTRIPE);
+//      scopeViewerSyncWide->addData(SCDATA2,inputVolumePtr,sampleCounter,RXSTRIPE);
       scopeViewerSyncWide->addData(SCDATA3,syncStateBuffer,sampleCounter,RXSTRIPE);
       scopeViewerSyncWide->addData(SCDATA4,freqPtr,sampleCounter,RXSTRIPE);
     }
@@ -205,100 +213,31 @@ void syncProcessor::extractSync()
   int lastSync;
   for(i=0;i<RXSTRIPE;i++)
     {
-      if(inputVolumePtr[i]<MINVOLUME)
-        {
-          switchSyncState(SYNCOFF,sampleCounter+i);
-#ifndef QT_NO_DEBUG
-          syncStateBuffer[i]=(unsigned char)syncState*STATESCALER;
-#endif
-          continue;
-        }
       switch(syncState)
         {
-        case SYNCVALID:
-        case SYNCOFF:
-          if(syncVolumePtr[i]>(inputVolumePtr[i]/sensitivityArray[squelch].onVolume))
+          case SYNCVALID:
+          case SYNCOFF:
+           if(syncVolumePtr[i]>sensitivityArray[squelch].onVolume)
             {
-              trackMax=syncVolumePtr[i];
-              holdOffCount=0;
-              holdOffTimeout=20;
               syncArray[syncArrayIndex].start=sampleCounter+i;
               syncArray[syncArrayIndex].startVolume=syncVolumePtr[i];
-              switchSyncState(SYNCUP,sampleCounter+i);
-            }
-          break;
-        case SYNCUP:
-          if(holdOffTimeout-- ==0)
-            {
-              switchSyncState(SYNCOFF,sampleCounter+i);
-            }
-          if(trackMax<syncVolumePtr[i])
-            {
-              trackMax=syncVolumePtr[i];
-              syncArray[syncArrayIndex].maxVolume=trackMax;
-              if(++holdOffCount>4)
-                {
-                  holdOffCount=0;
-                  switchSyncState(SYNCSTART,sampleCounter+i);
-                }
+              switchSyncState(SYNCACTIVE,sampleCounter+i);
             }
           break;
-        case SYNCSTART:
-          //track Maximum
-          if(trackMax<syncVolumePtr[i])
-            {
-              trackMax=syncVolumePtr[i];
-              holdOffCount=0;
-              syncArray[syncArrayIndex].maxVolume=trackMax;
-
-            }
-          else
+        case SYNCACTIVE:
+          if(syncVolumePtr[i]<sensitivityArray[squelch].offVolume)
             {
-              if(holdOffCount++==10)
+              syncArray[syncArrayIndex].end=sampleCounter+i;
+            if(validateSync())
                 {
-                  switchSyncState(SYNCON,sampleCounter+i);
+                  switchSyncState(SYNCVALID,sampleCounter+i);
                 }
-            }
-          break;
-        case SYNCON:
-          if(trackMax<syncVolumePtr[i]) //keep tracking maximum
-            {
-              trackMax=syncVolumePtr[i];
-              syncArray[syncArrayIndex].maxVolume=trackMax;
-            }
-          if(syncVolumePtr[i]<syncArray[syncArrayIndex].startVolume*sensitivityArray[squelch].offVolume)
-            {
-              syncArray[syncArrayIndex].end=sampleCounter+i;
-              holdOffCount=20;
-              switchSyncState(SYNCDOWN,sampleCounter+i);
-            }
-          break;
-
-        case SYNCDOWN:
-          if(syncVolumePtr[i]<syncArray[syncArrayIndex].startVolume*sensitivityArray[squelch].offVolume)
-            {
-              if(--holdOffCount==0)
+                else
                 {
-                  switchSyncState(SYNCEND,sampleCounter+i);
+                   switchSyncState(SYNCOFF,sampleCounter+i);
                 }
-            }
-          else
-            {
-              switchSyncState(SYNCON,sampleCounter+i);
-            }
-          break;
-
-        case SYNCEND:
-
-          if(validateSync())
-            {
-              switchSyncState(SYNCVALID,sampleCounter+i);
-            }
-          else
-            {
-              switchSyncState(SYNCOFF,sampleCounter+i);
-            }
-          break;
+          }
+        break;
         }
 #ifndef QT_NO_DEBUG
       syncStateBuffer[i]=(unsigned char)syncState*STATESCALER;
@@ -350,16 +289,8 @@ void syncProcessor::slotVisCodeDetected(int mode,uint visSampleCounter)
 bool syncProcessor::validateSync()
 {
   bool result;
-  //  if(syncArray[syncArrayIndex].endVolume<500)
-  //    {
-  //      result=false;
-  //    }
-  if(syncArray[syncArrayIndex].maxVolume<syncArray[syncArrayIndex].startVolume*sensitivityArray[squelch].startToMax)
-    {
-      result=false;
-    }
 #ifndef DISABLERETRACE
-  else if(syncArray[syncArrayIndex].diffStartEnd()>=MINRETRACEWIDTH)
+  if(syncArray[syncArrayIndex].diffStartEnd()>=MINRETRACEWIDTH)
     {
       syncArray[syncArrayIndex].retrace=true;
       result=true;
diff --git a/qsstv/sstv/syncprocessor.h b/qsstv/sstv/syncprocessor.h
index 5d34386..fa98d1d 100644
--- a/qsstv/sstv/syncprocessor.h
+++ b/qsstv/sstv/syncprocessor.h
@@ -121,7 +121,8 @@ class syncProcessor : public QObject
 {
   Q_OBJECT
 public:
-  enum esyncState {SYNCOFF,SYNCUP,SYNCSTART,SYNCON,SYNCDOWN,SYNCEND,SYNCVALID};
+//  enum esyncState {SYNCOFF,SYNCUP,SYNCSTART,SYNCON,SYNCDOWN,SYNCEND,SYNCVALID};
+  enum esyncState {SYNCOFF,SYNCACTIVE,SYNCVALID};
   enum esyncProcessState {MODEDETECT,INSYNC,SYNCLOSTNEWMODE,SYNCLOSTFALSESYNC,SYNCLOSTMISSINGLINES,SYNCLOST,RETRACEWAIT};
   explicit syncProcessor(bool narrow,QObject *parent = 0);
   ~syncProcessor();
@@ -146,13 +147,13 @@ public:
   quint32 sampleCounter;
   quint32 syncPosition;
   quint32 lastValidSyncCounter;
-  DSPFLOAT trackMax;
+//  DSPFLOAT trackMax;
   int      syncQuality;
   modeBase *currentModePtr;
 
   quint16      *freqPtr;
   DSPFLOAT     *syncVolumePtr;
-  unsigned int *inputVolumePtr;
+//  unsigned int *inputVolumePtr;
   videoFilter  *videoFilterPtr;
   bool         retraceFlag;
   bool tempOutOfSync;
@@ -217,8 +218,7 @@ private:
   void regression(DSPFLOAT &a, DSPFLOAT &b, bool initial);
   bool slantAdjust(bool initial);
   DSPFLOAT syncWidth;
-  qint8 holdOffCount;
-  qint8 holdOffTimeout;
+
 
 // signal quality
   quint16 falseSlantSync;
diff --git a/qsstv/sstv/visfskid.cpp b/qsstv/sstv/visfskid.cpp
index f923c5e..fe975fb 100644
--- a/qsstv/sstv/visfskid.cpp
+++ b/qsstv/sstv/visfskid.cpp
@@ -5,6 +5,8 @@
 const QString fskStateStr[fskIdDecoder::GETID+1]=
 {
   "FSKINIT",
+  "WAITS1500",
+  "WAITE1500",
   "WAITS1900",
   "WAITE1900",
   "WAITS2100",
@@ -59,7 +61,10 @@ bool fskDecoder::waitStartFreq(unsigned int freqL, unsigned int freqH, unsigned
 {
   if((avgFreq>=freqL) && (avgFreq<=freqH))
     {
-      if(avgCounter<avgCount) avgCounter++;
+      if(avgCounter<avgCount)
+      {
+          avgCounter++;
+      }
       else
         {
           timeoutCounter=0;
@@ -212,14 +217,15 @@ QString fskIdDecoder::getFSKId()
 void fskIdDecoder::switchState(efskState newState,unsigned int i)
 {
   Q_UNUSED(i);
-  addToLog(QString("%1 to %2 at samplecounter:%3 samplecounter%4").arg(fskStateStr[fskState]).arg(fskStateStr[newState]).arg(sampleCounter+i).arg(sampleCounter+i),LOGFSKID);
+  addToLog(QString("%1 to %2 at samplecounter:%3 syncSamplCntr%4").arg(fskStateStr[fskState]).arg(fskStateStr[newState]).arg(sampleCounter+i).arg(syncSampleCounter+i),LOGFSKID);
   fskState=newState;
 }
 
 
-void fskIdDecoder::extract(unsigned int syncSampleCtr, bool )
+void fskIdDecoder::extract(unsigned int syncSampleCtr, bool narrow)
 {
   int i;
+  if(narrow) return;
   syncSampleCounter=syncSampleCtr;
   bool timeout;
   for(i=0;i<RXSTRIPE;i++)
@@ -231,9 +237,10 @@ void fskIdDecoder::extract(unsigned int syncSampleCtr, bool )
           sampleCounter=0;
           avgCounter=0;
           switchState(WAITSTART1500,i);
+          timeoutCounter=0;
           break;
         case WAITSTART1500:
-          if(waitStartFreq(1400,1600))
+          if(waitStartFreq(500,1800))
             {
               switchState(WAITEND1500,i);
               startSampleCounter=sampleCounter+i;
@@ -241,9 +248,11 @@ void fskIdDecoder::extract(unsigned int syncSampleCtr, bool )
           break;
         case WAITEND1500:
           {
-            if(waitEndFreq(1400,1600))
+            if(waitEndFreq(1600,1800))
               {
-                if(((sampleCounter+i-startSampleCounter)>=FSKMIN1500) && ((sampleCounter+i-startSampleCounter)<2*FSKMIN1500))
+//                qDebug() << sampleCounter+i-startSampleCounter;
+                if(((sampleCounter+i-startSampleCounter)>=FSKMIN1500))
+//                        && ((sampleCounter+i-startSampleCounter)<2*FSKMIN1500))
                   {
                     switchState(WAITSTART2100,i);
                     timeoutCounter=0;
@@ -368,7 +377,7 @@ uint visDecoder::getCode()
 void visDecoder::switchState(evisState newState,unsigned int i)
 {
   Q_UNUSED(i);
-  addToLog(QString("%1 to %2 at samplecounter:%3 samplecounter%4").arg(visStateStr[visState]).arg(visStateStr[newState]).arg(sampleCounter+i).arg(sampleCounter+i),LOGFSKID);
+  addToLog(QString("%1 to %2 at samplecounter:%3 samplecounter%4").arg(visStateStr[visState]).arg(visStateStr[newState]).arg(sampleCounter+i).arg(sampleCounter+i),LOGVISCODE);
   visState=newState;
 }
 
diff --git a/qsstv/sstv/visfskid.h b/qsstv/sstv/visfskid.h
index 3d19b83..2ba19e8 100644
--- a/qsstv/sstv/visfskid.h
+++ b/qsstv/sstv/visfskid.h
@@ -5,7 +5,7 @@
 #include "sstvparam.h"
 
 
-#define FSKMIN1500 ((SAMPLERATE*200)/1000)
+#define FSKMIN1500 ((SAMPLERATE*100)/1000)
 #define FSKMIN2100 ((SAMPLERATE*70)/1000)
 #define FSKMIN1900 ((SAMPLERATE*18)/1000)
 #define FSKBIT     ((SAMPLERATE*22)/1000)
@@ -70,7 +70,7 @@ class fskIdDecoder : public fskDecoder
 public:
   enum efskState  {FSKINIT,WAITSTART1500,WAITEND1500,WAITSTART1900,WAITEND1900,WAITSTART2100,WAITEND2100,GETID};
   fskIdDecoder();
-  void extract(unsigned int syncSampleCtr, bool);
+  void extract(unsigned int syncSampleCtr, bool narrow);
   void reset();
   QString getFSKId();
 
diff --git a/qsstv/utils/ftp.cpp b/qsstv/utils/ftp.cpp
index c4e0301..b988693 100644
--- a/qsstv/utils/ftp.cpp
+++ b/qsstv/utils/ftp.cpp
@@ -33,12 +33,34 @@
 
 #define FTPTIMEOUTTIME 12000
 
+QString commandStr[15]=
+{
+  "None",
+  "SetTxMode",
+  "SetProxy",
+  "ConnectToHost",
+  "Login",
+  "Close",
+  "List",
+  "Cd",
+  "Get",
+  "Put",
+  "Remove",
+  "Mkdir",
+  "Rmdir",
+  "Rename",
+  "RawCommand"
+};
+
 ftpInterface::ftpInterface(QString id)
 {
   ftp=NULL;
   addToLog(id, LOGFTP);
   name=id;
   sourceFn=NULL;
+  timeoutExpired=false;
+  canCloseWhenDone=false;
+  displayProgress=true;
   init();
 }
 
@@ -55,6 +77,9 @@ void ftpInterface::init()
   if(ftp) delete ftp;
   addToLog(QString("FTP init '%1'").arg(name), LOGFTP);
   ftp = new QFtp( 0);
+
+  disconnectTimer.setInterval(FTPTIMEOUTTIME);
+
   connect( ftp, SIGNAL(commandStarted(int)),SLOT(ftp_commandStarted(int)) );
   connect( ftp, SIGNAL(commandFinished(int,bool)),SLOT(ftp_commandFinished(int,bool)) );
   connect( ftp, SIGNAL(done(bool)),SLOT(ftp_done(bool)) );
@@ -62,19 +87,29 @@ void ftpInterface::init()
   connect( ftp, SIGNAL(listInfo(const QUrlInfo &)),SLOT(ftp_listInfo(const QUrlInfo &)) );
   connect( ftp, SIGNAL(rawCommandReply(int, const QString &)),SLOT(ftp_rawCommandReply(int, const QString &)) );
   connect( ftp, SIGNAL(dataTransferProgress(qint64,qint64)),SLOT(slotProgress(qint64,qint64)) );
+
+  connect(&notifyTimer,     SIGNAL(timeout()), this, SLOT(notifyTick()));
+  connect(&timeoutTimer,    SIGNAL(timeout()), this, SLOT(slotTimeout()));
+  connect(&disconnectTimer, SIGNAL(timeout()), this, SLOT(slotDisconnect()));
+
+  timeoutTimer.setSingleShot(true);
+  timeoutTimer.setInterval(FTPTIMEOUTTIME);
 }
 
 void ftpInterface::destroy()
 {
+  disconnectTimer.stop();
   mremove_listids.clear();
   listingResults.clear();
   notifyId=-1;
   ftpDone=true;
+  connectPending=false;
+  ftpCommandSuccess=false;
   if(ftp)
     {
       addToLog("FTP show state in destroy",LOGFTP);
       ftp_stateChanged(ftp->state());
-      if( ftp->state() != QFtp::Unconnected ) 
+      if( ftp->state() != QFtp::Unconnected )
         {
           addToLog(QString("Closing '%1' to %2").arg(name).arg(host),LOGFTP);
           ftp->close();
@@ -84,35 +119,33 @@ void ftpInterface::destroy()
 
 void ftpInterface::setupConnection(QString tHost,int tPort,QString tUser,QString tPasswd,QString tDirectory)
 {
-    addToLog(QString("'%1' host %2").arg(name).arg(tHost), LOGFTP);
-    if(host!=tHost || user!=tUser || passwd!=tPasswd || port!=tPort || directory!=tDirectory)
-      {
-        if (ftp) destroy();
-      }
-    host=tHost;
-    user=tUser;
-    passwd=tPasswd;
-    directory=tDirectory;
-    port=tPort;
+  addToLog(QString("'%1' host %2, User=%3,directory=%4").arg(name).arg(tHost).arg(tUser).arg(tDirectory), LOGFTP);
+  if(host!=tHost || user!=tUser || passwd!=tPasswd || port!=tPort)
+    {
+      if (ftp) destroy();
+    }
+  host=tHost;
+  port=tPort;
+  user=tUser;
+  passwd=tPasswd;
+  changePath(tDirectory);
 }
 
 eftpError ftpInterface::doConnect()
 {
   aborting=false;
-  addToLog(QString("'%1' to %2").arg(name).arg(host),LOGFTP);
-  //dumpState();
-  
-  // if !ftpDone then we've had at least one command issued, which means
-  // that first command caused doConnect() to run and call connectToHost()
-  // if !isUnconnected() then the connection has already been established.
-  if(isUnconnected() && ftpDone)
+
+  if(isUnconnected() && !connectPending)
     {
-      addToLog(QString("FTP connect to host %1").arg(host),LOGFTP);
+      //addToLog(QString("FTP connect to host %1").arg(host),LOGFTP);
       connectToHost();
     }
+  else if (connectPending) {
+      addToLog(QString("'%1' connection pending to %2").arg(name).arg(host),LOGFTP);
+    }
   else
     {
-      addToLog(QString("FTP already connected to host %1").arg(host),LOGFTP);
+      addToLog(QString("'%1' already connected to %2, %3").arg(name).arg(host).arg(commandStr[ftp->currentCommand()]),LOGFTP);
     }
   return FTPOK;
 }
@@ -120,10 +153,14 @@ eftpError ftpInterface::doConnect()
 
 eftpError ftpInterface::uploadFile(QString fileName,QString targetFilename,bool reconnect)
 {
-//  int id;
+  int id;
+  Q_UNUSED(id);
   eftpError result;
   addToLog("uploadFile",LOGFTP);
-  if ( fileName.isNull() )  return FTPNAMEERROR;
+  if ( fileName.isNull() )  {
+      addToLog("fileName is NULL",LOGFTP);
+      return FTPNAMEERROR;
+    }
   if(reconnect)
     {
       result=doConnect();
@@ -134,6 +171,7 @@ eftpError ftpInterface::uploadFile(QString fileName,QString targetFilename,bool
     {
       //		   QMessageBox::critical( 0, tr("Upload error"),
       //                tr("Can't open file '%1' for reading.").arg(fileName) );
+      addToLog(QString("Unable to read '%1'").arg(fileName), LOGFTP);
       sourceFn=NULL;
       return FTPNAMEERROR;
     }
@@ -144,16 +182,15 @@ eftpError ftpInterface::uploadFile(QString fileName,QString targetFilename,bool
   ftpDone=false;
   if(fin.fileName().isEmpty())
     {
-      ftp->put( sourceFn, fi.fileName(),QFtp::Binary);
+      id=ftp->put( sourceFn, fi.fileName(),QFtp::Binary);
     }
   else
     {
-      ftp->put( sourceFn, fin.fileName(),QFtp::Binary);
+      id=ftp->put( sourceFn, fin.fileName(),QFtp::Binary);
     }
-//  addToLog(QString("FTP put file id: %1").arg(id),LOGFTP);
-  result = wait(-3);
+  addToLog(QString("'%1' put '%2', %3 bytes. id=%4").arg(name).arg(targetFilename).arg(sourceFn->size()).arg(id),LOGFTP);
+//  result = wait(-3);
   if (result!=FTPOK) return result;
-  addToLog("FTP starting progress",LOGFTP);
   return FTPOK;
 }
 
@@ -202,25 +239,23 @@ eftpError ftpInterface::downloadFile(QString sourceFileName,QString destinationF
 
 eftpError ftpInterface::wait(int timeout)
 {
-  if (timeout < 0) timeout = FTPTIMEOUTTIME - (0-timeout);
-  if (timeout) {
-     tim.setSingleShot(true);
-     tim.setInterval(timeout);
-     tim.start();
-     }
-     
+  timeoutTimer.stop();
+  if (timeout < 0) timeout = FTPTIMEOUTTIME * (0-timeout);
+  if (timeout)     timeoutTimer.setInterval(timeout);
+  addToLog(QString("'%1' tim.start timeout=%2").arg(name).arg(timeout),LOGFTP);
+  timeoutTimer.start();
+  timeoutExpired=false;
+
   while (!ftpDone)
     {
       if(aborting) return FTPCANCELED;
       qApp->processEvents();
-      if(timeout && !tim.isActive())
+      if(timeout && timeoutExpired)
         {
-          slotAbort();
-          addToLog(QString("'%1' Timeout (%2ms) Host:%3 ").arg(name).arg(timeout).arg(host),LOGALL);
+          addToLog(QString("'%1' Timeout Expired").arg(name),LOGALL);
           return FTPTIMEOUT;
         }
     }
-  if (timeout) tim.stop();
   if(!ftpCommandSuccess) return FTPERROR;
   return FTPOK;
 }
@@ -228,20 +263,19 @@ eftpError ftpInterface::wait(int timeout)
 eftpError ftpInterface::remove(QString path)
 {
   int id;
-  Q_UNUSED(id)
+  Q_UNUSED(id);
   eftpError result=doConnect();
   if(result!=FTPOK) return result;
 
   ftpDone=false;
   id = ftp->remove(path);
-  addToLog(QString("'%1' Name='%2'  id:%3").arg(name).arg(path).arg(id),LOGFTP);
+  addToLog(QString("Name=%1 Path=%2  id:%3").arg(name).arg(path).arg(id),LOGFTP);
   return FTPOK;
 }
 
 eftpError ftpInterface::mremove(QString path)
 {
   int id;
-  Q_UNUSED(id)
   eftpError result;
   addToLog(QString("FTP mremove"),LOGFTP);
 
@@ -252,13 +286,13 @@ eftpError ftpInterface::mremove(QString path)
   id = ftp->list(path);
   if (id>0) mremove_listids.append(id);
   addToLog(QString("'%1' Path='%2'  id=%3").arg(name).arg(path).arg(id),LOGFTP);
-  return FTPOK;  
+  return FTPOK;
 }
 
 eftpError ftpInterface::getListing(QString path)
 {
   int id;
-  Q_UNUSED(id)
+  Q_UNUSED(id);
   eftpError result;
   addToLog("FTP getListing",LOGFTP);
 
@@ -267,7 +301,7 @@ eftpError ftpInterface::getListing(QString path)
   ftpDone=false;
   id = ftp->list(path);
   addToLog(QString("'%1' Path='%2'  id:%3").arg(name).arg(path).arg(id),LOGFTP);
-  return FTPOK;  
+  return FTPOK;
 }
 
 QList <QUrlInfo> ftpInterface::getListingResults()
@@ -283,7 +317,7 @@ void ftpInterface::clearListingResults()
 
 eftpError ftpInterface::startNotifyCheck(QString fn, int interval, int repeats, bool rm)
 {
-  addToLog(QString("'%1' startNotifyCheck(%2,%3,%4,%5)").arg(name).arg(fn).arg(interval).arg(repeats).arg(rm),LOGNOTIFY);
+  addToLog(QString("'%1' startNotifyCheck(%2,%3,%4,%5)").arg(name).arg(fn).arg(interval).arg(repeats).arg(rm),LOGFTP);
   notifyMask    = "Dummy"+fn+"+++*";
   notifyTicks   = -1;
   notifyRepeats = repeats;
@@ -293,48 +327,72 @@ eftpError ftpInterface::startNotifyCheck(QString fn, int interval, int repeats,
   
   notifyTimer.setSingleShot(false);
   notifyTimer.setInterval(interval*1000);
-  connect(&notifyTimer, SIGNAL(timeout()), this, SLOT(notifyTick()));
   notifyTimer.start();
-  notifyTick();  
+
+  disconnectTimer.setInterval(interval*1000 * 2);
+
+  notifyTick();
   return FTPOK;
 }
 
 void ftpInterface::notifyTick()
 {
-   // runs once every interval seconds
-   notifyTicks++;
-   addToLog(QString("'%1': ticks=%2  notifyid=%3").arg(name).arg(notifyTicks).arg(notifyId), LOGNOTIFY);
-   if (notifyTicks>notifyRepeats)
-   {
+  // runs once every interval seconds
+  notifyTicks++;
+  addToLog(QString("'%1': ticks=%2  notifyid=%3").arg(name).arg(notifyTicks).arg(notifyId), LOGFTP);
+  if (notifyTicks>notifyRepeats)
+    {
       notifyTimer.stop();
-   }
-   else if (notifyId<0)
-   {
+      disconnectTimer.setInterval(FTPTIMEOUTTIME);
+    }
+  else if (notifyId<0)
+    {
       eftpError result=doConnect();
       if (result==FTPOK)
-      {
-         ftpDone=false;
-         notifyId = ftp->list(notifyMask);
-      }
-   }
+        {
+          ftpDone=false;
+          notifyId = ftp->list(notifyMask);
+        }
+    }
+}
+
+void ftpInterface::slotTimeout()
+{
+  timeoutExpired=true;
+  addToLog(QString("'%1' Timeout (%2ms) Host:%3 ").arg(name).arg(timeoutTimer.interval()).arg(host),LOGALL);
+  slotAbort();
 }
 
 void ftpInterface::connectToHost()
 {
+  int id;
+  Q_UNUSED(id);
   addToLog(QString("'%1' connectToHost %2").arg(name).arg(host), LOGFTP);
   destroy();
   ftpDone=false;
+  connectPending=true;
   ftp->connectToHost(host,port);
   ftp->login( user, passwd );
-  if(!directory.isEmpty()) changePath(directory);
+  if(!directory.isEmpty()) {
+      id = ftp->cd(directory);
+      addToLog(QString("'%1': cd '%2' id:%3").arg(name).arg(directory).arg(id),LOGFTP);
+    }
 }
 
 // This slot is connected to the QComboBox::activated() signal of the
 // remotePath.
 void ftpInterface::changePath( const QString &newPath )
 {
-  directory=newPath;
-  ftp->cd( newPath );
+  int id;
+  Q_UNUSED(id);
+  if (directory != newPath)
+    {
+      directory="";
+      doConnect();
+      id = ftp->cd( newPath );
+      addToLog(QString("'%1':'%2' id:%3").arg(name).arg(newPath).arg(id), LOGFTP);
+      directory=newPath;
+    }
 }
 
 
@@ -347,21 +405,42 @@ void ftpInterface::changePath( const QString &newPath )
 void ftpInterface::ftp_commandStarted(int id)
 {
   Q_UNUSED(id);
-  addToLog(QString("'%1' id:%2, %3").arg(name).arg(id).arg(ftp->currentCommand()),LOGFTP);
+  addToLog(QString("'%1' id:%2, %3").arg(name).arg(id).arg(commandStr[ftp->currentCommand()]),LOGFTP);
   if ( ftp->currentCommand() == QFtp::List )
     {
     }
-  if (tim.isActive()) tim.start();
+  addToLog(QString("'%1' tim.restart interval=%2").arg(name).arg(timeoutTimer.interval()),LOGFTP);
+  timeoutTimer.start();
 }
 
 void ftpInterface::ftp_commandFinished(int id,bool err)
 {
-  Q_UNUSED(id);
+  //  Q_UNUSED(id);
   QIODevice *p;
 
   slotProgress(0,0);
 
-  addToLog(QString("'%1' id:%2, error:%3").arg(name).arg(id).arg(err),LOGFTP);
+  addToLog(QString("'%1' id:%2,%3 error:%4").arg(name).arg(id).arg(commandStr[ftp->currentCommand()]).arg(err),LOGFTP);
+
+  if (ftp->currentCommand() == QFtp::Login) {
+      connectPending=false;
+    }
+  else if (ftp->currentCommand() == QFtp::List)
+    {
+      if (id==notifyId)
+        {
+          notifyId=-1;
+        }
+      else if (mremove_listids.contains(id))
+        {
+          mremove_listids.removeOne(id);
+        }
+      else
+        {
+          emit listingComplete();
+        }
+    }
+
   if(err)
     {
       addToLog(QString("FTP error:%1").arg(ftp->errorString()),LOGFTP);
@@ -372,9 +451,6 @@ void ftpInterface::ftp_commandFinished(int id,bool err)
       ftpCommandSuccess=true;
     }
 
-  mremove_listids.removeOne(id);
-  if (id==notifyId) notifyId=-1;
-  
   p=ftp->currentDevice();
   if(p)
     {
@@ -385,30 +461,43 @@ void ftpInterface::ftp_commandFinished(int id,bool err)
 
 void ftpInterface::ftp_done( bool error )
 {
+  timeoutTimer.stop();
 
   if ( error )
     {
-
-      //        QMessageBox::critical( 0, tr("FTP Error"), ftp->errorString() );
-
       // If we are connected, but not logged in, it is not meaningful to stay
       // connected to the server since the error is a really fatal one (login
       // failed).
       if(!isLoggedIn())
         {
+          emit commandsDone(error);
+          ftpCommandSuccess=false;
           addToLog(QString("'%1': error and not logged in-> disconnecting").arg(host),LOGFTP);
           destroy();
           ftpDone=true;
           return;
         }
-      addToLog(QString("'%1': error").arg(host),LOGFTP);
+      addToLog(QString("'%1': %2 error").arg(name).arg(host),LOGFTP);
     }
   else
     {
-      addToLog(QString("'%1': OK").arg(host),LOGFTP);
+      addToLog(QString("'%1': %2 OK").arg(name).arg(host),LOGFTP);
     }
   mremove_listids.clear();
+  if (!isUnconnected() && canCloseWhenDone)
+    {
+      addToLog(QString("'%1': schedule disconnect in %2ms").arg(name).arg(disconnectTimer.interval()),LOGFTP);
+      disconnectTimer.start();
+    }
+  ftpCommandSuccess=true;
   ftpDone=true;
+  emit commandsDone(error);
+}
+
+void ftpInterface::slotDisconnect()
+{
+  addToLog(QString("'%1'").arg(name), LOGFTP);
+  destroy();
 }
 
 bool ftpInterface::isLoggedIn()
@@ -437,55 +526,61 @@ void ftpInterface::dumpState()
     {
     case QFtp::Unconnected:
       addToLog(QString("FTPss Unconnected name:=%1 :host=%2").arg(name).arg(host),LOGFTP);
-      break;
+    break;
     case QFtp::HostLookup:
       addToLog(QString("FTPss Host lookup name:=%1 :host=%2").arg(name).arg(host),LOGFTP);
-      break;
+    break;
     case QFtp::Connecting:
       addToLog(QString("FTPss Connecting name:=%1 :host=%2").arg(name).arg(host),LOGFTP);
-      break;
+    break;
     case QFtp::Connected:
       addToLog(QString("FTPss Connected name:=%1 :host=%2").arg(name).arg(host),LOGFTP);
-      break;
+    break;
     case QFtp::LoggedIn:
       addToLog(QString("FTPss Logged In name:=%1 :host=%2").arg(name).arg(host),LOGFTP);
-      break;
+    break;
     case QFtp::Closing:
       addToLog(QString("FTPss Closing name:=%1 :host=%2").arg(name).arg(host),LOGFTP);
-      break;
+    break;
     default:
       addToLog(QString("FTPss uknown %1 name:=%2 host=%3").arg(ftp->state()).arg(name).arg(host),LOGFTP);
-      break;
+    break;
     }
 }
 
 
 void ftpInterface::ftp_listInfo( const QUrlInfo & ent)
 {
-  if (ent.isFile()) {
-     addToLog(QString("currentId=%1, name=%2").
-             arg(ftp->currentId()).arg(ent.name()),
-             LOGFTP);
-             
-     if (ftp->currentId()==notifyId) {
-        QString name = ent.name().mid(notifyMask.length());
-
-        if (!notifyList.contains(name)) {
-            addToLog(QString("New Notification:'%1'").arg(name), LOGALL);
-            notifyList.append(name);
-            emit notification(name);
+  timeoutTimer.start();
+  if (ent.isFile())
+    {
+      addToLog(QString("currentId=%1, name=%2").arg(ftp->currentId()).arg(ent.name()), LOGFTP);
+
+      if (ftp->currentId()==notifyId)
+        {
+          QString name = ent.name().mid(notifyMask.length());
+
+          if (!notifyList.contains(name))
+            {
+              addToLog(QString("New Notification:'%1'").arg(name), LOGALL);
+              notifyList.append(name);
+//              qDebug() << "info";
+              emit notification(name);
             }
-        
-        if (notifyRemove) remove(ent.name());
-     }
-     else if (mremove_listids.contains(ftp->currentId())) {
-        remove(ent.name());
-     }
-     else {
-        listingResults.append(ent);
-        addToLog(QString("List Entry: %1").arg(ent.name()), LOGFTP);
-     }
-  }
+
+          if (notifyRemove) remove(ent.name());
+        }
+      else if (mremove_listids.contains(ftp->currentId()))
+        {
+//          qDebug() << "rem";
+          remove(ent.name());
+        }
+      else
+        {
+          listingResults.append(ent);
+          addToLog(QString("List Entry: %1").arg(ent.name()), LOGFTP);
+        }
+    }
 }
 
 void ftpInterface::ftp_rawCommandReply( int code, const QString &text )
@@ -505,10 +600,13 @@ void ftpInterface::slotAbort()
 
 void ftpInterface::slotProgress(qint64 bytes ,qint64 total)
 {
-  displayProgressFTPEvent *stmb;
-  stmb=new displayProgressFTPEvent(bytes,total);
-  QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
-  if (tim.isActive()) tim.start();
+  if (displayProgress) {
+      displayProgressFTPEvent *stmb;
+      stmb=new displayProgressFTPEvent(bytes,total);
+      QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
+    }
+  addToLog(QString("'%1' tim.restart interval=%2").arg(name).arg(timeoutTimer.interval()),LOGFTP);
+  timeoutTimer.start();
 }
 
 eftpError ftpInterface::uploadToRXServer(QString fn)
@@ -520,40 +618,53 @@ eftpError ftpInterface::uploadToRXServer(QString fn)
   result=doConnect();
 
   if(result!=FTPOK) return result;
-  if(ftpSaveFormat==FTPIM)
+  if(fn.length()>0)
     {
-      ftpDone=false;
-      ftp->remove(QString("image%1").arg(ftpNumImages));
-      while(!ftpDone)
-        {
-          qApp->processEvents();
-        }
-
-      for(i=0;i<ftpNumImages-1;i++)
-        //        for(i=0;i<1;i++)
+      if(ftpSaveFormat==FTPIM)
         {
           ftpDone=false;
-          ftp->rename(QString("image%1").arg(ftpNumImages-1-i),QString("image%1").arg(ftpNumImages-i));
-          while(!ftpDone)
+          ftp->remove(QString("image%1").arg(ftpNumImages));
+          wait(-1);
+
+          for(i=ftpNumImages; i>0; i--)
             {
-              qApp->processEvents();
+              ftpDone=false;
+              ftp->rename(QString("image%1").arg(i-1),QString("image%1").arg(i));
+              wait(-1);
+              addToLog("FTP done:  in rename",LOGFTP);
             }
-          addToLog("FTP done:  in rename",LOGFTP);
+          ftpDone=false;
+          result=uploadFile(fn,"image1",false);
+        }
+      else
+        {
+          ftpDone=false;
+          result=uploadFile(fn,"",false);
         }
-      ftpDone=false;
-      return uploadFile(fn,"image1",false);
-    }
-  else
-    {
-      ftpDone=false;
-      return uploadFile(fn,"",false);
     }
+
+  if (result!=FTPOK) return result;
+
+  // indicate the images were updated
+  // width=1:online, 2:offline
+  // Height=change each time to indicate images were updated
+  int status=(fn.length()>0) ? 1 : 2;
+
+  QImage im(status,QDateTime::currentDateTime().time().minute(),QImage::Format_RGB32);
+  im.fill(Qt::black);
+  QByteArray ba;
+  QBuffer buffer(&ba);
+  buffer.open(QIODevice::WriteOnly);
+  im.save(&buffer, "JPG");
+  uploadData(ba,"checknew.jpg");
+  result=wait(-1);
+  return result;
 }
 
 
 QString ftpInterface::execFTPTest()
 {
-  QString ret;
+  QString ret="";
   QString fn;
   QString rfn;
   eftpError ftpResult;
@@ -570,63 +681,58 @@ QString ftpInterface::execFTPTest()
       fn=tst.fileName();
       tst.write("connection test\n");
       tst.close();
-      
+
       rfn = QString("test_%1.txt").arg( myCallsign);
-#if 1
       ftpResult=uploadFile(fn,rfn,true);
-#else
-      mremove("test_"+myCallsign+".*");
-      uploadData(QByteArray("Dummy\r\n"), rfn);
-      ftpResult = wait(-1);
-#endif
-      
+      ftpResult=wait(-1);
+
       switch(ftpResult)
         {
         case FTPCANCELED:
           ret="Connection Canceled";
-          break;
+        break;
         case FTPOK:
           ret="Connection OK";
-          break;
+        break;
         case FTPERROR:
           ret=getLastError();
-          break;
+        break;
         case FTPNAMEERROR:
           ret="Error in filename";
-          break;
+        break;
         case FTPTIMEOUT:
           ret="FTP timed out";
-          break;
+        break;
         default:
           ret="Unknown error";
-          break;
+        break;
         }
-    if (ftpResult==FTPOK) {
-        remove(rfn);
-        ftpResult=wait(-1);
-        switch(ftpResult)
-          {
-          case FTPCANCELED:
-            ret="mremove: Connection Canceled";
+      if (ftpResult==FTPOK) {
+          remove(rfn);
+          ftpResult=wait(-1);
+          switch(ftpResult)
+            {
+            case FTPCANCELED:
+              ret="mremove: Connection Canceled";
             break;
-          case FTPOK:
-            ret="Connection OK";
+            case FTPOK:
+              ret="Connection OK";
             break;
-          case FTPERROR:
-            ret=getLastError();
+            case FTPERROR:
+              ret=getLastError();
             break;
-          case FTPNAMEERROR:
-            ret="mremove: Error in filename";
+            case FTPNAMEERROR:
+              ret="mremove: Error in filename";
             break;
-          case FTPTIMEOUT:
-            ret="mremove: FTP timed out";
+            case FTPTIMEOUT:
+              ret="mremove: FTP timed out";
             break;
-          default:
-            ret="mremove: Unknown error";
+            default:
+              ret="mremove: Unknown error";
             break;
-          }
+            }
 
-       }
+        }
     }
   return ret;
 }
diff --git a/qsstv/utils/ftp.h b/qsstv/utils/ftp.h
index dce2af5..26ceb79 100644
--- a/qsstv/utils/ftp.h
+++ b/qsstv/utils/ftp.h
@@ -51,6 +51,8 @@ public:
   eftpError startNotifyCheck(QString fn, int interval, int repeats, bool rm);
   QList <QUrlInfo> getListingResults();
   void clearListingResults();
+  void closeWhenDone(bool can=true) { canCloseWhenDone=can; }
+  void hideProgress(bool hide=true) { displayProgress=!hide; }
   
   bool isUnconnected();
   bool isLoggedIn();
@@ -63,7 +65,9 @@ public:
 
 signals:
   void notification(QString info);
-  
+  void listingComplete();
+  void commandsDone(bool error);
+
 private slots:
   void ftp_commandStarted(int);
   void ftp_commandFinished(int,bool);
@@ -74,6 +78,8 @@ private slots:
   void slotAbort();
   void slotProgress(qint64 total, qint64 bytes);
   void notifyTick();
+  void slotTimeout();
+  void slotDisconnect();
     
 private:
   void connectToHost();
@@ -90,19 +96,23 @@ private:
   QString directory;
   int port;
   bool ftpCommandSuccess;
-  QTimer tim;
-
+  QTimer timeoutTimer;
+  bool   timeoutExpired;
   QString name;
 
   QList <int> mremove_listids;
   QList <QUrlInfo> listingResults;
   QList <QString>  notifyList;
   QTimer notifyTimer;
+  QTimer disconnectTimer;
   QString notifyMask;
   int notifyTicks;
   int notifyRepeats;
   bool notifyRemove;
   int notifyId;
+  bool connectPending;
+  bool canCloseWhenDone;
+  bool displayProgress;
 };
 
 //extern ftpInterface *ftpIntf;
diff --git a/qsstv/utils/hybridcrypt.cpp b/qsstv/utils/hybridcrypt.cpp
index d5323a8..ffff4ce 100644
--- a/qsstv/utils/hybridcrypt.cpp
+++ b/qsstv/utils/hybridcrypt.cpp
@@ -7,38 +7,10 @@
 
 hybridCrypt::hybridCrypt()
 {
-  const uchar *d;
-  QByteArray ba;
-  QResource qrc(":/icons/mgc.raw");
-  QResource qrc2(":/icons/mgc2.raw");
-  d=qrc.data();
-  key1=d[32]-0x36;
-  key2=d[33]-0x72;
-  key3=d[34]-0xd8;
-  key4=d[35]-0xFE;
-  ba.clear();
-  ba.append((const char *)qrc2.data());
-  deCrypt(&ba);
-  vhcFtpRemoteHost=hcFtpRemoteHost;
-  vhcFtpLogin=hcFtpLogin;
-  vhcFtpPassword=hcFtpPassword;
-  vhcFtpRemoteDirectory=hcFtpRemoteDirectory;
-  vhcFtpPort=21; // at this moment no port can by specified
-  hcFtpPort=vhcFtpPort;
-  if((enableSpecialServer) && (!hybridFtpRemoteHost.isEmpty()))
-    {
-      hcFtpRemoteHost=hybridFtpRemoteHost;
-      hcFtpLogin=hybridFtpLogin;
-      hcFtpPassword=hybridFtpPassword;
-      hcFtpRemoteDirectory=hybridFtpRemoteDirectory; //always relatif to /HybridFiles
-    }
-  else
-    {
-      hcFtpRemoteHost=vhcFtpRemoteHost;
-      hcFtpLogin=vhcFtpLogin;
-      hcFtpPassword=vhcFtpPassword;
-      hcFtpRemoteDirectory=vhcFtpRemoteDirectory;
-    }
+  key1=4;
+  key2=5;
+  key3=7;
+  key4=1;
 }
 
 
@@ -47,7 +19,14 @@ bool hybridCrypt::enCrypt(QByteArray *ba)
 {
   int i;
   QString string,hstr;
-
+  hcFtpPort=21;
+  if(!hybridFtpRemoteHost.isEmpty())
+    {
+      hcFtpRemoteHost=hybridFtpRemoteHost;
+      hcFtpLogin=hybridFtpLogin;
+      hcFtpPassword=hybridFtpPassword;
+      hcFtpRemoteDirectory=hybridFtpRemoteDirectory; //always relatif to /HybridFiles
+    }
 
   hstr=QChar(63)+hcFtpRemoteHost+QChar(34)+hcFtpLogin+QChar(60)+hcFtpPassword+QChar(62)+hcFtpRemoteDirectory+QChar(58);
 
@@ -139,14 +118,7 @@ bool hybridCrypt::deCrypt(QByteArray *ba)
       if(baSize%2!=0) return false;
     }
 
-  if(baSize<20)
-    {
-      hcFtpRemoteHost=vhcFtpRemoteHost;
-      hcFtpLogin=vhcFtpLogin;
-      hcFtpPassword=vhcFtpPassword;
-      hcFtpRemoteDirectory=vhcFtpRemoteDirectory;
-      return true;
-    }
+  if(baSize<20) return false;
   do
     {
       for(bufI=0;bufI<4;bufI++,charCount+=2)
@@ -228,14 +200,15 @@ bool hybridCrypt::getParam(QString resultStr)
   hcFtpRemoteHost=resultStr.mid(a+1,b-a-1);
   hcFtpLogin=resultStr.mid(b+1,c-b-1);
   hcFtpPassword=resultStr.mid(c+1,d-c-1);
+  hcFtpPort=21; // FIXED Port Settings
   tempDir=resultStr.mid(d+1,e-d-1);
   if( !tempDir.isEmpty())
     {
-      hcFtpRemoteDirectory=resultStr.mid(d+1,e-d-1)+"/"+vhcFtpRemoteDirectory;
+      hcFtpRemoteDirectory=resultStr.mid(d+1,e-d-1);
     }
   else
     {
-      hcFtpRemoteDirectory=vhcFtpRemoteDirectory;
+      hcFtpRemoteDirectory="";
     }
   addToLog(QString("host: %1, login: %2, pwd: %3, dir: %4").arg(hcFtpRemoteHost).arg(hcFtpLogin).arg(hcFtpPassword).arg(hcFtpRemoteDirectory),LOGALL);
   return true;
diff --git a/qsstv/utils/hybridcrypt.h b/qsstv/utils/hybridcrypt.h
index e256ff6..247698c 100644
--- a/qsstv/utils/hybridcrypt.h
+++ b/qsstv/utils/hybridcrypt.h
@@ -20,12 +20,6 @@ private:
     QString hcFtpPassword;
     QString hcFtpRemoteDirectory;
     int hcFtpPort;
-    QString vhcFtpRemoteHost;
-    QString vhcFtpLogin;
-    QString vhcFtpPassword;
-    QString vhcFtpRemoteDirectory;
-    int vhcFtpPort;
-
     short int key1,key2,key3,key4;
     void reverseString(QString & s);
     bool getParam(QString result);
diff --git a/qsstv/utils/jp2io.cpp b/qsstv/utils/jp2io.cpp
index 8bc17e2..ec50476 100644
--- a/qsstv/utils/jp2io.cpp
+++ b/qsstv/utils/jp2io.cpp
@@ -21,8 +21,8 @@ static size_t opj_strnlen_s(const char *src, size_t max_len)
   size_t len;
 
   if (src == NULL) {
-    return 0U;
-  }
+      return 0U;
+    }
   for (len = 0U; (*src != '\0') && (len < max_len); src++, len++);
   return len;
 }
@@ -31,16 +31,16 @@ static int opj_strcpy_s(char* dst, size_t dst_size, const char* src)
 {
   size_t src_len = 0U;
   if ((dst == NULL) || (dst_size == 0U)) {
-    return EINVAL;
-  }
+      return EINVAL;
+    }
   if (src == NULL) {
-    dst[0] = '\0';
-    return EINVAL;
-  }
+      dst[0] = '\0';
+      return EINVAL;
+    }
   src_len = opj_strnlen_s(src, dst_size);
   if (src_len >= dst_size) {
-    return ERANGE;
-  }
+      return ERANGE;
+    }
   memcpy(dst, src, src_len);
   dst[src_len] = '\0';
   return 0;
@@ -61,7 +61,7 @@ sample warning callback expecting a FILE* client object
 static void warning_callback(const char *msg, void *client_data) {
   (void)client_data;
   Q_UNUSED( msg )
- addToLog(QString("[WARNING] %1").arg(msg),LOGIMAG);
+  addToLog(QString("[WARNING] %1").arg(msg),LOGIMAG);
 }
 /**
 sample debug callback expecting no client object
@@ -104,19 +104,19 @@ bool jp2IO::check(QString fileName)
   size=fi.read(data,12);
   fi.close();
   if(size!=12)
-  {
-    return false;
-  }
+    {
+      return false;
+    }
   if (memcmp(data, JP2_RFC3745_MAGIC, 12) == 0 || memcmp(data, JP2_MAGIC, 4) == 0)
-  {
-    magicFormat = JP2_CFMT;
-    magicStr = ".jp2";
-  }
+    {
+      magicFormat = JP2_CFMT;
+      magicStr = ".jp2";
+    }
   else if (memcmp(data, J2K_CODESTREAM_MAGIC, 4) == 0)
-  {
-    magicFormat  = J2K_CFMT;
-    magicStr = ".j2k or .jpc or .j2c";
-  }
+    {
+      magicFormat  = J2K_CFMT;
+      magicStr = ".j2k or .jpc or .j2c";
+    }
   else return false;
   parameters.decod_format=magicFormat;
   return true;
@@ -125,26 +125,26 @@ bool jp2IO::check(QString fileName)
 void jp2IO::set_default_parameters(opj_decompress_parameters* parameters)
 {
   if (parameters)
-  {
-    memset(parameters, 0, sizeof(opj_decompress_parameters));
+    {
+      memset(parameters, 0, sizeof(opj_decompress_parameters));
 
-    /* default decoding parameters (command line specific) */
-    parameters->decod_format = -1;
-    parameters->cod_format = -1;
+      /* default decoding parameters (command line specific) */
+      parameters->decod_format = -1;
+      parameters->cod_format = -1;
 
-    /* default decoding parameters (core) */
-    opj_set_default_decoder_parameters(&(parameters->core));
-  }
+      /* default decoding parameters (core) */
+      opj_set_default_decoder_parameters(&(parameters->core));
+    }
 }
 
 void jp2IO::destroy_parameters(opj_decompress_parameters* parameters)
 {
   if (parameters) {
-    if (parameters->precision) {
-      free(parameters->precision);
-      parameters->precision = NULL;
+      if (parameters->precision) {
+          free(parameters->precision);
+          parameters->precision = NULL;
+        }
     }
-  }
 }
 
 QImage jp2IO::decode(QString fileName)
@@ -156,39 +156,39 @@ QImage jp2IO::decode(QString fileName)
 
   l_stream = opj_stream_create_default_file_stream(fileName.toLatin1(),1);
   if (!l_stream)
-  {
-    qDebug() << "ERROR -> failed to create the stream from the file " << parameters.infile;
-    destroy_parameters(&parameters);
-    return qimage;
-  }
+    {
+      qDebug() << "ERROR -> failed to create the stream from the file " << parameters.infile;
+      destroy_parameters(&parameters);
+      return qimage;
+    }
 
   /* decode the JPEG2000 stream */
   /* ---------------------- */
 
   switch(parameters.decod_format) {
-  case J2K_CFMT:	/* JPEG-2000 codestream */
-  {
-    /* Get a decoder handle */
-    l_codec = opj_create_decompress(OPJ_CODEC_J2K);
-    break;
-  }
-  case JP2_CFMT:	/* JPEG 2000 compressed image data */
-  {
-    /* Get a decoder handle */
-    l_codec = opj_create_decompress(OPJ_CODEC_JP2);
-    break;
-  }
-  case JPT_CFMT:	/* JPEG 2000, JPIP */
-  {
-    /* Get a decoder handle */
-    l_codec = opj_create_decompress(OPJ_CODEC_JPT);
-    break;
-  }
-  default:
-    //      fprintf(stderr, "skipping file..\n");
-    destroy_parameters(&parameters);
-    opj_stream_destroy(l_stream);
-  }
+    case J2K_CFMT:	/* JPEG-2000 codestream */
+      {
+        /* Get a decoder handle */
+        l_codec = opj_create_decompress(OPJ_CODEC_J2K);
+        break;
+      }
+    case JP2_CFMT:	/* JPEG 2000 compressed image data */
+      {
+        /* Get a decoder handle */
+        l_codec = opj_create_decompress(OPJ_CODEC_JP2);
+        break;
+      }
+    case JPT_CFMT:	/* JPEG 2000, JPIP */
+      {
+        /* Get a decoder handle */
+        l_codec = opj_create_decompress(OPJ_CODEC_JPT);
+        break;
+      }
+    default:
+      //      fprintf(stderr, "skipping file..\n");
+      destroy_parameters(&parameters);
+      opj_stream_destroy(l_stream);
+    }
 
   /* catch events using our callbacks and give a local context */
   opj_set_info_handler(l_codec, info_callback,00);
@@ -199,30 +199,17 @@ QImage jp2IO::decode(QString fileName)
 
   /* Setup the decoder decoding parameters using user parameters */
   if ( !opj_setup_decoder(l_codec, &(parameters.core)) ){
-    qDebug() << "ERROR -> opj_decompress: failed to setup the decoder";
-    destroy_parameters(&parameters);
-    opj_stream_destroy(l_stream);
-    opj_destroy_codec(l_codec);
-    return qimage;
-  }
+      qDebug() << "ERROR -> opj_decompress: failed to setup the decoder";
+      destroy_parameters(&parameters);
+      opj_stream_destroy(l_stream);
+      opj_destroy_codec(l_codec);
+      return qimage;
+    }
 
 
   /* Read the main header of the codestream and if necessary the JP2 boxes*/
   if(! opj_read_header(l_stream, l_codec, &jp2Image)){
-    qDebug() << "ERROR -> opj_decompress: failed to read the header";
-    destroy_parameters(&parameters);
-    opj_stream_destroy(l_stream);
-    opj_destroy_codec(l_codec);
-    opj_image_destroy(jp2Image);
-    return qimage;
-  }
-
-  if (!parameters.nb_tile_to_decode)
-  {
-    /* Optional if you want decode the entire image */
-    if (!opj_set_decode_area(l_codec, jp2Image, (OPJ_INT32)parameters.DA_x0,
-                             (OPJ_INT32)parameters.DA_y0, (OPJ_INT32)parameters.DA_x1, (OPJ_INT32)parameters.DA_y1)){
-      qDebug() <<	"ERROR -> opj_decompress: failed to set the decoded area";
+      qDebug() << "ERROR -> opj_decompress: failed to read the header";
       destroy_parameters(&parameters);
       opj_stream_destroy(l_stream);
       opj_destroy_codec(l_codec);
@@ -230,41 +217,30 @@ QImage jp2IO::decode(QString fileName)
       return qimage;
     }
 
-    /* Get the decoded image */
-    if (!(opj_decode(l_codec, l_stream, jp2Image) && opj_end_decompress(l_codec,	l_stream)))
+  if (!parameters.nb_tile_to_decode)
     {
-      qDebug() <<"ERROR -> opj_decompress: failed to decode image!";
-      destroy_parameters(&parameters);
-      opj_destroy_codec(l_codec);
-      opj_stream_destroy(l_stream);
-      opj_image_destroy(jp2Image);
-      return qimage;
+      /* Optional if you want decode the entire image */
+      if (!opj_set_decode_area(l_codec, jp2Image, (OPJ_INT32)parameters.DA_x0,
+                               (OPJ_INT32)parameters.DA_y0, (OPJ_INT32)parameters.DA_x1, (OPJ_INT32)parameters.DA_y1)){
+          qDebug() <<	"ERROR -> opj_decompress: failed to set the decoded area";
+          destroy_parameters(&parameters);
+          opj_stream_destroy(l_stream);
+          opj_destroy_codec(l_codec);
+          opj_image_destroy(jp2Image);
+          return qimage;
+        }
+
+      /* Get the decoded image */
+      if (!(opj_decode(l_codec, l_stream, jp2Image) && opj_end_decompress(l_codec,	l_stream)))
+        {
+          qDebug() <<"ERROR -> opj_decompress: failed to decode image!";
+          destroy_parameters(&parameters);
+          opj_destroy_codec(l_codec);
+          opj_stream_destroy(l_stream);
+          opj_image_destroy(jp2Image);
+          return qimage;
+        }
     }
-  }
-//  else {
-
-//    /* It is just here to illustrate how to use the resolution after set parameters */
-//    /*if (!opj_set_decoded_resolution_factor(l_codec, 5)) {
-//      fprintf(stderr, "ERROR -> opj_decompress: failed to set the resolution factor tile!\n");
-//      opj_destroy_codec(l_codec);
-//      opj_stream_destroy(l_stream);
-//      opj_image_destroy(jp2Image);
-//      return EXIT_FAILURE;
-//    }*/
-
-//    if (!opj_get_decoded_tile(l_codec, l_stream, jp2Image, parameters.tile_index)) {
-//      fprintf(stderr, "ERROR -> opj_decompress: failed to decode tile!\n");
-//      destroy_parameters(&parameters);
-//      opj_destroy_codec(l_codec);
-//      opj_stream_destroy(l_stream);
-//      opj_image_destroy(jp2Image);
-//      return qimage;
-//    }
-//    fprintf(stdout, "tile %d is decoded!\n\n", parameters.tile_index);
-//  }
-
-  //  tCumulative += opj_clock() - t;
-  //  numDecompressedImages++;
 
   /* Close the byte stream */
   opj_stream_destroy(l_stream);
@@ -277,95 +253,46 @@ QImage jp2IO::decode(QString fileName)
     jp2Image->color_space = OPJ_CLRSPC_GRAY;
 
   if(jp2Image->color_space == OPJ_CLRSPC_SYCC){
-    color_sycc_to_rgb(jp2Image);
-  }
+      color_sycc_to_rgb(jp2Image);
+    }
 
   else if(jp2Image->color_space == OPJ_CLRSPC_EYCC){
-    color_esycc_to_rgb(jp2Image);
-  }
+      color_esycc_to_rgb(jp2Image);
+    }
 
   if(jp2Image->icc_profile_buf)
-  {
-    free(jp2Image->icc_profile_buf);
-    jp2Image->icc_profile_buf = NULL; jp2Image->icc_profile_len = 0;
-  }
-
-  //  /* Force output precision */
-  //  /* ---------------------- */
-  //  if (parameters.precision != NULL)
-  //  {
-  //    OPJ_UINT32 compno;
-  //    for (compno = 0; compno < jp2Image->numcomps; ++compno)
-  //    {
-  //      OPJ_UINT32 precno = compno;
-  //      OPJ_UINT32 prec;
-
-  //      if (precno >= parameters.nb_precision) {
-  //        precno = parameters.nb_precision - 1U;
-  //      }
-
-  //      prec = parameters.precision[precno].prec;
-  //      if (prec == 0) {
-  //        prec = jp2Image->comps[compno].prec;
-  //      }
-
-  //      switch (parameters.precision[precno].mode) {
-  //        case OPJ_PREC_MODE_CLIP:
-  //          clip_component(&(jp2Image->comps[compno]), prec);
-  //          break;
-  //        case OPJ_PREC_MODE_SCALE:
-  //          scale_component(&(jp2Image->comps[compno]), prec);
-  //          break;
-  //        default:
-  //          break;
-  //      }
-
-  //    }
-  //  }
-
-  //  /* Upsample components */
-  //  /* ------------------- */
-  //  if (parameters.upsample)
-  //  {
-  //    jp2Image = upsample_image_components(jp2Image);
-  //    if (jp2Image == NULL) {
-  //      fprintf(stderr, "ERROR -> opj_decompress: failed to upsample image components!\n");
-  //      destroy_parameters(&parameters);
-  //      opj_destroy_codec(l_codec);
-  //      return EXIT_FAILURE;
-  //    }
-  //  }
+    {
+      free(jp2Image->icc_profile_buf);
+      jp2Image->icc_profile_buf = NULL; jp2Image->icc_profile_len = 0;
+    }
 
   /* Force RGB output */
   /* ---------------- */
   if (parameters.force_rgb)
-  {
-    switch (jp2Image->color_space) {
-    case OPJ_CLRSPC_SRGB:
-      break;
-    case OPJ_CLRSPC_GRAY:
-      jp2Image = convert_gray_to_rgb(jp2Image);
-      break;
-    default:
-      fprintf(stderr, "ERROR -> opj_decompress: don't know how to convert image to RGB colorspace!\n");
-      opj_image_destroy(jp2Image);
-      jp2Image = NULL;
-      break;
-    }
-    if (jp2Image == NULL) {
-      fprintf(stderr, "ERROR -> opj_decompress: failed to convert to RGB image!\n");
-      destroy_parameters(&parameters);
-      opj_destroy_codec(l_codec);
-      return qimage;
+    {
+      switch (jp2Image->color_space) {
+        case OPJ_CLRSPC_SRGB:
+        break;
+        case OPJ_CLRSPC_GRAY:
+          jp2Image = convert_gray_to_rgb(jp2Image);
+        break;
+        default:
+          fprintf(stderr, "ERROR -> opj_decompress: don't know how to convert image to RGB colorspace!\n");
+          opj_image_destroy(jp2Image);
+          jp2Image = NULL;
+        break;
+        }
+      if (jp2Image == NULL) {
+          fprintf(stderr, "ERROR -> opj_decompress: failed to convert to RGB image!\n");
+          destroy_parameters(&parameters);
+          opj_destroy_codec(l_codec);
+          return qimage;
+        }
     }
-  }
-
-
-
   // decode image width and height
   width = jp2Image->comps[0].w;
   wr = int_ceildivpow2(jp2Image->comps[0].w, jp2Image->comps[0].factor);
-//  height = jp2Image->comps[0].h;
+  //  height = jp2Image->comps[0].h;
   hr = int_ceildivpow2(jp2Image->comps[0].h, jp2Image->comps[0].factor);
 
   // alloc memory for a new image
@@ -374,21 +301,24 @@ QImage jp2IO::decode(QString fileName)
   // get a pointer to the first pixel data in result image
   QRgb *bits = (QRgb *)qimage.bits();
   for(int i = 0; i < wr * hr; i++) {
-    unsigned char R, G, B;
+      unsigned char R, G, B;
 
-    // calculate coords
-    int x = (i) % (wr);
-    //     int y = height - (i) / (wr) - 1;
-    int y = (i) / (wr);
+      // calculate coords
+      int x = (i) % (wr);
+      //     int y = height - (i) / (wr) - 1;
+      int y = (i) / (wr);
 #define idx( _x, _y ) ( _x + _y * width )
 
-    R = jp2Image->comps[0].data[ idx( x, y ) ];
-    G = jp2Image->comps[1].data[ idx( x, y ) ];
-    B = jp2Image->comps[2].data[ idx( x, y ) ];
+      R = jp2Image->comps[0].data[ idx( x, y ) ];
+      G = jp2Image->comps[1].data[ idx( x, y ) ];
+      B = jp2Image->comps[2].data[ idx( x, y ) ];
 
-    // fill the bit with read pallete
-    bits[i] = qRgb(R, G, B);
-  }
+      // fill the bit with read pallete
+      bits[i] = qRgb(R, G, B);
+    }
+  destroy_parameters(&parameters);
+  opj_destroy_codec(l_codec);
+  opj_image_destroy(jp2Image);
   return qimage;
 }
 
@@ -400,10 +330,10 @@ opj_image_t *jp2IO::convert_gray_to_rgb(opj_image_t* original)
 
   l_new_components = (opj_image_cmptparm_t*)malloc((original->numcomps + 2U) * sizeof(opj_image_cmptparm_t));
   if (l_new_components == NULL) {
-    fprintf(stderr, "ERROR -> opj_decompress: failed to allocate memory for RGB image!\n");
-    opj_image_destroy(original);
-    return NULL;
-  }
+      fprintf(stderr, "ERROR -> opj_decompress: failed to allocate memory for RGB image!\n");
+      opj_image_destroy(original);
+      return NULL;
+    }
 
   l_new_components[0].bpp  = l_new_components[1].bpp  = l_new_components[2].bpp  = original->comps[0].bpp;
   l_new_components[0].dx   = l_new_components[1].dx   = l_new_components[2].dx   = original->comps[0].dx;
@@ -416,24 +346,24 @@ opj_image_t *jp2IO::convert_gray_to_rgb(opj_image_t* original)
   l_new_components[0].y0   = l_new_components[1].y0   = l_new_components[2].y0   = original->comps[0].y0;
 
   for(compno = 1U; compno < original->numcomps; ++compno) {
-    l_new_components[compno+2U].bpp  = original->comps[compno].bpp;
-    l_new_components[compno+2U].dx   = original->comps[compno].dx;
-    l_new_components[compno+2U].dy   = original->comps[compno].dy;
-    l_new_components[compno+2U].h    = original->comps[compno].h;
-    l_new_components[compno+2U].w    = original->comps[compno].w;
-    l_new_components[compno+2U].prec = original->comps[compno].prec;
-    l_new_components[compno+2U].sgnd = original->comps[compno].sgnd;
-    l_new_components[compno+2U].x0   = original->comps[compno].x0;
-    l_new_components[compno+2U].y0   = original->comps[compno].y0;
-  }
+      l_new_components[compno+2U].bpp  = original->comps[compno].bpp;
+      l_new_components[compno+2U].dx   = original->comps[compno].dx;
+      l_new_components[compno+2U].dy   = original->comps[compno].dy;
+      l_new_components[compno+2U].h    = original->comps[compno].h;
+      l_new_components[compno+2U].w    = original->comps[compno].w;
+      l_new_components[compno+2U].prec = original->comps[compno].prec;
+      l_new_components[compno+2U].sgnd = original->comps[compno].sgnd;
+      l_new_components[compno+2U].x0   = original->comps[compno].x0;
+      l_new_components[compno+2U].y0   = original->comps[compno].y0;
+    }
 
   l_new_image = opj_image_create(original->numcomps + 2U, l_new_components, OPJ_CLRSPC_SRGB);
   free(l_new_components);
   if (l_new_image == NULL) {
-    fprintf(stderr, "ERROR -> opj_decompress: failed to allocate memory for RGB image!\n");
-    opj_image_destroy(original);
-    return NULL;
-  }
+      fprintf(stderr, "ERROR -> opj_decompress: failed to allocate memory for RGB image!\n");
+      opj_image_destroy(original);
+      return NULL;
+    }
 
   l_new_image->x0 = original->x0;
   l_new_image->x1 = original->x1;
@@ -449,11 +379,11 @@ opj_image_t *jp2IO::convert_gray_to_rgb(opj_image_t* original)
   memcpy(l_new_image->comps[2].data, original->comps[0].data, original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32));
 
   for(compno = 1U; compno < original->numcomps; ++compno) {
-    l_new_image->comps[compno+2U].factor        = original->comps[compno].factor;
-    l_new_image->comps[compno+2U].alpha         = original->comps[compno].alpha;
-    l_new_image->comps[compno+2U].resno_decoded = original->comps[compno].resno_decoded;
-    memcpy(l_new_image->comps[compno+2U].data, original->comps[compno].data, original->comps[compno].w * original->comps[compno].h * sizeof(OPJ_INT32));
-  }
+      l_new_image->comps[compno+2U].factor        = original->comps[compno].factor;
+      l_new_image->comps[compno+2U].alpha         = original->comps[compno].alpha;
+      l_new_image->comps[compno+2U].resno_decoded = original->comps[compno].resno_decoded;
+      memcpy(l_new_image->comps[compno+2U].data, original->comps[compno].data, original->comps[compno].w * original->comps[compno].h * sizeof(OPJ_INT32));
+    }
   opj_image_destroy(original);
   return l_new_image;
 }
@@ -462,7 +392,7 @@ QByteArray jp2IO::encode(QImage qimage, QImage &newImage,int &fileSize, int comp
 {
   QByteArray byteArray;
   QString fn=QString("%1/%2").arg(QDir::tempPath()).arg("qsstv.tmp");
-//  char *of=fn.toLatin1().data();
+  //  char *of=fn.toLatin1().data();
   bool success;
   init();
   fileSize=0;
@@ -471,22 +401,21 @@ QByteArray jp2IO::encode(QImage qimage, QImage &newImage,int &fileSize, int comp
   createImage(qimage);
   cparameters.cod_format=JP2_CFMT;
   if(opj_strcpy_s(cparameters.outfile, sizeof(cparameters.outfile), fn.toLatin1().data()) != 0)
-
-  {
-    return byteArray;
-  }
+    {
+      return byteArray;
+    }
   raw_cp.rawBitDepth = 0;
   raw_cp.rawComp = 0;
   raw_cp.rawComps = 0;
   raw_cp.rawHeight = 0;
   raw_cp.rawSigned = 0;
   raw_cp.rawWidth = 0;
-  cparameters.tcp_mct = (char) 255; // This will be set later according to the input image or the provided option
+  //  cparameters.tcp_mct = (char) 255; // This will be set later according to the input image or the provided option
   cparameters.tcp_mct = (jp2Image->numcomps >= 3) ? 1 : 0;
 
-   cparameters.tcp_rates[0] = compressionRatio;	/* MOD antonin : losslessbug */
-    cparameters.tcp_numlayers++;
-    cparameters.cp_disto_alloc = 1;
+  cparameters.tcp_rates[0] = compressionRatio;	/* MOD antonin : losslessbug */
+  cparameters.tcp_numlayers++;
+  cparameters.cp_disto_alloc = 1;
   l_codec = opj_create_compress(OPJ_CODEC_JP2);
   /* catch events using our callbacks and give a local context */
   opj_set_info_handler(l_codec, info_callback,00);
@@ -496,45 +425,46 @@ QByteArray jp2IO::encode(QImage qimage, QImage &newImage,int &fileSize, int comp
 
 
   if (! opj_setup_encoder(l_codec, &cparameters, jp2Image))
-  {
-    addToLog("failed to encode image: opj_setup_encoder",LOGIMAG);
-    opj_destroy_codec(l_codec);
-    opj_image_destroy(jp2Image);
-    return byteArray;
-
-  }
+    {
+      addToLog("failed to encode image: opj_setup_encoder",LOGIMAG);
+      opj_destroy_codec(l_codec);
+      opj_image_destroy(jp2Image);
+      return byteArray;
+    }
 
   l_stream = opj_stream_create_default_file_stream(cparameters.outfile,OPJ_FALSE);
   if (! l_stream)
-  {
-    return byteArray;
-  }
+    {
+      opj_destroy_codec(l_codec);
+      opj_image_destroy(jp2Image);
+      return byteArray;
+    }
   /* encode the image */
   success = opj_start_compress(l_codec,jp2Image,l_stream);
   if (!success)
-  {
-    addToLog("failed to encode image: opj_start_compress",LOGIMAG);
-  }
+    {
+      addToLog("failed to encode image: opj_start_compress",LOGIMAG);
+    }
   success = success && opj_encode(l_codec, l_stream);
   if (!success)
-  {
-    addToLog("failed to encode image: opj_encode",LOGIMAG);
-  }
+    {
+      addToLog("failed to encode image: opj_encode",LOGIMAG);
+    }
   success = success && opj_end_compress(l_codec, l_stream);
   if (!success)
-  {
-    addToLog("failed to encode image: opj_end_compress",LOGIMAG);
-  }
+    {
+      addToLog("failed to encode image: opj_end_compress",LOGIMAG);
+    }
 
   if (!success)
-  {
-    opj_stream_destroy(l_stream);
-    opj_destroy_codec(l_codec);
-    opj_image_destroy(jp2Image);
-    addToLog("failed to encode image",LOGIMAG);
-    remove(parameters.outfile);
-    return byteArray;
-  }
+    {
+      opj_stream_destroy(l_stream);
+      opj_destroy_codec(l_codec);
+      opj_image_destroy(jp2Image);
+      addToLog("failed to encode image",LOGIMAG);
+      remove(parameters.outfile);
+      return byteArray;
+    }
 
   opj_stream_destroy(l_stream);
   opj_destroy_codec(l_codec);
@@ -546,14 +476,15 @@ QByteArray jp2IO::encode(QImage qimage, QImage &newImage,int &fileSize, int comp
   if(raw_cp.rawComps) free(raw_cp.rawComps);
   QFile fi(fn);
   if(fi.open(QIODevice::ReadOnly))
-  {
-    byteArray=fi.readAll();
-    fileSize=byteArray.count();
-  }
+    {
+      byteArray=fi.readAll();
+      fileSize=byteArray.count();
+    }
   fi.close();
   check(fn);
   newImage=decode(fn);
   fi.remove();
+  remove(parameters.outfile);
   return byteArray;
 }
 
@@ -564,22 +495,22 @@ bool jp2IO::createImage(QImage qimage)
   opj_image_cmptparm_t cmptparm[4];	/* maximum of 4 components */
   memset(&cmptparm[0], 0, sizeof(cmptparm));
   for(i = 0; i < 4; i++)
-  {
-    cmptparm[i].prec = 8;
-    cmptparm[i].bpp  = 8;
-    cmptparm[i].sgnd = 0;
-    cmptparm[i].dx   = (OPJ_UINT32)cparameters.subsampling_dx;
-    cmptparm[i].dy   = (OPJ_UINT32)cparameters.subsampling_dy;
-    cmptparm[i].w    = qimage.width();
-    cmptparm[i].h    = qimage.height();
-  }
+    {
+      cmptparm[i].prec = 8;
+      cmptparm[i].bpp  = 8;
+      cmptparm[i].sgnd = 0;
+      cmptparm[i].dx   = (OPJ_UINT32)cparameters.subsampling_dx;
+      cmptparm[i].dy   = (OPJ_UINT32)cparameters.subsampling_dy;
+      cmptparm[i].w    = qimage.width();
+      cmptparm[i].h    = qimage.height();
+    }
 
   jp2Image = opj_image_create(numcmpts, &cmptparm[0],OPJ_CLRSPC_SRGB);
   if(!jp2Image) return false;
   if (numcmpts == 4)
-  {
-    jp2Image->comps[3].alpha = 1;
-  }
+    {
+      jp2Image->comps[3].alpha = 1;
+    }
 
   /* set image offset and reference grid */
   jp2Image->x0 = (OPJ_UINT32)cparameters.image_offset_x0;
@@ -597,16 +528,16 @@ bool jp2IO::createImage(QImage qimage)
   int x,y;
   bits= (QRgb *)qimage.bits();
   for(y = 0; y < height; y++)
-  {
-    for(x = 0; x < width; x++)
     {
-      color=bits[x+y* width];
-      jp2Image->comps[0].data[index] = (OPJ_INT32)qRed(color);	/* R */
-      jp2Image->comps[1].data[index] = (OPJ_INT32)qGreen(color);	/* G */
-      jp2Image->comps[2].data[index] = (OPJ_INT32)qBlue(color);	/* B */
-      index++;
+      for(x = 0; x < width; x++)
+        {
+          color=bits[x+y* width];
+          jp2Image->comps[0].data[index] = (OPJ_INT32)qRed(color);	/* R */
+          jp2Image->comps[1].data[index] = (OPJ_INT32)qGreen(color);	/* G */
+          jp2Image->comps[2].data[index] = (OPJ_INT32)qBlue(color);	/* B */
+          index++;
+        }
     }
-  }
   return true;
 }
 
diff --git a/qsstv/utils/logging.h b/qsstv/utils/logging.h
index 1f82a40..b874bab 100644
--- a/qsstv/utils/logging.h
+++ b/qsstv/utils/logging.h
@@ -17,10 +17,8 @@
 #define errorOut() qDebug()
 #ifdef ENABLELOGGING
 #define addToLog(x,y) logFilePtr->add(__FILE__,__func__,__LINE__,x,y)
-
 #else
-//#define addToLog(x,y) logFilePtr->dummyAdd(x,y) // to avoid parameter not used warnings
-#define addToLog(x,y) {} // to avoid parameter not used warnings
+#define addToLog(x,y) {}
 #endif
 
 class QTextStream;
diff --git a/qsstv/videocapt/cameradialog.cpp b/qsstv/videocapt/cameradialog.cpp
index cdd88b5..4c11854 100644
--- a/qsstv/videocapt/cameradialog.cpp
+++ b/qsstv/videocapt/cameradialog.cpp
@@ -42,11 +42,17 @@ cameraDialog::cameraDialog(QWidget *parent) :
   ui(new Ui::cameraDialog)
 {
   ui->setupUi(this);
+  cameraActive=false;
+  videoCapturePtr=NULL;
   listCameraDevices();
+  if(cameraList.count()==0)
+  {
+      return;
+  }
   connect(ui->settingsButton,SIGNAL(clicked()),SLOT(slotSettings()));
   ui->devicesComboBox->setCurrentIndex(0);
   imageSettings settingsDialog(cameraList.at(0).deviceName);
-  cameraActive=false;
+
   videoCapturePtr=new videoCapture;
   connect(ui->devicesComboBox,SIGNAL(currentIndexChanged(int)),SLOT(slotDeviceChanged(int)));
   connect(ui->formatsComboBox,SIGNAL(currentIndexChanged(int)),SLOT(slotFormatChanged(int)));
@@ -113,7 +119,7 @@ void cameraDialog::listCameraDevices()
     {
       ui->devicesComboBox->addItem(cameraList.at(i).deviceDescription);
     }
-  setupFormatComboBox(cameraList.at(0));
+  if(cameraList.count()>0) setupFormatComboBox(cameraList.at(0));
 }
 
 
@@ -253,6 +259,7 @@ void cameraDialog::slotSizeChanged(int idx)
 
 bool cameraDialog::restartCapturing(bool first)
 {
+    if(!videoCapturePtr) return false;
   if(!first)
     {
       killTimer(timerID);
diff --git a/qsstv/widgets/drmsegmentsview.ui b/qsstv/widgets/drmsegmentsview.ui
index 227e4ae..f02ba7c 100644
--- a/qsstv/widgets/drmsegmentsview.ui
+++ b/qsstv/widgets/drmsegmentsview.ui
@@ -21,16 +21,16 @@
     <number>0</number>
    </property>
    <property name="leftMargin">
-    <number>1</number>
+    <number>0</number>
    </property>
    <property name="topMargin">
-    <number>1</number>
+    <number>0</number>
    </property>
    <property name="rightMargin">
-    <number>1</number>
+    <number>0</number>
    </property>
    <property name="bottomMargin">
-    <number>1</number>
+    <number>0</number>
    </property>
    <item>
     <widget class="QLabel" name="drmSegmentLabel">
@@ -38,10 +38,10 @@
       <enum>QFrame::Box</enum>
      </property>
      <property name="frameShadow">
-      <enum>QFrame::Sunken</enum>
+      <enum>QFrame::Plain</enum>
      </property>
      <property name="lineWidth">
-      <number>3</number>
+      <number>2</number>
      </property>
      <property name="text">
       <string>TextLabel</string>
diff --git a/qsstv/widgets/extviewer.cpp b/qsstv/widgets/extviewer.cpp
index 135e7e6..cbea02f 100644
--- a/qsstv/widgets/extviewer.cpp
+++ b/qsstv/widgets/extviewer.cpp
@@ -8,6 +8,7 @@ extViewer::extViewer(QWidget *parent) :   QDialog(parent),   ui(new Ui::extViewe
   ui->setupUi(this);
   activeMovie=false;
   setModal(false);
+  setWindowState(Qt::WindowMaximized);
 }
 
 extViewer::~extViewer()
@@ -21,6 +22,7 @@ void extViewer::setup(QString fn)
   int fw,fh;
   // we want the original image
   ui->imViewer->stretch=true;
+  ui->imViewer->setType(imageViewer::EXTVIEW);
   ui->imViewer->openImage(fn,false,false,false);
   fileName=fn;
   QFileInfo fi(fn);
diff --git a/qsstv/widgets/fftdisplay.cpp b/qsstv/widgets/fftdisplay.cpp
index 56cb4a1..77dea74 100644
--- a/qsstv/widgets/fftdisplay.cpp
+++ b/qsstv/widgets/fftdisplay.cpp
@@ -158,7 +158,33 @@ void fftDisplay::showFFT(double *fftData)
 }
 
 
+void fftDisplay::drawMarkers(QPainter *painter, int top, int bot)
+{
+  painter->drawLine((((marker1-FFTLOW)*imWidth)/FFTSPAN),top,(((marker1-FFTLOW)*imWidth)/FFTSPAN),bot);
+  painter->drawLine((((marker2-FFTLOW)*imWidth)/FFTSPAN),top,(((marker2-FFTLOW)*imWidth)/FFTSPAN),bot);
+  painter->drawLine((((marker3-FFTLOW)*imWidth)/FFTSPAN),top,(((marker3-FFTLOW)*imWidth)/FFTSPAN),bot);
+}
 
+QImage *fftDisplay::getImage()
+{
+  QImage *im = new QImage(width(),height()+10,QImage::Format_RGB32);
+  QPainter p(im);
+  QPen pn;
+  if (!showWaterfall) {
+     }
+  else {
+     if (imagePtr) {
+        im->fill(Qt::black);
+        p.drawImage(0,5,*imagePtr);
+        pn.setColor(Qt::red);
+        pn.setWidth(3);
+        p.setPen(pn);
+        drawMarkers(&p,0,4);
+        drawMarkers(&p,height()+5,height()+9);
+        }
+     }
+  return im;
+}
 
 void fftDisplay::paintEvent(QPaintEvent *p)
 {
@@ -170,9 +196,7 @@ void fftDisplay::paintEvent(QPaintEvent *p)
       pn.setColor(Qt::red);
       pn.setWidth(1);
       painter.setPen(pn);
-      painter.drawLine((((marker1-FFTLOW)*imWidth)/FFTSPAN),0,(((marker1-FFTLOW)*imWidth)/FFTSPAN),imHeight);
-      painter.drawLine((((marker2-FFTLOW)*imWidth)/FFTSPAN),0,(((marker2-FFTLOW)*imWidth)/FFTSPAN),imHeight);
-      painter.drawLine((((marker3-FFTLOW)*imWidth)/FFTSPAN),0,(((marker3-FFTLOW)*imWidth)/FFTSPAN),imHeight);
+      drawMarkers(&painter,0,imHeight);
       pn.setColor(Qt::green);
       painter.setPen(pn);
       painter.drawPolyline(*fftArray);
@@ -187,4 +211,3 @@ void fftDisplay::paintEvent(QPaintEvent *p)
     }
   QLabel::paintEvent(p);
 }
-
diff --git a/qsstv/widgets/fftdisplay.h b/qsstv/widgets/fftdisplay.h
index 0b48eb4..c867812 100644
--- a/qsstv/widgets/fftdisplay.h
+++ b/qsstv/widgets/fftdisplay.h
@@ -31,11 +31,12 @@ public:
   void displayWaterfall(bool wf) {showWaterfall=wf;}
   void setMarkers(int mrk1=0, int mrk2=0, int mrk3=0);
   void setAvg(double d) {avgVal=d;}
+  QImage *getImage();
 
 private:
-
+  void drawMarkers(QPainter *painter, int top, int bot);
   void paintEvent(QPaintEvent *p);
-//  void mousePressEvent( QMouseEvent *e );
+  //  void mousePressEvent( QMouseEvent *e );
   int windowSize;
   int fftLength;
   int samplingrate;
@@ -43,13 +44,13 @@ private:
   double *arMagWAvg;
   double maxMagnitude;
   QPolygon *fftArray;
-//  bool ready;
+  //  bool ready;
   bool showWaterfall;
   double fftMax;
   double range;
   QImage *imagePtr;
   QImage scaledImage;
-//  void setSize(int w,int h);
+  //  void setSize(int w,int h);
   QMutex mutex;
   int marker1;
   int marker2;
diff --git a/qsstv/widgets/imageviewer.cpp b/qsstv/widgets/imageviewer.cpp
index e308442..9e444d0 100644
--- a/qsstv/widgets/imageviewer.cpp
+++ b/qsstv/widgets/imageviewer.cpp
@@ -58,7 +58,7 @@ imageViewer::imageViewer(QWidget *parent): QLabel(parent)
   setPalette(palette);
   setBackgroundRole(QPalette::Base);
   setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
-
+  setAspectMode(Qt::IgnoreAspectRatio);
   setBackgroundRole(QPalette::Dark);
 
   popup=new QMenu (this);
@@ -72,13 +72,22 @@ imageViewer::imageViewer(QWidget *parent): QLabel(parent)
   connect(editAct, SIGNAL(triggered()), this, SLOT(slotEdit()));
   printAct = new QAction(tr("&Print"), this);
   connect(printAct, SIGNAL(triggered()), this, SLOT(slotPrint()));
+  uploadAct = new QAction(tr("&Upload to FTP"), this);
+  connect(uploadAct, SIGNAL(triggered()), this, SLOT(slotUploadFTP()));
   deleteAct = new QAction(tr("&Delete"), this);
   connect(deleteAct, SIGNAL(triggered()), this, SLOT(slotDelete()));
   viewAct = new QAction(tr("&View"), this);
   connect(viewAct, SIGNAL(triggered()), this, SLOT(slotView()));
   propertiesAct = new QAction(tr("Propert&ies"), this);
   connect(propertiesAct, SIGNAL(triggered()), this, SLOT(slotProperties()));
+  zoomInAct = new QAction(tr("Zoom In (&+)"), this);
+  connect(zoomInAct, SIGNAL(triggered()), this, SLOT(slotZoomIn()));
+  zoomOutAct = new QAction(tr("Zoom Out (&-)"), this);
+  connect(zoomOutAct, SIGNAL(triggered()), this, SLOT(slotZoomOut()));
   connect(configDialogPtr,SIGNAL(bgColorChanged()), SLOT(slotBGColorChanged()));
+  clickTimer.setSingleShot(true);
+  clickTimer.setInterval(40);
+  connect(&clickTimer, SIGNAL(timeout()), this, SLOT(slotLeftClick()));
 
   init(RXIMG);
   activeMovie=false;
@@ -114,120 +123,117 @@ bool imageViewer::openImage(QString &filename,QString start,bool ask,bool showMe
   bool success=false;
   bool cacheHit=false;
 
-
-
   if(activeMovie)
-  {
-    activeMovie=false;
-    qm.stop();
-  }
+    {
+      activeMovie=false;
+      qm.stop();
+    }
   if (filename.isEmpty()&&!ask) return false;
   if(ask)
-  {
-    dirDialog dd((QWidget *)this,"Browse");
-    filename=dd.openFileName(start,"*");
-  }
-  if(filename.isEmpty())
-  {
-    imageFileName="";
-    return false;
-  }
-
-  if(fromCache)
-  {
-    cacheFileName=finf.absolutePath()+"/cache/"+finf.baseName()+finf.created().toString()+".png";
-    if(tempImage.load(cacheFileName))
     {
-      cacheHit=true;
-      success=true;
-      orgWidth=tempImage.text("orgWidth").toInt();
-      orgHeight=tempImage.text("orgHeight").toInt();
+      dirDialog dd((QWidget *)this,"Browse");
+      filename=dd.openFileName(start,"*");
     }
-  }
-  if(!success)
-  {
-    if(tempImage.load(filename))
+  if(filename.isEmpty())
     {
-      success=true;
+      imageFileName="";
+      return false;
     }
-    else if(ed.load(fi))
+
+  if(fromCache)
     {
-      success=true;
-      tempImage=QImage(ed.renderImage(0,0)->copy());
+      cacheFileName=finf.absolutePath()+"/cache/"+finf.baseName()+finf.created().toString()+".png";
+      if(tempImage.load(cacheFileName))
+        {
+          cacheHit=true;
+          success=true;
+          orgWidth=tempImage.text("orgWidth").toInt();
+          orgHeight=tempImage.text("orgHeight").toInt();
+        }
     }
-    else if(jp2.check(filename))
+  if(!success)
     {
-      tempImage=jp2.decode(filename);
-      if(!tempImage.isNull())
-      {
-        success=true;
-      }
+      if(jp2.check(filename))
+        {
+          tempImage=jp2.decode(filename);
+          if(!tempImage.isNull())
+            {
+              success=true;
+            }
+        }
+      else if(tempImage.load(filename))
+        {
+          success=true;
+        }
+      else if(ed.load(fi))
+        {
+          success=true;
+          tempImage=QImage(ed.renderImage(0,0)->copy());
+        }
     }
-  }
-
   if(!success)
-  {
-    if(showMessage)
     {
-      stmb= new displayMBoxEvent("Image Loader",QString("Unable to load image:\n%1").arg(filename));
-      QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
+      if(showMessage)
+        {
+          stmb= new displayMBoxEvent("Image Loader",QString("Unable to load image:\n%1").arg(filename));
+          QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
+        }
+      validImage=false;
+      imageFileName="";
+      return false;
     }
-    validImage=false;
-    imageFileName="";
-    return false;
-  }
 
   if(fromCache)
-  {
-    sourceImage=QImage();
-
-    if(!cacheHit)
     {
+      sourceImage=QImage();
+
+      if(!cacheHit)
+        {
+          orgWidth=tempImage.width();
+          orgHeight=tempImage.height();
+          tempImage=tempImage.scaledToWidth(120, Qt::FastTransformation);
+          // save cacheImage for next time
+          tempImage.setText("orgWidth",QString::number(orgWidth));
+          tempImage.setText("orgHeight",QString::number(orgHeight));
+          tempImage.save(cacheFileName,"PNG");
+        }
+      stretch=true;
+      displayedImage=tempImage;
+    }
+  else
+    {
+      sourceImage=tempImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
       orgWidth=tempImage.width();
       orgHeight=tempImage.height();
-      tempImage=tempImage.scaledToWidth(120, Qt::FastTransformation);
-      // save cacheImage for next time
-      tempImage.setText("orgWidth",QString::number(orgWidth));
-      tempImage.setText("orgHeight",QString::number(orgHeight));
-      tempImage.save(cacheFileName,"PNG");
-    }
-    stretch=true;
-    displayedImage=tempImage;
-  }
-  else
-  {
-    sourceImage=tempImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
-    orgWidth=tempImage.width();
-    orgHeight=tempImage.height();
-    displayedImage=sourceImage;
-  }
-
+      displayedImage=sourceImage;
+    }
+  view=QRect();
   imageFileName=filename;
 
   QFileInfo finfo(filename);
   if (finfo.suffix().toLower()=="gif")
-  {
-    //we will try a animated gif
-    qm.setFileName(filename);
-    if(qm.isValid())
-    {
-      if(qm.frameCount()>1)
-      {
-        activeMovie=true;
-        setMovie(&qm);
-        qm.start();
-        displayedImage=QImage();
-      }
-      else
-      {
-        displayImage();  // we have a single image gif
-      }
+    {
+      //we will try a animated gif
+      qm.setFileName(filename);
+      if(qm.isValid())
+        {
+          if(qm.frameCount()>1)
+            {
+              activeMovie=true;
+              setMovie(&qm);
+              qm.start();
+              displayedImage=QImage();
+            }
+          else
+            {
+              displayImage();  // we have a single image gif
+            }
+        }
     }
-  }
   else
-  {
-    displayImage();
-  }
+    {
+      displayImage();
+    }
   validImage=true;
   if (emitSignal) emit imageChanged();
   return true;
@@ -242,13 +248,14 @@ bool imageViewer::openImage(QImage im)
 {
   imageFileName="";
   if(!im.isNull())
-  {
-    validImage=true;
-    sourceImage=im;
-    displayedImage=im;
-    displayImage();
-    return true;
-  }
+    {
+      validImage=true;
+      sourceImage=im;
+      displayedImage=im;
+      compressedImageData.clear();
+      displayImage();
+      return true;
+    }
   validImage=false;
   return false;
 }
@@ -259,9 +266,9 @@ bool imageViewer::openImage(QByteArray *ba)
   QBuffer buffer(ba);
   buffer.open(QIODevice::ReadOnly);
   if(tempImage.load(&buffer,NULL))
-  {
-    return  openImage(tempImage.convertToFormat(QImage::Format_ARGB32_Premultiplied));
-  }
+    {
+      return  openImage(tempImage.convertToFormat(QImage::Format_ARGB32_Premultiplied));
+    }
   validImage=false;
   return false;
 }
@@ -272,6 +279,8 @@ void imageViewer::clear()
   imageFileName.clear();
   sourceImage=QImage();
   displayedImage=QImage();
+  compressedImageData.clear();
+  view=QRect();
   setPixmap(QPixmap());
   targetWidth=0;
   targetHeight=0;
@@ -289,10 +298,10 @@ void imageViewer::createImage(QSize sz,QColor fill,bool scale)
   clear();
   displayedImage=QImage(sz,QImage::Format_ARGB32_Premultiplied);
   if(!displayedImage.isNull())
-  {
-    displayedImage.fill(fill.rgb());
-    useCompression=false;
-  }
+    {
+      displayedImage.fill(fill.rgb());
+      useCompression=false;
+    }
   stretch=scale;
   displayImage();
   emit imageChanged();
@@ -317,139 +326,254 @@ QRgb *imageViewer::getScanLineAddress(int line)
 void imageViewer::displayImage()
 {
   if(displayedImage.isNull())
-  {
-    return;
-  }
-  if(hasScaledContents() || (displayedImage.width()>width()) || (displayedImage.height()>height()) || stretch)
-  {
-    QPixmap mp;
-    mp=QPixmap::fromImage(displayedImage.scaled(width()-2,height()-2,Qt::KeepAspectRatio,Qt::SmoothTransformation));
-    setPixmap(QPixmap::fromImage(displayedImage.scaled(width()-2,height()-2,Qt::KeepAspectRatio,Qt::SmoothTransformation)));
-//    qDebug()<< "mp size" << mp.width() << mp.height() << hasScaledContents() << "display width" << width() << height() << imageFileName;
-  }
-  else
-  {
-//    qDebug()<< "xy" << width() << height() << hasScaledContents();
+    {
+      return;
+    }
+  if (view.isNull()) {
+      if(hasScaledContents() || (displayedImage.width()>width()) || (displayedImage.height()>height()) || stretch)
+        {
+          QPixmap mp;
+          mp=QPixmap::fromImage(displayedImage.scaled(width()-2,height()-2,Qt::KeepAspectRatio,Qt::SmoothTransformation));
+          setPixmap(QPixmap::fromImage(displayedImage.scaled(width()-2,height()-2,Qt::KeepAspectRatio,Qt::SmoothTransformation)));
+          //    qDebug()<< "mp size" << mp.width() << mp.height() << hasScaledContents() << "display width" << width() << height() << imageFileName;
+        }
+      else
+        {
+          //    qDebug()<< "xy" << width() << height() << hasScaledContents();
+          setPixmap(QPixmap::fromImage(displayedImage));
+        }
+    }
+  else {
+      QImage im = displayedImage.copy(view);
+      setPixmap(QPixmap::fromImage(im.scaled(width()-2,height()-2,Qt::KeepAspectRatio,Qt::SmoothTransformation)));
+    }
+}
+
+void imageViewer::zoom(const QPoint centre, int dlevel)
+{
+  addToLog(QString("centre=%1,%2 dlevel=%3").arg(centre.x()).arg(centre.y()).arg(dlevel),LOGIMAG);
+  if (view.isNull()) {
+      view=displayedImage.rect();
+    }
 
-    setPixmap(QPixmap::fromImage(displayedImage));
-  }
+  while ((dlevel!=0) && (view.width()<=displayedImage.width())) {
+      if (dlevel>0) {
+          // halve the size of the viewed area
+          if ((view.width()>300) && (view.height()>300)) {
+              addToLog("zoom in",LOGIMAG);
+              view.adjust(+view.width()/4, +view.height()/4, -view.width()/4, -view.height()/4);
+            }
+          dlevel--;
+        }
+      else {
+          // double the size of the viewed area
+          addToLog("zoom out",LOGIMAG);
+          view.adjust(-view.width()/2, -view.height()/2, +view.width()/2, +view.height()/2);
+          dlevel++;
+        }
+    }
 
+  if ((view.width()  > displayedImage.width()) ||
+      (view.height() > displayedImage.height())
+      ) {
+      view=displayedImage.rect();
+    }
+  else {
+      view.moveCenter(centre);
+
+      // ensure the view is within the image
+      if (view.x()<0) view.moveLeft(0);
+      if (view.y()<0) view.moveTop(0);
+      if (view.x()+view.width() > displayedImage.width()) view.moveRight(displayedImage.width());
+      if (view.y()+view.height() > displayedImage.height()) view.moveBottom(displayedImage.height());
+    }
+  addToLog(QString("View:%1,%2,%3,%4").arg(view.x()).arg(view.y()).arg(view.width()).arg(view.height()),LOGIMAG);
+  displayImage();
 }
 
+QPoint imageViewer::mapToImage(const QPoint &pos)
+{
+  QRect cr = contentsRect();
+  cr.adjust(margin(),margin(),-margin(),-margin());
+  QRect aligned = QStyle::alignedRect(QApplication::layoutDirection(), QFlag(alignment()), pixmap()->size(), cr);
+  QRect inter = aligned.intersected(cr);
+
+  QPoint c = pos;
+  c-=inter.topLeft();
 
+  if (view.isNull()) {
+      c.setX(displayedImage.width()  * c.x()/inter.width());
+      c.setY(displayedImage.height() * c.y()/inter.height());
+    }
+  else {
+      c.setX(view.width()  * c.x()/inter.width());
+      c.setY(view.height() * c.y()/inter.height());
+    }
+
+  c+=view.topLeft();
+  return c;
+}
 
 void imageViewer::setType(thumbType tp)
 {
   ttype=tp;
   switch(ttype)
-  {
-  case RXIMG:
-  case PREVIEW:
-  case RXSSTVTHUMB:
-    imageFilePath=rxSSTVImagesPath;
+    {
+    case RXIMG:
+    case EXTVIEW:
+    case PREVIEW:
+    case RXSSTVTHUMB:
+      imageFilePath=rxSSTVImagesPath;
     break;
-  case RXDRMTHUMB:
-    imageFilePath=rxDRMImagesPath;
+    case RXDRMTHUMB:
+      imageFilePath=rxDRMImagesPath;
     break;
 
-  case TXSSTVTHUMB:
-    imageFilePath=txSSTVImagesPath;
+    case TXSSTVTHUMB:
+      imageFilePath=txSSTVImagesPath;
     break;
-  case TXDRMTHUMB:
-    imageFilePath=txDRMImagesPath;
+    case TXDRMTHUMB:
+      imageFilePath=txDRMImagesPath;
     break;
-  case TXIMG:
-  case TXSTOCKTHUMB:
-    imageFilePath=txStockImagesPath;
+    case TXIMG:
+    case TXSTOCKTHUMB:
+      imageFilePath=txStockImagesPath;
     break;
-  case TEMPLATETHUMB:
-    imageFilePath=templatesPath;
+    case TEMPLATETHUMB:
+      imageFilePath=templatesPath;
     break;
 
-  }
+    }
   if((tp==RXSSTVTHUMB) || (tp==RXDRMTHUMB) || (tp==TXSSTVTHUMB) || (tp==TXDRMTHUMB) ||(tp==TXSTOCKTHUMB) ||(tp==TEMPLATETHUMB))
-  {
-    setScaledContents(false);
-    setAlignment(Qt::AlignCenter);
-  }
+    {
+      setScaledContents(false);
+      setAlignment(Qt::AlignCenter);
+    }
   popup->removeAction(newAct);
   popup->removeAction(loadAct);
   popup->removeAction(toTXAct);
   popup->removeAction(editAct);
   popup->removeAction(printAct);
+  popup->removeAction(uploadAct);
   popup->removeAction(deleteAct);
   popup->removeAction(viewAct);
   popup->removeAction(propertiesAct);
   switch(tp)
-  {
-  case RXIMG:
-    popup->addAction(viewAct);
-    popup->addAction(propertiesAct);
+    {
+    case EXTVIEW:
+      popup->addAction(zoomInAct);
+      popup->addAction(zoomOutAct);
+      popup->addAction(propertiesAct);
+    break;
+
+    case RXIMG:
+      popup->addAction(viewAct);
+      popup->addAction(propertiesAct);
     break;
 
-  case TXIMG:
-    popup->addAction(newAct);
-    popup->addAction(loadAct);
-    popup->addAction(editAct);
-    popup->addAction(printAct);
-    popup->addAction(viewAct);
-    popup->addAction(propertiesAct);
+    case TXIMG:
+      popup->addAction(newAct);
+      popup->addAction(loadAct);
+      popup->addAction(editAct);
+      popup->addAction(printAct);
+      popup->addAction(viewAct);
+      popup->addAction(propertiesAct);
     break;
 
-  case PREVIEW:
-    popup->addAction(loadAct);
-    popup->addAction(toTXAct);
-    popup->addAction(viewAct);
-    popup->addAction(propertiesAct);
+    case PREVIEW:
+      popup->addAction(loadAct);
+      popup->addAction(toTXAct);
+      popup->addAction(viewAct);
+      popup->addAction(propertiesAct);
     break;
 
-  case RXSSTVTHUMB:
-  case RXDRMTHUMB:
-  case TXSSTVTHUMB:
-  case TXDRMTHUMB:
-    popup->addAction(toTXAct);
-    popup->addAction(printAct);
-    popup->addAction(deleteAct);
-    popup->addAction(viewAct);
-    popup->addAction(propertiesAct);
+    case RXSSTVTHUMB:
+    case RXDRMTHUMB:
+      popup->addAction(uploadAct);
+    case TXSSTVTHUMB:
+    case TXDRMTHUMB:
+      popup->addAction(toTXAct);
+      popup->addAction(printAct);
+      popup->addAction(deleteAct);
+      popup->addAction(viewAct);
+      popup->addAction(propertiesAct);
     break;
 
-  case TXSTOCKTHUMB:
-  case TEMPLATETHUMB:
-    popup->addAction(newAct);
-    popup->addAction(loadAct);
-    popup->addAction(toTXAct);
-    popup->addAction(editAct);
-    popup->addAction(printAct);
-    popup->addAction(deleteAct);
-    popup->addAction(viewAct);
-    popup->addAction(propertiesAct);
+    case TXSTOCKTHUMB:
+    case TEMPLATETHUMB:
+      popup->addAction(newAct);
+      popup->addAction(loadAct);
+      popup->addAction(toTXAct);
+      popup->addAction(editAct);
+      popup->addAction(printAct);
+      popup->addAction(deleteAct);
+      popup->addAction(viewAct);
+      popup->addAction(propertiesAct);
     break;
-  }
+    }
   popupEnabled=true;
 
 }
 
 void imageViewer::mousePressEvent( QMouseEvent *e )
 {
-  QString temp;
-  QString fn;
-  if (e->button() == Qt::RightButton)
-  {
-    if(popupEnabled)
+  if (e->button() == Qt::LeftButton)
     {
-      popup->popup(QCursor::pos());
+      if (e->type() == QEvent::MouseButtonDblClick)
+        {
+          clickTimer.stop();
+          if (ttype==EXTVIEW) {
+              if (pixmap()) {
+                  QPoint c = mapToImage(e->pos());
+                  if (e->modifiers() & Qt::ShiftModifier)
+                    zoom(c, -1);
+                  else
+                    zoom(c, +1);
+                }
+            }
+          else {
+              if (hasValidImage()) slotView();
+            }
+        }
+      else if (e->type() == QEvent::MouseButtonPress)
+        {
+          if (ttype==EXTVIEW) {
+              if (pixmap()) {
+                  clickPos = mapToImage(e->pos());
+                  clickTimer.start();
+                }
+            }
+        }
+    }
+  else if (e->button() == Qt::RightButton)
+    {
+      if(popupEnabled)
+        {
+          if (pixmap()) clickPos = mapToImage(e->pos());
+          popup->popup(QCursor::pos());
+        }
+    }
+}
+
+void imageViewer::slotLeftClick()
+{
+  switch (ttype)
+    {
+    case EXTVIEW:
+      zoom(clickPos, 0);
+    break;
+    default:
+    break;
     }
-  }
 }
 
 void imageViewer::slotDelete()
 {
   if(imageFileName.isEmpty()) return;
   if(QMessageBox::question(this,"Delete file","Do you want to delete the file and\n move it to the trash folder?",QMessageBox::Yes|QMessageBox::No)==QMessageBox::Yes)
-  {
-    trash(imageFileName,true);
-  }
+    {
+      trash(imageFileName,true);
+    }
   imageFileName="";
   emit layoutChanged();
 }
@@ -457,10 +581,10 @@ void imageViewer::slotDelete()
 void imageViewer::slotEdit()
 {
   if(imageFileName.isEmpty())
-  {
-    slotLoad();
-    if (imageFileName.isEmpty()) return;
-  }
+    {
+      slotLoad();
+      if (imageFileName.isEmpty()) return;
+    }
   callEditorEvent *ce = new callEditorEvent( this,imageFileName );
   QApplication::postEvent(dispatcherPtr, ce );  // Qt will delete it when done
 }
@@ -472,19 +596,19 @@ void imageViewer::slotLoad()
   dirDialog dd((QWidget *)this,"Browse");
   fileNameTmp=dd.openFileName(imageFilePath);
   if(openImage(fileNameTmp,true,false,false))
-  {
-    imageFileName=fileNameTmp;
-    if(ttype==TEMPLATETHUMB)
-    {
-      templatesChangedEvent *ce = new templatesChangedEvent( );
-      QApplication::postEvent(dispatcherPtr, ce );  // Qt will delete it when done
-    }
-    else if((ttype==TXIMG) ||(ttype==PREVIEW))
     {
-      emit imageChanged();
-    }
+      imageFileName=fileNameTmp;
+      if(ttype==TEMPLATETHUMB)
+        {
+          templatesChangedEvent *ce = new templatesChangedEvent( );
+          QApplication::postEvent(dispatcherPtr, ce );  // Qt will delete it when done
+        }
+      else if((ttype==TXIMG) ||(ttype==PREVIEW))
+        {
+          emit imageChanged();
+        }
 
-  }
+    }
 }
 
 
@@ -501,6 +625,24 @@ void imageViewer::slotPrint()
 }
 
 
+void imageViewer::slotUploadFTP()
+{
+  QString remoteDir;
+  switch (ttype) {
+    case RXSSTVTHUMB:
+      remoteDir = ftpRemoteSSTVDirectory;
+    break;
+    case RXDRMTHUMB:
+      remoteDir = ftpRemoteDRMDirectory;
+    break;
+    default:
+    break;
+    }
+  if (!remoteDir.isEmpty())
+    dispatcherPtr->uploadToRXServer(remoteDir, imageFileName);
+}
+
+
 void imageViewer::slotView()
 {
   extViewer vm(this);
@@ -522,25 +664,36 @@ void imageViewer::slotProperties()
 {
   QFileInfo fi(imageFileName);
   if(fi.exists())
-  {
-    QMessageBox::information(this,"Image Properties",
-                             "File: " + imageFileName
-                             + "\n File size:     " + QString::number(fi.size())
-                             + "\n Image width:   " + QString::number(orgWidth)
-                             + "\n Image heigth:  " + QString::number(orgHeight)
-                             + "\n Last Modified: " + fi.lastModified().toString()
-                             ,QMessageBox::Ok);
-  }
+    {
+      QMessageBox::information(this,"Image Properties",
+                               "File: " + imageFileName
+                               + "\n File size:     " + QString::number(fi.size())
+                               + "\n Image width:   " + QString::number(orgWidth)
+                               + "\n Image height:  " + QString::number(orgHeight)
+                               + "\n Last Modified: " + fi.lastModified().toString()
+                               ,QMessageBox::Ok);
+    }
   else
-  {
-    QMessageBox::information(this,"Image Properties",
-                             " Image width:   " + QString::number(orgWidth)
-                             + "\n Image heigth:  " + QString::number(orgHeight)
-                             ,QMessageBox::Ok);
-  }
+    {
+      QMessageBox::information(this,"Image Properties",
+                               " Image width:   " + QString::number(orgWidth)
+                               + "\n Image height:  " + QString::number(orgHeight)
+                               ,QMessageBox::Ok);
+    }
+
+}
+
+void imageViewer::slotZoomIn()
+{
+zoom(clickPos,+1);
+}
 
+void imageViewer::slotZoomOut()
+{
+zoom(clickPos,-1);
 }
 
+
 void imageViewer::slotToTX()
 {
   moveToTxEvent *mt=0;
@@ -553,23 +706,23 @@ void imageViewer::save(QString fileName,QString fmt,bool convertRGB, bool source
 {
   QImage im;
   if(source)
-  {
-    if(sourceImage.isNull()) return;
-  }
+    {
+      if(sourceImage.isNull()) return;
+    }
   else
-  {
-    if(displayedImage.isNull()) return;
-  }
+    {
+      if(displayedImage.isNull()) return;
+    }
   if(!convertRGB)
-  {
-    if(source) im=sourceImage;
-    else im=displayedImage;
-  }
+    {
+      if(source) im=sourceImage;
+      else im=displayedImage;
+    }
   else
-  {
-    if(source) im=sourceImage.convertToFormat(QImage::Format_RGB32);
-    else im=displayedImage.convertToFormat(QImage::Format_RGB32);;
-  }
+    {
+      if(source) im=sourceImage.convertToFormat(QImage::Format_RGB32);
+      else im=displayedImage.convertToFormat(QImage::Format_RGB32);;
+    }
   im.save(fileName,fmt.toUpper().toLatin1().data());
 }
 
@@ -579,14 +732,18 @@ bool imageViewer::copyToBuffer(QByteArray *ba)
   jp2IO jp2;
   int fileSize;
   if(displayedImage.isNull())
-  {
-    return false;
-  }
-  *ba=jp2.encode(displayedImage.convertToFormat(QImage::Format_RGB32),im,fileSize,compressionRatio);
-  if(fileSize==0)
-  {
-    return false;
-  }
+    {
+      return false;
+    }
+  if (compressedImageData.isEmpty())
+    {
+      compressedImageData=jp2.encode(displayedImage.convertToFormat(QImage::Format_RGB32),im,fileSize,compressionRatio);
+    }
+  *ba = compressedImageData;
+  if (compressedImageData.isEmpty())
+    {
+      return false;
+    }
   return true;
 }
 
@@ -614,79 +771,186 @@ void imageViewer::setParam(QString templateFn,bool usesTemplate,int width,int he
   displayImage();
 }
 
+void imageViewer::setAspectMode(Qt::AspectRatioMode mode)
+{
+  aspectRatioMode = mode;
+}
 
 int imageViewer::applyTemplate()
 {
   QImage *resultImage;
   jp2IO jp2;
   QImage overlayedImage;
+  int tWidth=targetWidth,tHeight=targetHeight;
+  int compRatio;
+
   if(sourceImage.isNull()) return 0;
   QFile fi(templateFileName);
   if(ttype!=TXIMG) return 0;
   editorScene tscene(0);
   resultImage=&sourceImage;
-  if(transmissionModeIndex==TRXDRM) useCompression=true;
-  else useCompression=false;
-  if((fi.fileName().isEmpty())  || (!useTemplate))
-  {
-    if(targetWidth!=0 && targetHeight!=0)
+  if(transmissionModeIndex==TRXDRM)
+    {
+      useCompression=true;
+     }
+  else
     {
-      displayedImage= QImage(sourceImage.scaled(targetWidth,targetHeight,Qt::IgnoreAspectRatio,Qt::SmoothTransformation)); // same resolution as sstv mode
+      useCompression=false;
+    }
 
+  compRatio=compressionRatio;
+
+  if (tWidth==0 && tHeight==0 && useCompression &&
+     (sourceImage.width()>1000 || sourceImage.height()>1000)
+      ) {
+      // if this is going DRM, and its not already a small image
+      // and the size slider is set for smaller sizes
+      // we can pre-scale the image to smaller dimensions to
+      // improve the compression speed
+      // Changing the ratio makes the slider work consistently
+      // About every 50 is where the compression ratio stops
+         // making much difference to the size. It's also the point where
+         // you are losing significant detail due to compression anyway.
+         addToLog(QString("CompressionRatio=%1").arg(compressionRatio),LOGIMAG);
+         if (compressionRatio > 150) {
+
+          tWidth =sourceImage.width() / 4;
+          tHeight=sourceImage.height() / 4;
+          compRatio = ((compRatio - 151) * 3) + 45;
+        }
+      else if (compressionRatio > 100) {
+          tWidth =sourceImage.width() / 3;
+          tHeight=sourceImage.height() / 3;
+          compRatio -= 73;
+        }
+      else if (compressionRatio > 50) {
+          tWidth =sourceImage.width() / 2;
+          tHeight=sourceImage.height() / 2;
+          compRatio -= 38;
+        }
     }
-    else
+
+  if((fi.fileName().isEmpty())  || (!useTemplate))
     {
-      displayedImage=sourceImage;
+      addToLog(QString("No Template, targetW,H=%1,%2").arg(targetWidth).arg(targetHeight), LOGIMAG);
+      if(tWidth!=0 && tHeight!=0)
+        {
+          QImage scaledImage = QImage(sourceImage
+                                      .scaled(tWidth,
+                                              tHeight,
+                                              aspectRatioMode,
+                                              Qt::SmoothTransformation
+                                              )
+                                      );
+          // Crop to intended dimensions at the centre of the image
+          displayedImage = QImage(scaledImage
+                                  .copy((scaledImage.width()-tWidth)/2,
+                                        (scaledImage.height()-tHeight)/2,
+                                        tWidth,
+                                        tHeight
+                                        )
+                                  );
+        }
+      else
+        {
+          displayedImage=sourceImage;
+        }
+      resultImage=&displayedImage;
     }
-    resultImage=&displayedImage;
-  }
   else
-  {
-    addToLog("apply temlate",LOGIMAG);
-    //  sconvert cnv;
-
-    if((!fi.fileName().isEmpty())  && (useTemplate))
-    {
-      tscene.load(fi);
-      tscene.addConversion('c',toCall,true);
-      tscene.addConversion('r',rsv);
-      tscene.addConversion('o',toOperator);
-      tscene.addConversion('t',QDateTime::currentDateTime().toUTC().toString("hh:mm"));
-      tscene.addConversion('d',QDateTime::currentDateTime().toUTC().toString("yyyy/MM/dd"));
-      tscene.addConversion('m',myCallsign);
-      tscene.addConversion('q',myQth);
-      tscene.addConversion('l',myLocator);
-      tscene.addConversion('n',myLastname);
-      tscene.addConversion('f',myFirstname);
-      tscene.addConversion('v',qsstvVersion);
-      tscene.addConversion('x',comment1);
-      tscene.addConversion('y',comment2);
-      tscene.addConversion('z',comment3);
-      addToLog(QString("applyTemplate size=%1,%2").arg(tscene.width()).arg(tscene.height()),LOGIMAG);
-      if(targetWidth!=0 && targetHeight!=0)
-      {
-        overlayedImage= QImage(sourceImage.scaled(targetWidth,targetHeight));
-        tscene.overlay(&overlayedImage);
-      }
-      else
-      {
-        tscene.overlay(&sourceImage);
-      }
-      resultImage=tscene.getImagePtr();
+    {
+      addToLog("apply temlate",LOGIMAG);
+      //  sconvert cnv;
+
+      if((!fi.fileName().isEmpty())  && (useTemplate))
+        {
+          tscene.load(fi);
+          tscene.addConversion('c',toCall,true);
+          tscene.addConversion('r',rsv);
+          tscene.addConversion('o',toOperator);
+          tscene.addConversion('t',QDateTime::currentDateTime().toUTC().toString("hh:mm"));
+          tscene.addConversion('d',QDateTime::currentDateTime().toUTC().toString("yyyy/MM/dd"));
+          tscene.addConversion('m',myCallsign);
+          tscene.addConversion('q',myQth);
+          tscene.addConversion('l',myLocator);
+          tscene.addConversion('n',myLastname);
+          tscene.addConversion('f',myFirstname);
+          tscene.addConversion('v',qsstvVersion);
+          tscene.addConversion('x',comment1);
+          tscene.addConversion('y',comment2);
+          tscene.addConversion('z',comment3);
+
+          addToLog(QString("Template size=%1,%2, SourceW,H=%3,%4 TargetW,H=%5,%6").
+                   arg(tscene.width()).arg(tscene.height()).
+                   arg(sourceImage.width()).arg(sourceImage.height()).
+                   arg(tWidth).arg(tHeight),
+                   LOGIMAG);
+          if(tWidth!=0 && tHeight!=0)
+            {
+              QImage scaledImage = QImage(sourceImage
+                                          .scaled(tWidth,
+                                                  tHeight,
+                                                  aspectRatioMode,
+                                                  Qt::SmoothTransformation
+                                                  )
+                                          );
+              overlayedImage= QImage(scaledImage
+                                     .copy((scaledImage.width()-tWidth)/2,
+                                           (scaledImage.height()-tHeight)/2,
+                                           tWidth,
+                                           tHeight
+                                           )
+                                     );
+              tscene.overlay(&overlayedImage);
+            }
+          else
+            {
+              tscene.overlay(&sourceImage);
+            }
+          resultImage=tscene.getImagePtr();
+          addToLog(QString("resultImageW,H=%1,%2").arg(resultImage->width()).arg(resultImage->height()), LOGIMAG);
+        }
     }
-  }
   if(useCompression)
-  {
-    int fileSize;
-    jp2.encode(resultImage->convertToFormat(QImage::Format_RGB32),compressedImage,fileSize,compressionRatio);
-    displayedImage=compressedImage;
-    return fileSize;
-  }
+    {
+      bool useOriginal=false;
+      int fileSize;
+      compressedImageData=jp2.encode(resultImage->convertToFormat(QImage::Format_RGB32),compressedImage,fileSize,compRatio);
+      if (!useTemplate && !imageFileName.isEmpty())
+        {
+          QFile original(imageFileName);
+          if (original.open(QIODevice::ReadOnly) && (original.size() < fileSize))
+            {
+              useOriginal=true;
+              compressedFilename=imageFileName;
+              addToLog(QString("Using original image data (%1 bytes)").arg(original.size()),LOGIMAG);
+              statusBarPtr->showMessage("Using original Image (smaller)");
+              compressedImageData = original.readAll();
+              displayedImage.load(imageFileName);
+            }
+        }
+      if (!useOriginal)
+        {
+          displayedImage=compressedImage;
+          int pos;
+          pos=imageFileName.lastIndexOf(".",-1);
+          compressedFilename=imageFileName.left(pos)+".jp2";
+          statusBarPtr->showMessage("");
+          addToLog(QString("Image Compressed to %1 bytes").arg(compressedImageData.size()),LOGIMAG);
+          addToLog(QString("displayedImageW,H=%1,%2  compRatio=%3").
+                   arg(displayedImage.width()).arg(displayedImage.height()).
+                   arg(compRatio),
+                   LOGIMAG);
+        }
+      addToLog(QString("compressed size %1").arg(compressedImageData.size()),LOGIMAG);
+      return fileSize;
+    }
   else
-  {
-    displayedImage=*resultImage;
-    return displayedImage.byteCount();
-  }
+    {
+      displayedImage=resultImage->convertToFormat(QImage::Format_RGB32);
+      compressedImageData.clear();
+      return displayedImage.byteCount();
+    }
 }
 
 
diff --git a/qsstv/widgets/imageviewer.h b/qsstv/widgets/imageviewer.h
index b106b93..df2a5aa 100644
--- a/qsstv/widgets/imageviewer.h
+++ b/qsstv/widgets/imageviewer.h
@@ -38,7 +38,7 @@ class imageViewer : public QLabel
   /*! thumbnail type */
 public:
   enum thumbType
-    {
+  {
     RXIMG, /*!< just for receiver */
     TXIMG, /*!< just for transmitter */
     RXSSTVTHUMB, /*!< thumbnail for receiver. */
@@ -47,8 +47,9 @@ public:
     TXDRMTHUMB,/*!< thumbnail for transmitter. */
     TXSTOCKTHUMB,/*!< thumbnail for transmitter. */
     TEMPLATETHUMB, /*!< thumbnail for template. */
-    PREVIEW /*!< preview tx. */
-    };
+    PREVIEW, /*!< preview tx. */
+    EXTVIEW /*!< extViewer. */
+  };
   imageViewer(QWidget *parent=0);
   ~imageViewer();
 
@@ -63,7 +64,7 @@ public:
   bool reload();
 
 
-//  void scale( int w, int h);
+  //  void scale( int w, int h);
   QImage * getImagePtr() {return &sourceImage;}
   bool hasValidImage();
   void setValidImage(bool v)
@@ -76,12 +77,16 @@ public:
   void copy(imageViewer *src);
   void setType(thumbType t);
   QString getFilename() {return imageFileName;}
+  QString getCompressedFilename() {return compressedFilename;}
   void enablePopup(bool en) {popupEnabled=en;}
   void displayImage();
+  QPoint mapToImage(const QPoint &pos);
+  void zoom(QPoint centre, int dlevel);
   void save(QString fileName, QString fmt, bool convertRGB, bool source);
   bool copyToBuffer(QByteArray *ba);
-//  int calcSize(int &sizeRatio);
+  //  int calcSize(int &sizeRatio);
   uint setSizeRatio(int sizeRatio,bool usesCompression);
+  void setAspectMode(Qt::AspectRatioMode mode);
   int getFileSize(){return fileSize;}
   QString toCall;
   QString toOperator;
@@ -106,10 +111,14 @@ private slots:
   void slotLoad();
   void slotNew();
   void slotPrint();
+  void slotUploadFTP();
   void slotProperties();
   void slotToTX();
   void slotView();
   void slotBGColorChanged();
+  void slotZoomIn();
+  void slotZoomOut();
+  void slotLeftClick();
 
 
 signals:
@@ -120,10 +129,13 @@ private:
   QImage displayedImage;
   QImage sourceImage;
   QImage compressedImage;
+  QByteArray compressedImageData;
+
 
   void mousePressEvent( QMouseEvent *e );
   bool validImage;
   QString imageFileName;
+  QString compressedFilename;
   QString imageFilePath;
   thumbType ttype;
   bool popupEnabled;
@@ -134,11 +146,14 @@ private:
   QAction *toTXAct;
   QAction *editAct;
   QAction *printAct;
+  QAction *uploadAct;
   QAction *deleteAct;
   QAction *viewAct;
   QAction *propertiesAct;
+  QAction *zoomInAct;
+  QAction *zoomOutAct;
 
-//  double psizeRatio;
+  //  double psizeRatio;
   int compressionRatio; // 0=lossless 99 is max compression
   int fileSize;
   QString format;
@@ -146,11 +161,15 @@ private:
   bool activeMovie;
   bool useCompression;
   QString templateFileName;
+  Qt::AspectRatioMode aspectRatioMode;
   bool useTemplate;
   int targetWidth;
   int targetHeight;
   int orgWidth;
   int orgHeight;
+  QRect view;
+  QPoint clickPos;
+  QTimer clickTimer;
 
 };
 
diff --git a/qsstv/widgets/spectrumwidget.cpp b/qsstv/widgets/spectrumwidget.cpp
index 516c1ef..db5bdcb 100644
--- a/qsstv/widgets/spectrumwidget.cpp
+++ b/qsstv/widgets/spectrumwidget.cpp
@@ -99,6 +99,11 @@ void spectrumWidget::displaySettings(bool drm)
     }
 }
 
+QImage *spectrumWidget::getImage()
+{
+  return ui->waterfallWidget->getImage();
+}
+
 void spectrumWidget::slotMaxDbChanged(int mb)
 {
   ui->spectrWidget->setMaxDb(mb);
diff --git a/qsstv/widgets/spectrumwidget.h b/qsstv/widgets/spectrumwidget.h
index a3b3a93..8415cc1 100644
--- a/qsstv/widgets/spectrumwidget.h
+++ b/qsstv/widgets/spectrumwidget.h
@@ -23,6 +23,8 @@ public:
   void writeSettings();
   void displaySettings(bool drm);
   double getVolumeDb();
+  QImage *getImage();
+
 private slots:
   void slotMaxDbChanged(int mb);
   void slotRangeChanged(int rg);
diff --git a/qsstv/widgets/vumeter.cpp b/qsstv/widgets/vumeter.cpp
index 8796eeb..511bd5a 100644
--- a/qsstv/widgets/vumeter.cpp
+++ b/qsstv/widgets/vumeter.cpp
@@ -39,6 +39,7 @@ vuMeter::vuMeter(QWidget *parent) : QWidget(parent)
   min = 0;
   max = 100;
   val =9;
+  prevValue = 0;
   horizontal=false;
   divisions=20;
   labelText="V";
diff --git a/qsstv_9_1.pro b/qsstv_9_2.pro
similarity index 100%
rename from qsstv_9_1.pro
rename to qsstv_9_2.pro

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-hamradio/qsstv.git



More information about the pkg-hamradio-commits mailing list