Logo Search packages:      
Sourcecode: sailcut version File versions  Download package

formdef.cpp

/*
 * Copyright (C) 1993-2005 Robert & Jeremy Lainé
 * See AUTHORS file for a full list of contributors.
 *
 * $Id: formdef.cpp,v 1.75 2005/10/23 17:53:57 sailcuter Exp $
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "formdef.h"
#include <QLabel>
#include <QMessageBox>
#include <QRadioButton>
#include <QLineEdit>
#include "sailworker.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

/** The constructor.
 *
 * @param parent the parent window
 * @param sailptr pointer to the CSailDef
 */
00038 CFormDef::CFormDef( QWidget* parent, CSailDef * sailptr )
        : QDialog(parent)
{
    setupUi(this);
    setModal(true);

    /* we store the pointer to the CSailDef so we can update it when
       the user clicks OK */
    saildef = sailptr;

    setSailCut( saildef->sailCut );
    setSailType( saildef->sailType );

    txtSailID->setText(QString(saildef->sailID));

    txtLOA->setText( QString::number(saildef->LOA ) );
    txtTriangBase->setText( QString::number(saildef->foreJ ) );
    txtTriangHoist->setText( QString::number(saildef->foreI ) );

    txtClothWidth->setText( QString::number( saildef->clothW ) );
    txtSeamWidth->setText( QString::number( saildef->seamW ) );
    txtLeechHemWidth->setText( QString::number( saildef->leechHemW ) );
    txtHemsWidth->setText( QString::number( saildef->hemsW ) );

    txtTackDist->setText( QString::number( saildef->tackX ) );
    txtTackHeight->setText( QString::number( saildef->tackY ) );
    txtRake->setText( QString::number( saildef->rake ) );

    txtLuffLen->setText( QString::number( saildef->luffL ) );
    txtLuffRound->setText( QString::number( saildef->luffR ) );
    txtLuffRoundPos->setText( QString::number( saildef->luffRP ) );

    txtGaffAngle->setText( QString::number( saildef->gaffDeg ) );
    txtGaffLen->setText( QString::number( saildef->gaffL ) );
    txtGaffRound->setText( QString::number( saildef->gaffR ) );

    txtLeechLen->setText( QString::number( saildef->leechL ) );
    txtLeechRound->setText( QString::number( saildef->leechR ) );
    txtLeechRoundPos->setText( QString::number( saildef->leechRP ) );

    txtFootLen->setText( QString::number( saildef->footL ) );
    txtFootRound->setText( QString::number( saildef->footR ) );

    txtTopDepth->setText ( QString::number( saildef->mould.profile[2].getDepth()*100 ) );
    txtMidDepth->setText ( QString::number( saildef->mould.profile[1].getDepth()*100 ) );
    txtFootDepth->setText ( QString::number( saildef->mould.profile[0].getDepth()*100 ) );

    txtTwistAngle->setText ( QString::number( saildef->twistDeg ) );
    txtSheetAngle->setText ( QString::number( saildef->sheetDeg ) );

    txtSections->setText ( QString::number( saildef->nbSections ) );
    txtGores->setText ( QString::number( saildef->nbGores ) );
    txtLuffGores->setText (QString::number( saildef->nbLuffGores ) );

    txtDihedral->setText ( QString::number( saildef->dihedralDeg ) );

    // radioRadial->setEnabled(false);

    // create button group for sail type
    QButtonGroup *bgrpSailType = new QButtonGroup( this );
    bgrpSailType->addButton( radioMainSail );
    bgrpSailType->addButton( radioJib );
    bgrpSailType->addButton( radioWing );

    // create button group for sail cut
    QButtonGroup *bgrpSailCut = new QButtonGroup( this );
    bgrpSailCut->addButton( radioCross );
    bgrpSailCut->addButton( radioTwist );
    bgrpSailCut->addButton( radioHorizontal );
    bgrpSailCut->addButton( radioVertical );
    bgrpSailCut->addButton( radioMitre );
    bgrpSailCut->addButton( radioRadial );

    // signals and slots connections
    connect( btnOK, SIGNAL( clicked() ), this, SLOT( accept() ) );
    connect( btnCancel, SIGNAL( clicked() ), this, SLOT( reject() ) );
    connect( btnCompute, SIGNAL( pressed() ), this, SLOT( slotCompute() ) );
    connect( bgrpSailType, SIGNAL( buttonClicked(QAbstractButton *) ), this, SLOT( slotSailType() ) );
    connect( bgrpSailCut, SIGNAL( buttonClicked(QAbstractButton *) ), this, SLOT( slotSailCut() ) );

    // calculate sail area and diagonal and display it
    compute();
}


/** The destructor.
 */
00125 CFormDef::~CFormDef()
{}



// member functions

/** Compute and Display ancillary data of the sail computation*/
00133 void CFormDef::compute()
{
    CSailWorker worker(*saildef);
    lblSailArea->setText ( QString::number( worker.Area() ) );
    lblDiagonal->setText ( QString::number( worker.Diagonal() ) );
}


/** Returns the sail cut from the form. */
00142 enumSailCut CFormDef::getSailCut()
{
    if ( radioHorizontal->isChecked() )
        return HORIZONTAL;
    else if ( radioMitre->isChecked() )
        return MITRE;
    else if ( radioRadial->isChecked() )
        return RADIAL;
    else if ( radioTwist->isChecked() )
        return TWIST;
    else if ( radioVertical->isChecked() )
        return VERTICAL;
    else
        /* default */
        return CROSS;
}


/** Returns the sail type from the form. */
00161 enumSailType CFormDef::getSailType()
{
    if ( radioJib->isChecked() )
        return JIB;
    else if ( radioWing->isChecked() )
        return WING;
    else
        /* default */
        return MAINSAIL;
}


/** Enables or disables appropriate controls depending
 *  on the sail cut.
 */
00176 void CFormDef::setSailCut( enumSailCut cut )
{
    switch ( cut )
    {
    case CROSS:
        radioCross->setChecked( true );
        break;
    case HORIZONTAL:
        radioHorizontal->setChecked( true );
        break;
    case RADIAL:
        radioRadial->setChecked( true );
        break;
    case TWIST:
        radioTwist->setChecked( true );
        break;
    case VERTICAL:
        radioVertical->setChecked( true );
        break;
    case MITRE:
        radioMitre->setChecked( true );
        break;
    }
}


/** Enables or disables appropriate controls depending
 *  on the sail type.
 */
00205 void CFormDef::setSailType( enumSailType type )
{
    switch ( type )
    {
    case MAINSAIL:
        //qDebug("setSailType( MAINSAIL )");

        radioMainSail->setChecked( true );
        txtTackDist->setEnabled( true );
        txtTackHeight->setEnabled( true );
        txtRake->setEnabled( true );

        txtTriangBase->setEnabled( true );
        txtTriangHoist->setEnabled( true );

        txtGaffLen->setEnabled( true );
        txtGaffRound->setEnabled( true );
        txtGaffAngle->setEnabled( true );

        txtDihedral->setEnabled( false );
        radioCross->setEnabled( true );
        radioHorizontal->setEnabled( true );
        radioRadial->setEnabled( true );
        radioTwist->setEnabled( true );
        radioVertical->setEnabled( true );
        radioMitre->setEnabled( true );
        break;

    case JIB:
        //qDebug("setSailType( JIB )");

        radioJib->setChecked( true );
        txtTackDist->setEnabled( false );
        txtTackHeight->setEnabled( true );
        txtRake->setEnabled( false );

        txtTriangBase->setEnabled( true );
        txtTriangHoist->setEnabled( true );

        txtGaffLen->setEnabled( true );
        txtGaffRound->setEnabled( true );
        txtGaffAngle->setEnabled( true );

        txtDihedral->setEnabled( false );
        radioCross->setEnabled( true );
        radioHorizontal->setEnabled( true );
        radioRadial->setEnabled( true );
        radioTwist->setEnabled( true );
        radioVertical->setEnabled( true );
        radioMitre->setEnabled( true );
        break;

    case WING:
        //qDebug("setSailType( WING )");

        radioWing->setChecked( true );
        txtTackDist->setEnabled( true );
        txtTackHeight->setEnabled( true );
        txtRake->setEnabled( true );

        txtTriangBase->setEnabled( true );
        txtTriangHoist->setEnabled( true );

        txtGaffLen->setEnabled( false );
        txtGaffRound->setEnabled( false );
        txtGaffAngle->setEnabled( false );

        txtDihedral->setEnabled( true );
        radioHorizontal->setChecked( true );
        radioCross->setEnabled( false );
        //radioHorizontal->setEnabled( true );
        radioRadial->setEnabled( false );
        radioTwist->setEnabled( false );
        radioVertical->setEnabled( false );
        radioMitre->setEnabled( false );
        break;

    }
}


// Qt overrides

/** Saves the parameters entered by the user in the CSailDef.
 *  slot connected to OK button
 */
00291 void CFormDef::accept()
{
    // return data if everything is OK. /////////////////////////
    if (check() ==true)
        QDialog::accept();
}


/** Check all dimensions entered in order
 *  to make sure that the sail is possible and reasonable
 */
00302 bool CFormDef::check()
{
    long L1=1, L2=1;
    real A1=0, A2=0;
    bool flag=true;
    QString txt;
    ///  create four palettes
    QPalette palStd, palHi, palLo, palRel;
    palStd = txtLuffLen->palette();
    palLo = palHi = palRel = palStd;
    palLo.setColor( QPalette::Text, Qt::magenta); // too low value
    palHi.setColor( QPalette::Text, Qt::red );    // too high value
    palRel.setColor( QPalette::Text, Qt::blue );  // related value to be checked

    ///  start collecting data
    saildef->sailCut = getSailCut();
    saildef->sailType = getSailType();
    txt = txtSailID->text();
    txt = txt.simplified();

    ///  check the sail ID text
    if (txt.length() > 40)
    {
        txt.truncate(40);
        flag = false;
        txtSailID->setPalette(palHi);
        txtSailID->setText(QString(txt));
    }
    else
    {
        txtSailID->setPalette(palStd);
        txtSailID->setText(QString(txt));
    }
    saildef->sailID = txt;

    ///  check length of boat and fore triangle wrt length of boat
    saildef->LOA = txtLOA->text().toDouble();

    if (saildef->LOA < 100)
    {
        flag = false;
        txtLOA->setPalette(palLo);
        saildef->LOA = 100;
    }
    else if (saildef->LOA > 100000)
    {
        flag = false;
        txtLOA->setPalette(palHi);
        saildef->LOA = 100000;
    }
    else
    {
        txtLOA->setPalette(palStd);
    }
    txtLOA->setText(QString::number(saildef->LOA));

    saildef->foreJ = txtTriangBase->text().toDouble();

    L1 = (long)(saildef->LOA);

    if (saildef->foreJ > 0.8* L1)
    {
        flag = false;
        txtTriangBase->setPalette(palHi);
        txtLOA->setPalette(palRel);
        saildef->foreJ = floor(0.8*L1);
    }
    else   if (saildef->foreJ < 0.1* L1)
    {
        flag = false;
        txtTriangBase->setPalette(palLo);
        txtLOA->setPalette(palRel);
        saildef->foreJ = ceil(0.1*L1);
    }
    else
    {
        txtTriangBase->setPalette(palStd);
        txtLOA->setPalette(palStd);
    }
    txtTriangBase->setText(QString::number(saildef->foreJ));

    saildef->foreI = txtTriangHoist->text().toDouble();

    if (saildef->foreI > 3*L1)
    {
        flag = false;
        txtTriangHoist->setPalette(palHi);
        txtLOA->setPalette(palRel);
        saildef->foreI = 3*L1;
    }
    else if (saildef->foreI < 0.3*L1)
    {
        flag = false;
        txtTriangHoist->setPalette(palLo);
        txtLOA->setPalette(palRel);
        saildef->foreI = ceil( 0.3*L1);
    }
    else
    {
        txtTriangBase->setPalette(palStd);
        txtLOA->setPalette(palStd);
    }
    txtTriangHoist->setText(QString::number(saildef->foreI));

    ///  check tack position
    L1 = (long)(saildef->LOA);

    saildef->tackX  = txtTackDist->text().toDouble();
    if (saildef->tackX > 0.8*L1)
    {
        flag = false;
        txtTackDist->setPalette(palHi);
        txtLOA->setPalette(palRel);
        saildef->tackX = floor(0.8*L1);
    }
    else
    {
        txtTackDist->setPalette(palStd);
        txtLOA->setPalette(palStd);
    }
    txtTackDist->setText(QString::number(saildef->tackX));

    saildef->tackY  = txtTackHeight->text().toDouble();
    L1 = (long)(saildef->foreI);

    saildef->tackY  = txtTackHeight->text().toDouble();
    if (saildef->tackY > 0.3*L1)
    {
        flag = false;
        txtTackHeight->setPalette(palHi);
        txtTriangHoist->setPalette(palRel);
        saildef->tackY = floor(0.3*L1);
    }
    else
    {
        txtTackHeight->setPalette(palStd);
        txtTriangHoist->setPalette(palStd);
    }
    txtTackHeight->setText(QString::number(saildef->tackY));

    ///  get data on the sides of sail
    saildef->luffL  = txtLuffLen->text().toDouble();
    saildef->luffR  = txtLuffRound->text().toDouble();
    saildef->luffRP = txtLuffRoundPos->text().toInt();

    saildef->gaffDeg = txtGaffAngle->text().toDouble();
    saildef->gaffL  = txtGaffLen->text().toDouble();
    saildef->gaffR  = txtGaffRound->text().toDouble();

    saildef->leechL = txtLeechLen->text().toDouble();
    saildef->leechR = txtLeechRound->text().toDouble();
    saildef->leechRP = txtLeechRoundPos->text().toInt();

    saildef->footL  = txtFootLen->text().toDouble();
    saildef->footR  = txtFootRound->text().toDouble();

    ///  check  rake
    saildef->rake   = txtRake->text().toDouble();

    switch (saildef->sailType )
    {
    case WING:
        L1 = (long)(saildef->luffL);
        if (saildef->rake > L1)
        {
            flag = false;
            txtRake->setPalette(palHi);
            saildef->rake =L1 - 1;
        }
        else if (saildef->rake < 0)
        {
            flag = false;
            txtRake->setPalette(palHi);
            saildef->rake =0;
        }
        else
        {
            txtRake->setPalette(palStd);
        }
        txtRake->setText(QString::number(saildef->rake));
        break;

    default:
        L1 = (long)(saildef->foreI);
        if (saildef->rake > 0.3*L1)
        {
            flag = false;
            txtRake->setPalette(palHi);
            txtTriangHoist->setPalette(palRel);
            saildef->rake = floor(0.3*L1 - 1);
        }
        else if (saildef->rake < -0.3*L1)
        {
            flag = false;
            txtRake->setPalette(palHi);
            txtTriangHoist->setPalette(palRel);
            saildef->rake =-floor(0.3*L1);
        }
        else
        {
            txtRake->setPalette(palStd);
            txtTriangHoist->setPalette(palStd);
        }
        txtRake->setText(QString::number(saildef->rake));
        break;
    }

    ///  check luff length and round, gaff length
    L1 = (long)(saildef->LOA);

    switch (saildef->sailType )
    {
    case MAINSAIL:
        L1 = (long) (saildef->foreI);
        if (saildef->luffL > 3*L1)
        {
            flag=false;
            txtTriangHoist->setPalette(palRel);
            txtLuffLen->setPalette(palHi);
            saildef->luffL = 3*L1;
        }
        else if (saildef->luffL < 0.3*L1)
        {
            flag=false;
            txtTriangHoist->setPalette(palRel);
            txtLuffLen->setPalette(palLo);
            saildef->luffL = 1 + 0.3*L1;
        }
        else
        {
            txtTriangHoist->setPalette(palStd);
            txtLuffLen->setPalette(palStd);
        }
        txtLuffLen->setText(QString::number(saildef->luffL));

        L2 =(long) ((saildef->luffL )/ 10); // luff round limit

        if (saildef->luffR > L2)
        {
            flag=false;
            txtLuffRound->setPalette(palHi);
            saildef->luffR = L2;
        }
        else if (saildef->luffR <0)
        {
            flag=false;
            txtLuffRound->setPalette(palLo);
            saildef->luffR = 0;
        }
        else
        {
            txtLuffRound->setPalette(palStd);
        }
        txtLuffRound->setText(QString::number(saildef->luffR) );

        // check main sail gaff length
        L1 =(long) (5);
        L2 =(long) (3 * saildef->luffL);

        if (saildef->gaffL < L1)
        {
            txtGaffLen->setPalette(palLo);
            saildef->gaffL= L1;
            flag = false;
        }
        else if (saildef->gaffL > L2)
        {
            txtGaffLen->setPalette(palHi);
            saildef->gaffL= L2;
            flag = false;
        }
        else
        {
            txtGaffLen->setPalette(palStd);
        }
        txtGaffLen->setText(QString::number(saildef->gaffL) );

        // check gaff round
        L1 = (long) ((saildef->gaffL )/ 8);

        if (saildef->gaffR > L1)
        {
            flag=false;
            txtGaffRound->setPalette(palHi);
            saildef->gaffR = L1;
        }
        else if (saildef->gaffR <0)
        {
            flag=false;
            txtGaffRound->setPalette(palLo);
            saildef->gaffR = 0;
        }
        else
        {
            txtGaffRound->setPalette(palStd);
        }
        txtGaffRound->setText(QString::number(saildef->gaffR) );

        break;

    case JIB:
        L1 =( long) (sqrt(((saildef->foreI - saildef->tackY) * (saildef->foreI - saildef->tackY)) + (saildef->foreJ * saildef->foreJ ))-1);
        if (saildef->luffL > L1)
        {
            flag=false;
            txtTriangHoist->setPalette(palRel);
            txtTackHeight->setPalette(palRel);
            txtLuffLen->setPalette(palHi);
            saildef->luffL = int (L1);
        }
        else if (saildef->luffL < L1/10)
        {
            flag=false;
            txtLuffLen->setPalette(palLo);
            saildef->luffL = int(1+real(L1)/10);
        }
        else
        {
            txtTriangHoist->setPalette(palStd);
            txtTackHeight->setPalette(palStd);
            txtLuffLen->setPalette(palStd);
        }
        txtLuffLen->setText(QString::number(saildef->luffL) );

        L2 = (long) ((saildef->luffL )/ 10); // round limit

        if (saildef->luffR > L2)
        {
            flag=false;
            txtLuffRound->setPalette(palHi);
            saildef->luffR = L2;
        }
        else if (saildef->luffR <-L2)
        {
            flag=false;
            txtLuffRound->setPalette(palLo);
            saildef->luffR = -L2;
        }
        else
        {
            txtLuffRound->setPalette(palStd);
        }
        txtLuffRound->setText(QString::number(saildef->luffR) );

        /// check jib gaff length
        L1 =(long) (1);
        L2 =(long) (70);

        if (saildef->gaffL < L1)
        {
            txtGaffLen->setPalette(palLo);
            saildef->gaffL = L1;
            flag = false;
        }
        else if (saildef->gaffL > L2)
        {
            txtGaffLen->setPalette(palHi);
            saildef->gaffL = L2;
            flag = false;
        }
        else
        {
            txtGaffLen->setPalette(palStd);
        }
        txtGaffLen->setText(QString::number(saildef->gaffL) );

        // reset gaff round
        txtGaffRound->setPalette(palStd);
        txtGaffRound->setText(QString::number(0) );

        break;

    case WING:
        ///  set gaff to minimum
        saildef->gaffL = 2;
        txtGaffLen->setText(QString::number(saildef->gaffL) );
        saildef->gaffR = 0;
        txtGaffRound->setText(QString::number(saildef->gaffR) );

        // check gaff angle and set it to be horizontal
        A1 = saildef->rake / saildef->luffL;
        saildef->gaffDeg = acos (A1) * 180/PI;
        txtGaffAngle->setText(QString::number(floor(saildef->gaffDeg)) );

        // adjust leech length such that foot is horizontal
        A1 = saildef->rake + saildef->gaffL - saildef->footL;
        A2 = saildef->luffL * sin(saildef->gaffDeg * PI/180);

        saildef->leechL = floor(sqrt( A1*A1 + A2*A2 ) );
        txtLeechLen->setText(QString::number(saildef->leechL) );

        L2 =(long) ((saildef->luffL )/ 4); // wing luff round limit

        if (saildef->luffR > L2)
        {
            flag=false;
            txtLuffRound->setPalette(palHi);
            saildef->luffR = L2;
        }
        else if (saildef->luffR <0)
        {
            flag=false;
            txtLuffRound->setPalette(palLo);
            saildef->luffR = 0;
        }
        else
        {
            txtLuffRound->setPalette(palStd);
        }
        txtLuffRound->setText(QString::number(saildef->luffR) );

        break;
    }

    ///  check leech length
    L1 = (long) saildef->luffL;
    L1 = L1 + (long) saildef->gaffL;

    if (saildef->leechL > 1.4*L1)
    {
        flag = false;
        txtLuffLen->setPalette(palRel);
        txtLeechLen->setPalette(palHi);
        saildef->leechL = 1.4*L1 -1;
    }
    else if (saildef->leechL < 0.5*L1)
    {
        flag = false;
        txtLuffLen->setPalette(palRel);
        txtLeechLen->setPalette(palLo);
        saildef->leechL = 0.5*L1 +1;
    }
    else
    {
        txtLuffLen->setPalette(palStd);
        txtLeechLen->setPalette(palStd);
    }
    txtLeechLen->setText(QString::number(saildef->leechL));

    ///  check leech round
    L1 = (long) (saildef->leechL / 10);
    if (saildef->leechR > 3*L1)
    {
        flag = false;
        txtLeechRound->setPalette(palHi);
        txtLeechRound->setText(QString::number(3*L1) );
    }
    else if (saildef->leechR <-L1)
    {
        flag = false;
        txtLeechRound->setPalette(palLo);
        txtLeechRound->setText(QString::number(-L1) );
    }
    else
        txtLeechRound->setPalette(palStd);

    ///  check foot length
    switch (saildef->sailType )
    {
    case MAINSAIL:
        L2 = (long)(saildef->luffL + saildef->gaffL - saildef->leechL);
        if (L2 < (long)(0.1*(saildef->luffL)))
            L2=(long)(0.1*(saildef->luffL));
        break;
    case JIB:
        L2 = (long)(saildef->luffL  - saildef->leechL);
        if (L2 < (long)(0.1*(saildef->luffL)))
            L2=(long)(0.1*(saildef->luffL));
        break;
    case WING:
        L2 = (long)(saildef->luffL  - saildef->leechL);
        if (L2 < (long)(0.1*(saildef->luffL)))
            L2=(long)(0.1*(saildef->luffL));
        break;
    }

    if (saildef->footL > saildef->leechL)
    {
        flag=false;
        txtLeechLen->setPalette( palRel );
        txtFootLen->setPalette( palHi );
        saildef->footL = saildef->leechL -1;
    }
    else if (saildef->footL < L2)
    {
        flag=false;
        txtLeechLen->setPalette( palRel );
        txtFootLen->setPalette( palLo );
        saildef->footL = L2 +1;
    }
    else
    {
        txtLeechLen->setPalette( palStd );
        txtFootLen->setPalette( palStd );
    }
    txtFootLen->setText( QString::number( saildef->footL ) );

    ///  check foot round
    L1 = (long)(saildef->footL / 5);

    switch (saildef->sailType)
    {
    case WING:
        saildef->footR = 0;
        txtFootRound->setText(QString::number(saildef->footR));
        break;

    default:

        if (saildef->footR > L1)
        {
            flag=false;
            txtFootLen->setPalette( palRel );
            txtFootRound->setPalette(palHi);
            saildef->footR = L1;
        }
        else if (saildef->footR <-L1)
        {
            flag=false;
            txtFootLen->setPalette( palRel );
            txtFootRound->setPalette(palLo);
            saildef->footR = 1-L1;
        }
        else
        {
            txtFootLen->setPalette( palStd );
            txtFootRound->setPalette(palStd );
        }
        txtFootRound->setText(QString::number(saildef->footR));
        break;
    }

    ///  get and check seams and hems width
    saildef->clothW = txtClothWidth->text().toDouble();
    saildef->seamW  = txtSeamWidth->text().toDouble();
    saildef->leechHemW = txtLeechHemWidth->text().toDouble();
    saildef->hemsW = txtHemsWidth->text().toDouble();

    if (saildef->clothW < saildef->leechL /100)
    {
        saildef->clothW = saildef->leechL /100 +1;
        flag = false;
        txtClothWidth->setPalette(palLo);
    }
    else if (saildef->clothW > saildef->leechL /3)
    {
        saildef->clothW = saildef->leechL /3;
        flag = false;
        txtClothWidth->setPalette(palHi);
    }

    txtClothWidth->setText( QString::number(saildef->clothW));

    L1 = (long)(5+ saildef->clothW / 10);

    if (saildef->seamW > L1)
    {
        flag=false;
        txtSeamWidth->setPalette( palHi);
        saildef->seamW = L1;
    }
    else if (saildef->seamW < 0)
    {
        flag=false;
        txtSeamWidth->setPalette( palLo);
        saildef->seamW = 0;
    }
    else
    {
        txtSeamWidth->setPalette( palStd);
    }
    txtSeamWidth->setText( QString::number(saildef->seamW));

    if (saildef->leechHemW > L1*2)
    {
        flag=false;
        txtLeechHemWidth->setPalette( palHi);
        saildef->leechHemW = L1*2;
    }
    else if (saildef->leechHemW  < 0)
    {
        flag=false;
        txtLeechHemWidth->setPalette( palLo);
        saildef->leechHemW = 0;
    }
    else
    {
        txtLeechHemWidth->setPalette( palStd);
    }
    txtLeechHemWidth->setText( QString::number(saildef->leechHemW));

    if (saildef->hemsW > L1)
    {
        flag=false;
        txtHemsWidth->setPalette( palHi);
        saildef->hemsW = L1;
    }
    else if (saildef->hemsW < 0)
    {
        flag=false;
        txtHemsWidth->setPalette( palLo);
        saildef->hemsW = 0;
    }
    else
    {
        txtHemsWidth->setPalette( palStd);
    }
    txtHemsWidth->setText( QString::number(saildef->hemsW));


    ///  get and check mould
    saildef->mould.profile[2].setDepth( real(txtTopDepth->text().toInt())/100 );
    saildef->mould.profile[1].setDepth( real(txtMidDepth->text().toInt())/100 );
    saildef->mould.profile[0].setDepth( real(txtFootDepth->text().toInt())/100 );


    ///  get and check dihedral angle
    saildef->dihedralDeg = txtDihedral->text().toInt();
    if (saildef->dihedralDeg<90)
    {
        flag = false;
        txtDihedral->setPalette( palLo );
        saildef->dihedralDeg = 90;
    }
    else if (saildef->dihedralDeg > 180)
    {
        flag = false;
        txtDihedral->setPalette( palHi );
        saildef->dihedralDeg = 180;
    }
    else
    {
        txtDihedral->setPalette( palStd );
    }
    txtDihedral->setText(QString::number(saildef->dihedralDeg));


    ///  get and check twist
    saildef->twistDeg = txtTwistAngle->text().toInt();
    if (saildef->twistDeg > 45)
    {
        flag = false;
        txtTwistAngle->setPalette( palHi );
        saildef->twistDeg = 45;
    }
    else if(saildef->twistDeg < 0)
    {
        flag = false;
        txtTwistAngle->setPalette( palLo );
        saildef->twistDeg = 0;
    }
    else
    {
        txtTwistAngle->setPalette( palStd );
    }
    txtTwistAngle->setText(QString::number(saildef->twistDeg));


    ///  get and check sheeting angle
    saildef->sheetDeg = txtSheetAngle->text().toInt();

    if (saildef->sheetDeg > 45)
    {
        flag=false;
        txtSheetAngle->setPalette( palHi);
        saildef->sheetDeg = 45;
    }
    else
    {
        txtSheetAngle->setPalette( palStd);
    }

    switch (saildef->sailType ) // set lower limit for sheeting main or jib
    {
    case MAINSAIL:
        L2 = 0;
        break;
    case JIB:
        L2 = 5;
        break;
    case WING:
        L2 = 0;
        break;
    }

    if(saildef->sheetDeg < L2)
    {
        flag=false;
        txtSheetAngle->setPalette( palLo);
        saildef->sheetDeg = L2;
    }
    else
    {
        txtSheetAngle->setPalette( palStd);
    }
    txtSheetAngle->setText(QString::number(saildef->sheetDeg));


    ///  get and check radial sections and gores
    if (saildef->sailCut == RADIAL)
    {
        saildef->nbGores = txtGores->text().toInt();

        if (saildef->nbGores < 3)
        {
            flag=false;
            txtGores->setPalette( palLo);
            txtGores->setText(QString::number(3));
        }
        else  if (saildef->nbGores >7)
        {
            flag=false;
            txtGores->setPalette( palHi);
            txtGores->setText(QString::number(7));
        }
        else
        {
            txtGores->setPalette( palStd);
        }
        saildef->nbGores = txtGores->text().toInt();

        saildef->nbSections = txtSections->text().toInt();

        if (saildef->nbSections < 3)
        {
            flag=false;
            txtSections->setPalette( palLo);
            txtSections->setText(QString::number(3));
        }
        else if (saildef->nbSections >8)
        {
            flag=false;
            txtSections->setPalette( palHi);
            txtSections->setText(QString::number(8));
        }
        else
        {
            txtSections->setPalette( palStd);
        }
        saildef->nbSections = txtSections->text().toInt();

        saildef->nbLuffGores = txtLuffGores->text().toInt();

        if (saildef->nbLuffGores < 1)
        {
            flag=false;
            txtLuffGores->setPalette( palLo);
            txtLuffGores->setText(QString::number(1));
        }
        else  if (saildef->nbLuffGores > saildef->nbGores -2)
        {
            flag=false;
            txtLuffGores->setPalette( palHi);
            txtLuffGores->setText(QString::number(saildef->nbGores -2));
        }
        else
        {
            txtLuffGores->setPalette( palStd);
        }
        saildef->nbLuffGores = txtLuffGores->text().toInt();
    }

    ///  return true IF everything is OK
    return flag;
}


/** Used to enable/disable appropriate controls when the user
 *  changes the sail cut.
 **/
01072 void CFormDef::slotSailCut()
{
    setSailCut( getSailCut() );
}



/** Saves the parameters entered by the user in the CSailDef.
 *  compute and display ancillary data
 *  slot connected to Compute button
 */
01083 void CFormDef::slotCompute()
{
    // ckeck data
    check();
    // calculate sail area and diagonal
    compute();

    // display ancillary data
    real h=0, w=0;
    QString txta, txtb, txtc, txtd, txte;

    CSailWorker worker(*saildef);

    txta = tr("Sail corners coordinates");
    txta = txta+"\n  "+tr("tack")+" \t x = "+QString::number(int(worker.tack.x())) +"\n\t y = "+QString::number(int(worker.tack.y())) +" mm" ;
    txta = txta+"\n  "+tr("clew")+" \t x = "+QString::number(int(worker.clew.x())) +"\n\t y = "+QString::number(int(worker.clew.y())) +" mm";
    txta = txta+"\n  "+tr("head")+" \t x = "+QString::number(int(worker.head.x())) +"\n\t y = "+QString::number(int(worker.head.y())) +" mm";
    txta = txta+"\n  "+tr("peak")+" \t x = "+QString::number(int(worker.peak.x())) +"\n\t y = "+QString::number(int(worker.peak.y())) +" mm";

    w = worker.SailLP();
    txtb = "\nLP = " +QString::number(int(w)) +" mm";

   txtc = "\n" + tr("IRC width measurements");
   h=0.5;
    w = worker.IRCwidth(h);
    // printf ("IRC width %f \n", w);
    txtc = txtc +"\n  h= "+QString::number(h)+"\t w= "+QString::number(int(w)) +" mm";

    h=0.75;
    w = worker.IRCwidth(h);
    txtc = txtc+ "\n  h= "+QString::number(h)+"\t w= "+QString::number(int(w)) +" mm";

    h=0.875;
    w = worker.IRCwidth(h);
    txtc = txtc  + "\n  h= "+QString::number(h)+"\t w= "+QString::number(int(w)) +" mm";

    displayData(  txta, txtb, txtc, txtd, txte );

}


/** display data in a message box
 */
01126 void CFormDef::displayData(QString &txt0, QString &txt1, QString &txt2, QString &txt3, QString &txt4 )
{
    QMessageBox* mb = new QMessageBox();
    mb->setIcon(QMessageBox::NoIcon);
    mb->setWindowTitle("Sailcut");
    mb->setText (QString(txt0+"\n" +txt1+"\n" +txt2+"\n" +txt3+"\n" +txt4));
    mb->setButtonText (0, "OK");
    mb->exec();
    delete mb;
}


/** Used to enable/disable appropriate controls when the user
 *  changes the sail type.
 **/
01141 void CFormDef::slotSailType()
{
    setSailType( getSailType() );
}

Generated by  Doxygen 1.6.0   Back to index