提交 edb397a5 编写于 作者: 丁劲犇's avatar 丁劲犇 😸

Initial Commit

上级
__pycache__
/network
*.qm
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
build/
bld/
[Bb]in/
[Oo]bj/
# Roslyn cache directories
*.ide/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
#NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding addin-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
## TODO: Comment the next line if you want to checkin your
## web deploy settings but do note that will include unencrypted
## passwords
*.pubxml
# NuGet Packages
packages/*
*.nupkg
## TODO: If the tool you use requires repositories.config
## uncomment the next line
#!packages/repositories.config
# Enable "build/" folder in the NuGet Packages folder since
# NuGet packages use it for MSBuild targets.
# This line needs to be after the ignore of the build folder
# (and the packages folder if the line above has been uncommented)
!packages/build/
# Windows Azure Build Output
csx/
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# C++ objects and libs
*.slo
*.lo
*.o
*.a
*.la
*.lai
*.so
*.dll
*.dylib
# Qt-es
/.qmake.cache
/.qmake.stash
*.pro.user
*.pro.user.*
*.moc
moc_*.cpp
qrc_*.cpp
ui_*.h
Makefile*
*-build-*
# QtCreator
*.autosave
build-*-Debug
build-*-Release
*.bak
*.qm
*_Saved
*.exe
*.db
.vs
*.pyc
/module_templates/csharp/app.config
/*
* Copyright (c) 2003, 2007-14 Matteo Frigo
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
*
* The following statement of license applies *only* to this header file,
* and *not* to the other files distributed with FFTW or derived therefrom:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/***************************** NOTE TO USERS *********************************
*
* THIS IS A HEADER FILE, NOT A MANUAL
*
* If you want to know how to use FFTW, please read the manual,
* online at http://www.fftw.org/doc/ and also included with FFTW.
* For a quick start, see the manual's tutorial section.
*
* (Reading header files to learn how to use a library is a habit
* stemming from code lacking a proper manual. Arguably, it's a
* *bad* habit in most cases, because header files can contain
* interfaces that are not part of the public, stable API.)
*
****************************************************************************/
#ifndef FFTW3_H
#define FFTW3_H
#include <stdio.h>
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/* If <complex.h> is included, use the C99 complex type. Otherwise
define a type bit-compatible with C99 complex */
#if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I)
# define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C
#else
# define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2]
#endif
#define FFTW_CONCAT(prefix, name) prefix ## name
#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name)
#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name)
#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name)
#define FFTW_MANGLE_QUAD(name) FFTW_CONCAT(fftwq_, name)
/* IMPORTANT: for Windows compilers, you should add a line
*/
#define FFTW_DLL
/*
here and in kernel/ifftw.h if you are compiling/using FFTW as a
DLL, in order to do the proper importing/exporting, or
alternatively compile with -DFFTW_DLL or the equivalent
command-line flag. This is not necessary under MinGW/Cygwin, where
libtool does the imports/exports automatically. */
#if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__))
/* annoying Windows syntax for shared-library declarations */
# if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */
# define FFTW_EXTERN extern __declspec(dllexport)
# else /* user is calling FFTW; import symbol */
# define FFTW_EXTERN extern __declspec(dllimport)
# endif
#else
# define FFTW_EXTERN extern
#endif
enum fftw_r2r_kind_do_not_use_me {
FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2,
FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6,
FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10
};
struct fftw_iodim_do_not_use_me {
int n; /* dimension size */
int is; /* input stride */
int os; /* output stride */
};
#include <stddef.h> /* for ptrdiff_t */
struct fftw_iodim64_do_not_use_me {
ptrdiff_t n; /* dimension size */
ptrdiff_t is; /* input stride */
ptrdiff_t os; /* output stride */
};
typedef void (*fftw_write_char_func_do_not_use_me)(char c, void *);
typedef int (*fftw_read_char_func_do_not_use_me)(void *);
/*
huge second-order macro that defines prototypes for all API
functions. We expand this macro for each supported precision
X: name-mangling macro
R: real data type
C: complex data type
*/
#define FFTW_DEFINE_API(X, R, C) \
\
FFTW_DEFINE_COMPLEX(R, C); \
\
typedef struct X(plan_s) *X(plan); \
\
typedef struct fftw_iodim_do_not_use_me X(iodim); \
typedef struct fftw_iodim64_do_not_use_me X(iodim64); \
\
typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind); \
\
typedef fftw_write_char_func_do_not_use_me X(write_char_func); \
typedef fftw_read_char_func_do_not_use_me X(read_char_func); \
\
FFTW_EXTERN void X(execute)(const X(plan) p); \
\
FFTW_EXTERN X(plan) X(plan_dft)(int rank, const int *n, \
C *in, C *out, int sign, unsigned flags); \
\
FFTW_EXTERN X(plan) X(plan_dft_1d)(int n, C *in, C *out, int sign, \
unsigned flags); \
FFTW_EXTERN X(plan) X(plan_dft_2d)(int n0, int n1, \
C *in, C *out, int sign, unsigned flags); \
FFTW_EXTERN X(plan) X(plan_dft_3d)(int n0, int n1, int n2, \
C *in, C *out, int sign, unsigned flags); \
\
FFTW_EXTERN X(plan) X(plan_many_dft)(int rank, const int *n, \
int howmany, \
C *in, const int *inembed, \
int istride, int idist, \
C *out, const int *onembed, \
int ostride, int odist, \
int sign, unsigned flags); \
\
FFTW_EXTERN X(plan) X(plan_guru_dft)(int rank, const X(iodim) *dims, \
int howmany_rank, \
const X(iodim) *howmany_dims, \
C *in, C *out, \
int sign, unsigned flags); \
FFTW_EXTERN X(plan) X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \
int howmany_rank, \
const X(iodim) *howmany_dims, \
R *ri, R *ii, R *ro, R *io, \
unsigned flags); \
\
FFTW_EXTERN X(plan) X(plan_guru64_dft)(int rank, \
const X(iodim64) *dims, \
int howmany_rank, \
const X(iodim64) *howmany_dims, \
C *in, C *out, \
int sign, unsigned flags); \
FFTW_EXTERN X(plan) X(plan_guru64_split_dft)(int rank, \
const X(iodim64) *dims, \
int howmany_rank, \
const X(iodim64) *howmany_dims, \
R *ri, R *ii, R *ro, R *io, \
unsigned flags); \
\
FFTW_EXTERN void X(execute_dft)(const X(plan) p, C *in, C *out); \
FFTW_EXTERN void X(execute_split_dft)(const X(plan) p, R *ri, R *ii, \
R *ro, R *io); \
\
FFTW_EXTERN X(plan) X(plan_many_dft_r2c)(int rank, const int *n, \
int howmany, \
R *in, const int *inembed, \
int istride, int idist, \
C *out, const int *onembed, \
int ostride, int odist, \
unsigned flags); \
\
FFTW_EXTERN X(plan) X(plan_dft_r2c)(int rank, const int *n, \
R *in, C *out, unsigned flags); \
\
FFTW_EXTERN X(plan) X(plan_dft_r2c_1d)(int n,R *in,C *out,unsigned flags); \
FFTW_EXTERN X(plan) X(plan_dft_r2c_2d)(int n0, int n1, \
R *in, C *out, unsigned flags); \
FFTW_EXTERN X(plan) X(plan_dft_r2c_3d)(int n0, int n1, \
int n2, \
R *in, C *out, unsigned flags); \
\
\
FFTW_EXTERN X(plan) X(plan_many_dft_c2r)(int rank, const int *n, \
int howmany, \
C *in, const int *inembed, \
int istride, int idist, \
R *out, const int *onembed, \
int ostride, int odist, \
unsigned flags); \
\
FFTW_EXTERN X(plan) X(plan_dft_c2r)(int rank, const int *n, \
C *in, R *out, unsigned flags); \
\
FFTW_EXTERN X(plan) X(plan_dft_c2r_1d)(int n,C *in,R *out,unsigned flags); \
FFTW_EXTERN X(plan) X(plan_dft_c2r_2d)(int n0, int n1, \
C *in, R *out, unsigned flags); \
FFTW_EXTERN X(plan) X(plan_dft_c2r_3d)(int n0, int n1, \
int n2, \
C *in, R *out, unsigned flags); \
\
FFTW_EXTERN X(plan) X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims, \
int howmany_rank, \
const X(iodim) *howmany_dims, \
R *in, C *out, \
unsigned flags); \
FFTW_EXTERN X(plan) X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims, \
int howmany_rank, \
const X(iodim) *howmany_dims, \
C *in, R *out, \
unsigned flags); \
\
FFTW_EXTERN X(plan) X(plan_guru_split_dft_r2c)( \
int rank, const X(iodim) *dims, \
int howmany_rank, \
const X(iodim) *howmany_dims, \
R *in, R *ro, R *io, \
unsigned flags); \
FFTW_EXTERN X(plan) X(plan_guru_split_dft_c2r)( \
int rank, const X(iodim) *dims, \
int howmany_rank, \
const X(iodim) *howmany_dims, \
R *ri, R *ii, R *out, \
unsigned flags); \
\
FFTW_EXTERN X(plan) X(plan_guru64_dft_r2c)(int rank, \
const X(iodim64) *dims, \
int howmany_rank, \
const X(iodim64) *howmany_dims, \
R *in, C *out, \
unsigned flags); \
FFTW_EXTERN X(plan) X(plan_guru64_dft_c2r)(int rank, \
const X(iodim64) *dims, \
int howmany_rank, \
const X(iodim64) *howmany_dims, \
C *in, R *out, \
unsigned flags); \
\
FFTW_EXTERN X(plan) X(plan_guru64_split_dft_r2c)( \
int rank, const X(iodim64) *dims, \
int howmany_rank, \
const X(iodim64) *howmany_dims, \
R *in, R *ro, R *io, \
unsigned flags); \
FFTW_EXTERN X(plan) X(plan_guru64_split_dft_c2r)( \
int rank, const X(iodim64) *dims, \
int howmany_rank, \
const X(iodim64) *howmany_dims, \
R *ri, R *ii, R *out, \
unsigned flags); \
\
FFTW_EXTERN void X(execute_dft_r2c)(const X(plan) p, R *in, C *out); \
FFTW_EXTERN void X(execute_dft_c2r)(const X(plan) p, C *in, R *out); \
\
FFTW_EXTERN void X(execute_split_dft_r2c)(const X(plan) p, \
R *in, R *ro, R *io); \
FFTW_EXTERN void X(execute_split_dft_c2r)(const X(plan) p, \
R *ri, R *ii, R *out); \
\
FFTW_EXTERN X(plan) X(plan_many_r2r)(int rank, const int *n, \
int howmany, \
R *in, const int *inembed, \
int istride, int idist, \
R *out, const int *onembed, \
int ostride, int odist, \
const X(r2r_kind) *kind, unsigned flags); \
\
FFTW_EXTERN X(plan) X(plan_r2r)(int rank, const int *n, R *in, R *out, \
const X(r2r_kind) *kind, unsigned flags); \
\
FFTW_EXTERN X(plan) X(plan_r2r_1d)(int n, R *in, R *out, \
X(r2r_kind) kind, unsigned flags); \
FFTW_EXTERN X(plan) X(plan_r2r_2d)(int n0, int n1, R *in, R *out, \
X(r2r_kind) kind0, X(r2r_kind) kind1, \
unsigned flags); \
FFTW_EXTERN X(plan) X(plan_r2r_3d)(int n0, int n1, int n2, \
R *in, R *out, X(r2r_kind) kind0, \
X(r2r_kind) kind1, X(r2r_kind) kind2, \
unsigned flags); \
\
FFTW_EXTERN X(plan) X(plan_guru_r2r)(int rank, const X(iodim) *dims, \
int howmany_rank, \
const X(iodim) *howmany_dims, \
R *in, R *out, \
const X(r2r_kind) *kind, unsigned flags); \
\
FFTW_EXTERN X(plan) X(plan_guru64_r2r)(int rank, const X(iodim64) *dims, \
int howmany_rank, \
const X(iodim64) *howmany_dims, \
R *in, R *out, \
const X(r2r_kind) *kind, unsigned flags); \
\
FFTW_EXTERN void X(execute_r2r)(const X(plan) p, R *in, R *out); \
\
FFTW_EXTERN void X(destroy_plan)(X(plan) p); \
FFTW_EXTERN void X(forget_wisdom)(void); \
FFTW_EXTERN void X(cleanup)(void); \
\
FFTW_EXTERN void X(set_timelimit)(double t); \
\
FFTW_EXTERN void X(plan_with_nthreads)(int nthreads); \
FFTW_EXTERN int X(init_threads)(void); \
FFTW_EXTERN void X(cleanup_threads)(void); \
FFTW_EXTERN void X(make_planner_thread_safe)(void); \
\
FFTW_EXTERN int X(export_wisdom_to_filename)(const char *filename); \
FFTW_EXTERN void X(export_wisdom_to_file)(FILE *output_file); \
FFTW_EXTERN char *X(export_wisdom_to_string)(void); \
FFTW_EXTERN void X(export_wisdom)(X(write_char_func) write_char, \
void *data); \
FFTW_EXTERN int X(import_system_wisdom)(void); \
FFTW_EXTERN int X(import_wisdom_from_filename)(const char *filename); \
FFTW_EXTERN int X(import_wisdom_from_file)(FILE *input_file); \
FFTW_EXTERN int X(import_wisdom_from_string)(const char *input_string); \
FFTW_EXTERN int X(import_wisdom)(X(read_char_func) read_char, void *data); \
\
FFTW_EXTERN void X(fprint_plan)(const X(plan) p, FILE *output_file); \
FFTW_EXTERN void X(print_plan)(const X(plan) p); \
FFTW_EXTERN char *X(sprint_plan)(const X(plan) p); \
\
FFTW_EXTERN void *X(malloc)(size_t n); \
FFTW_EXTERN R *X(alloc_real)(size_t n); \
FFTW_EXTERN C *X(alloc_complex)(size_t n); \
FFTW_EXTERN void X(free)(void *p); \
\
FFTW_EXTERN void X(flops)(const X(plan) p, \
double *add, double *mul, double *fmas); \
FFTW_EXTERN double X(estimate_cost)(const X(plan) p); \
FFTW_EXTERN double X(cost)(const X(plan) p); \
\
FFTW_EXTERN int X(alignment_of)(R *p); \
FFTW_EXTERN const char X(version)[]; \
FFTW_EXTERN const char X(cc)[]; \
FFTW_EXTERN const char X(codelet_optim)[];
/* end of FFTW_DEFINE_API macro */
FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex)
FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex)
FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex)
/* __float128 (quad precision) is a gcc extension on i386, x86_64, and ia64
for gcc >= 4.6 (compiled in FFTW with --enable-quad-precision) */
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) \
&& !(defined(__ICC) || defined(__INTEL_COMPILER) || defined(__CUDACC__) || defined(__PGI)) \
&& (defined(__i386__) || defined(__x86_64__) || defined(__ia64__))
# if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I)
/* note: __float128 is a typedef, which is not supported with the _Complex
keyword in gcc, so instead we use this ugly __attribute__ version.
However, we can't simply pass the __attribute__ version to
FFTW_DEFINE_API because the __attribute__ confuses gcc in pointer
types. Hence redefining FFTW_DEFINE_COMPLEX. Ugh. */
# undef FFTW_DEFINE_COMPLEX
# define FFTW_DEFINE_COMPLEX(R, C) typedef _Complex float __attribute__((mode(TC))) C
# endif
FFTW_DEFINE_API(FFTW_MANGLE_QUAD, __float128, fftwq_complex)
#endif
#define FFTW_FORWARD (-1)
#define FFTW_BACKWARD (+1)
#define FFTW_NO_TIMELIMIT (-1.0)
/* documented flags */
#define FFTW_MEASURE (0U)
#define FFTW_DESTROY_INPUT (1U << 0)
#define FFTW_UNALIGNED (1U << 1)
#define FFTW_CONSERVE_MEMORY (1U << 2)
#define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */
#define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */
#define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */
#define FFTW_ESTIMATE (1U << 6)
#define FFTW_WISDOM_ONLY (1U << 21)
/* undocumented beyond-guru flags */
#define FFTW_ESTIMATE_PATIENT (1U << 7)
#define FFTW_BELIEVE_PCOST (1U << 8)
#define FFTW_NO_DFT_R2HC (1U << 9)
#define FFTW_NO_NONTHREADED (1U << 10)
#define FFTW_NO_BUFFERING (1U << 11)
#define FFTW_NO_INDIRECT_OP (1U << 12)
#define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */
#define FFTW_NO_RANK_SPLITS (1U << 14)
#define FFTW_NO_VRANK_SPLITS (1U << 15)
#define FFTW_NO_VRECURSE (1U << 16)
#define FFTW_NO_SIMD (1U << 17)
#define FFTW_NO_SLOW (1U << 18)
#define FFTW_NO_FIXED_RADIX_LARGE_N (1U << 19)
#define FFTW_ALLOW_PRUNING (1U << 20)
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* FFTW3_H */
#include "dlgtest.h"
#include "ui_dlgtest.h"
#include <cmath>
DlgTest::DlgTest(QWidget *parent)
: QDialog(parent)
, ui(new Ui::DlgTest)
{
ui->setupUi(this);
m_nTid = startTimer(20);
}
DlgTest::~DlgTest()
{
delete ui;
}
void DlgTest::timerEvent(QTimerEvent * e)
{
static QUdpSocket sock;
static qint16 buf[32768];
static int ctt = 0;
if (e->timerId()==m_nTid)
{
int cp = rand() % 256;
for (int i = 0;i<2048;++i)
{
int cc1 = i /128;
int cci = i % 128;
buf[i] = cos(2*3.1415926*i/4.0)*2048+.5;
buf[i] *= (0.54 - 0.46 * cos (2*3.1415927 * cci / (128)));
if (((cc1 * 997+cp)%271) %2)
buf[i] *= -1;
if (ctt % 100 >= 50)
buf[i] =0;
buf[i] += rand() % 32-16;
}
++ctt;
sock.writeDatagram((char *)buf,2048*2,QHostAddress("127.0.0.1"),20338);
}
}
#ifndef DLGTEST_H
#define DLGTEST_H
#include <QDialog>
QT_BEGIN_NAMESPACE
namespace Ui { class DlgTest; }
QT_END_NAMESPACE
class DlgTest : public QDialog
{
Q_OBJECT
public:
DlgTest(QWidget *parent = nullptr);
~DlgTest();
protected:
void timerEvent(QTimerEvent * e) override;
private:
Ui::DlgTest *ui;
int m_nTid = -1;
};
#endif // DLGTEST_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DlgTest</class>
<widget class="QDialog" name="DlgTest">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>681</width>
<height>467</height>
</rect>
</property>
<property name="windowTitle">
<string>DlgTest</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="specWidget" name="widget" native="true"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>specWidget</class>
<extends>QWidget</extends>
<header>spectrum/specwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
#include "dlgtest.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
DlgTest w;
w.show();
return a.exec();
}
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
dlgtest.cpp \
spectrum/qtgui/agc_options.cpp \
spectrum/qtgui/bookmarks.cpp \
spectrum/qtgui/bookmarkstablemodel.cpp \
spectrum/qtgui/bookmarkstaglist.cpp \
spectrum/qtgui/demod_options.cpp \
spectrum/qtgui/dockrxopt.cpp \
spectrum/qtgui/freqctrl.cpp \
spectrum/qtgui/meter.cpp \
spectrum/qtgui/nb_options.cpp \
spectrum/qtgui/plotter.cpp \
spectrum/specwidget.cpp \
udp/cudpreciever.cpp
HEADERS += \
dlgtest.h \
spectrum/qtgui/agc_options.h \
spectrum/qtgui/bookmarks.h \
spectrum/qtgui/bookmarkstablemodel.h \
spectrum/qtgui/bookmarkstaglist.h \
spectrum/qtgui/demod_options.h \
spectrum/qtgui/dockrxopt.h \
spectrum/qtgui/freqctrl.h \
spectrum/qtgui/meter.h \
spectrum/qtgui/nb_options.h \
spectrum/qtgui/plotter.h \
spectrum/specwidget.h \
udp/cudpreciever.h
FORMS += \
dlgtest.ui \
spectrum/qtgui/agc_options.ui \
spectrum/qtgui/demod_options.ui \
spectrum/qtgui/dockrxopt.ui \
spectrum/qtgui/nb_options.ui \
spectrum/specwidget.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
win32{
mkoptions = $$find(QMAKESPEC, "vc")
count(mkoptions, 1){
INCLUDEPATH +="$$PWD/3rdlibs/win32/fftw"
contains(QT_ARCH, i386) {
LIBS+=-L"$$PWD/3rdlibs/win32/fftw/x86" -llibfftw3-3
} else {
LIBS+=-L"$$PWD/3rdlibs/win32/fftw/x64" -llibfftw3-3
}
} else: LIBS+=-lfftw3
}else: LIBS+=-lfftw3
/* -*- c++ -*- */
/*
* Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
* http://gqrx.dk/
*
* Copyright 2012-2013 Alexandru Csete OZ9AEC.
*
* Gqrx is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* Gqrx is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Gqrx; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include <QDebug>
#include <QString>
#include "agc_options.h"
#include "ui_agc_options.h"
CAgcOptions::CAgcOptions(QWidget *parent) :
QDialog(parent),
ui(new Ui::CAgcOptions)
{
ui->setupUi(this);
}
CAgcOptions::~CAgcOptions()
{
delete ui;
}
/*! \brief Catch window close events.
*
* This method is called when the user closes the dialog window using the
* window close icon. We catch the event and hide the dialog but keep it
* around for later use.
*/
void CAgcOptions::closeEvent(QCloseEvent *event)
{
hide();
event->ignore();
}
/*! \brief Get current gain slider value. */
int CAgcOptions::gain()
{
return ui->gainSlider->value();
}
/*! \brief Set AGC preset. */
void CAgcOptions::setPreset(agc_preset_e preset)
{
switch (preset)
{
case AGC_FAST:
setDecay(100);
enableDecay(false);
setSlope(0);
enableSlope(false);
enableGain(false);
break;
case AGC_MEDIUM:
setDecay(500);
enableDecay(false);
setSlope(0);
enableSlope(false);
enableGain(false);
break;
case AGC_SLOW:
setDecay(2000);
enableDecay(false);
setSlope(0);
enableSlope(false);
enableGain(false);
break;
case AGC_USER:
enableDecay(true);
enableSlope(true);
enableGain(false);
break;
case AGC_OFF:
enableGain(true);
break;
default:
qDebug() << __func__ << "Invalid AGC preset" << preset;
break;
}
}
/*! \brief Set new gain slider value. */
void CAgcOptions::setGain(int value)
{
ui->gainSlider->setValue(value);
ui->gainLabel->setText(QString("%1 dB").arg(ui->gainSlider->value()));
}
/*! \brief Enable or disable gain slider.
* \param enabled Whether the slider should be enabled or not.
*
* The gain slider is enabled when AGC is OFF to provide manual gain
* control. It is disabled when AGC is ON.
*/
void CAgcOptions::enableGain(bool enabled)
{
ui->gainLabel->setEnabled(enabled);
ui->gainSlider->setEnabled(enabled);
ui->label1->setEnabled(enabled);
}
/*! \brief Get current AGC threshold. */
int CAgcOptions::threshold()
{
return ui->thresholdSlider->value();
}
/*! \brief Set new AGC threshold. */
void CAgcOptions::setThreshold(int value)
{
ui->thresholdSlider->setValue(value);
ui->thresholdLabel->setText(QString("%1 dB").arg(ui->thresholdSlider->value()));
}
/*! \brief Get current AGC slope. */
int CAgcOptions::slope()
{
return ui->slopeSlider->value();
}
/*! \brief Set new AGC slope. */
void CAgcOptions::setSlope(int value)
{
ui->slopeSlider->setValue(value);
ui->slopeLabel->setText(QString("%1 dB").arg(ui->slopeSlider->value()));
}
/*! \brief Enable or disable AGC slope slider.
* \param enabled Whether the slider should be enabled or not.
*
* The slope slider is enabled when AGC is in user mode.
*/
void CAgcOptions::enableSlope(bool enabled)
{
ui->slopeSlider->setEnabled(enabled);
ui->slopeLabel->setEnabled(enabled);
ui->label3->setEnabled(enabled);
}
/*! \brief Get current decay value. */
int CAgcOptions::decay()
{
return ui->decaySlider->value();
}
/*! \brief Set new decay value. */
void CAgcOptions::setDecay(int value)
{
ui->decaySlider->setValue(value);
ui->decayLabel->setText(QString("%1 ms").arg(ui->decaySlider->value()));
}
/*! \brief Enable or disable AGC decay slider.
* \param enabled Whether the slider should be enabled or not.
*
* The decay slider is enabled when AGC is in user mode.
*/
void CAgcOptions::enableDecay(bool enabled)
{
ui->decaySlider->setEnabled(enabled);
ui->decayLabel->setEnabled(enabled);
ui->label4->setEnabled(enabled);
}
/*! \brief Get current state of AGC hang button. */
bool CAgcOptions::hang()
{
return ui->hangButton->isChecked();
}
/*! \brief Set state og AGC hang button. */
void CAgcOptions::setHang(bool checked)
{
ui->hangButton->setChecked(checked);
}
/*! \brief AGC gain slider value has changed. */
void CAgcOptions::on_gainSlider_valueChanged(int gain)
{
ui->gainLabel->setText(QString("%1 dB").arg(ui->gainSlider->value()));
emit gainChanged(gain);
}
/*! \brief AGC threshold slider value has changed. */
void CAgcOptions::on_thresholdSlider_valueChanged(int threshold)
{
ui->thresholdLabel->setText(QString("%1 dB").arg(ui->thresholdSlider->value()));
emit thresholdChanged(threshold);
}
/*! \brief AGC slope slider value has changed. */
void CAgcOptions::on_slopeSlider_valueChanged(int slope)
{
ui->slopeLabel->setText(QString("%1 dB").arg(ui->slopeSlider->value()));
emit slopeChanged(slope);
}
/*! \brief AGC decay slider value has changed. */
void CAgcOptions::on_decaySlider_valueChanged(int decay)
{
ui->decayLabel->setText(QString("%1 ms").arg(ui->decaySlider->value()));
emit decayChanged(decay);
}
/*! \brief AGC hang button has been toggled. */
void CAgcOptions::on_hangButton_toggled(bool checked)
{
ui->hangButton->setText(checked ? tr("Enabled") : tr("Disabled"));
emit hangChanged(checked);
}
/* -*- c++ -*- */
/*
* Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
* http://gqrx.dk/
*
* Copyright 2012-2013 Alexandru Csete OZ9AEC.
*
* Gqrx is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* Gqrx is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Gqrx; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef AGC_OPTIONS_H
#define AGC_OPTIONS_H
#include <QDialog>
#include <QCloseEvent>
namespace Ui {
class CAgcOptions;
}
/*! \brief Dialog windows with advanced AGC controls.
* \ingroup UI
*
* By default the user is presented with a combo box and a small tool button.
* The combo box contains the most common AGC presets (fast, medium, slow, user)
* plus an option to switch AGC OFF. The controls for the individual AGC parameters
* are inside this dialog and can be shown using the small tool button next to
* the combo box containing the presets.
*
* \todo A graph that shows the current AGC profile updated in real time.
*/
class CAgcOptions : public QDialog
{
Q_OBJECT
public:
explicit CAgcOptions(QWidget *parent = 0);
~CAgcOptions();
void closeEvent(QCloseEvent *event);
int gain();
void setGain(int value);
void enableGain(bool enabled);
int threshold();
void setThreshold(int value);
int slope();
void setSlope(int value);
void enableSlope(bool enabled);
int decay();
void setDecay(int value);
void enableDecay(bool enabled);
bool hang();
void setHang(bool checked);
enum agc_preset_e
{
AGC_FAST = 0, /*! decay = 500 ms, slope = 2 */
AGC_MEDIUM = 1, /*! decay = 1500 ms, slope = 2 */
AGC_SLOW = 2, /*! decay = 3000 ms, slope = 2 */
AGC_USER = 3,
AGC_OFF = 4
};
void setPreset(agc_preset_e preset);
signals:
void gainChanged(int gain);
void thresholdChanged(int threshold);
void slopeChanged(int slope);
void decayChanged(int decay);
void hangChanged(bool on);
private slots:
void on_gainSlider_valueChanged(int gain);
void on_thresholdSlider_valueChanged(int threshold);
void on_slopeSlider_valueChanged(int slope);
void on_decaySlider_valueChanged(int decay);
void on_hangButton_toggled(bool checked);
private:
Ui::CAgcOptions *ui;
};
#endif // AGC_OPTIONS_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CAgcOptions</class>
<widget class="QDialog" name="CAgcOptions">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>263</width>
<height>197</height>
</rect>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="windowTitle">
<string>AGC Settings</string>
</property>
<property name="windowIcon">
<iconset resource="../../resources/icons.qrc">
<normaloff>:/icons/icons/signal.svg</normaloff>:/icons/icons/signal.svg</iconset>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>AGC settings</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="horizontalSpacing">
<number>10</number>
</property>
<property name="verticalSpacing">
<number>5</number>
</property>
<item row="4" column="0">
<widget class="QLabel" name="label3">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Slope</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label2">
<property name="text">
<string>Threshold</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSlider" name="slopeSlider">
<property name="enabled">
<bool>false</bool>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>AGC slope</string>
</property>
<property name="maximum">
<number>10</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>0</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="thresholdLabel">
<property name="text">
<string>-100 dB</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label4">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Decay</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QPushButton" name="hangButton">
<property name="toolTip">
<string>Enable / disable AGC hang</string>
</property>
<property name="text">
<string>Disabled</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="gainLabel">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Manual gain. Used when AGC is switched off</string>
</property>
<property name="text">
<string>0 dB</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSlider" name="decaySlider">
<property name="enabled">
<bool>false</bool>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>AGC decay time</string>
</property>
<property name="minimum">
<number>50</number>
</property>
<property name="maximum">
<number>5000</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="pageStep">
<number>50</number>
</property>
<property name="value">
<number>500</number>
</property>
<property name="sliderPosition">
<number>500</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLabel" name="decayLabel">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>500 ms</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSlider" name="gainSlider">
<property name="enabled">
<bool>false</bool>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Manual gain. Used when AGC is switched off</string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label1">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Gain</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QLabel" name="slopeLabel">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>0 dB</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label5">
<property name="text">
<string>Hang</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSlider" name="thresholdSlider">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>AGC threshold (aka. knee)</string>
</property>
<property name="minimum">
<number>-160</number>
</property>
<property name="maximum">
<number>0</number>
</property>
<property name="value">
<number>-100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>gainSlider</tabstop>
<tabstop>thresholdSlider</tabstop>
<tabstop>slopeSlider</tabstop>
<tabstop>decaySlider</tabstop>
<tabstop>hangButton</tabstop>
</tabstops>
<resources>
<include location="../../resources/icons.qrc"/>
</resources>
<connections/>
</ui>
/* -*- c++ -*- */
/*
* Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
* http://gqrx.dk/
*
* Copyright 2013 Christian Lindner DL2VCL, Stefano Leucci.
*
* Gqrx is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* Gqrx is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Gqrx; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include <Qt>
#include <QFile>
#include <QStringList>
#include <QTextStream>
#include <QString>
#include <QSet>
#include <algorithm>
#include "bookmarks.h"
#include <stdio.h>
#include <wchar.h>
const QColor TagInfo::DefaultColor(Qt::lightGray);
const QString TagInfo::strUntagged("Untagged");
Bookmarks* Bookmarks::m_pThis = 0;
Bookmarks::Bookmarks()
{
TagInfo tag(TagInfo::strUntagged);
m_TagList.append(tag);
}
void Bookmarks::create()
{
m_pThis = new Bookmarks;
}
Bookmarks& Bookmarks::Get()
{
return *m_pThis;
}
void Bookmarks::setConfigDir(const QString& cfg_dir)
{
m_bookmarksFile = cfg_dir + "/bookmarks.csv";
printf("BookmarksFile is %s\n", m_bookmarksFile.toStdString().c_str());
}
void Bookmarks::add(BookmarkInfo &info)
{
m_BookmarkList.append(info);
std::stable_sort(m_BookmarkList.begin(),m_BookmarkList.end());
save();
emit( BookmarksChanged() );
}
void Bookmarks::remove(int index)
{
m_BookmarkList.removeAt(index);
save();
emit BookmarksChanged();
}
bool Bookmarks::load()
{
QFile file(m_bookmarksFile);
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
m_BookmarkList.clear();
m_TagList.clear();
// always create the "Untagged" entry.
findOrAddTag(TagInfo::strUntagged);
// Read Tags, until first empty line.
while (!file.atEnd())
{
QString line = QString::fromUtf8(file.readLine().trimmed());
if(line.isEmpty())
break;
if(line.startsWith("#"))
continue;
QStringList strings = line.split(";");
if(strings.count() == 2)
{
TagInfo &info = findOrAddTag(strings[0]);
info.color = QColor(strings[1].trimmed());
}
else
{
printf("\nBookmarks: Ignoring Line:\n %s\n", line.toLatin1().data());
}
}
std::sort(m_TagList.begin(),m_TagList.end());
// Read Bookmarks, after first empty line.
while (!file.atEnd())
{
QString line = QString::fromUtf8(file.readLine().trimmed());
if(line.isEmpty() || line.startsWith("#"))
continue;
QStringList strings = line.split(";");
if(strings.count() == 5)
{
BookmarkInfo info;
info.frequency = strings[0].toLongLong();
info.name = strings[1].trimmed();
info.modulation = strings[2].trimmed();
info.bandwidth = strings[3].toInt();
// Multiple Tags may be separated by comma.
QString strTags = strings[4];
QStringList TagList = strTags.split(",");
for(int iTag=0; iTag<TagList.size(); ++iTag)
{
info.tags.append(&findOrAddTag(TagList[iTag].trimmed()));
}
m_BookmarkList.append(info);
}
else
{
printf("\nBookmarks: Ignoring Line:\n %s\n", line.toLatin1().data());
}
}
file.close();
std::stable_sort(m_BookmarkList.begin(),m_BookmarkList.end());
emit BookmarksChanged();
return true;
}
return false;
}
//FIXME: Commas in names
bool Bookmarks::save()
{
QFile file(m_bookmarksFile);
if(file.open(QFile::WriteOnly | QFile::Truncate | QIODevice::Text))
{
QTextStream stream(&file);
stream << QString("# Tag name").leftJustified(20) + "; " +
QString(" color") << endl;
QSet<TagInfo*> usedTags;
for (int iBookmark = 0; iBookmark < m_BookmarkList.size(); iBookmark++)
{
BookmarkInfo& info = m_BookmarkList[iBookmark];
for(int iTag = 0; iTag < info.tags.size(); ++iTag)
{
TagInfo& tag = *info.tags[iTag];
usedTags.insert(&tag);
}
}
for (QSet<TagInfo*>::iterator i = usedTags.begin(); i != usedTags.end(); i++)
{
TagInfo& info = **i;
stream << info.name.leftJustified(20) + "; " + info.color.name() << endl;
}
stream << endl;
stream << QString("# Frequency").leftJustified(12) + "; " +
QString("Name").leftJustified(25)+ "; " +
QString("Modulation").leftJustified(20) + "; " +
QString("Bandwidth").rightJustified(10) + "; " +
QString("Tags") << endl;
for (int i = 0; i < m_BookmarkList.size(); i++)
{
BookmarkInfo& info = m_BookmarkList[i];
QString line = QString::number(info.frequency).rightJustified(12) +
"; " + info.name.leftJustified(25) + "; " +
info.modulation.leftJustified(20)+ "; " +
QString::number(info.bandwidth).rightJustified(10) + "; ";
for(int iTag = 0; iTag<info.tags.size(); ++iTag)
{
TagInfo& tag = *info.tags[iTag];
if(iTag!=0)
{
line.append(",");
}
line.append(tag.name);
}
stream << line << endl;
}
file.close();
return true;
}
return false;
}
QList<BookmarkInfo> Bookmarks::getBookmarksInRange(qint64 low, qint64 high)
{
BookmarkInfo info;
info.frequency=low;
QList<BookmarkInfo>::const_iterator lb = qLowerBound(m_BookmarkList, info);
info.frequency=high;
QList<BookmarkInfo>::const_iterator ub = qUpperBound(m_BookmarkList, info);
QList<BookmarkInfo> found;
while (lb != ub)
{
const BookmarkInfo& info = *lb;
//if(info.IsActive())
{
found.append(info);
}
lb++;
}
return found;
}
TagInfo &Bookmarks::findOrAddTag(QString tagName)
{
tagName = tagName.trimmed();
if (tagName.isEmpty())
tagName=TagInfo::strUntagged;
int idx = getTagIndex(tagName);
if (idx != -1)
return m_TagList[idx];
TagInfo info;
info.name=tagName;
m_TagList.append(info);
emit TagListChanged();
return m_TagList.last();
}
bool Bookmarks::removeTag(QString tagName)
{
tagName = tagName.trimmed();
// Do not delete "Untagged" tag.
if(tagName.compare(TagInfo::strUntagged, tagName)==0)
return false;
int idx = getTagIndex(tagName);
if (idx == -1)
return false;
// Delete Tag from all Bookmarks that use it.
TagInfo* pTagToDelete = &m_TagList[idx];
for(int i=0; i<m_BookmarkList.size(); ++i)
{
BookmarkInfo& bmi = m_BookmarkList[i];
for(int t=0; t<bmi.tags.size(); ++t)
{
TagInfo* pTag = bmi.tags[t];
if(pTag == pTagToDelete)
{
if(bmi.tags.size()>1) bmi.tags.removeAt(t);
else bmi.tags[0] = &findOrAddTag(TagInfo::strUntagged);
}
}
}
// Delete Tag.
m_TagList.removeAt(idx);
emit BookmarksChanged();
emit TagListChanged();
return true;
}
bool Bookmarks::setTagChecked(QString tagName, bool bChecked)
{
int idx = getTagIndex(tagName);
if (idx == -1) return false;
m_TagList[idx].active = bChecked;
emit BookmarksChanged();
emit TagListChanged();
return true;
}
int Bookmarks::getTagIndex(QString tagName)
{
tagName = tagName.trimmed();
for (int i = 0; i < m_TagList.size(); i++)
{
if (m_TagList[i].name == tagName)
return i;
}
return -1;
}
const QColor BookmarkInfo::GetColor() const
{
for(int iTag=0; iTag<tags.size(); ++iTag)
{
TagInfo& tag = *tags[iTag];
if(tag.active)
{
return tag.color;
}
}
return TagInfo::DefaultColor;
}
bool BookmarkInfo::IsActive() const
{
bool bActive = false;
for(int iTag=0; iTag<tags.size(); ++iTag)
{
TagInfo& tag = *tags[iTag];
if(tag.active)
{
bActive = true;
break;
}
}
return bActive;
}
/* -*- c++ -*- */
/*
* Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
* http://gqrx.dk/
*
* Copyright 2013 Christian Lindner DL2VCL, Stefano Leucci.
*
* Gqrx is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* Gqrx is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Gqrx; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef BOOKMARKS_H
#define BOOKMARKS_H
#include <QtGlobal>
#include <QObject>
#include <QString>
#include <QMap>
#include <QList>
#include <QStringList>
#include <QColor>
struct TagInfo
{
QString name;
QColor color;
bool active;
static const QColor DefaultColor;
static const QString strUntagged;
TagInfo()
{
active=true;
this->color=DefaultColor;
}
TagInfo(QString name)
{
active=true;
this->color=DefaultColor;
this->name = name;
}
bool operator<(const TagInfo &other) const
{
return name < other.name;
}
};
struct BookmarkInfo
{
qint64 frequency;
QString name;
QString modulation;
qint64 bandwidth;
QList<TagInfo*> tags;
BookmarkInfo()
{
this->frequency = 0;
this->bandwidth = 0;
}
/* BookmarkInfo( qint64 frequency, QString name, qint64 bandwidth, QString modulation )
{
this->frequency = frequency;
this->name = name;
this->modulation = modulation;
this->bandwidth = bandwidth;
}
*/
bool operator<(const BookmarkInfo &other) const
{
return frequency < other.frequency;
}
/*
void setTags(QString tagString);
QString getTagString();
bool hasTags(QString _tags);
bool hasTags(QStringList _tags);
*/
const QColor GetColor() const;
bool IsActive() const;
};
class Bookmarks : public QObject
{
Q_OBJECT
public:
// This is a Singleton Class now because you can not send qt-signals from static functions.
static void create();
static Bookmarks& Get();
void add(BookmarkInfo& info);
void remove(int index);
bool load();
bool save();
int size() { return m_BookmarkList.size(); }
BookmarkInfo& getBookmark(int i) { return m_BookmarkList[i]; }
QList<BookmarkInfo> getBookmarksInRange(qint64 low, qint64 high);
//int lowerBound(qint64 low);
//int upperBound(qint64 high);
QList<TagInfo> getTagList() { return QList<TagInfo>(m_TagList); }
TagInfo& findOrAddTag(QString tagName);
int getTagIndex(QString tagName);
bool removeTag(QString tagName);
bool setTagChecked(QString tagName, bool bChecked);
void setConfigDir(const QString&);
private:
Bookmarks(); // Singleton Constructor is private.
QList<BookmarkInfo> m_BookmarkList;
QList<TagInfo> m_TagList;
QString m_bookmarksFile;
static Bookmarks* m_pThis;
signals:
void BookmarksChanged(void);
void TagListChanged(void);
};
#endif // BOOKMARKS_H
/* -*- c++ -*- */
/*
* Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
* http://gqrx.dk/
*
* Copyright 2013 Christian Lindner DL2VCL, Stefano Leucci.
*
* Gqrx is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* Gqrx is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Gqrx; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include <QFile>
#include <QStringList>
#include "bookmarks.h"
#include "bookmarkstablemodel.h"
#include "dockrxopt.h"
BookmarksTableModel::BookmarksTableModel(QObject *parent) :
QAbstractTableModel(parent)
{
}
int BookmarksTableModel::rowCount ( const QModelIndex & /*parent*/ ) const
{
return m_Bookmarks.size();
}
int BookmarksTableModel::columnCount ( const QModelIndex & /*parent*/ ) const
{
return 5;
}
QVariant BookmarksTableModel::headerData ( int section, Qt::Orientation orientation, int role ) const
{
if(orientation == Qt::Horizontal && role == Qt::DisplayRole)
{
switch(section)
{
case COL_FREQUENCY:
return QString("Frequency");
break;
case COL_NAME:
return QString("Name");
break;
case COL_MODULATION:
return QString("Modulation");
break;
case COL_BANDWIDTH:
return QString("Bandwidth");
break;
case COL_TAGS:
return QString("Tag");
break;
}
}
if(orientation == Qt::Vertical && role == Qt::DisplayRole)
{
return section;
}
return QVariant();
}
QVariant BookmarksTableModel::data ( const QModelIndex & index, int role ) const
{
BookmarkInfo& info = *m_Bookmarks[index.row()];
if(role==Qt::BackgroundColorRole)
{
QColor bg(info.GetColor());
bg.setAlpha(0x60);
return bg;
}
else if(role == Qt::DisplayRole || role==Qt::EditRole)
{
switch(index.column())
{
case COL_FREQUENCY:
return info.frequency;
case COL_NAME:
return (role==Qt::EditRole)?QString(info.name):info.name;
case COL_MODULATION:
return info.modulation;
case COL_BANDWIDTH:
return (info.bandwidth==0)?QVariant(""):QVariant(info.bandwidth);
case COL_TAGS:
QString strTags;
for(int iTag=0; iTag<info.tags.size(); ++iTag)
{
if(iTag!=0)
{
strTags.append(",");
}
TagInfo& tag = *info.tags[iTag];
strTags.append(tag.name);
}
return strTags;
}
}
return QVariant();
}
bool BookmarksTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if(role==Qt::EditRole)
{
BookmarkInfo &info = *m_Bookmarks[index.row()];
switch(index.column())
{
case COL_FREQUENCY:
{
info.frequency = value.toLongLong();
emit dataChanged(index, index);
}
break;
case COL_NAME:
{
info.name = value.toString();
emit dataChanged(index, index);
return true;
}
break;
case COL_MODULATION:
{
Q_ASSERT(!value.toString().contains(";")); // may not contain a comma because tablemodel is saved as comma-separated file (csv).
if(DockRxOpt::IsModulationValid(value.toString()))
{
info.modulation = value.toString();
emit dataChanged(index, index);
}
}
break;
case COL_BANDWIDTH:
{
info.bandwidth = value.toInt();
emit dataChanged(index, index);
}
break;
case COL_TAGS:
{
info.tags.clear();
QString strValue = value.toString();
QStringList strList = strValue.split(",");
for(int i=0; i<strList.size(); ++i)
{
QString strTag = strList[i].trimmed();
info.tags.append( &Bookmarks::Get().findOrAddTag(strTag) );
}
emit dataChanged(index, index);
return true;
}
break;
}
return true; // return true means success
}
return false;
}
Qt::ItemFlags BookmarksTableModel::flags ( const QModelIndex& index ) const
{
Qt::ItemFlags flags = 0;
switch(index.column())
{
case COL_FREQUENCY:
case COL_NAME:
case COL_BANDWIDTH:
case COL_MODULATION:
flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
break;
case COL_TAGS:
flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
break;
}
return flags;
}
void BookmarksTableModel::update()
{
int iRow = 0;
m_Bookmarks.clear();
for(int iBookmark=0; iBookmark<Bookmarks::Get().size(); iBookmark++)
{
BookmarkInfo& info = Bookmarks::Get().getBookmark(iBookmark);
bool bActive = false;
for(int iTag=0; iTag<info.tags.size(); ++iTag)
{
TagInfo& tag = *info.tags[iTag];
if(tag.active)
{
bActive = true;
break;
}
}
if(bActive)
{
m_mapRowToBookmarksIndex[iRow]=iBookmark;
m_Bookmarks.append(&info);
++iRow;
}
}
emit layoutChanged();
}
BookmarkInfo *BookmarksTableModel::getBookmarkAtRow(int row)
{
return m_Bookmarks[row];
}
int BookmarksTableModel::GetBookmarksIndexForRow(int iRow)
{
return m_mapRowToBookmarksIndex[iRow];
}
/* -*- c++ -*- */
/*
* Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
* http://gqrx.dk/
*
* Copyright 2013 Christian Lindner DL2VCL, Stefano Leucci.
*
* Gqrx is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* Gqrx is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Gqrx; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef BOOKMARKSTABLEMODEL_H
#define BOOKMARKSTABLEMODEL_H
#include <QAbstractTableModel>
#include <QList>
#include "bookmarks.h"
class BookmarksTableModel : public QAbstractTableModel
{
Q_OBJECT
public:
enum EColumns
{
COL_FREQUENCY,
COL_NAME,
COL_MODULATION,
COL_BANDWIDTH,
COL_TAGS
};
explicit BookmarksTableModel(QObject *parent = 0);
int rowCount ( const QModelIndex & parent = QModelIndex() ) const;
int columnCount ( const QModelIndex & parent = QModelIndex() ) const;
QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const;
bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole );
Qt::ItemFlags flags ( const QModelIndex & index ) const;
BookmarkInfo* getBookmarkAtRow(int row);
int GetBookmarksIndexForRow(int iRow);
private:
QList<BookmarkInfo*> m_Bookmarks;
QMap<int,int> m_mapRowToBookmarksIndex;
signals:
public slots:
void update();
};
#endif
/* -*- c++ -*- */
/*
* Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
* http://gqrx.dk/
*
* Copyright 2014 Stefano Leucci, Christian Lindner DL2VCL.
*
* Gqrx is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* Gqrx is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Gqrx; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "bookmarkstaglist.h"
#include "bookmarks.h"
#include <QColorDialog>
#include <stdio.h>
#include <QMenu>
#include <QHeaderView>
BookmarksTagList::BookmarksTagList(QWidget *parent, bool bShowUntagged )
: QTableWidget(parent)
, m_bUpdating(false)
, m_bShowUntagged(bShowUntagged)
{
connect(this, SIGNAL(cellClicked(int,int)),
this, SLOT(on_cellClicked(int,int)));
// right click menu
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
this, SLOT(ShowContextMenu(const QPoint&)));
horizontalHeader()->setVisible(false);
verticalHeader()->setVisible(false);
setColumnCount(2);
setColumnWidth(0, 20);
horizontalHeader()->setStretchLastSection(true);
setSelectionMode(QAbstractItemView::SingleSelection);
setSelectionBehavior(QAbstractItemView::SelectRows);
setSortingEnabled(true);
}
void BookmarksTagList::on_cellClicked(int row, int column)
{
if(column==0)
{
changeColor(row, column);
}
if(column==1)
{
toggleCheckedState(row, column);
}
}
void BookmarksTagList::changeColor(int row, int /*column*/)
{
TagInfo &info = Bookmarks::Get().findOrAddTag(item(row, 1)->text());
QColor color = QColorDialog::getColor(info.color, this);
if(!color.isValid())
return;
info.color=color;
updateTags();
Bookmarks::Get().save();
}
void BookmarksTagList::toggleCheckedState(int row, int column)
{
QTableWidgetItem* p = item(row,column);
if(p->checkState()==Qt::Unchecked)
{
p->setCheckState(Qt::Checked);
}
else
{
p->setCheckState(Qt::Unchecked);
}
}
void BookmarksTagList::updateTags()
{
m_bUpdating = true;
// Remember which items were unchecked.
QStringList unchecked;
for(int i=0; i<rowCount(); i++)
{
if(item(i,1)->checkState()==Qt::Unchecked)
unchecked.append(item(i,1)->text());
}
// Get current List of Tags.
QList<TagInfo> newTags = Bookmarks::Get().getTagList();
if(!m_bShowUntagged)
{
for(int i=0; i<newTags.size(); ++i)
{
TagInfo& taginfo = newTags[i];
if(taginfo.name.compare(TagInfo::strUntagged)==0)
{
newTags.removeAt(i);
break;
}
}
}
// Rebuild List in GUI.
clear();
setSortingEnabled(false);
setRowCount(0);
for(int i=0; i<newTags.count(); i++)
{
AddTag(newTags[i].name,
( unchecked.contains(newTags[i].name) ? Qt::Unchecked : Qt::Checked ),
newTags[i].color);
}
setSortingEnabled(true);
m_bUpdating = false;
}
void BookmarksTagList::setSelectedTagsAsString(const QString& strTags)
{
QStringList list = strTags.split(",");
int iRows = rowCount();
for(int i=0; i<iRows; ++i)
{
QTableWidgetItem* pItem = item(i,1);
QString name = pItem->text();
bool bChecked = list.contains(name);
pItem->setCheckState(bChecked ? Qt::Checked : Qt::Unchecked);
}
setSortingEnabled(true);
}
void BookmarksTagList::setSelectedTags(QList<TagInfo*> tags)
{
int iRows = rowCount();
for(int i=0; i<iRows; ++i)
{
QTableWidgetItem* pItem = item(i,1);
QString name = pItem->text();
bool bChecked = false;
for(QList<TagInfo*>::const_iterator it=tags.begin(), itend=tags.end(); it!=itend; ++it)
{
TagInfo* pTag = *it;
if(pTag->name == name) bChecked = true;
}
pItem->setCheckState(bChecked ? Qt::Checked : Qt::Unchecked);
}
setSortingEnabled(true);
}
QString BookmarksTagList::getSelectedTagsAsString()
{
QString strResult;
int iRows = rowCount();
bool bFirst = true;
for(int i=0; i<iRows; ++i)
{
QTableWidgetItem* pItem = item(i,1);
if(pItem->checkState() == Qt::Checked)
{
if(!bFirst) strResult += ", ";
strResult += pItem->text();
bFirst = false;
}
}
return strResult;
}
void BookmarksTagList::ShowContextMenu(const QPoint& pos)
{
QMenu* menu=new QMenu(this);
// Rename currently does not work.
// The problem is that after the tag name is changed in GUI
// you can not find the right TagInfo because you dont know
// the old tag name.
#if 0
// MenuItem "Rename"
{
QAction* actionRename = new QAction("Rename", this);
menu->addAction(actionRename);
connect(actionRename, SIGNAL(triggered()), this, SLOT(RenameSelectedTag()));
}
#endif
// MenuItem "Create new Tag"
{
QAction* actionNewTag = new QAction("Create new Tag", this);
menu->addAction(actionNewTag);
connect(actionNewTag, SIGNAL(triggered()), this, SLOT(AddNewTag()));
}
// Menu "Delete Tag"
{
QAction* actionDeleteTag = new QAction("Delete Tag", this);
menu->addAction(actionDeleteTag);
connect(actionDeleteTag, SIGNAL(triggered()), this, SLOT(DeleteSelectedTag()));
}
// Menu "Select All"
{
QAction* action = new QAction("Select All", this);
menu->addAction(action);
connect(action, SIGNAL(triggered()), this, SLOT(SelectAll()));
}
// Menu "Deselect All"
{
QAction* action = new QAction("Deselect All", this);
menu->addAction(action);
connect(action, SIGNAL(triggered()), this, SLOT(DeselectAll()));
}
menu->popup(viewport()->mapToGlobal(pos));
}
#if 0
bool BookmarksTagList::RenameSelectedTag()
{
QModelIndexList selected = selectionModel()->selectedRows();
if(selected.empty())
{
return true;
}
int iRow = selected.first().row();
QTableWidgetItem* pItem = item(iRow,1);bUpdating
editItem(pItem);
//Bookmarks::Get().save();
return true;
}
#endif
void BookmarksTagList::AddNewTag()
{
AddTag("*new*");
scrollToBottom();
editItem(item(rowCount()-1, 1));
}
void BookmarksTagList::AddTag(QString name, Qt::CheckState checkstate, QColor color)
{
int i = rowCount();
setRowCount(i+1);
// Column 1
QTableWidgetItem *item = new QTableWidgetItem(name);
item->setCheckState(checkstate);
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
setItem(i, 1, item);
// Column 0
item = new QTableWidgetItem();
item->setFlags(Qt::ItemIsEnabled);
item->setBackgroundColor(color);
setItem(i, 0, item);
}
void BookmarksTagList::DeleteSelectedTag()
{
QModelIndexList selected = selectionModel()->selectedRows();
if(selected.empty())
{
return;
}
int iRow = selected.first().row();
QTableWidgetItem* pItem = item(iRow,1);
QString strTagName = pItem->text();
DeleteTag(strTagName);
return;
}
void BookmarksTagList::DeleteTag(const QString& name)
{
Bookmarks::Get().removeTag(name);
updateTags();
}
void BookmarksTagList::SelectAll()
{
int iRows = rowCount();
for(int i=0; i<iRows; ++i)
{
QTableWidgetItem* pItem = item(i,1);
QString name = pItem->text();
pItem->setCheckState(Qt::Checked);
}
}
void BookmarksTagList::DeselectAll()
{
int iRows = rowCount();
for(int i=0; i<iRows; ++i)
{
QTableWidgetItem* pItem = item(i,1);
QString name = pItem->text();
pItem->setCheckState(Qt::Unchecked);
}
}
/* -*- c++ -*- */
/*
* Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
* http://gqrx.dk/
*
* Copyright 2014 Stefano Leucci, Christian Lindner DL2VCL.
*
* Gqrx is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* Gqrx is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Gqrx; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef BOOKMARKSTAGLIST_H
#define BOOKMARKSTAGLIST_H
#include <QTableWidget>
#include "bookmarks.h"
/// A QWidget containing the List of Bookmark-Tags.
class BookmarksTagList : public QTableWidget
{
Q_OBJECT
public:
explicit BookmarksTagList(QWidget *parent = 0, bool bShowUntagged = true);
QString getSelectedTagsAsString();
void setSelectedTagsAsString(const QString& strTags);
void setSelectedTags(QList<TagInfo*> tags);
bool m_bUpdating;
private:
bool m_bShowUntagged;
signals:
public slots:
void updateTags();
void on_cellClicked(int row, int column);
void changeColor(int row, int column);
void toggleCheckedState(int row, int column);
void ShowContextMenu(const QPoint& pos);
//bool RenameSelectedTag();
void AddNewTag();
void AddTag(QString name, Qt::CheckState checkstate = Qt::Checked, QColor color = TagInfo::DefaultColor);
void DeleteSelectedTag();
void DeleteTag(const QString& name);
void SelectAll();
void DeselectAll();
};
#endif // BOOKMARKSTAGLIST_H
/* -*- c++ -*- */
/*
* Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
* http://gqrx.dk/
*
* Copyright 2011-2013 Alexandru Csete OZ9AEC.
*
* Gqrx is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* Gqrx is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Gqrx; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include <QDebug>
#include "demod_options.h"
#include "ui_demod_options.h"
/* convert between deemphasis time constant and combo-index */
const double tau_tbl[] = {
0.0, 25.0e-6, 50.0e-6, 75.0e-6, 100.0e-6, 250.0e-6, 530.0e-6, 1.0e-3
};
const int tau_tbl_maxidx = 7;
double tau_from_index(int index)
{
if (index < 0 || index > tau_tbl_maxidx)
return 0.0;
return tau_tbl[index];
}
int tau_to_index(double tau)
{
int i;
for (i = 0; i < tau_tbl_maxidx; i++)
{
if (tau < (tau_tbl[i] + 0.5 * (tau_tbl[i+1] - tau_tbl[i])))
return i;
}
return 0;
}
/* convert betweenFM max dev and combo index */
double maxdev_from_index(int index)
{
switch(index)
{
case 0:
/* Voice 2.5k */
return 2500.0;
case 1:
/* Voice 5k */
return 5000.0;
case 2:
/* APT 17k */
return 17000.0;
case 3:
/* APT 25k (17k but need some margin for Doppler and freq error) */
return 25000.0;
default:
/* Voice 5k */
qDebug() << "Invalid max_dev index: " << index;
return 5000.0;
}
}
int maxdev_to_index(double max_dev)
{
if (max_dev < 3000.0)
/* Voice 2.5k */
return 0;
else if (max_dev < 10000.0)
/* Voice 5k */
return 1;
else if (max_dev < 20000.0)
/* APT 17k */
return 2;
else
/* APT 25k */
return 3;
}
CDemodOptions::CDemodOptions(QWidget *parent) :
QDialog(parent),
ui(new Ui::CDemodOptions)
{
ui->setupUi(this);
}
CDemodOptions::~CDemodOptions()
{
delete ui;
}
/*! \brief Catch window close events.
*
* This method is called when the user closes the demod options dialog
* window using the window close icon. We catch the event and hide the
* dialog but keep it around for later use.
*/
void CDemodOptions::closeEvent(QCloseEvent *event)
{
hide();
event->ignore();
}
void CDemodOptions::setCurrentPage(int index)
{
if (index < PAGE_NUM)
ui->demodOptions->setCurrentIndex(index);
}
int CDemodOptions::currentPage() const
{
return ui->demodOptions->currentIndex();
}
void CDemodOptions::setCwOffset(int offset)
{
ui->cwOffsetSpin->setValue(offset);
}
int CDemodOptions::getCwOffset(void) const
{
return ui->cwOffsetSpin->value();
}
void CDemodOptions::setMaxDev(double max_dev)
{
ui->maxdevSelector->setCurrentIndex(maxdev_to_index(max_dev));
}
double CDemodOptions::getMaxDev(void) const
{
return maxdev_from_index(ui->maxdevSelector->currentIndex());
}
void CDemodOptions::setEmph(double tau)
{
ui->emphSelector->setCurrentIndex((tau_to_index(tau)));
}
double CDemodOptions::getEmph(void) const
{
return tau_from_index(ui->emphSelector->currentIndex());
}
void CDemodOptions::on_maxdevSelector_activated(int index)
{
emit fmMaxdevSelected(maxdev_from_index(index));
}
void CDemodOptions::on_emphSelector_activated(int index)
{
emit fmEmphSelected(tau_from_index(index));
}
void CDemodOptions::on_dcrCheckBox_toggled(bool checked)
{
emit amDcrToggled(checked);
}
void CDemodOptions::on_cwOffsetSpin_valueChanged(int value)
{
emit cwOffsetChanged(value);
}
/* -*- c++ -*- */
/*
* Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
* http://gqrx.dk/
*
* Copyright 2011-2013 Alexandru Csete OZ9AEC.
*
* Gqrx is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* Gqrx is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Gqrx; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef DEMOD_OPTIONS_H
#define DEMOD_OPTIONS_H
#include <QDialog>
#include <QCloseEvent>
namespace Ui {
class CDemodOptions;
}
/*! \brief Widget for adjusting demodulator options.
*
*/
class CDemodOptions : public QDialog
{
Q_OBJECT
public:
/*! \brief Index in the QStackedWidget. */
enum page {
PAGE_NO_OPT = 0,
PAGE_FM_OPT = 1,
PAGE_AM_OPT = 2,
PAGE_CW_OPT = 3,
PAGE_NUM = 4
};
explicit CDemodOptions(QWidget *parent = 0);
~CDemodOptions();
void closeEvent(QCloseEvent *event);
void setCurrentPage(int index);
int currentPage() const;
void setCwOffset(int offset);
int getCwOffset(void) const;
void setMaxDev(double max_dev);
double getMaxDev(void) const;
void setEmph(double tau);
double getEmph(void) const;
signals:
/*! \brief Signal emitted when new FM deviation is selected. */
void fmMaxdevSelected(double max_dev);
/*! \brief Signal emitted when new FM de-emphasis constant is selected. */
void fmEmphSelected(double tau);
/*! \brief Signal emitted when AM DCR is toggled. */
void amDcrToggled(bool enabled);
/*! \brief CW offset changed. */
void cwOffsetChanged(int offset);
private slots:
void on_maxdevSelector_activated(int index);
void on_emphSelector_activated(int index);
void on_dcrCheckBox_toggled(bool checked);
void on_cwOffsetSpin_valueChanged(int value);
private:
Ui::CDemodOptions *ui;
};
#endif // DEMOD_OPTIONS_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDemodOptions</class>
<widget class="QDialog" name="CDemodOptions">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>240</width>
<height>110</height>
</rect>
</property>
<property name="windowTitle">
<string>Mode options</string>
</property>
<property name="windowIcon">
<iconset resource="../../resources/icons.qrc">
<normaloff>:/icons/icons/signal.svg</normaloff>:/icons/icons/signal.svg</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QStackedWidget" name="demodOptions">
<property name="minimumSize">
<size>
<width>0</width>
<height>72</height>
</size>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="demodNoOpt">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>No options for
this demodulator</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="demodFmOpt">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QFormLayout" name="pagedemodFormLayout2">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="horizontalSpacing">
<number>10</number>
</property>
<property name="verticalSpacing">
<number>5</number>
</property>
<property name="leftMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="maxdevLabel">
<property name="text">
<string>Max dev</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="maxdevSelector">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Maximum FM deviation</string>
</property>
<property name="statusTip">
<string>Maximum FM deviation</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>Voice (2.5 kHz)</string>
</property>
</item>
<item>
<property name="text">
<string>Voice (5 kHz)</string>
</property>
</item>
<item>
<property name="text">
<string>APT (17 kHz)</string>
</property>
</item>
<item>
<property name="text">
<string>APT (25 kHz)</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="emphLabel">
<property name="text">
<string>Tau</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="emphSelector">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Time constant for the FM de-emphasis IIR filter.
For narrow band FM use 530 μs.
50 μs and 75 μs are used for broadcast FM depending on region.
For digital modes it is best to switch it off.</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="editable">
<bool>false</bool>
</property>
<property name="currentIndex">
<number>3</number>
</property>
<item>
<property name="text">
<string>Off</string>
</property>
</item>
<item>
<property name="text">
<string>25 μs</string>
</property>
</item>
<item>
<property name="text">
<string>50 μs</string>
</property>
</item>
<item>
<property name="text">
<string>75 μs</string>
</property>
</item>
<item>
<property name="text">
<string>100 μs</string>
</property>
</item>
<item>
<property name="text">
<string>250 μs</string>
</property>
</item>
<item>
<property name="text">
<string>530 μs</string>
</property>
</item>
<item>
<property name="text">
<string>1 ms</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="demodAmOpt">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QCheckBox" name="dcrCheckBox">
<property name="toolTip">
<string>Enable/disable DC removal.</string>
</property>
<property name="text">
<string>DCR</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page">
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>20</x>
<y>30</y>
<width>161</width>
<height>29</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>CW offset</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="cwOffsetSpin">
<property name="suffix">
<string> Hz</string>
</property>
<property name="maximum">
<number>2000</number>
</property>
<property name="value">
<number>700</number>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../resources/icons.qrc"/>
</resources>
<connections/>
</ui>
此差异已折叠。
/* -*- c++ -*- */
/*
* Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
* http://gqrx.dk/
*
* Copyright 2011-2013 Alexandru Csete OZ9AEC.
*
* Gqrx is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* Gqrx is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Gqrx; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef DOCKRXOPT_H
#define DOCKRXOPT_H
#include <QDockWidget>
#include <QSettings>
#include "agc_options.h"
#include "demod_options.h"
#include "nb_options.h"
#define FILTER_PRESET_WIDE 0
#define FILTER_PRESET_NORMAL 1
#define FILTER_PRESET_NARROW 2
#define FILTER_PRESET_USER 3
namespace Ui {
class DockRxOpt;
}
/**
* @brief Dock window with receiver options.
* @ingroup UI
*
* This dock widget encapsulates the receiver options. The controls
* are grouped in a tool box that allows packing many controls in little space.
* The UI itself is in the dockrxopt.ui file.
*
* This class also provides the signal/slot API necessary to connect
* the encapsulated widgets to the rest of the application.
*/
class DockRxOpt : public QDockWidget
{
Q_OBJECT
public:
/**
* Mode selector entries.
*
* @note If you change this enum, remember to update the TCP interface.
* @note Keep in same order as the Strings in ModulationStrings, see
* DockRxOpt.cpp constructor.
*/
enum rxopt_mode_idx {
MODE_OFF = 0, /*!< Demodulator completely off. */
MODE_RAW = 1, /*!< Raw I/Q passthrough. */
MODE_AM = 2, /*!< Amplitude modulation. */
MODE_NFM = 3, /*!< Narrow band FM. */
MODE_WFM_MONO = 4, /*!< Broadcast FM (mono). */
MODE_WFM_STEREO = 5, /*!< Broadcast FM (stereo). */
MODE_LSB = 6, /*!< Lower side band. */
MODE_USB = 7, /*!< Upper side band. */
MODE_CWL = 8, /*!< CW using LSB filter. */
MODE_CWU = 9, /*!< CW using USB filter. */
MODE_WFM_STEREO_OIRT = 10, /*!< Broadcast FM (stereo oirt). */
MODE_LAST = 11
};
explicit DockRxOpt(qint64 filterOffsetRange = 90000, QWidget *parent = 0);
~DockRxOpt();
void readSettings(QSettings *settings);
void saveSettings(QSettings *settings);
void setFilterOffsetRange(qint64 range_hz);
void setFilterParam(int lo, int hi);
void setCurrentFilter(int index);
int currentFilter() const;
void setCurrentFilterShape(int index);
int currentFilterShape() const;
void setHwFreq(qint64 freq_hz);
void setRxFreqRange(qint64 min_hz, qint64 max_hz);
int currentDemod() const;
QString currentDemodAsString();
double currentMaxdev() const;
double currentEmph() const;
double currentSquelchLevel() const;
void getFilterPreset(int mode, int preset, int * lo, int * hi) const;
int getCwOffset() const;
double getSqlLevel(void) const;
static QStringList ModulationStrings;
static QString GetStringForModulationIndex(int iModulationIndex);
static int GetEnumForModulationString(QString param);
static bool IsModulationValid(QString strModulation);
public slots:
void setRxFreq(qint64 freq_hz);
void setCurrentDemod(int demod);
void setFilterOffset(qint64 freq_hz);
void setSquelchLevel(double level);
private:
void updateHwFreq();
void updateDemodOptPage(int demod);
unsigned int filterIdxFromLoHi(int lo, int hi) const;
signals:
/** Signal emitted when receiver frequency has changed */
void rxFreqChanged(qint64 freq_hz);
/** Signal emitted when the channel filter frequency has changed. */
void filterOffsetChanged(qint64 freq_hz);
/** Signal emitted when new demodulator is selected. */
void demodSelected(int demod);
/** Signal emitted when new FM deviation is selected. */
void fmMaxdevSelected(double max_dev);
/** Signal emitted when new FM de-emphasis constant is selected. */
void fmEmphSelected(double tau);
/** Signal emitted when AM DCR status is toggled. */
void amDcrToggled(bool enabled);
/** Signal emitted when baseband gain has changed. Gain is in dB. */
//void bbGainChanged(double gain);
/** Signal emitted when squelch level has changed. Level is in dBFS. */
void sqlLevelChanged(double level);
/**
* Signal emitted when auto squelch level is clicked.
*
* @note Need current signal/noise level returned
*/
double sqlAutoClicked();
/** Signal emitted when AGC is togglen ON/OFF. */
void agcToggled(bool agc_on);
/** Signal emitted when AGC hang is toggled. */
void agcHangToggled(bool use_hang);
/** Signal emitted when AGC threshold has changed. Threshold in dB. */
void agcThresholdChanged(int value);
/** Signal emitted when AGC slope has changed. Slope is in dB.*/
void agcSlopeChanged(int slope);
/** Signal emitted when AGC decay has changed. Decay is in millisec.*/
void agcDecayChanged(int decay);
/** Signal emitted when AGC manual gain has changed. Gain is in dB.*/
void agcGainChanged(int gain);
/** Signal emitted when noise blanker status has changed. */
void noiseBlankerChanged(int nbid, bool on, double threshold);
void cwOffsetChanged(int offset);
private slots:
void on_freqSpinBox_valueChanged(double freq);
void on_filterFreq_newFrequency(qint64 freq);
void on_filterCombo_activated(int index);
void on_modeSelector_activated(int index);
void on_modeButton_clicked();
void on_agcButton_clicked();
void on_autoSquelchButton_clicked();
void on_resetSquelchButton_clicked();
//void on_agcPresetCombo_activated(int index);
void on_agcPresetCombo_currentIndexChanged(int index);
void on_sqlSpinBox_valueChanged(double value);
void on_nb1Button_toggled(bool checked);
void on_nb2Button_toggled(bool checked);
void on_nbOptButton_clicked();
// Signals coming from noise blanker pop-up
void nbOpt_thresholdChanged(int nbid, double value);
// Signals coming from demod options pop-up
void demodOpt_fmMaxdevSelected(double max_dev);
void demodOpt_fmEmphSelected(double tau);
void demodOpt_amDcrToggled(bool enabled);
void demodOpt_cwOffsetChanged(int offset);
// Signals coming from AGC options popup
void agcOpt_hangToggled(bool checked);
void agcOpt_gainChanged(int value);
void agcOpt_thresholdChanged(int value);
void agcOpt_slopeChanged(int value);
void agcOpt_decayChanged(int value);
private:
Ui::DockRxOpt *ui; /** The Qt designer UI file. */
CDemodOptions *demodOpt; /** Demodulator options. */
CAgcOptions *agcOpt; /** AGC options. */
CNbOptions *nbOpt; /** Noise blanker options. */
bool agc_is_on;
qint64 hw_freq_hz; /** Current PLL frequency in Hz. */
};
#endif // DOCKRXOPT_H
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
/* -*- c++ -*- */
/* + + + This Software is released under the "Simplified BSD License" + + +
*
* Copyright 2010 Moe Wheatley. All rights reserved.
* Copyright 2011-2013 Alexandru Csete OZ9AEC.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY Moe Wheatley ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL Moe Wheatley OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of Moe Wheatley.
*/
#pragma once
#include <QtGui>
#include <QFrame>
#include <QImage>
class CMeter : public QFrame
{
Q_OBJECT
public:
explicit CMeter(QWidget *parent = 0);
explicit CMeter(double min_level = -100.0, double max_level = 10.0,
QWidget *parent = 0);
~CMeter();
QSize minimumSizeHint() const;
QSize sizeHint() const;
void setMin(double min_level);
void setMax(double max_level);
void setRange(double min_level, double max_level);
void draw();
void UpdateOverlay(){DrawOverlay();}
public slots:
void setLevel(double dbfs);
void setSqlLevel(double dbfs);
protected:
void paintEvent(QPaintEvent *event);
void resizeEvent(QResizeEvent* event);
private:
void DrawOverlay();
QFont m_Font;
QPixmap m_2DPixmap;
QPixmap m_OverlayPixmap;
QSize m_Size;
QString m_Str;
qreal m_pixperdb; // pixels / dB
int m_Siglevel;
int m_dBFS;
qreal m_Sql;
qreal m_SqlLevel;
};
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册