337 changes: 300 additions & 37 deletions src/gui/raster/qgsrasterformatoptionswidget.cpp
Original file line number Diff line number Diff line change
@@ -1,94 +1,347 @@
#include "qgsrasterformatoptionswidget.h"
#include "qgslogger.h"

#include "gdal.h"
#include "cpl_string.h"
#include "cpl_conv.h"
#include "cpl_minixml.h"

#include <QSettings>
#include <QInputDialog>
#include <QMessageBox>
#include <QTextEdit>
#include <QDialogButtonBox>

// todo put this somewhere else - how can we access gdal provider?
char** papszFromStringList( const QStringList& list )
{
char **papszRetList = NULL;
foreach( QString elem, list )
{
papszRetList = CSLAddString( papszRetList, elem.toLocal8Bit().constData() );
}
return papszRetList;
}

QgsRasterFormatOptionsWidget::QgsRasterFormatOptionsWidget( QWidget* parent, QString format, QString provider ): QWidget( parent ), mFormat( format ), mProvider( provider )

QMap< QString, QStringList > QgsRasterFormatOptionsWidget::mBuiltinProfiles;

QgsRasterFormatOptionsWidget::QgsRasterFormatOptionsWidget( QWidget* parent, QString format, QString provider )
: QWidget( parent ), mFormat( format ), mProvider( provider )

{
setupUi( this );

if ( mBuiltinProfiles.isEmpty() )
{
// key=profileKey values=format,profileName,options
mBuiltinProfiles[ "z_adefault" ] = ( QStringList() << "" << tr( "Default" ) << "" );
// these GTiff profiles are based on Tim's benchmarks at
// http://linfiniti.com/2011/05/gdal-efficiency-of-various-compression-algorithms/
// big: no compression | medium: reasonable size/speed tradeoff | small: smallest size
mBuiltinProfiles[ "z_gtiff_1big" ] = ( QStringList() << "GTiff" << tr( "No compression" )
<< "COMPRESS=NONE BIGTIFF=IF_NEEDED" );
mBuiltinProfiles[ "z_gtiff_2medium" ] = ( QStringList() << "GTiff" << tr( "Low compression" )
<< "COMPRESS=PACKBITS" );
mBuiltinProfiles[ "z_gtiff_3small" ] = ( QStringList() << "GTiff" << tr( "High compression" )
<< "COMPRESS=DEFLATE PREDICTOR=2 ZLEVEL=9" );
mBuiltinProfiles[ "z_gtiff_4jpeg" ] = ( QStringList() << "GTiff" << tr( "Lossy compression" )
<< "COMPRESS=JPEG" );
}

showProfileButtons( false );
connect( mProfileComboBox, SIGNAL( currentIndexChanged ( const QString & ) ),
this, SLOT( profileChanged() ) );
connect( mProfileApplyButton, SIGNAL( clicked() ), this, SLOT( apply() ) );
update();

connect( mProfileComboBox, SIGNAL( currentIndexChanged( const QString & ) ),
this, SLOT( updateOptions() ) );
connect( mOptionsTable, SIGNAL( cellChanged( int, int ) ), this, SLOT( optionsTableChanged() ) );
// connect( mOptionsAddButton, SIGNAL( clicked() ), this, SLOT( optionsTableAddNewRow() ) );
// connect( mOptionsDeleteButton, SIGNAL( clicked() ), this, SLOT( optionsTableDeleteRow() ) );
connect( mOptionsHelpButton, SIGNAL( clicked() ), this, SLOT( optionsHelp() ) );
connect( mOptionsValidateButton, SIGNAL( clicked() ), this, SLOT( optionsValidate() ) );

updateProfiles();
}

QgsRasterFormatOptionsWidget::~QgsRasterFormatOptionsWidget()
{
}

void QgsRasterFormatOptionsWidget::setFormat( QString format )
{
mFormat = format;
updateProfiles();
}

void QgsRasterFormatOptionsWidget::setProvider( QString provider )
{
mProvider = provider;
}


void QgsRasterFormatOptionsWidget::showProfileButtons( bool show )
{
mProfileButtons->setVisible( show );
}

void QgsRasterFormatOptionsWidget::update()
void QgsRasterFormatOptionsWidget::updateProfiles()
{
// mCreateOptionsLineEdit->setText( createOption( mProfileComboBox->currentText() ) );
// build profiles list = user + builtin(last)
QStringList profileKeys = profiles();
QMapIterator<QString, QStringList> it( mBuiltinProfiles );
while ( it.hasNext() )
{
it.next();
QString profileKey = it.key();
if ( ! profileKeys.contains( profileKey ) )
{
// insert key if is for all formats or this format (GTiff)
if ( it.value()[0] == "" || it.value()[0] == mFormat )
profileKeys.insert( 0, profileKey );
}
}
qSort( profileKeys );

// populate mOptionsMap and mProfileComboBox
mOptionsMap.clear();
mProfileComboBox->blockSignals( true );
mProfileComboBox->clear();
foreach ( QString profileName, profiles() )
foreach( QString profileKey, profileKeys )
{
mProfileComboBox->addItem( profileName );
QString profileName, profileOptions;
profileOptions = createOptions( profileKey );
if ( mBuiltinProfiles.contains( profileKey ) )
{
profileName = mBuiltinProfiles[ profileKey ][ 1 ];
if ( profileOptions.isEmpty() )
profileOptions = mBuiltinProfiles[ profileKey ][ 2 ];
}
else
{
profileName = profileKey;
}
mOptionsMap[ profileKey ] = profileOptions;
mProfileComboBox->addItem( profileName, profileKey );
}

// update UI
mProfileComboBox->blockSignals( false );
mProfileComboBox->setCurrentIndex( 0 );
profileChanged();
updateOptions();
}

// void QgsRasterFormatOptionsWidget::on_mProfileComboBox_currentIndexChanged( const QString & text )
void QgsRasterFormatOptionsWidget::updateOptions()
{
QString myOptions = mOptionsMap.value( currentProfileKey() );
QStringList myOptionsList = myOptions.trimmed().split( " ", QString::SkipEmptyParts );

if ( mOptionsStackedWIdget->currentIndex() == 0 )
{
mOptionsTable->setRowCount( 0 );
for ( int i = 0; i < myOptionsList.count(); i++ )
{
QStringList key_value = myOptionsList[i].split( "=" );
if ( key_value.count() == 2 )
{
mOptionsTable->insertRow( i );
mOptionsTable->setItem( i, 0, new QTableWidgetItem( key_value[0] ) );
mOptionsTable->setItem( i, 1, new QTableWidgetItem( key_value[1] ) );
}
}
}
else
{
mOptionsLineEdit->setText( myOptions );
}
}

void QgsRasterFormatOptionsWidget::apply()
{
setProfiles();
setCreateOptions( mProfileComboBox->currentText(), mCreateOptionsLineEdit->text() );
profileChanged();
setCreateOptions();
}

// void QgsRasterFormatOptionsWidget::on_mProfileComboBox_currentIndexChanged( const QString & text )
void QgsRasterFormatOptionsWidget::profileChanged()

void QgsRasterFormatOptionsWidget::optionsHelp()
{
QgsDebugMsg("Entered");
mCreateOptionsLineEdit->setText( createOptions( mProfileComboBox->currentText() ) );
QString message;

if ( mProvider == "gdal" && mFormat != "" && mFormat != "_pyramids" )
{
GDALDriverH myGdalDriver = GDALGetDriverByName( mFormat.toLocal8Bit().constData() );
if ( myGdalDriver )
{
// need to serialize xml to get newlines
CPLXMLNode *psCOL = CPLParseXMLString( GDALGetMetadataItem( myGdalDriver,
GDAL_DMD_CREATIONOPTIONLIST, "" ) );
char *pszFormattedXML = CPLSerializeXMLTree( psCOL );
if ( pszFormattedXML )
message = tr( "Create Options:\n\n%1" ).arg( pszFormattedXML );
if ( psCOL )
CPLDestroyXMLNode( psCOL );
if ( pszFormattedXML )
CPLFree( pszFormattedXML );
}
if ( message.isEmpty() )
message = tr( "Cannot get create options for driver %1" ).arg( mFormat );
}
else
message = tr( "No help available" );

// show simple noon-modal dialog - should we make this basic xml pretty?
QDialog *dlg = new QDialog( this );
QVBoxLayout *layout = new QVBoxLayout();
QTextEdit *textEdit = new QTextEdit( dlg );
layout->addWidget( textEdit );
textEdit->setReadOnly( true );
textEdit->setText( message );
QDialogButtonBox *buttonBox = new QDialogButtonBox( QDialogButtonBox::Close );
connect( buttonBox, SIGNAL( accepted() ), dlg, SLOT( accept() ) );
connect( buttonBox, SIGNAL( rejected() ), dlg, SLOT( reject() ) );
layout->addWidget( buttonBox );
dlg->setLayout( layout );
dlg->resize( 600, 600 );
dlg->show(); //non modal
}

bool QgsRasterFormatOptionsWidget::optionsValidate( bool message )
{
QStringList options = createOptions();
bool ok = false;

if ( !options.isEmpty() && mProvider == "gdal" && mFormat != "" && mFormat != "_pyramids" )
{
GDALDriverH myGdalDriver = GDALGetDriverByName( mFormat.toLocal8Bit().constData() );
if ( myGdalDriver )
{
// print error string?
char** papszOptions = papszFromStringList( options );
ok = ( GDALValidateCreationOptions( myGdalDriver, papszOptions ) == TRUE );
CSLDestroy( papszOptions );
if ( message )
{
if ( ok )
QMessageBox::information( this, "", tr( "Valid" ), QMessageBox::Close );
else
QMessageBox::warning( this, "", tr( "Invalid" ), QMessageBox::Close );
}
}
}
return ok;
}

void QgsRasterFormatOptionsWidget::optionsTableChanged()
{
QTableWidgetItem *key, *value;
QString options;
for ( int i = 0 ; i < mOptionsTable->rowCount(); i++ )
{
key = mOptionsTable->item( i, 0 );
if ( ! key || key->text().isEmpty() )
continue;
value = mOptionsTable->item( i, 1 );
if ( ! value || value->text().isEmpty() )
continue;
options += key->text() + "=" + value->text() + " ";
}
options = options.trimmed();
mOptionsMap[ currentProfileKey()] = options;
mOptionsLineEdit->setText( options );
}

void QgsRasterFormatOptionsWidget::on_mOptionsLineEdit_editingFinished()
{
mOptionsMap[ currentProfileKey()] = mOptionsLineEdit->text().trimmed();
}

void QgsRasterFormatOptionsWidget::on_mProfileNewButton_clicked()
{
QString profileName = QInputDialog::getText( this, "", tr("Profile name:") );
QString profileName = QInputDialog::getText( this, "", tr( "Profile name:" ) );
if ( ! profileName.isEmpty() )
{
profileName = profileName.trimmed();
profileName.replace( " ", "_" );
profileName.replace( "=", "_" );
mProfileComboBox->addItem( profileName );
mProfileComboBox->setCurrentIndex( mProfileComboBox->count()-1 );
mOptionsMap[ profileName ] = "";
mProfileComboBox->addItem( profileName, profileName );
mProfileComboBox->setCurrentIndex( mProfileComboBox->count() - 1 );
}
}

void QgsRasterFormatOptionsWidget::on_mProfileDeleteButton_clicked()
{
int index = mProfileComboBox->currentIndex();
QString profileName = mProfileComboBox->currentText();
if ( index != -1 )
QString profileKey = currentProfileKey();
if ( index != -1 && ! mBuiltinProfiles.contains( profileKey ) )
{
mOptionsMap.remove( profileKey );
mProfileComboBox->removeItem( index );
setCreateOptions( profileName, "" );
}
}

void QgsRasterFormatOptionsWidget::on_mProfileResetButton_clicked()
{
QString profileKey = currentProfileKey();
if ( mBuiltinProfiles.contains( profileKey ) )
{
mOptionsMap[ profileKey ] = mBuiltinProfiles[ profileKey ][ 2 ];
}
else
{
mOptionsMap[ profileKey ] = "";
}
mOptionsLineEdit->setText( mOptionsMap.value( currentProfileKey() ) );
updateOptions();
}

void QgsRasterFormatOptionsWidget::on_mOptionsLabel_clicked()
{
mOptionsStackedWIdget->setCurrentIndex(( mOptionsStackedWIdget->currentIndex() + 1 ) % 2 );
updateOptions();
}

void QgsRasterFormatOptionsWidget::optionsTableEnableDeleteButton()
{
mOptionsDeleteButton->setEnabled( mOptionsTable->currentRow() >= 0 );
}

void QgsRasterFormatOptionsWidget::on_mOptionsAddButton_clicked()
{
mOptionsTable->insertRow( mOptionsTable->rowCount() );
// select the added row
int newRow = mOptionsTable->rowCount() - 1;
QTableWidgetItem* item = new QTableWidgetItem();
mOptionsTable->setItem( newRow, 0, item );
mOptionsTable->setCurrentItem( item );
}

void QgsRasterFormatOptionsWidget::on_mOptionsDeleteButton_clicked()
{
if ( mOptionsTable->currentRow() >= 0 )
{
mOptionsTable->removeRow( mOptionsTable->currentRow() );
// select the previous row or the next one if there is no previous row
QTableWidgetItem* item = mOptionsTable->item( mOptionsTable->currentRow(), 0 );
mOptionsTable->setCurrentItem( item );
optionsTableChanged();
}
}


QString QgsRasterFormatOptionsWidget::settingsKey( QString profileName ) const
{
{
if ( profileName != "" )
profileName = "/profile_" + profileName;
else
profileName = "/profile_default" + profileName;
return mProvider + "/driverOptions/" + mFormat.toLower() + profileName + "/create";
return mProvider + "/driverOptions/" + mFormat.toLower() + profileName + "/create";
}

QString QgsRasterFormatOptionsWidget::currentProfileKey() const
{
return mProfileComboBox->itemData( mProfileComboBox->currentIndex() ).toString();
}

QStringList QgsRasterFormatOptionsWidget::createOptions() const
{
return mCreateOptionsLineEdit->text().trimmed().split( " " ) ;
return mOptionsMap.value( currentProfileKey() ).trimmed().split( " ", QString::SkipEmptyParts );
}

QString QgsRasterFormatOptionsWidget::createOptions( QString profileName ) const
Expand All @@ -103,23 +356,33 @@ void QgsRasterFormatOptionsWidget::deleteCreateOptions( QString profileName )
mySettings.remove( settingsKey( profileName ) );
}

void QgsRasterFormatOptionsWidget::setCreateOptions( QString profileName, QString value )
void QgsRasterFormatOptionsWidget::setCreateOptions()
{
QSettings mySettings;
mySettings.setValue( settingsKey( profileName ), value.trimmed() );
QString myProfiles;
QMap< QString, QString >::iterator i = mOptionsMap.begin();
while ( i != mOptionsMap.end() )
{
setCreateOptions( i.key(), i.value() );
myProfiles += i.key() + QString( " " );
++i;
}
mySettings.setValue( mProvider + "/driverOptions/" + mFormat.toLower() + "/profiles", myProfiles.trimmed() );
}

QStringList QgsRasterFormatOptionsWidget::profiles() const
void QgsRasterFormatOptionsWidget::setCreateOptions( QString profileName, QString options )
{
QSettings mySettings;
return mySettings.value( mProvider + "/driverOptions/" + mFormat.toLower() + "/profiles", "" ).toString().split( " " );
mySettings.setValue( settingsKey( profileName ), options.trimmed() );
}

void QgsRasterFormatOptionsWidget::setProfiles() const
void QgsRasterFormatOptionsWidget::setCreateOptions( QString profileName, QStringList list )
{
setCreateOptions( profileName, list.join( " " ) );
}

QStringList QgsRasterFormatOptionsWidget::profiles() const
{
QSettings mySettings;
QString myProfiles;
for ( int i = 0 ; i < mProfileComboBox->count() ; i++ )
myProfiles += mProfileComboBox->itemText( i ) + QString( " " );
return mySettings.setValue( mProvider + "/driverOptions/" + mFormat.toLower() + "/profiles", myProfiles.trimmed() );
return mySettings.value( mProvider + "/driverOptions/" + mFormat.toLower() + "/profiles", "" ).toString().trimmed().split( " ", QString::SkipEmptyParts );
}
36 changes: 26 additions & 10 deletions src/gui/raster/qgsrasterformatoptionswidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,52 @@
class GUI_EXPORT QgsRasterFormatOptionsWidget: public QWidget, private Ui::QgsRasterFormatOptionsWidgetBase
{
Q_OBJECT

public:
QgsRasterFormatOptionsWidget( QWidget* parent = 0, QString format = "GTiff", QString provider = "gdal" );
~QgsRasterFormatOptionsWidget();

void setFormat( QString format ) { mFormat = format; }
void setProvider( QString provider ) { mProvider = provider; }
QgsRasterFormatOptionsWidget( QWidget* parent = 0, QString format = "GTiff", QString provider = "gdal" );
~QgsRasterFormatOptionsWidget();

public slots:
void setFormat( QString format );
void setProvider( QString provider );
QStringList createOptions() const;
void showProfileButtons( bool show = true );
void update();

public slots:

void apply();
void optionsHelp();
bool optionsValidate( bool message = true );

private slots:
/* void on_mProfileComboBox_currentIndexChanged( const QString & text ); */
void profileChanged();

void on_mProfileNewButton_clicked();
void on_mProfileDeleteButton_clicked();
void on_mProfileResetButton_clicked();
void on_mOptionsAddButton_clicked();
void on_mOptionsDeleteButton_clicked();
void on_mOptionsLabel_clicked();
void on_mOptionsLineEdit_editingFinished();
void optionsTableChanged();
void optionsTableEnableDeleteButton();
void updateOptions();

private:

QString mFormat;
QString mProvider;
QMap< QString, QString> mOptionsMap;
static QMap< QString, QStringList > mBuiltinProfiles;

QString settingsKey( QString profile ) const;
QString currentProfileKey() const;
QString createOptions( QString profile ) const;
void deleteCreateOptions( QString profile );
void setCreateOptions( QString profile, QString value );
void setCreateOptions( );
void setCreateOptions( QString profile, QString options );
void setCreateOptions( QString profile, QStringList list );
QStringList profiles() const;
void setProfiles() const;
void updateProfiles();

};

Expand Down
61 changes: 54 additions & 7 deletions src/ui/qgsoptionsbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
<item row="2" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<property name="iconSize">
<size>
Expand Down Expand Up @@ -757,7 +757,7 @@
<string>GDAL</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_27">
<item row="0" column="0">
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_13">
<property name="title">
<string>GDAL Drivers</string>
Expand Down Expand Up @@ -796,11 +796,6 @@
<string>Flags</string>
</property>
</column>
<column>
<property name="text">
<string>opt</string>
</property>
</column>
<column>
<property name="text">
<string>Description</string>
Expand All @@ -811,6 +806,58 @@
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_16">
<property name="title">
<string>GDAL Driver Options</string>
</property>
<layout class="QGridLayout" name="gridLayout_29">
<item row="0" column="1">
<widget class="QComboBox" name="cmbEditCreateOptions"/>
</item>
<item row="0" column="3">
<spacer name="horizontalSpacer_15">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="4">
<widget class="QPushButton" name="pbnEditPyramidsOptions">
<property name="text">
<string>Edit Pyramids Options</string>
</property>
</widget>
</item>
<item row="0" column="5">
<spacer name="horizontalSpacer_16">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="pbnEditCreateOptions">
<property name="text">
<string>Edit Create Options</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
Expand Down
291 changes: 193 additions & 98 deletions src/ui/qgsrasterformatoptionswidgetbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,128 +6,223 @@
<rect>
<x>0</x>
<y>0</y>
<width>378</width>
<height>132</height>
<width>406</width>
<height>205</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="mProfileComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<item row="0" column="0">
<widget class="QLabel" name="mProfileLabel">
<property name="text">
<string>Profile</string>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="minimumSize">
<property name="sizeHint" stdset="0">
<size>
<width>150</width>
<height>0</height>
<width>20</width>
<height>5</height>
</size>
</property>
</widget>
</spacer>
</item>
<item row="1" column="1" colspan="2">
<widget class="QWidget" name="mProfileButtons" native="true">
<layout class="QHBoxLayout" name="mProfileButtonsLayout">
<item>
<widget class="QPushButton" name="mProfileApplyButton">
<property name="text">
<string>Apply</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mProfileNewButton">
<property name="text">
<string>New</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mProfileDeleteButton">
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
</layout>
<item row="2" column="1">
<widget class="QStackedWidget" name="mOptionsStackedWIdget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="page">
<layout class="QGridLayout" name="gridLayout_2">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QTableWidget" name="mOptionsTable">
<property name="minimumSize">
<size>
<width>204</width>
<height>0</height>
</size>
</property>
<attribute name="horizontalHeaderMinimumSectionSize">
<number>30</number>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>Value</string>
</property>
</column>
</widget>
</item>
<item row="0" column="1">
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QPushButton" name="mOptionsAddButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>+</string>
</property>
<property name="iconSize">
<size>
<width>1</width>
<height>1</height>
</size>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QPushButton" name="mOptionsValidateButton">
<property name="text">
<string>Validate</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QPushButton" name="mOptionsHelpButton">
<property name="text">
<string>Help</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="mOptionsDeleteButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>-</string>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
<zorder>mOptionsLineEdit</zorder>
<zorder>mOptionsTable</zorder>
<zorder>layoutWidget</zorder>
</widget>
<widget class="QWidget" name="page_2">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QLineEdit" name="mOptionsLineEdit">
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
</layout>
<zorder>mOptionsTable</zorder>
<zorder>layoutWidget</zorder>
<zorder>mOptionsLineEdit</zorder>
</widget>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="mCreateOptionsLabel">
<property name="text">
<string>Options</string>
<widget class="QPushButton" name="mOptionsLabel">
<property name="styleSheet">
<string notr="true">Text-align:left</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QLineEdit" name="mCreateOptionsLineEdit"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="mProfileLabel">
<property name="text">
<string>Profile</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QTableWidget" name="mOptionsTable">
<property name="minimumSize">
<size>
<width>204</width>
<height>0</height>
</size>
<string>Options</string>
</property>
<attribute name="horizontalHeaderMinimumSectionSize">
<number>30</number>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<property name="flat">
<bool>true</bool>
</attribute>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>Value</string>
</property>
</column>
</property>
</widget>
</item>
<item row="3" column="2">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="mOptionsAddButton">
<property name="text">
<string>Add</string>
<item row="0" column="1">
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QComboBox" name="mProfileComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnDel">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<property name="minimumSize">
<size>
<width>20</width>
<height>40</height>
<width>150</width>
<height>0</height>
</size>
</property>
</spacer>
</widget>
</item>
<item row="1" column="0">
<widget class="QWidget" name="mProfileButtons" native="true">
<layout class="QHBoxLayout" name="mProfileButtonsLayout">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="mProfileNewButton">
<property name="text">
<string>New</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mProfileDeleteButton">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mProfileResetButton">
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
Expand Down