Пример #1
0
void QgsSymbolSelectorWidget::symbolChanged()
{
  SymbolLayerItem *currentItem = static_cast<SymbolLayerItem *>( model->itemFromIndex( layersTree->currentIndex() ) );
  if ( !currentItem || currentItem->isLayer() )
    return;
  // disconnect to avoid recreating widget
  disconnect( layersTree->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSymbolSelectorWidget::layerChanged );
  if ( currentItem->parent() )
  {
    // it is a sub-symbol
    QgsSymbol *symbol = currentItem->symbol();
    SymbolLayerItem *parent = static_cast<SymbolLayerItem *>( currentItem->parent() );
    parent->removeRow( 0 );
    loadSymbol( symbol, parent );
    layersTree->setCurrentIndex( parent->child( 0 )->index() );
    parent->updatePreview();
  }
  else
  {
    //it is the symbol itself
    loadSymbol();
    QModelIndex newIndex = layersTree->model()->index( 0, 0 );
    layersTree->setCurrentIndex( newIndex );
  }
  updatePreview();
  // connect it back once things are set
  connect( layersTree->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSymbolSelectorWidget::layerChanged );
}
QgsSymbolV2PropertiesDialog::QgsSymbolV2PropertiesDialog( QgsSymbolV2* symbol, QWidget* parent )
    : QDialog( parent ), mSymbol( symbol )
{
  setupUi( this );

  // setup icons
  btnAddLayer->setIcon( QIcon( QgsApplication::iconPath( "symbologyAdd.png" ) ) );
  btnRemoveLayer->setIcon( QIcon( QgsApplication::iconPath( "symbologyRemove.png" ) ) );
  btnLock->setIcon( QIcon( QgsApplication::iconPath( "symbologyLock.png" ) ) );
  btnUp->setIcon( QIcon( QgsApplication::iconPath( "symbologyUp.png" ) ) );
  btnDown->setIcon( QIcon( QgsApplication::iconPath( "symbologyDown.png" ) ) );

  // set widget functions
  // (should be probably moved somewhere else)
  _initWidgetFunctions();

  loadSymbol();

  connect( btnUp, SIGNAL( clicked() ), this, SLOT( moveLayerUp() ) );
  connect( btnDown, SIGNAL( clicked() ), this, SLOT( moveLayerDown() ) );
  connect( btnAddLayer, SIGNAL( clicked() ), this, SLOT( addLayer() ) );
  connect( btnRemoveLayer, SIGNAL( clicked() ), this, SLOT( removeLayer() ) );
  connect( btnLock, SIGNAL( clicked() ), this, SLOT( lockLayer() ) );

  populateLayerTypes();
  connect( cboLayerType, SIGNAL( currentIndexChanged( int ) ), this, SLOT( layerTypeChanged() ) );

  loadPropertyWidgets();

  updateUi();

  // set first layer as active
  QModelIndex newIndex = listLayers->model()->index( 0, 0 );
  listLayers->setCurrentIndex( newIndex );
}
Пример #3
0
// ---------------------------------------------------------------------
// Makes the schematic symbol subcircuit with the correct number
// of ports.
void Subcircuit::createSymbol()
{
  int No;
  QString FileName(Props.getFirst()->Value);
  FileName = getSubcircuitFile();

  tx = INT_MIN;
  ty = INT_MIN;
  if(loadSymbol(FileName) > 0) {  // try to load subcircuit symbol
    if(tx == INT_MIN)  tx = x1+4;
    if(ty == INT_MIN)  ty = y2+4;
    // remove unused ports
    for(Port *pp = Ports.first(); pp != 0; ) {
      if(!pp->avail) { Ports.remove(); pp = Ports.current (); }
      else pp = Ports.next();
    }
  }
  else {
    No = QucsApp::testFile(FileName);
    if(No < 0)  No = 0;

    Ports.clear();
    remakeSymbol(No);  // no symbol was found -> create standard symbol
  }
}
Пример #4
0
// ---------------------------------------------------------------------
// Makes the schematic symbol subcircuit with the correct number
// of ports.
void Subcircuit::createSymbol()
{
  int No;
  QString FileName(Props.getFirst()->Value);
  FileName = getSubcircuitFile();

  tx = INT_MIN;
  ty = INT_MIN;
  if(loadSymbol(FileName) > 0) {  // try to load subcircuit symbol
    if(tx == INT_MIN)  tx = x1+4;
    if(ty == INT_MIN)  ty = y2+4;
    // remove unused ports
    QMutableListIterator<Port *> ip(Ports);
    Port *pp;
    while (ip.hasNext()) {
      pp = ip.next();
      if(!pp->avail) {
          pp = ip.peekNext();
          ip.remove();
      }
    }
  }
  else {
    No = QucsApp::testFile(FileName);
    if(No < 0)  No = 0;

    Ports.clear();
    remakeSymbol(No);  // no symbol was found -> create standard symbol
  }
}
Пример #5
0
void QgsSymbolSelectorWidget::changeLayer( QgsSymbolLayer *newLayer )
{
  SymbolLayerItem *item = currentLayerItem();
  QgsSymbolLayer *layer = item->layer();

  if ( layer->subSymbol() )
  {
    item->removeRow( 0 );
  }
  // update symbol layer item
  item->setLayer( newLayer );
  // When it is a marker symbol
  if ( newLayer->subSymbol() )
  {
    loadSymbol( newLayer->subSymbol(), item );
    layersTree->setExpanded( item->index(), true );
  }

  // Change the symbol at last to avoid deleting item's layer
  QgsSymbol *symbol = static_cast<SymbolLayerItem *>( item->parent() )->symbol();
  int layerIdx = item->parent()->rowCount() - item->row() - 1;
  symbol->changeSymbolLayer( layerIdx, newLayer );

  item->updatePreview();
  updatePreview();
  // Important: This lets the layer have its own layer properties widget
  layerChanged();
}
Пример #6
0
void checkLoading(void *handle, void *funcPtr, const char *libKey) {
  funcPtr = loadSymbol(handle, libKey);
  char *err = getLastError();
  if (err != NULL) {
    fprintf(stderr, "\033[31m%s\033[00m\n", err);
    exit(-1);
  }
}
QgsSymbolV2SelectorDialog::QgsSymbolV2SelectorDialog( QgsSymbolV2* symbol, QgsStyleV2* style, const QgsVectorLayer* vl, QWidget* parent, bool embedded )
    : QDialog( parent )
    , mAdvancedMenu( NULL )
    , mVectorLayer( vl )
    , mMapCanvas( 0 )
{
#ifdef Q_OS_MAC
  setWindowModality( Qt::WindowModal );
#endif
  mStyle = style;
  mSymbol = symbol;
  mPresentWidget = NULL;

  setupUi( this );

  QSettings settings;
  restoreGeometry( settings.value( "/Windows/SymbolSelectorDialog/geometry" ).toByteArray() );

  // can be embedded in renderer properties dialog
  if ( embedded )
  {
    buttonBox->hide();
    layout()->setContentsMargins( 0, 0, 0, 0 );
  }
  // setup icons
  btnAddLayer->setIcon( QIcon( QgsApplication::iconPath( "symbologyAdd.svg" ) ) );
  btnRemoveLayer->setIcon( QIcon( QgsApplication::iconPath( "symbologyRemove.svg" ) ) );
  QIcon iconLock;
  iconLock.addFile( QgsApplication::iconPath( "locked.svg" ), QSize(), QIcon::Normal, QIcon::On );
  iconLock.addFile( QgsApplication::iconPath( "unlocked.svg" ), QSize(), QIcon::Normal, QIcon::Off );
  btnLock->setIcon( iconLock );
  btnUp->setIcon( QIcon( QgsApplication::iconPath( "symbologyUp.svg" ) ) );
  btnDown->setIcon( QIcon( QgsApplication::iconPath( "symbologyDown.svg" ) ) );

  model = new QStandardItemModel( layersTree );
  // Set the symbol
  layersTree->setModel( model );
  layersTree->setHeaderHidden( true );

  QItemSelectionModel* selModel = layersTree->selectionModel();
  connect( selModel, SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ), this, SLOT( layerChanged() ) );

  loadSymbol( symbol, static_cast<SymbolLayerItem*>( model->invisibleRootItem() ) );
  updatePreview();

  connect( btnUp, SIGNAL( clicked() ), this, SLOT( moveLayerUp() ) );
  connect( btnDown, SIGNAL( clicked() ), this, SLOT( moveLayerDown() ) );
  connect( btnAddLayer, SIGNAL( clicked() ), this, SLOT( addLayer() ) );
  connect( btnRemoveLayer, SIGNAL( clicked() ), this, SLOT( removeLayer() ) );
  connect( btnLock, SIGNAL( clicked() ), this, SLOT( lockLayer() ) );
  connect( btnSaveSymbol, SIGNAL( clicked() ), this, SLOT( saveSymbol() ) );

  updateUi();

  // set symbol as active item in the tree
  QModelIndex newIndex = layersTree->model()->index( 0, 0 );
  layersTree->setCurrentIndex( newIndex );
}
Пример #8
0
QgsSymbolV2SelectorWidget::QgsSymbolV2SelectorWidget( QgsSymbolV2* symbol, QgsStyleV2* style, const QgsVectorLayer* vl, QWidget* parent )
    : QgsPanelWidget( parent )
    , mAdvancedMenu( nullptr )
    , mVectorLayer( vl )
    , mMapCanvas( nullptr )
{
#ifdef Q_OS_MAC
  setWindowModality( Qt::WindowModal );
#endif
  mStyle = style;
  mSymbol = symbol;
  mPresentWidget = nullptr;

  setupUi( this );

  // setup icons
  btnAddLayer->setIcon( QIcon( QgsApplication::iconPath( "symbologyAdd.svg" ) ) );
  btnRemoveLayer->setIcon( QIcon( QgsApplication::iconPath( "symbologyRemove.svg" ) ) );
  QIcon iconLock;
  iconLock.addFile( QgsApplication::iconPath( "locked.svg" ), QSize(), QIcon::Normal, QIcon::On );
  iconLock.addFile( QgsApplication::iconPath( "locked.svg" ), QSize(), QIcon::Active, QIcon::On );
  iconLock.addFile( QgsApplication::iconPath( "unlocked.svg" ), QSize(), QIcon::Normal, QIcon::Off );
  iconLock.addFile( QgsApplication::iconPath( "unlocked.svg" ), QSize(), QIcon::Active, QIcon::Off );
  btnLock->setIcon( iconLock );
  btnDuplicate->setIcon( QIcon( QgsApplication::iconPath( "mActionDuplicateLayer.svg" ) ) );
  btnUp->setIcon( QIcon( QgsApplication::iconPath( "symbologyUp.svg" ) ) );
  btnDown->setIcon( QIcon( QgsApplication::iconPath( "symbologyDown.svg" ) ) );

  model = new QStandardItemModel( layersTree );
  // Set the symbol
  layersTree->setModel( model );
  layersTree->setHeaderHidden( true );

  QItemSelectionModel* selModel = layersTree->selectionModel();
  connect( selModel, SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ), this, SLOT( layerChanged() ) );

  loadSymbol( symbol, static_cast<SymbolLayerItem*>( model->invisibleRootItem() ) );
  updatePreview();

  connect( btnUp, SIGNAL( clicked() ), this, SLOT( moveLayerUp() ) );
  connect( btnDown, SIGNAL( clicked() ), this, SLOT( moveLayerDown() ) );
  connect( btnAddLayer, SIGNAL( clicked() ), this, SLOT( addLayer() ) );
  connect( btnRemoveLayer, SIGNAL( clicked() ), this, SLOT( removeLayer() ) );
  connect( btnLock, SIGNAL( clicked() ), this, SLOT( lockLayer() ) );
  connect( btnDuplicate, SIGNAL( clicked() ), this, SLOT( duplicateLayer() ) );
  connect( this, SIGNAL( symbolModified() ), this, SIGNAL( widgetChanged() ) );

  updateUi();

  // set symbol as active item in the tree
  QModelIndex newIndex = layersTree->model()->index( 0, 0 );
  layersTree->setCurrentIndex( newIndex );

  setPanelTitle( tr( "Symbol selector" ) );
}
void QgsSymbolV2PropertiesDialog::addLayer()
{
  QgsSymbolLayerV2* newLayer = QgsSymbolLayerV2Registry::instance()->defaultSymbolLayer( mSymbol->type() );

  mSymbol->appendSymbolLayer( newLayer );

  loadSymbol();

  QModelIndex newIndex = listLayers->model()->index( 0, 0 );
  listLayers->setCurrentIndex( newIndex );

  updateUi();
}
void QgsSymbolV2PropertiesDialog::removeLayer()
{
  int idx = currentLayerIndex();
  if ( idx < 0 ) return;
  int row = currentRowIndex();
  mSymbol->deleteSymbolLayer( idx );

  loadSymbol();

  updateUi();

  // set previous layer as active
  QModelIndex newIndex = listLayers->model()->index( qMin( row, mSymbol->symbolLayerCount() - 1 ), 0 );
  listLayers->setCurrentIndex( newIndex );
}
void QgsSymbolV2PropertiesDialog::moveLayerByOffset( int offset )
{
  int rowIdx = currentRowIndex();
  int layerIdx = currentLayerIndex();

  // switch layers
  QgsSymbolLayerV2* tmpLayer = mSymbol->takeSymbolLayer( layerIdx );
  mSymbol->insertSymbolLayer( layerIdx - offset, tmpLayer );

  loadSymbol();

  QModelIndex newIndex = listLayers->model()->index( rowIdx + offset, 0 );
  listLayers->setCurrentIndex( newIndex );

  updateUi();
}
Пример #12
0
std::tuple<Font, bool> loadFont(std::string filename)
{
	Font font;
	std::ifstream fileStream(filename);
	if(not fileStream)
	{
		std::cerr << "unable to open font file " << filename << std::endl;
		return std::make_tuple(font, false);
	}
	fr::FileReader reader(fileStream);

	auto tableObject = reader.getList("table");
	if(tableObject == nullptr)
		return std::make_tuple(font, false);
	
	for(auto obj : tableObject->datum)
	{
		loadSymbol(font, obj);
	}
	return std::make_tuple(font, true);
}
Пример #13
0
// ---------------------------------------------------------------------
// Makes the schematic symbol subcircuit with the correct number
// of ports.
void LibComp::createSymbol()
{
  tx = INT_MIN;
  ty = INT_MIN;
  if(loadSymbol() > 0) {
    if(tx == INT_MIN)  tx = x1+4;
    if(ty == INT_MIN)  ty = y2+4;
  }
  else {
    // only paint a rectangle
    Lines.append(new Line(-15, -15, 15, -15, QPen(Qt::darkBlue,2)));
    Lines.append(new Line( 15, -15, 15,  15, QPen(Qt::darkBlue,2)));
    Lines.append(new Line(-15,  15, 15,  15, QPen(Qt::darkBlue,2)));
    Lines.append(new Line(-15, -15,-15,  15, QPen(Qt::darkBlue,2)));

    x1 = -18; y1 = -18;
    x2 =  18; y2 =  18;

    tx = x1+4;
    ty = y2+4;
  }
}
Пример #14
0
void QgsSymbolSelectorWidget::loadSymbol( QgsSymbol *symbol, SymbolLayerItem *parent )
{
  SymbolLayerItem *symbolItem = new SymbolLayerItem( symbol );
  QFont boldFont = symbolItem->font();
  boldFont.setBold( true );
  symbolItem->setFont( boldFont );
  parent->appendRow( symbolItem );

  int count = symbol->symbolLayerCount();
  for ( int i = count - 1; i >= 0; i-- )
  {
    SymbolLayerItem *layerItem = new SymbolLayerItem( symbol->symbolLayer( i ) );
    layerItem->setEditable( false );
    symbolItem->appendRow( layerItem );
    if ( symbol->symbolLayer( i )->subSymbol() )
    {
      loadSymbol( symbol->symbolLayer( i )->subSymbol(), layerItem );
    }
    layersTree->setExpanded( layerItem->index(), true );
  }
  layersTree->setExpanded( symbolItem->index(), true );
}
Пример #15
0
void QgsSymbolSelectorWidget::duplicateLayer()
{
  QModelIndex idx = layersTree->currentIndex();
  if ( !idx.isValid() )
    return;

  SymbolLayerItem *item = static_cast<SymbolLayerItem *>( model->itemFromIndex( idx ) );
  if ( !item->isLayer() )
    return;

  QgsSymbolLayer *source = item->layer();

  int insertIdx = item->row();
  item = static_cast<SymbolLayerItem *>( item->parent() );

  QgsSymbol *parentSymbol = item->symbol();

  QgsSymbolLayer *newLayer = source->clone();
  if ( insertIdx == -1 )
    parentSymbol->appendSymbolLayer( newLayer );
  else
    parentSymbol->insertSymbolLayer( item->rowCount() - insertIdx, newLayer );

  SymbolLayerItem *newLayerItem = new SymbolLayerItem( newLayer );
  item->insertRow( insertIdx == -1 ? 0 : insertIdx, newLayerItem );
  if ( newLayer->subSymbol() )
  {
    loadSymbol( newLayer->subSymbol(), newLayerItem );
    layersTree->setExpanded( newLayerItem->index(), true );
  }
  item->updatePreview();

  layersTree->setCurrentIndex( model->indexFromItem( newLayerItem ) );
  updateUi();
  updatePreview();
}
Пример #16
0
int loadSymbolSet(symbolSetObj *symbolset, mapObj *map)
{
  int status=1;
  char szPath[MS_MAXPATHLEN], *pszSymbolPath=NULL;

  int foundSymbolSetToken=MS_FALSE;
  int token;

  if(!symbolset) {
    msSetError(MS_SYMERR, "Symbol structure unallocated.", "loadSymbolSet()");
    return(-1);
  }

  symbolset->map = (mapObj *)map;

  if(!symbolset->filename) return(0);

  /*
  ** Open the file
  */
  if((msyyin = fopen(msBuildPath(szPath, symbolset->map->mappath, symbolset->filename), "r")) == NULL) {
    msSetError(MS_IOERR, "(%s)", "loadSymbolSet()", symbolset->filename);
    return(-1);
  }

  pszSymbolPath = msGetPath(szPath);

  msyystate = MS_TOKENIZE_FILE; /* restore lexer state to INITIAL, and do return comments */
  msyylex(); /* sets things up, but doesn't process any tokens */

  msyylineno = 0; /* reset line counter */
  msyyrestart(msyyin); /* flush the scanner - there's a better way but this works for now */

  /*
  ** Read the symbol file
  */
  for(;;) {
    token = msyylex();

    if(!foundSymbolSetToken && token != SYMBOLSET) {
      msSetError(MS_IDENTERR, "First token must be SYMBOLSET, this doesn't look like a symbol file.", "msLoadSymbolSet()");
      return(-1);
    }

    switch(token) {
      case(END):
      case(EOF):
        status = 0;
        break;
      case(SYMBOL):
        /* Allocate/init memory for new symbol if needed */
        if (msGrowSymbolSet(symbolset) == NULL) {
          status = -1;
        } else if((loadSymbol((symbolset->symbol[symbolset->numsymbols]), pszSymbolPath) == -1))
          status = -1;
        else
          symbolset->numsymbols++;
        break;
      case(SYMBOLSET):
        foundSymbolSetToken = MS_TRUE;
        break;
      default:
        msSetError(MS_IDENTERR, "Parsing error near (%s):(line %d)", "loadSymbolSet()", msyystring_buffer, msyylineno);
        status = -1;
    } /* end switch */

    if(status != 1) break;
  } /* end for */

  fclose(msyyin);
  msyyin = NULL;
  free(pszSymbolPath);
  return(status);
}
Пример #17
0
void QgsSymbolSelectorWidget::loadSymbol()
{
  model->clear();
  loadSymbol( mSymbol, static_cast<SymbolLayerItem *>( model->invisibleRootItem() ) );
}
Пример #18
0
QgsSymbolSelectorWidget::QgsSymbolSelectorWidget( QgsSymbol *symbol, QgsStyle *style, QgsVectorLayer *vl, QWidget *parent )
  : QgsPanelWidget( parent )
  , mVectorLayer( vl )
{
#ifdef Q_OS_MAC
  setWindowModality( Qt::WindowModal );
#endif
  mStyle = style;
  mSymbol = symbol;
  mPresentWidget = nullptr;

  setupUi( this );
  this->layout()->setContentsMargins( 0, 0, 0, 0 );

  // setup icons
  btnAddLayer->setIcon( QIcon( QgsApplication::iconPath( "symbologyAdd.svg" ) ) );
  btnRemoveLayer->setIcon( QIcon( QgsApplication::iconPath( "symbologyRemove.svg" ) ) );
  QIcon iconLock;
  iconLock.addFile( QgsApplication::iconPath( QStringLiteral( "locked.svg" ) ), QSize(), QIcon::Normal, QIcon::On );
  iconLock.addFile( QgsApplication::iconPath( QStringLiteral( "locked.svg" ) ), QSize(), QIcon::Active, QIcon::On );
  iconLock.addFile( QgsApplication::iconPath( QStringLiteral( "unlocked.svg" ) ), QSize(), QIcon::Normal, QIcon::Off );
  iconLock.addFile( QgsApplication::iconPath( QStringLiteral( "unlocked.svg" ) ), QSize(), QIcon::Active, QIcon::Off );
  btnLock->setIcon( iconLock );
  btnDuplicate->setIcon( QIcon( QgsApplication::iconPath( "mActionDuplicateLayer.svg" ) ) );
  btnUp->setIcon( QIcon( QgsApplication::iconPath( "mActionArrowUp.svg" ) ) );
  btnDown->setIcon( QIcon( QgsApplication::iconPath( "mActionArrowDown.svg" ) ) );

  model = new QStandardItemModel( layersTree );
  // Set the symbol
  layersTree->setModel( model );
  layersTree->setHeaderHidden( true );

  //get first feature from layer for previews
  if ( mVectorLayer )
  {
    QgsFeatureIterator it = mVectorLayer->getFeatures( QgsFeatureRequest().setLimit( 1 ) );
    it.nextFeature( mPreviewFeature );
    mPreviewExpressionContext.appendScopes( QgsExpressionContextUtils::globalProjectLayerScopes( mVectorLayer ) );
    mPreviewExpressionContext.setFeature( mPreviewFeature );
  }
  else
  {
    mPreviewExpressionContext.appendScopes( QgsExpressionContextUtils::globalProjectLayerScopes( nullptr ) );
  }

  QItemSelectionModel *selModel = layersTree->selectionModel();
  connect( selModel, &QItemSelectionModel::currentChanged, this, &QgsSymbolSelectorWidget::layerChanged );

  loadSymbol( symbol, static_cast<SymbolLayerItem *>( model->invisibleRootItem() ) );
  updatePreview();

  connect( btnUp, &QAbstractButton::clicked, this, &QgsSymbolSelectorWidget::moveLayerUp );
  connect( btnDown, &QAbstractButton::clicked, this, &QgsSymbolSelectorWidget::moveLayerDown );
  connect( btnAddLayer, &QAbstractButton::clicked, this, &QgsSymbolSelectorWidget::addLayer );
  connect( btnRemoveLayer, &QAbstractButton::clicked, this, &QgsSymbolSelectorWidget::removeLayer );
  connect( btnLock, &QAbstractButton::clicked, this, &QgsSymbolSelectorWidget::lockLayer );
  connect( btnDuplicate, &QAbstractButton::clicked, this, &QgsSymbolSelectorWidget::duplicateLayer );
  connect( this, &QgsSymbolSelectorWidget::symbolModified, this, &QgsPanelWidget::widgetChanged );

  updateUi();

  // set symbol as active item in the tree
  QModelIndex newIndex = layersTree->model()->index( 0, 0 );
  layersTree->setCurrentIndex( newIndex );

  setPanelTitle( tr( "Symbol Selector" ) );

  connect( QgsApplication::svgCache(), &QgsSvgCache::remoteSvgFetched, this, [ = ]
  {
    // when a remote svg has been fetched, update the widget's previews
    // this is required if the symbol utilizes remote svgs, and the current previews
    // have been generated using the temporary "downloading" svg. In this case
    // we require the preview to be regenerated to use the correct fetched
    // svg
    symbolChanged();
    updatePreview();
  } );
}
Пример #19
0
static void loadSSL(void) {
  // SHELLINABOX_LIBSSL_SO can be used to select the specific
  // soname of libssl for systems where it is not libssl.so.
  // The feature is currently disabled.
  const char* path_libssl = NULL; // = getenv ("SHELLINABOX_LIBSSL_SO");
  if (path_libssl == NULL)
    path_libssl = "libssl.so";
  check(!SSL_library_init);
  struct {
    union {
      void *avoid_gcc_warning_about_type_punning;
      void **var;
    };
    const char *fn;
  } symbols[] = {
    { { &BIO_ctrl },                    "BIO_ctrl" },
    { { &BIO_f_buffer },                "BIO_f_buffer" },
    { { &BIO_free_all },                "BIO_free_all" },
    { { &BIO_new },                     "BIO_new" },
    { { &BIO_new_socket },              "BIO_new_socket" },
    { { &BIO_pop },                     "BIO_pop" },
    { { &BIO_push },                    "BIO_push" },
    { { &ERR_clear_error },             "ERR_clear_error" },
    { { &ERR_clear_error },             "ERR_clear_error" },
    { { &ERR_peek_error },              "ERR_peek_error" },
    { { &ERR_peek_error },              "ERR_peek_error" },
    { { &SSL_CTX_callback_ctrl },       "SSL_CTX_callback_ctrl" },
    { { &SSL_CTX_check_private_key },   "SSL_CTX_check_private_key" },
    { { &SSL_CTX_ctrl },                "SSL_CTX_ctrl" },
    { { &SSL_CTX_free },                "SSL_CTX_free" },
    { { &SSL_CTX_new },                 "SSL_CTX_new" },
    { { &SSL_CTX_use_PrivateKey_file }, "SSL_CTX_use_PrivateKey_file" },
    { { &SSL_CTX_use_PrivateKey_ASN1 }, "SSL_CTX_use_PrivateKey_ASN1" },
    { { &SSL_CTX_use_certificate_file },"SSL_CTX_use_certificate_file"},
    { { &SSL_CTX_use_certificate_ASN1 },"SSL_CTX_use_certificate_ASN1"},
    { { &SSL_ctrl },                    "SSL_ctrl" },
    { { &SSL_free },                    "SSL_free" },
    { { &SSL_get_error },               "SSL_get_error" },
    { { &SSL_get_ex_data },             "SSL_get_ex_data" },
    { { &SSL_get_rbio },                "SSL_get_rbio" },
#ifdef HAVE_TLSEXT
    { { &SSL_get_servername },          "SSL_get_servername" },
#endif
    { { &SSL_get_wbio },                "SSL_get_wbio" },
    { { &SSL_library_init },            "SSL_library_init" },
    { { &SSL_new },                     "SSL_new" },
    { { &SSL_read },                    "SSL_read" },
#ifdef HAVE_TLSEXT
    { { &SSL_set_SSL_CTX },             "SSL_set_SSL_CTX" },
#endif
    { { &SSL_set_accept_state },        "SSL_set_accept_state" },
    { { &SSL_set_bio },                 "SSL_set_bio" },
    { { &SSL_set_ex_data },             "SSL_set_ex_data" },
    { { &SSL_shutdown },                "SSL_shutdown" },
    { { &SSL_write },                   "SSL_write" },
    { { &SSLv23_server_method },        "SSLv23_server_method" },
    { { &d2i_X509 },                    "d2i_X509" },
    { { &X509_free },                   "X509_free" },
    { { &x_SSL_CTX_set_cipher_list },   "SSL_CTX_set_cipher_list" },
    { { &x_sk_zero },                   "sk_zero" }
  };
  for (unsigned i = 0; i < sizeof(symbols)/sizeof(symbols[0]); i++) {
    if (!(*symbols[i].var = loadSymbol(path_libssl, symbols[i].fn))) {
      debug("Failed to load SSL support. Could not find \"%s\"",
            symbols[i].fn);
      for (unsigned j = 0; j < sizeof(symbols)/sizeof(symbols[0]); j++) {
        *symbols[j].var = NULL;
      }
      return;
    }
  }
  // These are optional
  x_SSL_COMP_get_compression_methods = loadSymbol(path_libssl, "SSL_COMP_get_compression_methods");
  // ends

  SSL_library_init();
  dcheck(!ERR_peek_error());
  debug("Loaded SSL suppport");
}
bool OsmAnd::CoreResourcesEmbeddedBundle_P::loadResources()
{
    typedef const void* (*GetPointerFunctionPtr)();
    typedef const char* NamePtr;
    typedef const uint8_t* DataPtr;

    // Regular expressions to extract pure resource name or qualifiers
    const QRegularExpression resourceNameWithQualifiersRegExp("(?:\\[(.*)\\])(.*)");

    // Find out what number of resources there is in the bundle
    const auto pGetResourcesCount = reinterpret_cast<GetPointerFunctionPtr>(loadSymbol("__get____CoreResourcesEmbeddedBundle__ResourcesCount"));
    if (pGetResourcesCount == nullptr)
        return false;
    const auto resourcesCount = *reinterpret_cast<const uint32_t*>(pGetResourcesCount());

    for (auto resourceIdx = 0u; resourceIdx < resourcesCount; resourceIdx++)
    {
        ResourceData resourceData;

        const auto pGetResourceName = reinterpret_cast<GetPointerFunctionPtr>(loadSymbol(
            QString(QLatin1String("__get____CoreResourcesEmbeddedBundle__ResourceName_%1")).arg(resourceIdx).toLatin1()));
        if (pGetResourceName == nullptr)
            return false;
        const auto resourceName = reinterpret_cast<const char*>(pGetResourceName());

        const auto pGetResourceSize = reinterpret_cast<GetPointerFunctionPtr>(loadSymbol(
            QString(QLatin1String("__get____CoreResourcesEmbeddedBundle__ResourceSize_%1")).arg(resourceIdx).toLatin1()));
        if (pGetResourceSize == nullptr)
            return false;
        resourceData.size = *reinterpret_cast<const size_t*>(pGetResourceSize());

        const auto pGetResourceData = reinterpret_cast<GetPointerFunctionPtr>(loadSymbol(
            QString(QLatin1String("__get____CoreResourcesEmbeddedBundle__ResourceData_%1")).arg(resourceIdx).toLatin1()));
        if (pGetResourceData == nullptr)
            return false;
        resourceData.data = reinterpret_cast<const uint8_t*>(pGetResourceData());

        // Process resource name
        QStringList qualifiers;
        QString pureResourceName;
        const auto resourceNameComponents = resourceNameWithQualifiersRegExp.match(QLatin1String(resourceName));
        if (resourceNameComponents.hasMatch())
        {
            qualifiers = resourceNameComponents.captured(1).split(QLatin1Char(';'), QString::SkipEmptyParts);
            pureResourceName = resourceNameComponents.captured(2);
        }
        else
        {
            pureResourceName = QLatin1String(resourceName);
        }

        // Get resource entry for this resource
        auto& resourceEntry = _resources[pureResourceName];
        if (qualifiers.isEmpty())
        {
            resourceEntry.defaultVariant = resourceData;
        }
        else
        {
            for (const auto& qualifier : constOf(qualifiers))
            {
                const auto qualifierComponents = qualifier.trimmed().split(QLatin1Char('='), QString::SkipEmptyParts);

                bool ok = false;
                if (qualifierComponents.size() == 2 && qualifierComponents.first() == QLatin1String("ddf"))
                {
                    const auto ddfValue = qualifierComponents.last().toFloat(&ok);
                    if (!ok)
                    {
                        LogPrintf(LogSeverityLevel::Warning,
                            "Unsupported value '%s' for DDF qualifier",
                            qPrintable(qualifierComponents.last()));
                    }
                    resourceEntry.variantsByDisplayDensityFactor.insert(ddfValue, resourceData);
                }
                else
                {
                    LogPrintf(LogSeverityLevel::Warning,
                        "Unsupported qualifier '%s'",
                        qPrintable(qualifier.trimmed()));
                }
            }
        }
    }

    return true;
}