2013-09-02 08:39:29 +02:00
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight 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 at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuWellImportWizard.h"
2015-08-01 23:04:04 +02:00
#include "RifJsonEncodeDecode.h"
2017-02-24 13:32:25 +01:00
#include "RimOilFieldEntry.h"
#include "RimOilRegionEntry.h"
2015-08-01 23:04:04 +02:00
#include "RimWellPathImport.h"
2013-09-02 08:39:29 +02:00
2013-09-05 07:34:04 +02:00
#include "cafPdmDocument.h"
2015-08-12 18:44:03 +02:00
#include "cafPdmObject.h"
2015-08-01 23:04:04 +02:00
#include "cafPdmObjectGroup.h"
2013-09-05 07:34:04 +02:00
#include "cafPdmUiListView.h"
2015-08-01 23:04:04 +02:00
#include "cafPdmUiListViewEditor.h"
#include "cafPdmUiPropertyView.h"
#include "cafPdmUiTreeView.h"
#include "cafPdmUiTreeViewEditor.h"
2017-05-11 09:23:13 +02:00
#include "cafUtils.h"
2013-09-02 08:39:29 +02:00
2015-08-01 23:04:04 +02:00
#include <QObject>
#include <QtGui>
#include <QtNetwork>
2013-09-05 07:34:04 +02:00
2015-12-01 05:19:49 -08:00
#include <algorithm>
2013-09-02 08:39:29 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellImportWizard :: RiuWellImportWizard ( const QString & webServiceAddress , const QString & downloadFolder , RimWellPathImport * wellPathImportObject , QWidget * parent /*= 0*/ )
: QWizard ( parent )
{
2013-09-06 13:06:39 +02:00
m_wellPathImportObject = wellPathImportObject ;
2013-09-02 08:39:29 +02:00
m_destinationFolder = downloadFolder ;
m_webServiceAddress = webServiceAddress ;
2013-09-26 13:54:57 +02:00
m_myProgressDialog = new QProgressDialog ( this );
2013-09-06 15:59:25 +02:00
m_firstTimeRequestingAuthentication = true ;
2013-09-02 08:39:29 +02:00
2013-09-05 08:45:24 +02:00
addPage ( new AuthenticationPage ( webServiceAddress , this ));
2013-09-08 09:05:26 +02:00
m_fieldSelectionPageId = addPage ( new FieldSelectionPage ( m_wellPathImportObject , this ));
m_wellSelectionPageId = addPage ( new WellSelectionPage ( m_wellPathImportObject , this ));
2013-09-06 13:06:39 +02:00
m_wellSummaryPageId = addPage ( new WellSummaryPage ( m_wellPathImportObject , this ));
2013-09-04 08:03:11 +02:00
2013-09-08 09:05:26 +02:00
connect ( this , SIGNAL ( currentIdChanged ( int )), SLOT ( slotCurrentIdChanged ( int )));
2013-09-05 07:34:04 +02:00
2013-09-02 08:39:29 +02:00
connect ( & m_networkAccessManager , SIGNAL ( authenticationRequired ( QNetworkReply * , QAuthenticator * )),
this , SLOT ( slotAuthenticationRequired ( QNetworkReply * , QAuthenticator * )));
#ifndef QT_NO_OPENSSL
connect ( & m_networkAccessManager , SIGNAL ( sslErrors ( QNetworkReply * , QList < QSslError > )),
this , SLOT ( sslErrors ( QNetworkReply * , QList < QSslError > )));
#endif
}
2015-08-12 18:44:03 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellImportWizard ::~ RiuWellImportWizard ()
{
}
2013-09-02 08:39:29 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiuWellImportWizard :: jsonFieldsFilePath ()
{
return m_destinationFolder + "/fields.json" ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiuWellImportWizard :: jsonWellsFilePath ()
{
return m_destinationFolder + "/wellpaths.json" ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellImportWizard :: downloadFields ()
{
QString wellFileName = jsonWellsFilePath ();
2017-05-11 09:23:13 +02:00
if ( caf :: Utils :: fileExists ( wellFileName ))
2013-09-02 08:39:29 +02:00
{
QFile :: remove ( wellFileName );
}
QString completeUrlText = m_webServiceAddress + "/resinsight/projects" ;
QString destinationFileName = jsonFieldsFilePath ();
m_currentDownloadState = DOWNLOAD_FIELDS ;
issueHttpRequestToFile ( completeUrlText , destinationFileName );
return ;
}
2013-09-04 08:03:11 +02:00
2013-09-02 08:39:29 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellImportWizard :: issueHttpRequestToFile ( QString completeUrlText , QString destinationFileName )
{
setUrl ( completeUrlText );
m_file = new QFile ( destinationFileName );
if ( ! m_file -> open ( QIODevice :: WriteOnly )) {
QMessageBox :: information ( this , tr ( "HTTP" ),
tr ( "Unable to save the file %1: %2." )
. arg ( destinationFileName ). arg ( m_file -> errorString ()));
delete m_file ;
m_file = 0 ;
return ;
}
// schedule the request
m_httpRequestAborted = false ;
startRequest ( m_url );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellImportWizard :: cancelDownload ()
{
//m_statusLabel->setText(tr("Download canceled."));
m_httpRequestAborted = true ;
m_reply -> abort ();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellImportWizard :: httpFinished ()
{
if ( m_httpRequestAborted ) {
if ( m_file ) {
m_file -> close ();
m_file -> remove ();
delete m_file ;
m_file = 0 ;
}
m_reply -> deleteLater ();
2013-09-26 13:54:57 +02:00
m_myProgressDialog -> hide ();
2013-09-02 08:39:29 +02:00
return ;
}
m_file -> flush ();
m_file -> close ();
QVariant redirectionTarget = m_reply -> attribute ( QNetworkRequest :: RedirectionTargetAttribute );
if ( m_reply -> error ()) {
m_file -> remove ();
QMessageBox :: information ( this , tr ( "HTTP" ),
tr ( "Download failed: %1." )
. arg ( m_reply -> errorString ()));
} else if ( ! redirectionTarget . isNull ()) {
QUrl newUrl = m_url . resolved ( redirectionTarget . toUrl ());
if ( QMessageBox :: question ( this , tr ( "HTTP" ),
tr ( "Redirect to %1 ?" ). arg ( newUrl . toString ()),
QMessageBox :: Yes | QMessageBox :: No ) == QMessageBox :: Yes ) {
m_url = newUrl ;
m_reply -> deleteLater ();
m_file -> open ( QIODevice :: WriteOnly );
m_file -> resize ( 0 );
startRequest ( m_url );
return ;
}
} else {
2013-09-06 15:59:25 +02:00
//m_statusLabel->setText(tr("Downloaded data to %1.").arg(m_destinationFolder));
2013-09-02 08:39:29 +02:00
}
if ( m_currentDownloadState == DOWNLOAD_WELL_PATH )
{
QString singleWellPathFilePath = m_file -> fileName ();
QFile file ( singleWellPathFilePath );
if ( file . open ( QFile :: ReadOnly ))
{
QString singleWellPathContent = file . readAll ();
// Strip leading and trailing []
if ( singleWellPathContent . indexOf ( '{' ) > 0 )
{
singleWellPathContent = singleWellPathContent . right ( singleWellPathContent . size () - singleWellPathContent . indexOf ( '{' ));
}
if ( singleWellPathContent [ singleWellPathContent . size () - 1 ] == ']' )
{
singleWellPathContent = singleWellPathContent . left ( singleWellPathContent . size () - 1 );
}
QString wellPathName = getValue ( "name" , singleWellPathContent );
if ( ! singleWellPathContent . isEmpty () && ! wellPathName . isEmpty ())
{
// Write out the content without leading/trailing []
file . close ();
file . remove ( singleWellPathFilePath );
if ( file . open ( QFile :: WriteOnly ))
{
QTextStream out ( & file );
out << singleWellPathContent ;
}
}
2013-09-26 13:54:57 +02:00
m_myProgressDialog -> setLabelText ( QString ( "Downloaded well path : %1" ). arg ( wellPathName ));
2013-09-02 08:39:29 +02:00
}
2013-09-26 13:54:57 +02:00
int newValue = m_myProgressDialog -> maximum () - m_wellRequestQueue . size ();
m_myProgressDialog -> setValue ( newValue );
2013-09-02 08:39:29 +02:00
}
m_reply -> deleteLater ();
m_reply = 0 ;
delete m_file ;
m_file = 0 ;
2013-09-04 08:03:11 +02:00
if ( m_currentDownloadState == DOWNLOAD_WELLS || m_currentDownloadState == DOWNLOAD_WELL_PATH )
2013-09-02 08:39:29 +02:00
{
2013-09-06 15:59:25 +02:00
checkDownloadQueueAndIssueRequests ();
2013-09-02 08:39:29 +02:00
}
else if ( m_currentDownloadState == DOWNLOAD_FIELDS )
{
updateFieldsModel ();
m_currentDownloadState = DOWNLOAD_UNDEFINED ;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellImportWizard :: httpReadyRead ()
{
// this slot gets called every time the QNetworkReply has new data.
// We read all of its new data and write it into the file.
// That way we use less RAM than when reading it at the finished()
// signal of the QNetworkReply
if ( m_file )
m_file -> write ( m_reply -> readAll ());
2013-09-05 08:45:24 +02:00
}
2013-09-02 08:39:29 +02:00
//--------------------------------------------------------------------------------------------------
2013-09-05 08:45:24 +02:00
/// This slot will be called for the first network reply that will need authentication.
/// If the authentication is successful, the username/password is cached in the QNetworkAccessManager
2013-09-02 08:39:29 +02:00
//--------------------------------------------------------------------------------------------------
void RiuWellImportWizard :: slotAuthenticationRequired ( QNetworkReply * networkReply , QAuthenticator * authenticator )
{
2013-09-05 08:45:24 +02:00
if ( m_firstTimeRequestingAuthentication )
{
// Use credentials from first wizard page
authenticator -> setUser ( field ( "username" ). toString ());
authenticator -> setPassword ( field ( "password" ). toString ());
2013-09-02 08:39:29 +02:00
2013-09-05 08:45:24 +02:00
m_firstTimeRequestingAuthentication = false ;
}
else
{
QMessageBox :: information ( this , "Authentication failed" , "Failed to authenticate credentials. You will now be directed back to the first wizard page." );
m_firstTimeRequestingAuthentication = true ;
2013-09-02 08:39:29 +02:00
2013-09-05 08:45:24 +02:00
restart ();
}
2013-09-02 08:39:29 +02:00
}
#ifndef QT_NO_OPENSSL
void RiuWellImportWizard :: sslErrors ( QNetworkReply * , const QList < QSslError > & errors )
{
QString errorString ;
foreach ( const QSslError & error , errors ) {
if ( ! errorString . isEmpty ())
errorString += ", " ;
errorString += error . errorString ();
}
if ( QMessageBox :: warning ( this , tr ( "HTTP" ),
tr ( "One or more SSL errors has occurred: %1" ). arg ( errorString ),
QMessageBox :: Ignore | QMessageBox :: Abort ) == QMessageBox :: Ignore ) {
m_reply -> ignoreSslErrors ();
}
}
#endif
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellImportWizard :: setUrl ( const QString & httpAddress )
{
m_url = httpAddress ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellImportWizard :: startRequest ( QUrl url )
{
m_reply = m_networkAccessManager . get ( QNetworkRequest ( url ));
connect ( m_reply , SIGNAL ( finished ()),
this , SLOT ( httpFinished ()));
connect ( m_reply , SIGNAL ( readyRead ()),
this , SLOT ( httpReadyRead ()));
}
//--------------------------------------------------------------------------------------------------
/// Search for string, and find the associated value inside the next quoted string
// text content : "A" : "B"
// A search for key "A" returns B
//--------------------------------------------------------------------------------------------------
QString RiuWellImportWizard :: getValue ( const QString & key , const QString & stringContent )
{
QString quotedKey = " \" " + key + " \" " ;
int pos = stringContent . indexOf ( quotedKey );
if ( pos >= 0 )
{
int valueStartPos = stringContent . indexOf ( " \" " , pos + quotedKey . size ());
int valueEndPos = stringContent . indexOf ( " \" " , valueStartPos + 1 );
if ( valueStartPos >= 0 && valueEndPos > valueStartPos )
{
return stringContent . mid ( valueStartPos + 1 , valueEndPos - valueStartPos - 1 );
}
}
return QString ();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellImportWizard :: updateFieldsModel ()
{
QString fileName = jsonFieldsFilePath ();
2017-05-11 09:23:13 +02:00
if ( caf :: Utils :: fileExists ( fileName ))
2013-09-02 08:39:29 +02:00
{
2016-06-06 10:43:36 +02:00
ResInsightInternalJson :: JsonReader jsonReader ;
2013-09-02 08:39:29 +02:00
QMap < QString , QVariant > jsonMap = jsonReader . decodeFile ( fileName );
QStringList regions ;
QStringList fields ;
QStringList edmIds ;
QMapIterator < QString , QVariant > it ( jsonMap );
while ( it . hasNext ())
{
it . next ();
2013-09-08 09:05:26 +02:00
// If we have an array, skip to next node
if ( it . key () == "length" )
continue ;
2013-09-02 08:39:29 +02:00
2013-09-08 09:05:26 +02:00
QMap < QString , QVariant > fieldMap = it . value (). toMap ();
regions . push_back ( fieldMap [ "region" ]. toString ());
fields . push_back ( fieldMap [ "name" ]. toString ());
edmIds . push_back ( fieldMap [ "edmId" ]. toString ());
2013-09-02 08:39:29 +02:00
}
2013-09-06 13:06:39 +02:00
m_wellPathImportObject -> updateRegions ( regions , fields , edmIds );
2013-09-26 07:54:57 +02:00
for ( size_t i = 0 ; i < m_wellPathImportObject -> regions . size (); i ++ )
{
m_wellPathImportObject -> regions [ i ] -> updateState ();
}
2013-09-06 13:06:39 +02:00
m_wellPathImportObject -> updateConnectedEditors ();
2013-09-02 08:39:29 +02:00
}
}
2013-09-04 08:03:11 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellImportWizard :: downloadWells ()
{
2013-09-06 13:06:39 +02:00
for ( size_t rIdx = 0 ; rIdx < m_wellPathImportObject -> regions . size (); rIdx ++ )
2013-09-04 08:03:11 +02:00
{
2013-09-06 13:06:39 +02:00
RimOilRegionEntry * oilRegion = m_wellPathImportObject -> regions [ rIdx ];
2013-09-04 08:03:11 +02:00
if ( oilRegion -> selected )
{
for ( size_t fIdx = 0 ; fIdx < oilRegion -> fields . size (); fIdx ++ )
{
RimOilFieldEntry * oilField = oilRegion -> fields [ fIdx ];
if ( oilField -> selected )
{
DownloadEntity urlToFile ;
QString wellRequest ;
2013-09-06 13:06:39 +02:00
if ( m_wellPathImportObject -> utmFilterMode == RimWellPathImport :: UTM_FILTER_OFF )
2013-09-04 08:03:11 +02:00
{
wellRequest = QString ( "/resinsight/projects/%1/wells" ). arg ( oilField -> edmId );
}
else
{
2013-09-26 13:54:57 +02:00
wellRequest = QString ( "/resinsight/projects/%1/wellsInArea?north=%2&south=%3&east=%4&west=%5&utmzone=32N" )
2013-09-04 08:03:11 +02:00
. arg ( oilField -> edmId )
2013-09-06 13:06:39 +02:00
. arg ( QString :: number ( m_wellPathImportObject -> north , 'g' , 10 ))
. arg ( QString :: number ( m_wellPathImportObject -> south , 'g' , 10 ))
. arg ( QString :: number ( m_wellPathImportObject -> east , 'g' , 10 ))
. arg ( QString :: number ( m_wellPathImportObject -> west , 'g' , 10 ));
2013-09-04 08:03:11 +02:00
}
urlToFile . requestUrl = m_webServiceAddress + wellRequest ;
urlToFile . responseFilename = m_destinationFolder + QString ( "/wells_%1.json" ). arg ( oilField -> edmId );
oilField -> wellsFilePath = urlToFile . responseFilename ;
m_wellRequestQueue . push_back ( urlToFile );
}
}
}
}
m_currentDownloadState = DOWNLOAD_WELLS ;
2013-09-06 15:59:25 +02:00
checkDownloadQueueAndIssueRequests ();
2013-09-04 08:03:11 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellImportWizard :: downloadWellPaths ()
{
2015-08-12 18:44:03 +02:00
WellSelectionPage * wellSelectionPage = dynamic_cast < WellSelectionPage *> ( page ( m_wellSelectionPageId ));
std :: vector < DownloadEntity > downloadEntities ;
wellSelectionPage -> selectedWellPathEntries ( downloadEntities , NULL );
2013-09-04 08:03:11 +02:00
2015-08-12 18:44:03 +02:00
for ( size_t i = 0 ; i < downloadEntities . size (); i ++ )
{
m_wellRequestQueue . push_back ( downloadEntities [ i ]);
2013-09-04 08:03:11 +02:00
}
m_currentDownloadState = DOWNLOAD_WELL_PATH ;
2013-09-26 13:54:57 +02:00
m_myProgressDialog -> setMaximum ( m_wellRequestQueue . size ());
m_myProgressDialog -> setValue ( 0 );
m_myProgressDialog -> show ();
2013-09-06 15:59:25 +02:00
checkDownloadQueueAndIssueRequests ();
2013-09-04 08:03:11 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-09-06 15:59:25 +02:00
void RiuWellImportWizard :: checkDownloadQueueAndIssueRequests ()
2013-09-04 08:03:11 +02:00
{
if ( m_wellRequestQueue . size () > 0 )
{
DownloadEntity firstItem = m_wellRequestQueue [ 0 ];
m_wellRequestQueue . pop_front ();
QString completeUrlText = firstItem . requestUrl ;
QString absoluteFilePath = firstItem . responseFilename ;
issueHttpRequestToFile ( completeUrlText , absoluteFilePath );
return ;
}
if ( m_currentDownloadState == DOWNLOAD_WELLS )
{
2013-09-26 13:54:57 +02:00
m_myProgressDialog -> hide ();
2013-09-04 08:03:11 +02:00
// Update UI with downloaded wells
2013-09-06 13:06:39 +02:00
for ( size_t rIdx = 0 ; rIdx < m_wellPathImportObject -> regions . size (); rIdx ++ )
2013-09-04 08:03:11 +02:00
{
2013-09-06 13:06:39 +02:00
RimOilRegionEntry * oilRegion = m_wellPathImportObject -> regions [ rIdx ];
2013-09-04 08:03:11 +02:00
if ( oilRegion -> selected )
{
for ( size_t fIdx = 0 ; fIdx < oilRegion -> fields . size (); fIdx ++ )
{
RimOilFieldEntry * oilField = oilRegion -> fields [ fIdx ];
if ( oilField -> selected )
{
2013-09-08 09:05:26 +02:00
parseWellsResponse ( oilField );
2013-09-04 08:03:11 +02:00
}
}
}
}
2013-09-07 20:43:29 +02:00
m_wellPathImportObject -> updateConnectedEditors ();
2013-09-04 08:03:11 +02:00
}
else if ( m_currentDownloadState == DOWNLOAD_WELL_PATH )
{
WellSummaryPage * wellSummaryPage = dynamic_cast < WellSummaryPage *> ( page ( m_wellSummaryPageId ));
if ( wellSummaryPage )
{
wellSummaryPage -> updateSummaryPage ();
}
}
m_currentDownloadState = DOWNLOAD_UNDEFINED ;
2013-09-06 15:59:25 +02:00
2013-09-26 13:54:57 +02:00
m_myProgressDialog -> hide ();
2013-09-04 08:03:11 +02:00
}
2013-09-05 08:45:24 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellImportWizard :: resetAuthenticationCount ()
{
m_firstTimeRequestingAuthentication = true ;
}
2013-09-06 13:06:39 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QStringList RiuWellImportWizard :: absoluteFilePathsToWellPaths () const
{
QStringList filePaths ;
2015-08-12 18:44:03 +02:00
WellSelectionPage * wellSelectionPage = dynamic_cast < WellSelectionPage *> ( page ( m_wellSelectionPageId ));
std :: vector < DownloadEntity > downloadEntities ;
wellSelectionPage -> selectedWellPathEntries ( downloadEntities , NULL );
for ( size_t i = 0 ; i < downloadEntities . size (); i ++ )
2013-09-06 13:06:39 +02:00
{
2017-05-11 09:23:13 +02:00
if ( caf :: Utils :: fileExists ( downloadEntities [ i ]. responseFilename ))
2013-09-06 13:06:39 +02:00
{
2015-08-12 18:44:03 +02:00
filePaths . push_back ( downloadEntities [ i ]. responseFilename );
2013-09-06 13:06:39 +02:00
}
}
return filePaths ;
}
2013-09-08 09:05:26 +02:00
//--------------------------------------------------------------------------------------------------
/// Set wells hidden from the field selection page
/// TODO: This can be refactored when UIOrdering for objects is created
//--------------------------------------------------------------------------------------------------
void RiuWellImportWizard :: slotCurrentIdChanged ( int currentId )
{
bool hideWells = true ;
if ( currentId == m_wellSelectionPageId ) hideWells = false ;
for ( size_t rIdx = 0 ; rIdx < m_wellPathImportObject -> regions . size (); rIdx ++ )
{
RimOilRegionEntry * oilRegion = m_wellPathImportObject -> regions [ rIdx ];
{
for ( size_t fIdx = 0 ; fIdx < oilRegion -> fields . size (); fIdx ++ )
{
RimOilFieldEntry * oilField = oilRegion -> fields [ fIdx ];
2015-08-05 13:27:36 +02:00
oilField -> wells . uiCapability () -> setUiHidden ( hideWells );
2013-09-08 09:05:26 +02:00
}
}
}
// Update the editors to propagate the changes to UI
m_wellPathImportObject -> updateConnectedEditors ();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellImportWizard :: parseWellsResponse ( RimOilFieldEntry * oilFieldEntry )
{
QStringList surveyNames ;
QStringList planNames ;
2017-05-11 09:23:13 +02:00
if ( caf :: Utils :: fileExists ( oilFieldEntry -> wellsFilePath ))
2013-09-08 09:05:26 +02:00
{
2016-06-06 10:43:36 +02:00
ResInsightInternalJson :: JsonReader jsonReader ;
2013-09-08 09:05:26 +02:00
QMap < QString , QVariant > jsonMap = jsonReader . decodeFile ( oilFieldEntry -> wellsFilePath );
QMapIterator < QString , QVariant > it ( jsonMap );
while ( it . hasNext ())
{
it . next ();
// If we have an array, skip to next node
if ( it . key () == "length" )
continue ;
QMap < QString , QVariant > rootMap = it . value (). toMap ();
if ( m_wellPathImportObject -> wellTypeSurvey )
{
QMap < QString , QVariant > surveyMap = rootMap [ "survey" ]. toMap ();
QString name = surveyMap [ "name" ]. toString ();
if ( ! oilFieldEntry -> find ( name , RimWellPathEntry :: WELL_SURVEY ))
{
QMap < QString , QVariant > linksMap = surveyMap [ "links" ]. toMap ();
QString requestUrl = m_webServiceAddress + linksMap [ "entity" ]. toString ();
QString surveyType = surveyMap [ "surveyType" ]. toString ();
RimWellPathEntry * surveyWellPathEntry = RimWellPathEntry :: createWellPathEntry ( name , surveyType , requestUrl , m_destinationFolder , RimWellPathEntry :: WELL_SURVEY );
oilFieldEntry -> wells . push_back ( surveyWellPathEntry );
}
surveyNames . push_back ( name );
}
if ( m_wellPathImportObject -> wellTypePlans )
{
QList < QVariant > plansList = rootMap [ "plans" ]. toList ();
QListIterator < QVariant > planIt ( plansList );
while ( planIt . hasNext ())
{
QMap < QString , QVariant > planMap = planIt . next (). toMap ();
QString name = planMap [ "name" ]. toString ();
if ( ! oilFieldEntry -> find ( name , RimWellPathEntry :: WELL_PLAN ))
{
QMap < QString , QVariant > linksMap = planMap [ "links" ]. toMap ();
QString requestUrl = m_webServiceAddress + linksMap [ "entity" ]. toString ();
QString surveyType = planMap [ "surveyType" ]. toString ();
RimWellPathEntry * surveyWellPathEntry = RimWellPathEntry :: createWellPathEntry ( name , surveyType , requestUrl , m_destinationFolder , RimWellPathEntry :: WELL_PLAN );
oilFieldEntry -> wells . push_back ( surveyWellPathEntry );
}
planNames . push_back ( name );
}
}
}
}
// Delete the well path entries in the model that are not part of the reply from the web service
std :: vector < RimWellPathEntry *> wellsToRemove ;
for ( size_t i = 0 ; i < oilFieldEntry -> wells . size (); i ++ )
{
RimWellPathEntry * wellPathEntry = oilFieldEntry -> wells [ i ];
if ( wellPathEntry -> wellPathType == RimWellPathEntry :: WELL_PLAN )
{
if ( ! planNames . contains ( wellPathEntry -> name ))
{
wellsToRemove . push_back ( wellPathEntry );
}
}
else
{
if ( ! surveyNames . contains ( wellPathEntry -> name ))
{
wellsToRemove . push_back ( wellPathEntry );
}
}
}
for ( size_t i = 0 ; i < wellsToRemove . size (); i ++ )
{
oilFieldEntry -> wells . removeChildObject ( wellsToRemove [ i ]);
delete wellsToRemove [ i ];
}
WellSelectionPage * wellSelectionPage = dynamic_cast < WellSelectionPage *> ( page ( m_wellSelectionPageId ));
if ( wellSelectionPage )
2013-09-26 07:54:57 +02:00
wellSelectionPage -> buildWellTreeView ();
2013-09-08 09:05:26 +02:00
}
2013-09-08 10:53:25 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellImportWizard :: setCredentials ( const QString & username , const QString & password )
{
// Set the initial value of the fields defined in the Authorization page
setField ( "username" , username );
setField ( "password" , password );
}
2015-08-12 18:44:03 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RiuWellImportWizard :: wellSelectionPageId ()
{
return m_wellSelectionPageId ;
}
2013-09-04 08:03:11 +02:00
2013-09-02 08:39:29 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-09-05 08:45:24 +02:00
AuthenticationPage :: AuthenticationPage ( const QString & webServiceAddress , QWidget * parent /*= 0*/ ) : QWizardPage ( parent )
2013-09-02 08:39:29 +02:00
{
setTitle ( "SSIHUB - Login" );
QVBoxLayout * layout = new QVBoxLayout ;
QLabel * label = new QLabel ( "Please enter your login information for SSIHUB at : " + webServiceAddress );
layout -> addWidget ( label );
QFormLayout * formLayout = new QFormLayout ;
layout -> addLayout ( formLayout );
2013-09-08 10:53:25 +02:00
QLineEdit * usernameLineEdit = new QLineEdit ( "" , this );
QLineEdit * passwordlLineEdit = new QLineEdit ( "" , this );
2013-09-02 08:39:29 +02:00
passwordlLineEdit -> setEchoMode ( QLineEdit :: Password );
formLayout -> addRow ( "&Username:" , usernameLineEdit );
formLayout -> addRow ( "&Password:" , passwordlLineEdit );
setLayout ( layout );
// Make variables accessible to other pages in wizard
// Use * at end of field name to indicate mandatory field
registerField ( "username" , usernameLineEdit );
registerField ( "password" , passwordlLineEdit );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-09-05 08:45:24 +02:00
void AuthenticationPage :: initializePage ()
{
RiuWellImportWizard * wiz = dynamic_cast < RiuWellImportWizard *> ( wizard ());
wiz -> resetAuthenticationCount ();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
FieldSelectionPage :: FieldSelectionPage ( RimWellPathImport * wellPathImport , QWidget * parent /*= 0*/ )
2013-09-02 08:39:29 +02:00
{
setTitle ( "Field Selection" );
QVBoxLayout * layout = new QVBoxLayout ;
setLayout ( layout );
QLabel * label = new QLabel ( "Select fields" );
layout -> addWidget ( label );
2013-09-05 08:45:24 +02:00
// Tree view
caf :: PdmUiTreeView * treeView = new caf :: PdmUiTreeView ( this );
2015-07-29 14:41:36 +02:00
treeView -> setPdmItem ( wellPathImport );
2013-09-05 08:45:24 +02:00
layout -> addWidget ( treeView );
layout -> setStretchFactor ( treeView , 10 );
2013-09-05 07:34:04 +02:00
2013-09-02 08:39:29 +02:00
// Property view
2015-08-12 18:44:03 +02:00
m_propertyView = new caf :: PdmUiPropertyView ( this );
layout -> addWidget ( m_propertyView );
m_propertyView -> showProperties ( wellPathImport );
2013-09-05 07:34:04 +02:00
setSizePolicy ( QSizePolicy ( QSizePolicy :: Expanding , QSizePolicy :: Expanding ));
2013-09-02 08:39:29 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void FieldSelectionPage :: initializePage ()
{
RiuWellImportWizard * wiz = dynamic_cast < RiuWellImportWizard *> ( wizard ());
wiz -> downloadFields ();
}
2015-08-12 18:44:03 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
FieldSelectionPage ::~ FieldSelectionPage ()
{
m_propertyView -> showProperties ( NULL );
}
2013-09-02 08:39:29 +02:00
2013-09-26 10:57:35 +02:00
2013-09-02 08:39:29 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-09-04 08:03:11 +02:00
WellSelectionPage :: WellSelectionPage ( RimWellPathImport * wellPathImport , QWidget * parent /*= 0*/ )
2013-09-02 08:39:29 +02:00
{
2013-09-05 07:34:04 +02:00
QVBoxLayout * layout = new QVBoxLayout ;
setLayout ( layout );
QLabel * label = new QLabel ( "Select wells" );
layout -> addWidget ( label );
m_wellSelectionTreeView = new caf :: PdmUiTreeView ( this );
layout -> addWidget ( m_wellSelectionTreeView );
2013-09-07 20:43:29 +02:00
2013-09-08 09:52:25 +02:00
m_wellPathImportObject = wellPathImport ;
2013-09-26 10:57:35 +02:00
m_regionsWithVisibleWells = new ObjectGroupWithHeaders ;
2015-08-12 18:44:03 +02:00
m_regionsWithVisibleWells -> objects . uiCapability () -> setUiHidden ( true );
2013-09-04 08:03:11 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void WellSelectionPage :: initializePage ()
{
RiuWellImportWizard * wiz = dynamic_cast < RiuWellImportWizard *> ( wizard ());
2013-09-05 07:34:04 +02:00
if ( ! wiz ) return ;
2013-09-02 08:39:29 +02:00
2013-09-05 07:34:04 +02:00
wiz -> downloadWells ();
2013-09-26 10:57:35 +02:00
setButtonText ( QWizard :: NextButton , "Download" );
2013-09-08 09:05:26 +02:00
}
2013-09-02 08:39:29 +02:00
2013-09-08 09:05:26 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-09-26 07:54:57 +02:00
void WellSelectionPage :: buildWellTreeView ()
2013-09-08 09:05:26 +02:00
{
2013-09-26 12:21:15 +02:00
for ( size_t rIdx = 0 ; rIdx < m_regionsWithVisibleWells -> objects . size (); rIdx ++ )
{
caf :: PdmObjectGroup * regGroup = dynamic_cast < caf :: PdmObjectGroup *> ( m_regionsWithVisibleWells -> objects [ rIdx ]);
if ( ! regGroup )
continue ;
for ( size_t fIdx = 0 ; fIdx < regGroup -> objects . size (); fIdx ++ )
{
2013-09-26 13:54:57 +02:00
caf :: PdmObjectGroup * fieldGroup = dynamic_cast < caf :: PdmObjectGroup *> ( regGroup -> objects [ fIdx ]);
2013-09-26 12:21:15 +02:00
if ( ! fieldGroup )
continue ;
// RimWellPathEntry objects are present here, they must be taken out out the container, but not deleted
// If fieldGroup->objects->deleteObjects is performed, the objects are deleted
fieldGroup -> objects . clear ();
}
}
// Delete all temporary pdm object groups
2015-08-12 18:44:03 +02:00
m_regionsWithVisibleWells -> objects . deleteAllChildObjects ();
2013-09-08 09:52:25 +02:00
for ( size_t rIdx = 0 ; rIdx < m_wellPathImportObject -> regions . size (); rIdx ++ )
{
RimOilRegionEntry * oilRegion = m_wellPathImportObject -> regions [ rIdx ];
if ( oilRegion -> selected )
{
2015-08-13 12:15:36 +02:00
caf :: PdmObjectCollection * regGroup = new caf :: PdmObjectCollection ;
2015-08-12 18:44:03 +02:00
regGroup -> objects . uiCapability () -> setUiHidden ( true );
2015-08-05 12:34:07 +02:00
regGroup -> setUiName ( oilRegion -> userDescriptionField () -> uiCapability () -> uiValue (). toString ());
2013-09-26 12:21:15 +02:00
m_regionsWithVisibleWells -> objects . push_back ( regGroup );
for ( size_t fIdx = 0 ; fIdx < oilRegion -> fields . size (); fIdx ++ )
{
RimOilFieldEntry * oilField = oilRegion -> fields [ fIdx ];
if ( oilField -> selected )
{
2015-08-13 12:15:36 +02:00
caf :: PdmObjectCollection * fieldGroup = new caf :: PdmObjectCollection ;
2015-08-12 18:44:03 +02:00
fieldGroup -> objects . uiCapability () -> setUiHidden ( true );
2015-10-23 15:46:25 +02:00
fieldGroup -> setUiName ( oilField -> userDescriptionField () -> uiCapability () -> uiValue (). toString ());
2013-09-26 12:21:15 +02:00
regGroup -> objects . push_back ( fieldGroup );
for ( size_t wIdx = 0 ; wIdx < oilField -> wells . size (); wIdx ++ )
{
RimWellPathEntry * wellPathEntry = oilField -> wells [ wIdx ];
2015-08-12 18:44:03 +02:00
// Create a copy of the PdmObject, as it is not supported to have multiple parents of any objects
2016-12-12 07:29:44 +01:00
QString objStr = wellPathEntry -> writeObjectToXmlString ();
2015-08-12 18:44:03 +02:00
RimWellPathEntry * wellPathCopy = new RimWellPathEntry ;
2016-12-12 07:29:44 +01:00
wellPathCopy -> readObjectFromXmlString ( objStr , caf :: PdmDefaultObjectFactory :: instance ());
2015-08-12 18:44:03 +02:00
fieldGroup -> objects . push_back ( wellPathCopy );
2013-09-26 12:21:15 +02:00
}
2015-12-01 13:28:44 +01:00
sortObjectsByDescription ( fieldGroup );
2013-09-26 12:21:15 +02:00
}
}
2013-09-08 09:52:25 +02:00
}
}
2015-07-29 14:41:36 +02:00
m_wellSelectionTreeView -> setPdmItem ( m_regionsWithVisibleWells );
2013-09-08 09:52:25 +02:00
m_regionsWithVisibleWells -> updateConnectedEditors ();
2013-09-26 07:54:57 +02:00
m_wellSelectionTreeView -> treeView () -> expandAll ();
2013-09-08 09:52:25 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
WellSelectionPage ::~ WellSelectionPage ()
{
2015-08-12 18:44:03 +02:00
if ( m_wellSelectionTreeView )
{
m_wellSelectionTreeView -> setPdmItem ( NULL );
}
2013-09-08 09:52:25 +02:00
delete m_regionsWithVisibleWells ;
2013-09-04 08:03:11 +02:00
}
2013-09-02 08:39:29 +02:00
2015-08-12 18:44:03 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void WellSelectionPage :: selectedWellPathEntries ( std :: vector < DownloadEntity >& downloadEntities , caf :: PdmObjectHandle * objHandle )
{
if ( objHandle == NULL )
{
objHandle = m_regionsWithVisibleWells ;
}
std :: vector < caf :: PdmFieldHandle *> childFields ;
objHandle -> fields ( childFields );
for ( size_t i = 0 ; i < childFields . size (); i ++ )
{
std :: vector < caf :: PdmObjectHandle *> childObjects ;
childFields [ i ] -> childObjects ( & childObjects );
for ( size_t j = 0 ; j < childObjects . size (); j ++ )
{
RimWellPathEntry * wellPathEntry = ( dynamic_cast < RimWellPathEntry *> ( childObjects [ j ]));
if ( wellPathEntry )
{
if ( wellPathEntry -> selected && wellPathEntry -> isWellPathValid ())
{
DownloadEntity urlToFile ;
2015-08-13 15:09:43 +02:00
urlToFile . name = wellPathEntry -> name ;
2015-08-12 18:44:03 +02:00
urlToFile . requestUrl = wellPathEntry -> requestUrl ;
urlToFile . responseFilename = wellPathEntry -> wellPathFilePath ;
downloadEntities . push_back ( urlToFile );
}
}
else
{
selectedWellPathEntries ( downloadEntities , childObjects [ j ]);
}
}
}
}
2015-12-01 13:28:44 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool lessByDescription ( const caf :: PdmPointer < caf :: PdmObjectHandle >& obj1 , const caf :: PdmPointer < caf :: PdmObjectHandle >& obj2 )
{
caf :: PdmUiFieldHandle * uiFieldHandle1 = NULL ;
caf :: PdmUiFieldHandle * uiFieldHandle2 = NULL ;
if ( obj1 . notNull () && obj1 -> uiCapability () && obj1 -> uiCapability () -> userDescriptionField ())
{
uiFieldHandle1 = obj1 -> uiCapability () -> userDescriptionField () -> uiCapability ();
}
if ( obj2 . notNull () && obj2 -> uiCapability () && obj2 -> uiCapability () -> userDescriptionField ())
{
uiFieldHandle2 = obj2 -> uiCapability () -> userDescriptionField () -> uiCapability ();
}
if ( uiFieldHandle1 && uiFieldHandle2 )
{
QString string1 = uiFieldHandle1 -> uiValue (). toString ();
QString string2 = uiFieldHandle2 -> uiValue (). toString ();
return string1 < string2 ;
}
return true ;
}
2013-09-02 08:39:29 +02:00
2015-12-01 13:28:44 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void WellSelectionPage :: sortObjectsByDescription ( caf :: PdmObjectCollection * objects )
{
std :: sort ( objects -> objects . begin (), objects -> objects . end (), lessByDescription );
}
2013-09-08 09:05:26 +02:00
2013-09-02 08:39:29 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-09-04 08:03:11 +02:00
WellSummaryPage :: WellSummaryPage ( RimWellPathImport * wellPathImport , QWidget * parent /*= 0*/ )
2013-09-02 08:39:29 +02:00
{
2013-09-04 08:03:11 +02:00
m_wellPathImportObject = wellPathImport ;
2013-09-26 07:54:57 +02:00
m_wellPathImportObject -> setUiHidden ( true );
2013-09-02 08:39:29 +02:00
QVBoxLayout * layout = new QVBoxLayout ;
2013-09-04 08:03:11 +02:00
setLayout ( layout );
2013-09-02 08:39:29 +02:00
2013-09-04 08:03:11 +02:00
m_textEdit = new QTextEdit ( this );
2013-09-08 10:54:29 +02:00
m_textEdit -> setReadOnly ( true );
2013-09-04 08:03:11 +02:00
layout -> addWidget ( m_textEdit );
2013-09-05 07:34:04 +02:00
2013-09-26 12:21:15 +02:00
QPushButton * button = new QPushButton ( "Show/hide details" , this );
2013-09-08 10:05:24 +02:00
connect ( button , SIGNAL ( clicked ()), this , SLOT ( slotShowDetails ()));
layout -> addWidget ( button );
2013-09-05 07:34:04 +02:00
m_listView = new caf :: PdmUiListView ( this );
2013-09-26 12:21:15 +02:00
layout -> setStretchFactor ( m_listView , 10 );
2013-09-05 07:34:04 +02:00
layout -> addWidget ( m_listView );
2013-09-08 10:05:24 +02:00
m_listView -> hide ();
2013-09-05 07:34:04 +02:00
2015-08-13 12:15:36 +02:00
m_objectGroup = new caf :: PdmObjectCollection ;
2013-09-26 10:57:35 +02:00
setButtonText ( QWizard :: FinishButton , "Import" );
2013-09-02 08:39:29 +02:00
}
2013-09-04 08:03:11 +02:00
2013-09-02 08:39:29 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-09-04 08:03:11 +02:00
void WellSummaryPage :: initializePage ()
2013-09-02 08:39:29 +02:00
{
2013-09-04 08:03:11 +02:00
RiuWellImportWizard * wiz = dynamic_cast < RiuWellImportWizard *> ( wizard ());
wiz -> downloadWellPaths ();
2013-09-02 08:39:29 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-09-04 08:03:11 +02:00
void WellSummaryPage :: updateSummaryPage ()
2013-09-02 08:39:29 +02:00
{
2013-09-05 07:34:04 +02:00
m_objectGroup -> objects . clear ();
2013-09-04 08:03:11 +02:00
m_textEdit -> setText ( "Summary of imported wells \n\n " );
2013-09-02 08:39:29 +02:00
2013-09-08 10:05:24 +02:00
size_t wellPathCount = 0 ;
QString errorString ;
2015-08-12 18:44:03 +02:00
RiuWellImportWizard * wiz = dynamic_cast < RiuWellImportWizard *> ( wizard ());
WellSelectionPage * wellSelectionPage = dynamic_cast < WellSelectionPage *> ( wiz -> page ( wiz -> wellSelectionPageId ()));
std :: vector < DownloadEntity > downloadEntities ;
wellSelectionPage -> selectedWellPathEntries ( downloadEntities , NULL );
for ( size_t i = 0 ; i < downloadEntities . size (); i ++ )
2013-09-04 08:03:11 +02:00
{
2017-05-11 09:23:13 +02:00
if ( caf :: Utils :: fileExists ( downloadEntities [ i ]. responseFilename ))
2013-09-04 08:03:11 +02:00
{
2015-08-12 18:44:03 +02:00
wellPathCount ++ ;
}
else
{
2015-08-13 15:09:43 +02:00
errorString += QString ( "Failed to get file '%1' from well '%2' \n " ). arg ( downloadEntities [ i ]. responseFilename ). arg ( downloadEntities [ i ]. name );
2013-09-04 08:03:11 +02:00
}
2013-09-05 07:34:04 +02:00
2015-08-13 15:09:43 +02:00
2015-08-12 18:44:03 +02:00
SummaryPageDownloadEntity * sumPageEntity = new SummaryPageDownloadEntity ;
2015-08-13 15:09:43 +02:00
sumPageEntity -> name = downloadEntities [ i ]. name ;
2015-08-12 18:44:03 +02:00
sumPageEntity -> responseFilename = downloadEntities [ i ]. responseFilename ;
sumPageEntity -> requestUrl = downloadEntities [ i ]. requestUrl ;
m_objectGroup -> objects (). push_back ( sumPageEntity );
}
2013-09-08 10:05:24 +02:00
2013-09-26 10:57:35 +02:00
m_textEdit -> setText ( QString ( "Downloaded successfully %1 well paths. \n Please push 'Import' button to import well paths into ResInsight. \n\n " ). arg ( wellPathCount ));
2013-09-08 10:05:24 +02:00
if ( ! errorString . isEmpty ())
{
m_textEdit -> append ( "Detected following errors during well path download. See details below." );
m_textEdit -> append ( errorString );
}
2013-09-05 07:34:04 +02:00
m_listView -> setPdmObject ( m_objectGroup );
m_objectGroup -> updateConnectedEditors ();
2013-09-02 08:39:29 +02:00
}
2013-09-08 10:05:24 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void WellSummaryPage :: slotShowDetails ()
{
2013-09-26 12:21:15 +02:00
if ( m_listView -> isHidden ())
{
m_listView -> show ();
}
else
{
m_listView -> hide ();
}
2013-09-08 10:05:24 +02:00
}
2015-08-12 18:44:03 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ObjectGroupWithHeaders :: defineObjectEditorAttribute ( QString uiConfigName , caf :: PdmUiEditorAttribute * attribute )
{
caf :: PdmUiTreeViewEditorAttribute * myAttr = dynamic_cast < caf :: PdmUiTreeViewEditorAttribute *> ( attribute );
if ( myAttr )
{
QStringList colHeaders ;
colHeaders << "Wells" ;
myAttr -> columnHeaders = colHeaders ;
}
}
CAF_PDM_SOURCE_INIT ( SummaryPageDownloadEntity , "SummaryPageDownloadEntity" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
SummaryPageDownloadEntity :: SummaryPageDownloadEntity ()
{
CAF_PDM_InitObject ( "SummaryPageDownloadEntity" , "" , "" , "" );
2015-08-13 15:09:43 +02:00
CAF_PDM_InitFieldNoDefault ( & name , "Name" , "" , "" , "" , "" );
2015-08-12 18:44:03 +02:00
CAF_PDM_InitFieldNoDefault ( & requestUrl , "RequestUrl" , "" , "" , "" , "" );
CAF_PDM_InitFieldNoDefault ( & responseFilename , "ResponseFilename" , "" , "" , "" , "" );
}