/*************************************************************************** |FILENAME| - description ------------------- begin : |DATE| copyright : (C) |YEAR| by |AUTHOR| email : |EMAIL| ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * The PSK part is based on WinPSK 1.0 by Moe Wheatly, AE4JY * ***************************************************************************/ #include "linpsk.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "controlpanel.h" #include "crxdisplay.h" #include "ctxdisplay.h" #include "ctxfunctions.h" #include "parameter.h" #include "addrxwindow.h" #include "spectrumdisplay.h" #include "frequencyselect.h" #include "cledbutton.h" #include "rttymodulator.h" #include "pskmodulator.h" #include "bpskmodulator.h" #include "qpskmodulator.h" #include "mfskmodulator.h" #include "ctxbuffer.h" #include "crxchannel.h" #include "input.h" #include "textinput.h" #include "waveinput.h" #include "csound.h" #include "generalsettings.h" #include "modemenu.h" #include "macrowindow.h" #include "addmacro.h" #include "deletemacro.h" #include "macros.h" #include "qsodata.h" #include "editmacro.h" #include "deletemacro.h" #include "renamemacro.h" #include "color.h" #include "crecording.h" #include "portaudio.h" #ifdef HAVE_CONFIG #include "config.h" #else #define VERSION "0.8.1" #endif #ifdef LINPSK_FOR_MAC #define ProgramName "DarwinPSK " #else #define ProgramName "LinPSK " #endif extern Parameter settings; /* * Constructs a LinPSK as a child of 'parent', with the * name 'name' and widget flags set to 'f'. * */ LinPSK::LinPSK( QWidget* parent, const char* name, WFlags fl ) : QMainWindow( parent, name, fl ) { RxDisplay = 0; TxDisplay = 0; Control = 0; Sound = 0; if (Pa_Initialize() == paNoError ) { settings.isInitialized=true; settings.setupDevices(); } else QMessageBox::warning(0,ProgramName, "Could not initialize Soundsystem.\nCheck, if audiodevice is in use"); SaveParameters= new Parameter(); Macro =new Macros(); // Macros will be used in read_config if (! read_config()) QMessageBox::information(0,ProgramName, "LinPSK.config not found, using default values\nFile will be generated if you save the settings"); if (settings.ApplicationFont == 0) { settings.ApplicationFont = new QFont(qApp->font().family()); settings.ApplicationFont->setPixelSize(10); qApp->setFont(*settings.ApplicationFont,true); } else qApp->setFont(*settings.ApplicationFont,true); // Save Settings to be able to make local modifications *SaveParameters=settings; if(WindowColors.size() == 0 ) WindowColors.push_back(color[0]); Modulator = 0; setCentralWidget( new QWidget( this,QString(ProgramName) +QString( VERSION)) ); centralWidget()->setMinimumSize(settings.MinimumWindowWidth,settings.MinimumWindowHeight); setCaption(QString (ProgramName) + QString(VERSION)); // Create Statusbar QStatusBar *StatusBar=this->statusBar(); StatusBar->setFixedHeight(settings.StatusBarHeight); //Messages msg=new QLabel(StatusBar); StatusBar->addWidget(msg,2,true); msg->setText(tr("Ready")); // IMD IMD = new QLabel(StatusBar); StatusBar -> addWidget(IMD,1,true); //Clockadjust /** Never needed clockadj=new QLabel(StatusBar); clockadj->setText("CLK ppm = 0"); StatusBar->addWidget(clockadj,1,true); **/ // Time zeit=new QLabel(StatusBar); StatusBar->addWidget(zeit,1,true); // date datum=new QLabel(StatusBar); StatusBar ->addWidget(datum,1,true); setclock(); // Let the time pass QTimer *clock=new QTimer(this); connect(clock,SIGNAL(timeout()),SLOT(setclock())); clock->start(60000,false); RxDisplay = new CRxDisplay( centralWidget(), "RxDisplay" ); RxDisplay->setColorList(&WindowColors); TxDisplay = new CTxDisplay( centralWidget(), "TxDisplay" ); Control = new ControlPanel( centralWidget(), "Control" ); Control->Display->setColorList(&WindowColors); Control->MacroBox->updateMacroWindow(Macro); // actions // ================= File Actions ======== Open_Demo_File = new QAction( this, "Open_Demo_File" ); add_Rx_Window = new QAction( this, "add_Rx_Window" ); fileExitAction = new QAction( this, "fileExitAction" ); // ================= Help Actions ========= helpContentsAction = new QAction( this, "helpContentsAction" ); helpIndexAction = new QAction( this, "helpIndexAction" ); helpAboutAction = new QAction( this, "helpAboutAction" ); // ================= Settings ================= General_Settings = new QAction( this, "General_Settings" ); AddMacros = new QAction( this, "AddMacros" ); EditMacros = new QAction( this, "EditMacros" ); DeleteMacros = new QAction(this, "DeleteMacros"); RenameMacros = new QAction(this, "RenameMacros"); FontSettings = new QAction( this, "FontSettings" ); ColorSettings = new QAction( this, "ColorSettings" ); SaveSettings = new QAction( this, "SaveSettings" ); //================Actions for RX Window =========== Clear_RxWindow = new QAction (this,"Clear_Rx_Window"); ChangeRxMode = new QAction(this,"Change_Rx_Mode"); // menubar menubar = new QMenuBar( this, "menubar" ); fileMenu = new QPopupMenu( this ); // File Menu Open_Demo_File->addTo( fileMenu ); add_Rx_Window->addTo( fileMenu ); fileMenu->insertSeparator(); fileMenu->insertSeparator(); fileExitAction->addTo( fileMenu ); menubar->insertItem( "", fileMenu, 0 ); editMenu = new QPopupMenu( this ); // Settings Menu General_Settings->addTo( editMenu ); editMenu->insertSeparator(); AddMacros->addTo( editMenu ); EditMacros->addTo( editMenu ); DeleteMacros->addTo( editMenu ); RenameMacros->addTo( editMenu ); editMenu->insertSeparator(); FontSettings->addTo( editMenu ); ColorSettings->addTo( editMenu ); // EditFiles->addTo( editMenu ); editMenu->insertSeparator(); SaveSettings->addTo( editMenu ); menubar->insertItem( "", editMenu, 1 ); // ChangeRxParams changeRxParams = new QPopupMenu(this); ChangeRxMode->addTo(changeRxParams); changeRxParams->insertSeparator(); Clear_RxWindow->addTo(changeRxParams); menubar->insertItem("",changeRxParams,2); // menubar->insertSeparator(3); // Helpmenu helpMenu = new QPopupMenu( this ); helpContentsAction->addTo( helpMenu ); helpIndexAction->addTo( helpMenu ); helpMenu->insertSeparator(); helpAboutAction->addTo( helpMenu ); menubar->insertItem( "", helpMenu, 4 ); languageChange(); // signals and slots connections connect( fileExitAction, SIGNAL( activated() ), this, SLOT( Exit() ) ); connect( helpIndexAction, SIGNAL( activated() ), this, SLOT( helpIndex() ) ); connect( helpContentsAction, SIGNAL( activated() ), this, SLOT( helpContents() ) ); connect( helpAboutAction, SIGNAL( activated() ), this, SLOT( helpAbout() ) ); connect( Open_Demo_File, SIGNAL( activated() ), this, SLOT( fileOpen() ) ); connect( add_Rx_Window, SIGNAL( activated() ), this, SLOT( addRxWindow() ) ); //=================================Settings Menu================== connect( General_Settings, SIGNAL( activated() ),this, SLOT(generalSettings() ) ); connect( AddMacros , SIGNAL( activated() ), this, SLOT(addMacro() ) ); connect( EditMacros , SIGNAL( activated() ), this, SLOT(editMacro() ) ); connect( DeleteMacros , SIGNAL( activated() ), this, SLOT(deleteMacro() ) ); connect( RenameMacros , SIGNAL( activated() ), this, SLOT(renameMacro() ) ); //=============================================================================== connect( ColorSettings , SIGNAL( activated() ),this, SLOT(chooseColor() ) ); connect( FontSettings , SIGNAL( activated() ),this, SLOT(FontSetup() ) ); connect( SaveSettings , SIGNAL( activated() ),this, SLOT(saveSettings() )); //================================= Help Menu ==================================== connect( helpAboutAction , SIGNAL( activated() ),this, SLOT(HelpAbout() )); //================================= Rx Parames =================== connect ( ChangeRxMode , SIGNAL( activated() ),this, SLOT(setRxMode())); connect ( Clear_RxWindow , SIGNAL( activated() ),settings.ActChannel, SLOT(clearRxWindow())); //================================================================ connect(TxDisplay,SIGNAL(startRx()),this,SLOT(startRx())); connect(TxDisplay,SIGNAL(startTx()),this,SLOT(startTx())); connect(Macro,SIGNAL(StartRx()),this,SLOT(startRx())); connect(Macro,SIGNAL(StartTx()),this,SLOT(startTx())); connect(RxDisplay,SIGNAL(startPlotting(double *, bool)), Control->Display,SLOT(startPlot(double *, bool ))); connect(Control->Display,SIGNAL(FrequencyChanged(double)),RxDisplay->RxFreq,SLOT(setFrequency(double))); connect(RxDisplay,SIGNAL(new_IMD(float)),this,SLOT(setIMD(float))); connect(Control->MacroBox,SIGNAL(callMacro(int)),this,SLOT(executeMacro(int))); connect(RxDisplay,SIGNAL(newActiveChannel()),this,SLOT(setChannelParams())); connect(RxDisplay->Recording->Record,SIGNAL(toggled(bool)),this,SLOT(recording(bool))); //=================================================================== TxBuffer = new CTxBuffer(); TxDisplay->TxWindow->setTxBuffer(TxBuffer); TxTimer = new QTimer(this); connect(TxTimer,SIGNAL(timeout()),this,SLOT(process_txdata())); apply_settings(); } /* * Destroys the object and frees any allocated resources */ LinPSK::~LinPSK() { // no need to delete child widgets, Qt does it all for us } /* * Sets the strings of the subwidgets using the current * language. */ void LinPSK::languageChange() { // File Open_Demo_File->setText( tr( "Open Demo File" ) ); Open_Demo_File->setMenuText( tr( "&Open Demo File" ) ); Open_Demo_File->setAccel( tr( "Ctrl+O" ) ); fileExitAction->setText( tr( "Exit" ) ); fileExitAction->setMenuText( tr( "E&xit" ) ); fileExitAction->setAccel( QString::null ); // Help helpContentsAction->setText( tr( "Contents" ) ); helpContentsAction->setMenuText( tr( "&Contents..." ) ); helpContentsAction->setAccel( QString::null ); helpIndexAction->setText( tr( "Index" ) ); helpIndexAction->setMenuText( tr( "&Index..." ) ); helpIndexAction->setAccel( QString::null ); helpAboutAction->setText( tr( "About" ) ); helpAboutAction->setMenuText( tr( "&About" ) ); helpAboutAction->setAccel( QString::null ); add_Rx_Window->setText( tr( "add Rx Window" ) ); add_Rx_Window->setMenuText( tr( "&Add another RxWindow" ) ); // Settings General_Settings->setText( tr( "General Settings" ) ); AddMacros->setText( tr( "Add Macro" ) ); FontSettings->setText( tr( "Font Settings" ) ); ColorSettings->setText( tr( "Color Settings" ) ); EditMacros->setText( tr( "Edit Macro" ) ); DeleteMacros->setText( tr("Delete Macro") ); RenameMacros->setText( tr("Rename Macro") ); // EditFiles->setText( tr( "Edit Files" ) ); SaveSettings->setText( tr( "Save Settings" ) ); // Rx Params Clear_RxWindow->setMenuText( tr ("Clear active RX Channel") ); ChangeRxMode->setMenuText( tr ("Change Mode of active Rx Channel") ); menubar->findItem( 0 )->setText( tr( "&File" ) ); menubar->findItem( 1 )->setText( tr( "&Settings" ) ); menubar->findItem( 2 )->setText( tr( "&RxParams" ) ); menubar->findItem( 4 )->setText( tr( "&Help" ) ); } void LinPSK::fileOpen() { QString fileName; fileName = QFileDialog::getOpenFileName(0, settings.DemoModeFileType[settings.DemoTypeNumber],this); if (!fileName.isEmpty()) settings.inputFilename = fileName; } void LinPSK::Exit() { if (settings.Status == ON ) // We arejust transmitting { QMessageBox::information(0,ProgramName, "You should stop transmitting before closing this window!"); return; } else { if (RxDisplay != 0) RxDisplay->stop_process_loop(); settings=*SaveParameters; save_config(); qApp->quit(); return; } } void LinPSK::helpIndex() { } void LinPSK::helpContents() { } void LinPSK::helpAbout() { } void LinPSK::addRxWindow() { AddRxWindow *Channel=new AddRxWindow(); if ( Channel->exec() != 0) { AfcMode modus; modus=RxDisplay->RxFreq->getAfcMode(); settings.ActChannel->setAfcMode(modus); if (WindowColors.size() <= settings.RxChannels ) WindowColors.push_back(color[(settings.RxChannels*51)% 256]); Mode rxmode = (Mode) Channel->RxMode->currentItem(); RxDisplay->addRxWindow(Channel->Frequency->value(), rxmode, Channel->TitleText->text()); settings.ActChannel->setWindowColor(WindowColors.at(settings.RxChannels)); settings.RxChannels++; RxDisplay->RxFreq->setAfcDisplayMode(settings.ActChannel->AfcProperties()); } } void LinPSK::calculateSizeofComponents() { /** Anteile in percent of mainwindow **/ /** RXDisplay **/ #define RXPART 36 /** TXDisplay **/ #define TXPART 20 /** Controlpanel **/ #ifndef LINPSK_FOR_MAC #define CONTROLPART 35 #else #define CONTROLPART 40 #endif /** Statuspart **/ #define STATUSPART 3 int width,height; int xpos,ypos; int windowsheight; width=this->width(); height=this->height(); xpos=0; ypos=0;; windowsheight=height*RXPART/100; if (RxDisplay !=0 ) RxDisplay->setGeometry(xpos,ypos,width,windowsheight); ypos=ypos+windowsheight; windowsheight=height*TXPART/100; if (TxDisplay !=0) TxDisplay->setGeometry(xpos,ypos,width,windowsheight); ypos=ypos+windowsheight; windowsheight=height*CONTROLPART/100; if (Control !=0) Control->setGeometry(xpos,ypos,width,windowsheight); } void LinPSK::resizeEvent( QResizeEvent * ) { calculateSizeofComponents(); } void LinPSK::setclock() { QCString s; QDateTime t; t=QDateTime::currentDateTime(); t=t.addSecs(settings.timeoffset*3600); s.sprintf(" %2d:%2d UTC",t.time().hour(),t.time().minute()); s.replace(QRegExp(": "),":0"); zeit->setText(s); zeit->update(); s.sprintf("%2d. %s.%4d",t.date().day(),t.date().monthName(t.date().month()).data(),t.date().year()); datum->setText(s); } void LinPSK::setIMD(float IMDvalue) { QString s; if ( IMDvalue != 0.0) s.sprintf(" IMD = %6.2f dB",IMDvalue); else s.sprintf(" IMD " ); IMD->setText(s); } void LinPSK::startRx() { if ( Modulator != 0 ) { while(TxBuffer->Filled()) // Wait until Buffer is not filled qApp->processEvents(100); TxBuffer->insert(TXOFF_CODE); } else { if (Sound > 0) Sound->PTT(false); if (RxDisplay->start_process_loop()) { QString Info; TxDisplay->TxFunctions->RXTX->setStatus(OFF); if (settings.ActChannel != 0 ) switch(settings.ActChannel->getModulationType() ) { case QPSK: Info="QPSK"; break; case BPSK: Info="BPSK"; break; case RTTY: Info="RTTY"; break; case MFSK16: Info="MFSK16"; break; default: Info="undefined"; } msg->setText(tr("Receiving ")+Info); } else TxDisplay->TxFunctions->RXTX->setStatus(UNDEF); Control->Display->show(); } settings.Status=TxDisplay->TxFunctions->RXTX->getstatus(); } void LinPSK::startTx() { Mode ModulationType; QString errorstring; QString Info; double Frequency; RxDisplay->stop_process_loop(); if (settings.ActChannel == 0 ) { QMessageBox::critical(0," Programm Error! LinPsk","No active Channel available"); TxDisplay->TxFunctions->RXTX->setStatus(UNDEF); return; } ModulationType = settings.ActChannel->getModulationType(); if (TxDisplay->TxFreq->getAfcMode() != Off) // net ? TxDisplay->TxFreq->setFrequency(settings.ActChannel->getRxFrequency()); Frequency=TxDisplay->TxFreq->getFrequency(); switch (ModulationType) { case QPSK: Modulator = new QPskModulator(11025,Frequency,TxBuffer); Info="QPSK"; break; case BPSK: Modulator = new BPSKModulator(11025,Frequency,TxBuffer); Info="BPSK"; break; case RTTY: Modulator = new RTTYModulator(11025,Frequency,TxBuffer); if(settings.ActChannel->getParameter(Extra) != 0) Modulator->setParameter(Extra,settings.ActChannel->getParameter(Extra)); Info="RTTY"; break; case MFSK16: Modulator = new MFSKModulator(11025,Frequency,TxBuffer); Info="MFSK16"; break; default: Modulator = new BPSKModulator(11025,Frequency,TxBuffer); Info="BPSK"; break; } if (settings.DemoMode) { if (settings.DemoTypeNumber == 0) Sound = new WaveInput(-1); else Sound = new TextInput(-1); msg->setText(tr("Transmitting (Demo)")); } else Sound = new CSound(settings.serial); if ( Sound <= 0 ) { QMessageBox::critical(0," Programm Error! LinPsk","Could not create Sound Device for Output"); TxDisplay->TxFunctions->RXTX->setStatus(ON); return; } if (!Sound->open_Device_write(&errorstring)) { QMessageBox::information(0,ProgramName,errorstring); // TxDisplay->TxFunctions->RXTX->setStatus(UNDEF); stopTx(); return; } connect(Modulator,SIGNAL(charSend(char)),settings.ActChannel,SLOT(updateRx(char))); TxTimer->start(200,false); TxDisplay->TxFunctions->RXTX->setStatus(ON); msg->setText(tr("Transmitting ")+Info); TxDisplay->TxWindow->setFocus(); settings.Status=TxDisplay->TxFunctions->RXTX->getstatus(); Control->Display->hide(); Txcount=BUF_SIZE; process_txdata(); // Generate first Sample process_txdata(); process_txdata(); Sound->PTT(true); } void LinPSK::process_txdata() { int length; if (Txcount >0) { length = Modulator->CalcSignal(Output,BUF_SIZE); if (length <= 0) { length = -length; while (length < BUF_SIZE) Output[length++] = 0.0; length=BUF_SIZE; TxTimer->stop(); while ( (Txcount=Sound->putSamples(Output,length)) == 0 ) usleep(10000); stopTx(); return; } } else length = BUF_SIZE; Txcount=Sound->putSamples(Output,length); // If Txcount >= 0 and length < BUF_SIZE // we've reached end of Transmiision } void LinPSK::generalSettings() { GeneralSettings *LocalSettings=new GeneralSettings(this); if ( LocalSettings->exec() != 0) settings = LocalSettings->getSettings(); apply_settings(); } void LinPSK::chooseColor() { int ID =settings.ActChannel->getID(); QColor color=QColorDialog::getColor(WindowColors[ID],this); if (color.isValid()) { settings.ActChannel->setWindowColor(color); WindowColors[ID]=color; RxDisplay->repaint(); RxDisplay->RxHeader->repaint(); } } void LinPSK::FontSetup() { bool ok; QFont f=QFontDialog::getFont(&ok,font(),this); if (ok) { settings.ApplicationFont->setFamily(f.family()); int ii=f.pixelSize(); if (ii <= 0) { ii=f.pointSize(); settings.ApplicationFont->setPointSize(ii); } else settings.ApplicationFont->setPixelSize(ii); qApp->setFont(f,true); } } void LinPSK::stopTx() { TxTimer->stop(); Modulator->disconnect(); if ( Sound != 0) Sound->close_Device(); delete Modulator; Modulator = 0; startRx(); } void LinPSK::apply_settings() { selectPTTDevice(); //if(settings.ActualInputDevice >= 0) // if ( setVolume(settings.InputDevices[settings.ActualInputDevice],true,settings.InputVolume) != paNoError) // QMessageBox::critical(0," Error Mixer Device for Input","Cant't set Input Volume.\nCheck Permissions or use Mixer Application"); //if (settings.ActualOutputDevice >= 0) // if ( //setVolume(settings.OutputDevices[settings.ActualOutputDevice],false,settings.OutputVolume) != paNoError) // QMessageBox::critical(0," Error Mixer Device for Output","Can't set Output Volume. \nCheck Permissions or use Mixer Application"); } void LinPSK::setChannelParams() { Control->Display->setPhasePointer(settings.ActChannel->getPhasePointer()); Clear_RxWindow->disconnect(); Control->QSO->init(); connect ( Clear_RxWindow , SIGNAL( activated() ),settings.ActChannel, SLOT(clearRxWindow())); if (settings.ActChannel != 0 ) { QString Info; switch(settings.ActChannel->getModulationType() ) { case QPSK: Info="QPSK"; break; case BPSK: Info="BPSK"; break; case RTTY: Info="RTTY"; break; case MFSK16: Info="MFSK16"; break; // case RTTY2: // Info="RTTY2"; // break; default: Info="undefined"; } RxDisplay->RxFreq->setAfcDisplayMode(settings.ActChannel->AfcProperties()); msg->setText(tr("Receiving ")+Info); } } void LinPSK::setRxMode() { QString Info; ModeMenu Menu ; ExtraParameter *Param; Param = (ExtraParameter *) settings.ActChannel->getParameter(Extra); if (Param != 0) Menu.setParameter(*Param); if ( Menu.exec() != 0) { Mode rxmode = (Mode) Menu.RxMode->currentItem(); settings.ActChannel->setMode(rxmode); RxDisplay->RxFreq->setAfcDisplayMode(settings.ActChannel->AfcProperties()); RxDisplay->RxFreq->setAfcMode(settings.ActChannel->getAfcMode()); Control->Display->setPhasePointer(settings.ActChannel->getPhasePointer()); settings.ActChannel->setParameter(Extra,&Menu.getParameter()); } if (settings.ActChannel != 0 ) switch(settings.ActChannel->getModulationType() ) { case QPSK: Info="QPSK"; break; case BPSK: Info="BPSK"; break; case RTTY: Info="RTTY"; break; case MFSK16: Info="MFSK16"; break; default: Info="undefined"; } msg->setText(tr("Receiving ")+Info); } void LinPSK::save_config() { QFile ConfigFile("LinPSKConfig.xml"); if( QDir::setCurrent(QDir::homeDirPath()) ) { if ( ConfigFile.open(IO_WriteOnly) ) // File is writable { QDomDocument Configuration("LinpskConfiguration"); QDomElement root=Configuration.createElement("Parameters"); Configuration.appendChild(root); /** Windows Parameter **/ QDomElement Element=Configuration.createElement("WindowsParameter"); root.appendChild(Element); QDomElement MinimumWindowWidth=Configuration.createElement("MinimumWindowWidth"); Element.appendChild(MinimumWindowWidth); MinimumWindowWidth.setAttribute("Value",settings.MinimumWindowWidth); QDomElement WindowWidth=Configuration.createElement("WindowWidth"); Element.appendChild(WindowWidth); WindowWidth.setAttribute("Value",width()); QDomElement MinimumWindowHeight=Configuration.createElement("MinimumWindowHeight"); Element.appendChild(MinimumWindowHeight); MinimumWindowHeight.setAttribute("Value",settings.MinimumWindowHeight); QDomElement Xpos=Configuration.createElement("Xpos"); Element.appendChild(Xpos); Xpos.setAttribute("Value",this->x()); QDomElement Ypos=Configuration.createElement("Ypos"); Element.appendChild(Ypos); Ypos.setAttribute("Value",this->y()); QDomElement WindowHeight=Configuration.createElement("WindowHeight"); Element.appendChild(WindowHeight); WindowHeight.setAttribute("Value",height()); QDomElement StatusBarHeight=Configuration.createElement("StatusBarHeight"); Element.appendChild(StatusBarHeight); StatusBarHeight.setAttribute("Value",settings.StatusBarHeight); QDomElement Windowfont=Configuration.createElement("Font"); Element.appendChild(Windowfont); Windowfont.setAttribute("Name",qApp->font().family()); Windowfont.setAttribute("Size",qApp->font().pointSize()); /** Colors **/ if (WindowColors.size() > 0 ) { QDomElement Colors=Configuration.createElement("Colors"); root.appendChild(Colors); for(unsigned int i=0; i= 0 ) { QDomElement InputDevice=Configuration.createElement("InputDevice"); Operating.appendChild(InputDevice); InputDevice.setAttribute("Value",settings.ActualInputDevice); } if(settings.ActualOutputDevice >= 0 ) { QDomElement OutputDevice=Configuration.createElement("OutputDevice"); Operating.appendChild(OutputDevice); OutputDevice.setAttribute("Value",settings.ActualOutputDevice); } /** To be changed InputSource.setAttribute("Device",settings.SoundDevice); **/ QDomElement InputVolume=Configuration.createElement("InputVolume"); Operating.appendChild(InputVolume); InputVolume.setAttribute("Value",settings.InputVolume); QDomElement OutputVolume=Configuration.createElement("OutputVolume"); Operating.appendChild(OutputVolume); OutputVolume.setAttribute("Value",settings.OutputVolume); if ( (Macro->count() > 0) ) { QDomElement Macrosection=Configuration.createElement("Macros"); root.appendChild(Macrosection); for(unsigned int i=0; icount();i++) { QDomElement Macrodefinition=Configuration.createElement("Macro"); Macrosection.appendChild(Macrodefinition); QDomElement Name=Configuration.createElement("Name"); Macrodefinition.appendChild(Name); Name.appendChild(Configuration.createTextNode(Macro->getMacroName(i))); QDomElement Definition=Configuration.createElement("Definition"); Macrodefinition.appendChild(Definition); Definition.appendChild(Configuration.createTextNode(Macro->getDefinition(i))); QDomElement Accelerator=Configuration.createElement("Accelerator"); Macrodefinition.appendChild(Accelerator); Accelerator.appendChild(Configuration.createTextNode(Macro->getAccelerator(i))); } } QString s=Configuration.toString(); ConfigFile.writeBlock(s,s.length()); ConfigFile.close(); } else QMessageBox::critical(0,"LinPSK","Could not write LinPskConfig.xml in home directory\n"); } else QMessageBox::critical(0,"LinPSK","Could not switch to home directory \n"); } void LinPSK::executeMacro(int MacroNumber) { Macro->executeMacro(MacroNumber,TxBuffer); } void LinPSK::addMacro() { AddMacro *NewMacro = new AddMacro(); NewMacro->setKeywords(Macro); if ( NewMacro->exec() !=0 ) { Macro->insert(NewMacro->MacroName->text(), NewMacro->MacroDefinition->text(),NewMacro->Accelerator->text(),NewMacro->Position->value()); Control->MacroBox->updateMacroWindow(Macro); } } void LinPSK::editMacro() { if ( Macro->count() > 0 ) { EditMacro *Edit = new EditMacro(); Edit->init(Macro); if ( Edit->exec() !=0 ) Control->MacroBox->updateMacroWindow(Macro); } } void LinPSK::deleteMacro() { if ( Macro->count() > 0 ) { DeleteMacro *Del = new DeleteMacro(); Del->init(Macro); if ( Del->exec() != 0 ) Control->MacroBox->updateMacroWindow(Macro); } } void LinPSK::renameMacro() { if ( Macro->count() > 0 ) { RenameMacro *Ren = new RenameMacro(); Ren->init(Macro); if ( Ren->exec() != 0 ) Control->MacroBox->updateMacroWindow(Macro); } } bool LinPSK::read_config() { QFile ConfigFile("LinPSKConfig.xml"); QDomDocument Configuration("LinpskConfiguration"); QString s; int HeighttoSet = 0; int WidthtoSet = 0; int X= -1; int Y= -1; // Try to read settings from Configfile s=QDir::homeDirPath(); QDir d=QDir::home(); d.setCurrent(s.data()); if ( ConfigFile.open(IO_ReadOnly) ) // File exists and is readable { if ( !Configuration.setContent(&ConfigFile) ) { ConfigFile.close(); return false; } QDomElement root = Configuration.documentElement(); QDomNode n = root.firstChild(); while( !n.isNull() ) { s = n.nodeName(); if (s == "WindowsParameter") { if (n.hasChildNodes() ) { for(QDomNode n1=n.firstChild(); !n1.isNull(); n1=n1.nextSibling()) { QDomElement e=n1.toElement(); QString Name = e.tagName(); if (Name == "Font") { if (settings.ApplicationFont == 0 ) settings.ApplicationFont = new QFont(e.attribute("Name",qApp->font().family())); else settings.ApplicationFont->setFamily(e.attribute("Name",qApp->font().family())); int size = e.attribute("Size","10").toInt(); if (size < 10 ) size=10; settings.ApplicationFont->setPointSize(size); } else { int Value=e.attribute("Value","0").toInt(); if ( Value > 0) { if ( Name == "MinimumWindowWidth") settings.MinimumWindowWidth=Value; if ( Name == "MinimumWindowHeight") settings.MinimumWindowHeight = Value; if ( Name == "WindowWidth") WidthtoSet=Value; if ( Name == "WindowHeight") HeighttoSet = Value; if (Name == "Xpos") X = Value; if (Name == "Ypos") Y = Value; if ( Name == "StatusBarHeight") settings.StatusBarHeight = Value; } } // else } // for } } else { if ( s == "Colors" ) { int count=0; for(QDomNode n1=n.firstChild(); !n1.isNull(); n1=n1.nextSibling()) count++; WindowColors.reserve(count); count =0; for(QDomNode n1=n.firstChild(); !n1.isNull(); n1=n1.nextSibling()) { int r= n1.toElement().attribute("r","0").toInt(); int g= n1.toElement().attribute("g","0").toInt(); int b= n1.toElement().attribute("b","0").toInt(); WindowColors.push_back(QColor(r,g,b)); } } if ( s == "Mode" ) { settings.DemoTypeNumber =n.toElement().attribute("DemoTypeNumber","0").toInt(); if (n.toElement().attribute("DemoMode","true") == "true" ) settings.DemoMode =true; else { settings.DemoMode=false; settings.inputFilename=""; } } if ( s == "Operating" ) { for(QDomNode n1=n.firstChild(); !n1.isNull(); n1=n1.nextSibling()) { QString Value; QDomElement e=n1.toElement(); QString Name = e.tagName(); if ( Name == "Callsign") settings.callsign=e.text(); else Value = e.attribute("Value","0"); if ( Name == "PTT") settings.SerialDevice=e.attribute("Device",settings.SerialDevice); if ( Name == "QsoFile" ) settings.QSOFileName=e.attribute("FileName",settings.QSOFileName); if ( Name == "Timeoffset" ) settings.timeoffset = Value.toInt(); if ( Name == "InputDevice") { settings.ActualInputDevice = Value.toInt(); if ( (settings.ActualInputDevice + 1 )> settings.NumberofInputDevices ) // Device no longer available settings.ActualInputDevice = -1; } if ( Name == "OutputDevice") { settings.ActualOutputDevice = Value.toInt(); if ( (settings.ActualOutputDevice + 1 )> settings.NumberofOutputDevices ) // Device no longer available settings.ActualOutputDevice = -1; } if ( Name == "InputVolume" ) settings.InputVolume = Value.toInt(); if ( Name == "OutputVolume" ) settings.OutputVolume = Value.toInt(); if ( Name == "Slashed0") if ( Value == "true" ) settings.slashed0=true; else settings.slashed0=false; } } if ( s == "Macros" ) { /** int count=0; for(QDomNode n1=n.firstChild(); !n1.isNull(); n1=n1.nextSibling()) count++; Macro->MacroNames.reserve(count); Macro->MacroText.reserve(count); **/ int count=0; for(QDomNode n1=n.firstChild(); !n1.isNull(); n1=n1.nextSibling()) { if ( n1.hasChildNodes() ) { QString sAcc=""; QString sName=""; QString sDef=""; for(QDomNode n2=n1.firstChild(); !n2.isNull();n2=n2.nextSibling()) { QString s3; s3=n2.toElement().tagName(); if( s3 == "Name") sName=n2.toElement().text(); if(s3 == "Definition") sDef=n2.toElement().text(); if(s3 =="Accelerator" ) sAcc = n2.toElement().text(); } count++; Macro->insert(sName,sDef,sAcc,count); } } } } n = n.nextSibling(); } ConfigFile.close(); if ( ( HeighttoSet > 0 ) && (WidthtoSet >0 ) ) resize(WidthtoSet,HeighttoSet); if ( ( X >= 0 ) && ( Y >= 0) ) move (X,Y); return true; } else return false; } void LinPSK::selectPTTDevice() { //if (settings.serial >0 ) // close(settings.serial); settings.serial = -1; if (settings.SerialDevice != "None") //{ // QMessageBox::information(0,"LinPsk","Trying to open Device " + settings.SerialDevice); settings.serial=open(settings.SerialDevice,O_EXCL| O_WRONLY); // if (settings.serial > 0 ) // QMessageBox::information(0,"LinPsk","Opening successfull"); // else // QMessageBox::information(0,"LinPsk","Opening unsuccessfull"); //} int flags=TIOCM_RTS|TIOCM_DTR; if (settings.serial >0) ioctl(settings.serial,TIOCMBIC,&flags); else settings.SerialDevice="None"; //Their seems to be a wrong Value in the ConfigFile } void LinPSK::recording(bool on) { settings.ActChannel->record(on); } void LinPSK::HelpAbout() { QMessageBox::about(this,tr("About..."), ProgramName + QString(VERSION) + "\n written by Volker Schroer, DL1KSV\n"); setActiveWindow(); } void LinPSK::saveSettings() { *SaveParameters=settings; save_config(); } void LinPSK::closeEvent( QCloseEvent *e) { if (settings.Status != ON ) // We are not just transmitting { if (RxDisplay != 0) RxDisplay->stop_process_loop(); e->accept(); } else { QMessageBox::information(0,ProgramName, "You should stop transmitting before closing this window!"); e->ignore(); } return; }