Merged master 8748

This commit is contained in:
Jordan Sherer
2018-08-05 11:33:30 -04:00
parent 8f8772f1bd
commit 62899069bf
1222 changed files with 70382 additions and 406763 deletions
@@ -1,31 +0,0 @@
#ifndef PHASE_EQUALIZATION_DIALOG_HPP__
#define PHASE_EQUALIZATION_DIALOG_HPP__
#include <QObject>
#include "pimpl_h.hpp"
class QWidget;
class QSettings;
class QDir;
class PhaseEqualizationDialog
: public QObject
{
Q_OBJECT
public:
explicit PhaseEqualizationDialog (QSettings *
, QDir const& data_directory
, QVector<double> const& coefficients
, QWidget * = nullptr);
Q_SLOT void show ();
Q_SIGNAL void phase_equalization_changed (QVector<double> const&);
private:
class impl;
pimpl<impl> m_;
};
#endif
@@ -1,56 +0,0 @@
#ifndef LIVE_FREQUENCY_VALIDATOR_HPP__
#define LIVE_FREQUENCY_VALIDATOR_HPP__
#include <QObject>
#include <QRegExpValidator>
#include "Radio.hpp"
class Bands;
class FrequencyList;
class QComboBox;
class QWidget;
//
// Class LiveFrequencyValidator
//
// QLineEdit validator that controls input to an editable
// QComboBox where the user can enter a valid band or a valid
// frequency in megahetz.
//
// Collabrations
//
// Implements the QRegExpValidator interface. Validates input
// from the supplied QComboBox as either a valid frequency in
// megahertz or a valid band as defined by the supplied column of
// the supplied QAbstractItemModel.
//
class LiveFrequencyValidator final
: public QRegExpValidator
{
Q_OBJECT;
public:
using Frequency = Radio::Frequency;
LiveFrequencyValidator (QComboBox * combo_box // associated combo box
, Bands const * bands // bands model
, FrequencyList const * frequencies // working
// frequencies
// model
, Frequency const * nominal_frequency
, QWidget * parent = nullptr);
State validate (QString& input, int& pos) const override;
void fixup (QString& input) const override;
Q_SIGNAL void valid (Frequency) const;
private:
Bands const * bands_;
FrequencyList const * frequencies_;
Frequency const * nominal_frequency_;
QComboBox * combo_box_;
};
#endif
@@ -1,200 +0,0 @@
/************************************************************************/
/* */
/* Free software: Progressive edge-growth (PEG) algorithm */
/* Created by Xiaoyu Hu */
/* Evangelos Eletheriou */
/* Dieter Arnold */
/* IBM Research, Zurich Research Lab., Switzerland */
/* */
/* The C++ sources files have been compiled using xlC compiler */
/* at IBM RS/6000 running AIX. For other compilers and platforms,*/
/* minor changes might be needed. */
/* */
/* Bug reporting to: xhu@zurich.ibm.com */
/**********************************************************************/
////
// Modified by F. P. Beekhof; 2008 / 08 / 19
////
#include <cstdlib>
#include <cstring>
#include <string>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cmath>
#include <vector>
#include "BigGirth.h"
#include "Random.h"
#include "CyclesOfGraph.h"
const double EPS = 1e-6;
using namespace std;
void usage()
{
cout<<"*******************************************************************************************"<<endl;
cout<<" Usage Reminder: MainPEG -numM M -numN N -codeName CodeName -degFileName DegFileName " <<endl;
cout<<" option: -sglConcent SglConcent " <<endl;
cout<<" sglConcent==0 ----- strictly concentrated parity-check " <<endl;
cout<<" degree distribution (including regular graphs)" <<endl;
cout<<" sglConcent==1 ----- Best-effort concentrated (DEFAULT) " <<endl;
cout<<" option: -tgtGirth TgtGirth " <<endl;
cout<<" TgtGirth==4, 6 ...; if very large, then greedy PEG (DEFAULT) " <<endl;
cout<<" IF sglConcent==0, TgtGirth is recommended to be set relatively small" <<endl;
cout<<" option: -q " <<endl;
cout<<" Quiet mode. Produces less output to the screen. " <<endl;
cout<<" option: -outputMode <0,1,2> " <<endl;
cout<<" Specifies output format. " <<endl;
cout<<" '0': H in compressed format (default) " <<endl;
cout<<" '1': H in un-compressed format " <<endl;
cout<<" '2': G and H in compressed format " <<endl;
cout<<" " <<endl;
cout<<" Remarks: File CodeName stores the generated PEG Tanner graph. The first line contains"<<endl;
cout<<" the block length, N. The second line defines the number of parity-checks, M."<<endl;
cout<<" The third line defines the number of columns of the compressed parity-check "<<endl;
cout<<" matrix. The following M lines are then the compressed parity-check matrix. "<<endl;
cout<<" Each of the M rows contains the indices (1 ... N) of 1's in the compressed "<<endl;
cout<<" row of parity-check matrix. If not all column entries are used, the column "<<endl;
cout<<" is filled up with 0's. "<<endl;
cout<<" "<<endl;
cout<<" If both G and H are in the output, (outMode 2), the first line contains"<<endl;
cout<<" N, the 2nd line K, the number of message bits, the 3rd line M, the 4th line"<<endl;
cout<<" contains the number of rows of the compressed generator matrix; the 5th"<<endl;
cout<<" defines the number of columns of the compressed parity-check matrix. The"<<endl;
cout<<" format of G is almost like that of H, but vertical -- i.e. the padding"<<endl;
cout<<" zeroes are on the bottom. "<<endl;
cout<<" "<<endl;
cout<<" File DegFileName is the input file to specify the degree distribution (node "<<endl;
cout<<" perspective). The first line contains the number of various degrees. The second"<<endl;
cout<<" defines the row vector of degree sequence in the increasing order. The vector"<<endl;
cout<<" of fractions of the corresponding degree is defined in the last line. "<<endl;
cout<<" "<<endl;
cout<<" A log file called 'leftHandGirth.dat' will also be generated and stored in the"<<endl;
cout<<" current directory, which gives the girth of the left-hand subgraph of j, where"<<endl;
cout<<" 1<=j<=N. The left-hand subgraph of j is defined as all the edges emanating from"<<endl;
cout<<" bit nodes {1 ... j} and their associated nodes. "<<endl;
cout<<" "<<endl;
cout<<" The last point is, when strictly concentrated parity-check degree distribution"<<endl;
cout<<" is invoked, i.e. sglConcent==0, the girth might be weaken to some extent as "<<endl;
cout<<" compared to the generic PEG algorithm. "<<endl;
cout<<"**********************************************************************************************"<<endl;
exit(-1);
}
int main(int argc, char * argv[]){
int sglConcent=1; // default to non-strictly concentrated parity-check distribution
int targetGirth=100000; // default to greedy PEG version
std::string codeName, degFileName;
int M = -1, N = -1;
bool verbose = true;
const int OUTPUT_MODE_H_COMPRESSED = 0;
const int OUTPUT_MODE_H = 1;
const int OUTPUT_MODE_G_H_COMPRESSED = 2;
int output_mode = OUTPUT_MODE_H_COMPRESSED; // default
if (argc<9) {
usage();
}else {
for(int i=1;i<argc;++i){
if (strcmp(argv[i], "-numM")==0) {
if (++i >= argc) usage();
M=atoi(argv[i]);
} else if(strcmp(argv[i], "-numN")==0) {
if (++i >= argc) usage();
N=atoi(argv[i]);
} else if(strcmp(argv[i], "-codeName")==0) {
if (++i >= argc) usage();
codeName = argv[i];
} else if(strcmp(argv[i], "-degFileName")==0) {
if (++i >= argc) usage();
degFileName = argv[i];
} else if(strcmp(argv[i], "-sglConcent")==0) {
if (++i >= argc) usage();
sglConcent=atoi(argv[i]);
} else if(strcmp(argv[i], "-tgtGirth")==0) {
if (++i >= argc) usage();
targetGirth=atoi(argv[i]);
} else if(strcmp(argv[i], "-outputMode")==0) {
if (++i >= argc) usage();
output_mode=atoi(argv[i]);
} else if(strcmp(argv[i], "-q")==0) {
verbose=false;
} else{
usage();
}
}
if (M == -1 || N == -1) {
cout<<"Error: M or N not specified!"<<endl;
exit(-1);
}
if (M>N) {
cout<<"Error: M must be smaller than N!"<<endl;
exit(-1);
}
}
std::vector<int> degSeq(N);
ifstream infn(degFileName.c_str());
if (!infn) {cout << "\nCannot open file " << degFileName << endl; exit(-1); }
int m;
infn >>m;
std::vector<int> deg(m);
std::vector<double> degFrac(m);
for(int i=0;i<m;i++) infn>>deg[i];
for(int i=0;i<m;i++) infn>>degFrac[i];
infn.close();
double dtmp=0.0;
for(int i=0;i<m;i++) dtmp+=degFrac[i];
cout.setf(ios::fixed, ios::floatfield);
if(abs(dtmp-1.0)>EPS) {
cout.setf(ios::fixed, ios::floatfield);
cout <<"\n Invalid degree distribution (node perspective): sum != 1.0 but "<<setprecision(10)<<dtmp<<endl; exit(-1);
}
for(int i=1;i<m;++i) degFrac[i]+=degFrac[i-1];
for(int i=0;i<N;++i) {
dtmp=double(i)/double(N);
int j;
for(j=m-1;j>=0;--j) {
if(dtmp>degFrac[j]) break;
}
if(dtmp<degFrac[0]) degSeq[i]=deg[0];
else degSeq[i]=deg[j+1];
}
BigGirth bigGirth(M, N, &degSeq[0], codeName.c_str(),
sglConcent, targetGirth, verbose);
switch(output_mode)
{
case OUTPUT_MODE_H_COMPRESSED: bigGirth.writeToFile_Hcompressed(); break;
case OUTPUT_MODE_H: // different output format
bigGirth.writeToFile_Hmatrix(); break;
case OUTPUT_MODE_G_H_COMPRESSED:
// different output format: including generator matrix (compressed)
bigGirth.writeToFile(); break;
default:
cout << "Error: invalid output mode specified." << endl << endl;
usage();
}
//computing local girth distribution
if (verbose && N<10000) {
cout<<" Now computing the local girth on the global Tanner graph setting. "<<endl;
cout<<" might take a bit long time. Please wait ... "<<endl;
bigGirth.loadH();
CyclesOfGraph cog(M, N, bigGirth.H);
cog.getCyclesTable();
cog.printCyclesTable();
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

@@ -1,164 +0,0 @@
program chkfft
! Tests and times one-dimensional FFTs computed by four2a().
! An all-Fortran version of four2a() is available, but the preferred
! version uses calls to the FFTW library.
parameter (NMAX=8*1024*1024) !Maximum FFT length
complex a(NMAX),b(NMAX)
real ar(NMAX),br(NMAX)
real mflops
character infile*12,arg*8
logical list
common/patience/npatience
equivalence (a,ar),(b,br)
nargs=iargc()
if(nargs.ne.5) then
print*,'Usage: chkfft <nfft | infile> nr nw nc np'
print*,' nfft: length of FFT'
print*,' nfft=0: do lengths 2^n, n=2^4 to 2^23'
print*,' infile: name of file with nfft values, one per line'
print*,' nr: 0/1 to not read (or read) wisdom'
print*,' nw: 0/1 to not write (or write) wisdom'
print*,' nc: 0/1 for real or complex data'
print*,' np: 0-4 patience for finding best algorithm'
go to 999
endif
list=.false.
nfft=-1
call getarg(1,infile)
open(10,file=infile,status='old',err=1)
list=.true. !A valid file name was provided
go to 2
1 read(infile,*) nfft !Takje first argument to be nfft
2 call getarg(2,arg)
read(arg,*) nr
call getarg(3,arg)
read(arg,*) nw
call getarg(4,arg)
read(arg,*) ncomplex
call getarg(5,arg)
read(arg,*) npatience
call sgran()
if(list) write(*,1000) infile,nr,nw,ncomplex,npatience
1000 format(/'infile: ',a12,' nr:',i2,' nw',i2,' nc:',i2,' np:',i2/)
if(.not.list) write(*,1002) nfft,nr,nw,ncomplex,npatience
1002 format(/'nfft: ',i10,' nr:',i2,' nw',i2,' nc:',i2,' np:',i2/)
open(12,file='chkfft.out',status='unknown')
open(13,file='fftwf_wisdom.dat',status='unknown')
if(nr.ne.0) then
call import_wisdom_from_file(isuccess,13)
if(isuccess.eq.0) then
write(*,1010)
1010 format('Failed to import FFTW wisdom.')
go to 999
endif
endif
idum=-1 !Set random seed
ndim=1 !One-dimensional transforms
do i=1,NMAX !Set random data
x=gran()
y=gran()
b(i)=cmplx(x,y) !Generate random data
enddo
iters=1000000
if(list .or. (nfft.gt.0)) then
n1=1
n2=1
if(nfft.eq.-1) n2=999999
write(*,1020)
1020 format(' NFFT Time rms MHz MFlops iters', &
' tplan'/61('-'))
else
n1=4
n2=23
write(*,1030)
1030 format(' n N=2^n Time rms MHz MFlops iters', &
' tplan'/63('-'))
endif
do ii=n1,n2 !Test one or more FFT lengths
if(list) then
read(10,*,end=900) nfft !Read nfft from file
else if(n2.gt.n1) then
nfft=2**ii !Do powers of 2
endif
iformf=1
iformb=1
if(ncomplex.eq.0) then
iformf=0 !Real-to-complex transform
iformb=-1 !Complex-to-real (inverse) transform
endif
if(nfft.gt.NMAX) go to 900
a(1:nfft)=b(1:nfft) !Copy test data into a()
t0=second()
call four2a(a,nfft,ndim,-1,iformf) !Get planning time for forward FFT
call four2a(a,nfft,ndim,+1,iformb) !Get planning time for backward FFT
t2=second()
tplan=t2-t0 !Total planning time for this length
total=0.
do iter=1,iters !Now do many iterations
a(1:nfft)=b(1:nfft) !Copy test data into a()
t0=second()
call four2a(a,nfft,ndim,-1,iformf) !Forward FFT
call four2a(a,nfft,ndim,+1,iformb) !Backward FFT on same data
t1=second()
total=total+t1-t0
if(total.ge.1.0) go to 40 !Cut iterations short if t>1 s
enddo
iter=iters
40 time=0.5*total/iter !Time for one FFT of current length
tplan=0.5*tplan-time !Planning time for one FFT
if(tplan.lt.0) tplan=0.
a(1:nfft)=a(1:nfft)/nfft
! Compute RMS difference between original array and back-transformed array.
sq=0.
if(ncomplex.eq.1) then
do i=1,nfft
sq=sq + real(a(i)-b(i))**2 + imag(a(i)-b(i))**2
enddo
else
do i=1,nfft
sq=sq + (ar(i)-br(i))**2
enddo
endif
rms=sqrt(sq/nfft)
freq=1.e-6*nfft/time
mflops=5.0/(1.e6*time/(nfft*log(float(nfft))/log(2.0)))
if(n2.eq.1 .or. n2.eq.999999) then
write(*,1050) nfft,time,rms,freq,mflops,iter,tplan
write(12,1050) nfft,time,rms,freq,mflops,iter,tplan
1050 format(i8,f11.7,f12.8,f7.2,f8.1,i8,f6.1)
else
write(*,1060) ii,nfft,time,rms,freq,mflops,iter,tplan
write(12,1060) ii,nfft,time,rms,freq,mflops,iter,tplan
1060 format(i2,i8,f11.7,f12.8,f7.2,f8.1,i8,f6.1)
endif
if(mod(ii,50).eq.0) call four2a(0,-1,0,0,0)
enddo
900 continue
if(nw.eq.1) then
rewind 13
call export_wisdom_to_file(13)
! write(*,1070)
!1070 format(/'Exported FFTW wisdom')
endif
999 call four2a(0,-1,0,0,0)
end program chkfft
@@ -1,186 +0,0 @@
subroutine osd174(llr,apmask,norder,decoded,cw,nhardmin,dmin)
!
! An ordered-statistics decoder for the (174,87) code.
!
include "ldpc_174_87_params.f90"
integer*1 apmask(N),apmaskr(N)
integer*1 gen(K,N)
integer*1 genmrb(K,N),g2(N,K)
integer*1 temp(K),m0(K),me(K),mi(K)
integer indices(N),nxor(N)
integer*1 cw(N),ce(N),c0(N),hdec(N)
integer*1 decoded(K)
integer indx(N)
real llr(N),rx(N),absrx(N)
logical first
data first/.true./
save first,gen
if( first ) then ! fill the generator matrix
gen=0
do i=1,M
do j=1,22
read(g(i)(j:j),"(Z1)") istr
do jj=1, 4
irow=(j-1)*4+jj
if( btest(istr,4-jj) ) gen(irow,i)=1
enddo
enddo
enddo
do irow=1,K
gen(irow,M+irow)=1
enddo
first=.false.
endif
! re-order received vector to place systematic msg bits at the end
rx=llr(colorder+1)
apmaskr=apmask(colorder+1)
! hard decode the received word
hdec=0
where(rx .ge. 0) hdec=1
! use magnitude of received symbols as a measure of reliability.
absrx=abs(rx)
call indexx(absrx,N,indx)
! re-order the columns of the generator matrix in order of decreasing reliability.
do i=1,N
genmrb(1:K,i)=gen(1:K,indx(N+1-i))
indices(i)=indx(N+1-i)
enddo
! do gaussian elimination to create a generator matrix with the most reliable
! received bits in positions 1:K in order of decreasing reliability (more or less).
! reliability will not be strictly decreasing because column re-ordering is needed
! to put the generator matrix in systematic form. the "indices" array tracks
! column permutations caused by reliability sorting and gaussian elimination.
do id=1,K ! diagonal element indices
do icol=id,K+20 ! The 20 is ad hoc - beware
iflag=0
if( genmrb(id,icol) .eq. 1 ) then
iflag=1
if( icol .ne. id ) then ! reorder column
temp(1:K)=genmrb(1:K,id)
genmrb(1:K,id)=genmrb(1:K,icol)
genmrb(1:K,icol)=temp(1:K)
itmp=indices(id)
indices(id)=indices(icol)
indices(icol)=itmp
endif
do ii=1,K
if( ii .ne. id .and. genmrb(ii,id) .eq. 1 ) then
genmrb(ii,1:N)=ieor(genmrb(ii,1:N),genmrb(id,1:N))
endif
enddo
exit
endif
enddo
enddo
g2=transpose(genmrb)
! The hard decisions for the K MRB bits define the order 0 message, m0.
! Encode m0 using the modified generator matrix to find the "order 0" codeword.
! Flip various combinations of bits in m0 and re-encode to generate a list of
! codewords. Test all such codewords against the received word to decide which
! codeword is most likely to be correct.
hdec=hdec(indices) ! hard decisions from received symbols
m0=hdec(1:K) ! zero'th order message
absrx=absrx(indices)
rx=rx(indices)
apmaskr=apmaskr(indices)
s1=sum(absrx(1:K))
s2=sum(absrx(K+1:N))
xlam=7.0 ! larger values reject more error patterns
rho=s1/(s1+xlam*s2)
call mrbencode(m0,c0,g2,N,K)
nxor=ieor(c0,hdec)
nhardmin=sum(nxor)
dmin=sum(nxor*absrx)
thresh=rho*dmin
cw=c0
nt=0
nrejected=0
do iorder=1,norder
mi(1:K-iorder)=0
mi(K-iorder+1:K)=1
iflag=0
do while(iflag .ge. 0 )
if(all(iand(apmaskr(1:K),mi).eq.0)) then ! reject patterns with ap bits
dpat=sum(mi*absrx(1:K))
nt=nt+1
if( dpat .lt. thresh ) then ! reject unlikely error patterns
me=ieor(m0,mi)
call mrbencode(me,ce,g2,N,K)
nxor=ieor(ce,hdec)
dd=sum(nxor*absrx)
if( dd .lt. dmin ) then
dmin=dd
cw=ce
nhardmin=sum(nxor)
thresh=rho*dmin
endif
else
nrejected=nrejected+1
endif
endif
! get the next test error pattern, iflag will go negative
! when the last pattern with weight iorder has been generated
call nextpat(mi,k,iorder,iflag)
enddo
enddo
!write(*,*) 'nhardmin ',nhardmin
!write(*,*) 'total patterns ',nt,' number rejected ',nrejected
! re-order the codeword to place message bits at the end
cw(indices)=cw
hdec(indices)=hdec
decoded=cw(M+1:N)
cw(colorder+1)=cw ! put the codeword back into received-word order
return
end subroutine osd174
subroutine mrbencode(me,codeword,g2,N,K)
integer*1 me(K),codeword(N),g2(N,K)
! fast encoding for low-weight test patterns
codeword=0
do i=1,K
if( me(i) .eq. 1 ) then
codeword=ieor(codeword,g2(1:N,i))
endif
enddo
return
end subroutine mrbencode
subroutine nextpat(mi,k,iorder,iflag)
integer*1 mi(k),ms(k)
! generate the next test error pattern
ind=-1
do i=1,k-1
if( mi(i).eq.0 .and. mi(i+1).eq.1) ind=i
enddo
if( ind .lt. 0 ) then ! no more patterns of this order
iflag=ind
return
endif
ms=0
ms(1:ind-1)=mi(1:ind-1)
ms(ind)=1
ms(ind+1)=0
if( ind+1 .lt. k ) then
nz=iorder-sum(ms)
ms(k-nz+1:k)=1
endif
mi=ms
iflag=ind
return
end subroutine nextpat
@@ -0,0 +1,68 @@
!subroutine symspec65(dd,npts,ss,nqsym,savg)
subroutine symspec65(dd,npts,nqsym,savg)
! Compute JT65 symbol spectra at quarter-symbol steps
parameter (NFFT=8192)
parameter (NSZ=3413) !NFFT*5000/12000
parameter (MAXHSYM=322)
parameter (MAXQSYM=552)
real*8 hstep
real*4 dd(npts)
! real*4 ss(MAXHSYM,NSZ)
real*4 ss(MAXQSYM,NSZ)
real*4 savg(NSZ)
real*4 x(NFFT)
real*4 w(NFFT)
complex c(0:NFFT/2)
logical first
common/refspec/dfref,ref(NSZ)
equivalence (x,c)
data first/.true./
save /refspec/,first,w
common/sync/ss
hstep=2048.d0*12000.d0/11025.d0 !half-symbol = 2229.116 samples
qstep=hstep/2.0 !quarter-symbol = 1114.558 samples
nsps=nint(2*hstep)
df=12000.0/NFFT
nhsym=(npts-NFFT)/hstep
nqsym=(npts-NFFT)/qstep
savg=0.
fac1=1.e-3
if(first) then
! Compute the FFT window
! width=0.25*nsps
do i=1,NFFT
! z=(i-NFFT/2)/width
w(i)=1
if(i.gt.4458) w(i)=0
! w(i)=exp(-z*z)
enddo
first=.false.
endif
do j=1,nqsym
i0=(j-1)*qstep
x=fac1*w*dd(i0+1:i0+NFFT)
call four2a(c,NFFT,1,-1,0) !r2c forward FFT
do i=1,NSZ
s=real(c(i))**2 + aimag(c(i))**2
ss(j,i)=s
savg(i)=savg(i)+s
enddo
enddo
savg=savg/nhsym
! call flat65(ss,nhsym,MAXQSYM,NSZ,ref) !Flatten the 2d spectrum, saving
call flat65(ss,nqsym,MAXQSYM,NSZ,ref) !Flatten the 2d spectrum, saving
dfref=df ! the reference spectrum ref()
savg=savg/ref
! do j=1,nhsym
do j=1,nqsym
ss(j,1:NSZ)=ss(j,1:NSZ)/ref
enddo
return
end subroutine symspec65
@@ -1,41 +0,0 @@
// -*- Mode: C++ -*-
#ifndef DISPLAYTEXT_H
#define DISPLAYTEXT_H
#include <QTextEdit>
#include "logbook/logbook.h"
#include "decodedtext.h"
class DisplayText : public QTextEdit
{
Q_OBJECT
public:
explicit DisplayText(QWidget *parent = 0);
void setContentFont (QFont const&);
void insertLineSpacer(QString const&);
void displayDecodedText(DecodedText decodedText, QString myCall, bool displayDXCCEntity,
LogBook logBook, QColor color_CQ, QColor color_MyCall,
QColor color_DXCC, QColor color_NewCall);
void displayTransmittedText(QString text, QString modeTx, qint32 txFreq,
QColor color_TxMsg, bool bFastMode);
void displayQSY(QString text);
signals:
void selectCallsign(bool shift, bool ctrl);
public slots:
void appendText(QString const& text, QString const& bg = "white");
protected:
void mouseDoubleClickEvent(QMouseEvent *e);
private:
void _appendDXCCWorkedB4(/*mod*/DecodedText& t1, QString &bg, LogBook logBook,
QColor color_CQ, QColor color_DXCC, QColor color_NewCall);
QTextCharFormat m_charFormat;
};
#endif // DISPLAYTEXT_H