PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Qsettings::registerFormat und namespace ?



undefined
17-07-2008, 18:11
Schreibe gerade an einer Qt Bibliothek und versuche hierbei innerhalb eines Namespace eine eigene Konfigurations Klasse zu schreiben in der ich mit Qsettings::registerFormat das Datenkonstrukt neu erstelle. Das funktioniert auch alles so weit nur kann ich nicht meine Funktionen die von QSettings als typedef Definiert sind in meine Klassen aufnehmen. Sobald ich das mache gibt es ein undefined Symbols.
Header:


#ifndef QTIDY_H
#define QTIDY_H

#include "tidy.h"

#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QVariant>
#include <QtCore/QSettings>

namespace QTidy
{
class Config : private QSettings
{
Q_OBJECT

public:
explicit Config ( const QString &configFile = 0 );
void setValue ( const QString &param, const QVariant &value );
QVariant value ( const QString &param, const QVariant &dValue = QVariant() );
~Config();

private:
bool ConfigStatus;
QSettings *m_QSettings;
QString cfgFile;
bool ParseConfigFile ( const QString &file, QSettings::Scope scope = QSettings::UserScope );

}; /* eof QTidy::Config */

} /* eof namespace QTidy */

#endif

CPP File:


#include "QTidy.h"

/* QtCore */
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QSettings>
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
#include <QtCore/QByteArray>
#include <QtCore/QMap>
#include <QtCore/QDebug>

namespace QTidy
{
bool readTidyrc ( QIODevice &device, QSettings::SettingsMap &map )
{
if ( device.isOpen () )
{
if ( ! map.empty() )
map.clear();

while ( ! device.atEnd() )
{
QByteArray line = device.readLine().trimmed();
if ( ! line.startsWith ( "#" ) && line.contains ( ":" ) )
{
QStringList tmp = QString ( line ).split ( ":" );
const QString key ( tmp.at ( 0 ).trimmed() );
const QString val ( tmp.at ( 1 ).trimmed() );
if ( ! key.isEmpty() && ! val.isEmpty() )
{
if ( val.contains ( QRegExp ( "^(yes|no)$" ) ) )
map.insert ( key, QVariant ( val.contains ( "yes" ) ) );
else if ( val.contains ( QRegExp ( "^[0-9]+$" ) ) )
map.insert ( key, QVariant ( val ).toInt() );
else
map.insert ( key, QVariant ( val ) );
}
tmp.clear();
}
}
return true;
}
return false;
}

bool writeTidyrc ( QIODevice &device, const QSettings::SettingsMap &map )
{
if ( device.isOpen () && ! map.empty() )
{
QMap<QString,QVariant>::const_iterator it;
for ( it = map.begin(); it != map.end(); ++it )
{
QString buffer;
QString val = it.value().toString();
if ( val == "true" )
buffer = QString ( "%1: yes\n" ).arg ( it.key() );
else if ( val == "false" )
buffer = QString ( "%1: no\n" ).arg ( it.key() );
else
buffer = QString ( "%1: %2\n" ).arg ( it.key(), val );

if ( ! buffer.isEmpty() )
device.write ( buffer.toAscii() );

buffer.clear();
}
return true;
}
return false;
}

/* Configuration */
Config::Config ( const QString &configFile )
{
ConfigStatus = false;
QStringList files;
if ( ! configFile.isEmpty() )
files << configFile;

/* @see TIDY_USER_CONFIG_FILE:$(tidy_source)/include/platform.h */
files << "~/.tidyrc";
foreach ( QString f, files )
{
if ( ParseConfigFile ( f, QSettings::UserScope ) )
{
ConfigStatus = true;
break;
}
}

/* @see TIDY_CONFIG_FILE:$(tidy_source)/include/platform.h */
if ( ! ConfigStatus )
{
files.clear();
files << "/etc/tidy.conf" << "/etc/tidyrc" << "/etc/tidy_config.txt";
foreach ( QString f, files )
{
if ( ParseConfigFile ( f, QSettings::SystemScope ) )
{
ConfigStatus = true;
break;
}
}
}
}

bool Config::ParseConfigFile ( const QString &file, QSettings::Scope scope )
{
QFileInfo cfg;
if ( scope == QSettings::UserScope )
cfg.setFile ( QDir::home(), QFileInfo ( file ).fileName() );
else
cfg.setFile ( file );

if ( cfg.exists() )
{
if ( ! cfg.isWritable() )
{
qCritical ( "Permission Denied for '%s'!", qPrintable ( file ) );
return false;
}

const QSettings::Format format = QSettings::registerFormat ( "",
QTidy::readTidyrc, QTidy::writeTidyrc );

m_QSettings = new QSettings ( cfg.absoluteFilePath(), format );
if ( m_QSettings->status() == QSettings::NoError )
{
ConfigStatus = true;
cfgFile = cfg.absoluteFilePath();
return true;
}
}
return false;
}

void Config::setValue ( const QString &param, const QVariant &value )
{
if ( ConfigStatus )
m_QSettings->setValue ( param, value );
}

QVariant Config::value ( const QString &param, const QVariant &dValue )
{
if ( ConfigStatus )
return m_QSettings->value ( param, dValue );
else
return QVariant();
}

Config::~Config()
{}

} /* namespace QTidy */

In der Docu von QT steht das diese Funktion Threadsave ist, und ein Pointer auf den Funktionen liegt, kann es sein das es daran liegt oder wo habe ich hier den Fehler?
In den Quellen von qt unter src/corelib/io/qsettings.h wird’s wie folgt definiert.


typedef QMap<QString, QVariant> SettingsMap;
typedef bool (*ReadFunc)(QIODevice &device, SettingsMap &map);
typedef bool (*WriteFunc)(QIODevice &device, const SettingsMap &map);

static Format registerFormat(const QString &extension, ReadFunc readFunc, WriteFunc writeFunc,
Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive);

anda_skoa
17-07-2008, 22:13
Vielleicht kannst du auch noch den Fehler posten, damit man einen Anhaltspunkt hat, was dem Linker fehlen könnte.

Außerdem bin ich mir nicht sicher, ob du jedesmal das Format registrieren solltest.

Ciao,
_

undefined
18-07-2008, 07:01
Danke genau das war es, ich habe die Funktionen als static deklariert und jetzt stimmt es.


namespace QTidy
{
class Config : private QSettings
{
Q_OBJECT

public:
explicit Config ( const QString &configFile = 0 );
void setValue ( const QString &param, const QVariant &value );
QVariant value ( const QString &param, const QVariant &dValue = QVariant() );
~Config();

private:
bool ConfigStatus;
QSettings *m_QSettings;
QString cfgFile;
static bool readTidyrc ( QIODevice &device, QSettings::SettingsMap &map );
static bool writeTidyrc ( QIODevice &device, const QSettings::SettingsMap &map );
bool ParseConfigFile ( const QString &file, QSettings::Scope scope = QSettings::UserScope );

}; /* eof QTidy::Config */

} /* eof namespace QTidy */



const QSettings::Format format = QSettings::registerFormat ( "",
QTidy::Config::readTidyrc,
QTidy::Config::writeTidyrc );


Die alte Fehlermeldung war:


QTidyConfig.cpp:132: Fehler: keine passende Funktion für Aufruf von
QTidy::Config::registerFormat( const char [1],
<unresolved overloaded function type>,
<unresolved overloaded function type>)

/usr/include/QtCore/qsettings.h:191: Anmerkung: Kandidaten sind: static QSettings::Format QSettings::registerFormat(
const QString&,
bool (*)(QIODevice&,QMap<QString, QVariant>&),
bool (*)(QIODevice&, const QMap<QString, QVariant>&),
Qt::CaseSensitivity)

PS: registerFormat wird nur einmal aufgerufen und zwar dann wenn die erste beschreibare config gefunden wurde.