[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-pim
Subject:    [Kde-pim] [patch] Akonadi directories based on XDG base directory
From:       Kevin Krammer <kevin.krammer () gmx ! at>
Date:       2007-08-20 21:26:34
Message-ID: 200708202326.48570.kevin.krammer () gmx ! at
[Download RAW message or body]

[Attachment #2 (multipart/signed)]

[Attachment #4 (multipart/mixed)]


Hi all,

as promised I create a patch set for looking up data and config directories 
based on the XDG base dir specification, i.e. environment variable 
XDG_CONFIG_HOME, XDG_DATA_HOME and their respective _DIRS variants.

Lookup is handled by a new class, XdgBaseDirs, see attachment.
There is one copy in server/src (using the server export macro) and one in 
libakonadi (using the lib export macro)

This class is a bit modelled after KStandardDirs, but at the moment is just 
handles "resource types" config and data.

For example, assuming all these XDG_ variables being unset, 
and .config/akonadi/akonadiserverrc does not exist yet, you can use a global 
example config /etc/xdg/akonadi/akonadiserverrc if you do not like the 
hardcoded defaults but want to delete the test directories every now and 
then.

The Unix socket will by default end up in the data dir, i.e. 
$HOME/.local/share/akonadi/
Configs, like profilesrc or akonadiconnectionrc will by default end up 
in .config/akonadi/

See http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html for the 
other variable defaults.

Cheers,
Kevin

-- 
Kevin Krammer, KDE developer, xdg-utils developer
KDE user support, developer mentoring

["server.diff" (text/x-diff)]

Index: server/control/agentmanager.h
===================================================================
--- server/control/agentmanager.h	(Revision 702576)
+++ server/control/agentmanager.h	(Arbeitskopie)
@@ -34,7 +34,7 @@
  * The agent manager has knowledge about all available agents (it scans
  * for .desktop files in the agent directory) and the available configured
  * instances.
- */ 
+ */
 class AgentManager : public QObject
 {
   Q_OBJECT
@@ -252,7 +252,7 @@
     /**
      * Returns the path of the config file.
      */
-    static QString configPath();
+    static QString configPath( bool writeable );
 
     /**
      * Loads the internal state from config file.
Index: server/control/profilemanager.h
===================================================================
--- server/control/profilemanager.h	(Revision 702576)
+++ server/control/profilemanager.h	(Arbeitskopie)
@@ -128,7 +128,7 @@
     void profileAgentRemoved( const QString &profileIdentifier, const QString \
&agentIdentifier );  
   private:
-    QString profilePath() const;
+    QString profilePath( bool writeable ) const;
 
     QMap<QString, QStringList> mProfiles;
     org::kde::Akonadi::Tracer *mTracer;
Index: server/control/agentmanager.cpp
===================================================================
--- server/control/agentmanager.cpp	(Revision 702576)
+++ server/control/agentmanager.cpp	(Arbeitskopie)
@@ -29,6 +29,7 @@
 #include "agentmanager.h"
 #include "agentmanageradaptor.h"
 #include "processcontrol.h"
+#include "xdgbasedirs.h"
 
 AgentManager::AgentManager( QObject *parent )
   : QObject( parent )
@@ -376,24 +377,26 @@
   return QString( "%1/share/apps/akonadi/agents" ).arg( AKONADIDIR );
 }
 
-QString AgentManager::configPath()
+QString AgentManager::configPath( bool writeable )
 {
-  const QString homePath = QDir::homePath();
-  const QString akonadiHomeDir = QString( "%1/%2" ).arg( homePath, ".akonadi" );
+  Akonadi::XdgBaseDirs baseDirs;
 
-  if ( !QDir( akonadiHomeDir ).exists() ) {
-    QDir dir;
-    dir.mkdir( akonadiHomeDir );
-  }
+  const QString configFile =
+    baseDirs.findResourceFile( "config", QLatin1String( "akonadi/agentsrc" ) );
 
-  return akonadiHomeDir + "/agentsrc";
+  if ( !writeable && !configFile.isEmpty() )
+    return configFile;
+
+  const QString configDir = baseDirs.saveDir( "config", "akonadi" );
+
+  return configDir + QLatin1String( "/agentsrc" );
 }
 
 void AgentManager::load()
 {
   mInstanceInfos.clear();
 
-  QSettings file( configPath(), QSettings::IniFormat );
+  QSettings file( configPath( false ), QSettings::IniFormat );
   file.beginGroup( "InstanceCounters" );
 
   QStringList entries = file.childGroups();
@@ -468,7 +471,7 @@
 
 void AgentManager::save()
 {
-  QSettings file( configPath(), QSettings::IniFormat );
+  QSettings file( configPath( true ), QSettings::IniFormat );
 
   file.clear();
   file.beginGroup( "InstanceCounters" );
Index: server/control/profilemanager.cpp
===================================================================
--- server/control/profilemanager.cpp	(Revision 702576)
+++ server/control/profilemanager.cpp	(Arbeitskopie)
@@ -24,6 +24,7 @@
 
 #include "profilemanager.h"
 #include "profilemanageradaptor.h"
+#include "xdgbasedirs.h"
 
 ProfileManager::ProfileManager( QObject *parent )
   : QObject( parent )
@@ -43,7 +44,7 @@
 
 void ProfileManager::load()
 {
-  QSettings settings( profilePath(), QSettings::IniFormat );
+  QSettings settings( profilePath( false ), QSettings::IniFormat );
 
   const QStringList profiles = settings.childGroups();
   for ( int i = 0; i < profiles.count(); ++i ) {
@@ -58,7 +59,7 @@
 
 void ProfileManager::save()
 {
-  QSettings settings( profilePath(), QSettings::IniFormat );
+  QSettings settings( profilePath( true ), QSettings::IniFormat );
   settings.clear();
 
   QMapIterator<QString, QStringList> it( mProfiles );
@@ -162,17 +163,19 @@
   return mProfiles[ identifier ];
 }
 
-QString ProfileManager::profilePath() const
+QString ProfileManager::profilePath( bool writeable ) const
 {
-  const QString homePath = QDir::homePath();
-  const QString akonadiHomeDir = QString( "%1/%2" ).arg( homePath, ".akonadi" );
+  Akonadi::XdgBaseDirs baseDirs;
 
-  if ( !QDir( akonadiHomeDir ).exists() ) {
-    QDir dir;
-    dir.mkdir( akonadiHomeDir );
-  }
+  const QString configFile =
+    baseDirs.findResourceFile( "config", QLatin1String( "akonadi/profilesrc" ) );
 
-  return akonadiHomeDir + "/profilesrc";
+  if ( !writeable && !configFile.isEmpty() )
+    return configFile;
+
+  const QString configDir = baseDirs.saveDir( "config", "akonadi" );
+
+  return configDir + QLatin1String( "/profilesrc" );
 }
 
 #include "profilemanager.moc"
Index: server/control/CMakeLists.txt
===================================================================
--- server/control/CMakeLists.txt	(Revision 702576)
+++ server/control/CMakeLists.txt	(Arbeitskopie)
@@ -14,6 +14,7 @@
   processcontrol.cpp
   profilemanager.cpp
   searchprovidermanager.cpp
+  ../src/xdgbasedirs.cpp
 )
 
 qt4_generate_dbus_interface( ../../libakonadi/resource.h \
                org.kde.Akonadi.Resource.xml )
Index: server/src/storage/datastore.cpp
===================================================================
--- server/src/storage/datastore.cpp	(Revision 702576)
+++ server/src/storage/datastore.cpp	(Arbeitskopie)
@@ -27,6 +27,7 @@
 #include "selectquerybuilder.h"
 #include "handlerhelper.h"
 #include "countquerybuilder.h"
+#include "xdgbasedirs.h"
 
 #include <QtCore/QCoreApplication>
 #include <QtCore/QDir>
@@ -68,7 +69,14 @@
 {
   // load database settings if needed
   if ( mDbDriverName.isEmpty() ) {
-    QSettings settings( QDir::homePath() + \
QLatin1String("/.akonadi/akonadiserverrc"), QSettings::IniFormat ); +    XdgBaseDirs \
baseDirs; +
+    QString serverConfigFile = baseDirs.findResourceFile( "config", QLatin1String( \
"akonadi/akonadiserverrc" ) ); +    if ( serverConfigFile.isEmpty() ) {
+      serverConfigFile = baseDirs.saveDir( "config", QLatin1String( "akonadi" )) + \
QLatin1String( "/akonadiserverrc" ); +    }
+
+    QSettings settings( serverConfigFile, QSettings::IniFormat );
     QString defaultDriver = QLatin1String("QMYSQL");
 
     mDbDriverName = settings.value( QLatin1String("General/Driver"), defaultDriver \
).toString(); @@ -85,8 +93,8 @@
       defaultOptions = QString::fromLatin1( "SERVER_DATADIR=%1" ).arg( storagePath() \
);  } else if ( mDbDriverName == QLatin1String( "QMYSQL" ) ) {
       defaultDbName = QLatin1String( "akonadi" );
-      defaultOptions = QString::fromLatin1( "UNIX_SOCKET=%1/db_misc/mysql.socket" )
-                                     .arg( QDir::homePath() + QLatin1String( \
"/.akonadi/"  ) ); +      QString miscDir = baseDirs.saveDir( "data", QLatin1String( \
"akonadi/db_misc" ) ); +      defaultOptions = QString::fromLatin1( \
"UNIX_SOCKET=%1/mysql.socket" ).arg( miscDir );  } else if ( mDbDriverName == \
QLatin1String( "QSQLITE" ) ) {  defaultDbName = storagePath();
     }
@@ -188,16 +196,18 @@
 {
   /**
    * We need the following path for the database directory:
-   *   $HOME/.akonadi/db/akonadi/
+   *   $XDG_DATA_HOME/akonadi/db/akonadi/
    */
-  const QString akonadiHomeDir = QDir::homePath() + QDir::separator() + \
                QLatin1String(".akonadi") + QDir::separator();
-  if ( !QDir( akonadiHomeDir ).exists() ) {
-    QDir dir;
-    if ( !dir.mkdir( akonadiHomeDir ) )
-      Tracer::self()->error( "DataStore::storagePath",
-                             QString::fromLatin1( "Unable to create directory '%1'" \
).arg( akonadiHomeDir ) ); +  XdgBaseDirs baseDirs;
+
+  QString akonadiHomeDir = baseDirs.saveDir( "data", QLatin1String( "akonadi" ) );
+  if ( akonadiHomeDir.isEmpty() ) {
+    Tracer::self()->error( "DataStore::storagePath",
+                           QString::fromLatin1( "Unable to create directory \
'%1/akonadi'" ).arg( baseDirs.homePath( "data" ) ) );  }
 
+  akonadiHomeDir += QLatin1Char( '/' );
+
   if ( driverName() == QLatin1String( "QSQLITE" ) ) {
     const QString akonadiPath = akonadiHomeDir + QLatin1String("akonadi.db");
     if ( !QFile::exists( akonadiPath ) ) {
Index: server/src/akonadi.cpp
===================================================================
--- server/src/akonadi.cpp	(Revision 702576)
+++ server/src/akonadi.cpp	(Arbeitskopie)
@@ -27,6 +27,7 @@
 #include "notificationmanager.h"
 #include "resourcemanager.h"
 #include "tracer.h"
+#include "xdgbasedirs.h"
 #include "xesammanager.h"
 
 #include <QtCore/QCoreApplication>
@@ -50,20 +51,24 @@
 #endif
     , mDatabaseProcess( 0 )
 {
-    // create the akonadi directory
-    QDir homeDir = QDir::home();
-    if ( !homeDir.exists( QLatin1String( ".akonadi/" ) ) )
-      homeDir.mkdir( QLatin1String( ".akonadi/" ) );
+    XdgBaseDirs baseDirs;
 
-    QSettings settings( QDir::homePath() + \
QLatin1String("/.akonadi/akonadiserverrc"), QSettings::IniFormat ); +    QString \
serverConfigFile = baseDirs.findResourceFile( "config", QLatin1String( \
"akonadi/akonadiserverrc" ) ); +    if ( serverConfigFile.isEmpty() ) {
+      serverConfigFile = baseDirs.saveDir( "config", QLatin1String( "akonadi" )) + \
QLatin1String( "/akonadiserverrc" ); +    }
+
+    QSettings settings( serverConfigFile, QSettings::IniFormat );
     if ( settings.value( QLatin1String("General/Driver"), QLatin1String( "QMYSQL" ) \
                ).toString() == QLatin1String( "QMYSQL" )
          && settings.value( QLatin1String( "QMYSQL/StartServer" ), true ).toBool() )
       startDatabaseProcess();
 
     s_instance = this;
 
-    QSettings connectionSettings( QDir::homePath() + \
QLatin1String("/.akonadi/akonadiconnectionrc"), QSettings::IniFormat ); +    QString \
connectionSettingsFile = baseDirs.saveDir( "config", QLatin1String( "akonadi" ) ) + \
QLatin1String( "/akonadiconnectionrc" );  
+    QSettings connectionSettings( connectionSettingsFile, QSettings::IniFormat );
+
 #ifdef Q_OS_WIN
     int port = settings.value( QLatin1String( "Connection/Port" ), 4444 ).toInt();
     if ( !listen( QHostAddress::LocalHost, port ) )
@@ -73,10 +78,11 @@
     connectionSettings.setValue( QLatin1String( "Data/Address" ), \
                serverAddress().toString() );
     connectionSettings.setValue( QLatin1String( "Data/Port" ), serverPort() );
 #else
-    QString socketDir = settings.value( QLatin1String( "Connection/SocketDirectory" \
), QLatin1String( ".akonadi" ) ).toString(); +    QString defaultSocketDir = \
baseDirs.saveDir( "data", QLatin1String( "akonadi" ) ); +    QString socketDir = \
settings.value( QLatin1String( "Connection/SocketDirectory" ), defaultSocketDir \
).toString();  if ( socketDir[0] != QLatin1Char( '/' ) )
     {
-      homeDir.mkdir( socketDir );
+      QDir::home().mkdir( socketDir );
       socketDir = QDir::homePath() + QLatin1Char( '/' ) + socketDir;
     }
 
@@ -133,16 +139,29 @@
       }
     }
 
-    QSettings settings( QDir::homePath() + \
QLatin1String("/.akonadi/akonadiserverrc"), QSettings::IniFormat ); +    XdgBaseDirs \
baseDirs; +
+    QString serverConfigFile = baseDirs.findResourceFile( "config", QLatin1String( \
"akonadi/akonadiserverrc" ) ); +    if ( serverConfigFile.isEmpty() ) {
+      serverConfigFile = baseDirs.saveDir( "config", QLatin1String( "akonadi" )) + \
QLatin1String( "/akonadiserverrc" ); +    }
+
+    QSettings settings( serverConfigFile, QSettings::IniFormat );
     if ( settings.value( QLatin1String("General/Driver") ).toString() == \
                QLatin1String( "QMYSQL" )
          && settings.value( QLatin1String( "QMYSQL/StartServer" ), true ).toBool() )
       stopDatabaseProcess();
 
+    QString connectionSettingsFile = baseDirs.saveDir( "config", QLatin1String( \
"akonadi" ) ) + QLatin1String( "/akonadiconnectionrc" ); +
 #ifndef Q_OS_WIN
-    if ( !QDir::home().remove( QLatin1String( ".akonadi/akonadiserver.socket" ) ) )
+    QSettings connectionSettings( connectionSettingsFile, QSettings::IniFormat );
+    QString defaultSocketDir = baseDirs.saveDir( "data", QLatin1String( "akonadi" ) \
); +    QString socketDir = settings.value( QLatin1String( \
"Connection/SocketDirectory" ), defaultSocketDir ).toString(); +
+    if ( !QDir::home().remove( socketDir + QLatin1String( "/akonadiserver.socket" ) \
) )  qWarning("Failed to remove Unix socket");
 #endif
-    if ( !QDir::home().remove( QLatin1String( ".akonadi/akonadiconnectionrc" ) ) )
+    if ( !QDir::home().remove( connectionSettingsFile ) )
         qWarning("Failed to remove runtime connection config file");
 
     QTimer::singleShot( 0, this, SLOT( doQuit() ) );
@@ -172,24 +191,28 @@
 void AkonadiServer::startDatabaseProcess()
 {
   // create the database directories if they don't exists
-  QDir akonadiDirectory( QDir::home().path() + QLatin1String( "/.akonadi/" ) );
+  XdgBaseDirs baseDirs;
 
-  if ( !akonadiDirectory.exists( QLatin1String( "db_data/" ) ) )
-    akonadiDirectory.mkdir( QLatin1String( "db_data/" ) );
+  QString dataDir = baseDirs.saveDir( "data", QLatin1String( "akonadi/db_data" ) );
+  QString logDir  = baseDirs.saveDir( "data", QLatin1String( "akonadi/db_log" ) );
+  QString miscDir = baseDirs.saveDir( "data", QLatin1String( "akonadi/db_misc" ) );
 
-  if ( !akonadiDirectory.exists( QLatin1String( "db_log/" ) ) )
-    akonadiDirectory.mkdir( QLatin1String( "db_log/" ) );
+  if ( dataDir.isEmpty() )
+    qFatal("Akonadi server was not able not create database data directory");
 
-  if ( !akonadiDirectory.exists( QLatin1String( "db_misc/" ) ) )
-    akonadiDirectory.mkdir( QLatin1String( "db_misc/" ) );
+  if ( logDir.isEmpty() )
+    qFatal("Akonadi server was not able not create database log directory");
 
+  if ( miscDir.isEmpty() )
+    qFatal("Akonadi server was not able not create database misc directory");
+
   // synthesize the mysqld command
   QStringList arguments;
-  arguments << QString::fromLatin1( "--datadir=%1/db_data/" ).arg( \
                akonadiDirectory.path() );
-  arguments << QString::fromLatin1( "--log-bin=%1/db_log/" ).arg( \
                akonadiDirectory.path() );
-  arguments << QString::fromLatin1( "--log-bin-index=%1/db_log/" ).arg( \
                akonadiDirectory.path() );
-  arguments << QString::fromLatin1( "--socket=%1/db_misc/mysql.socket" ).arg( \
                akonadiDirectory.path() );
-  arguments << QString::fromLatin1( "--pid-file=%1/db_misc/mysql.pid" ).arg( \
akonadiDirectory.path() ); +  arguments << QString::fromLatin1( "--datadir=%1/" \
).arg( dataDir ); +  arguments << QString::fromLatin1( "--log-bin=%1/" ).arg( logDir \
); +  arguments << QString::fromLatin1( "--log-bin-index=%1/" ).arg( logDir );
+  arguments << QString::fromLatin1( "--socket=%1/mysql.socket" ).arg( miscDir );
+  arguments << QString::fromLatin1( "--pid-file=%1/mysql.pid" ).arg( miscDir );
   arguments << QString::fromLatin1( "--skip-grant-table" );
   arguments << QString::fromLatin1( "--skip-networking" );
 
@@ -198,7 +221,7 @@
   mDatabaseProcess->waitForStarted();
 
   QSqlDatabase db = QSqlDatabase::addDatabase( QLatin1String( "QMYSQL" ), \
                QLatin1String( "initConnection" ) );
-  db.setConnectOptions( QString::fromLatin1( "UNIX_SOCKET=%1/db_misc/mysql.socket" \
).arg( akonadiDirectory.path() ) ); +  db.setConnectOptions( QString::fromLatin1( \
"UNIX_SOCKET=%1/mysql.socket" ).arg( miscDir ) );  
   bool opened = false;
   for ( int i = 0; i < 10; ++i ) {
Index: server/CMakeLists.txt
===================================================================
--- server/CMakeLists.txt	(Revision 702576)
+++ server/CMakeLists.txt	(Arbeitskopie)
@@ -83,6 +83,7 @@
   src/cachepolicymanager.cpp
   src/cachecleaner.cpp
   src/xesammanager.cpp
+  src/xdgbasedirs.cpp
 )
 
 qt4_generate_dbus_interface(../server/src/cachepolicymanager.h \
org.kde.Akonadi.CachePolicyManager.xml)


["libakonadi.diff" (text/x-diff)]

Index: libakonadi/session.cpp
===================================================================
--- libakonadi/session.cpp	(Revision 702576)
+++ libakonadi/session.cpp	(Arbeitskopie)
@@ -23,6 +23,7 @@
 #include "imapparser.h"
 #include "job.h"
 #include "job_p.h"
+#include "xdgbasedirs.h"
 
 #include <kdebug.h>
 
@@ -60,7 +61,9 @@
 #else
   if ( socket->state() != QAbstractSocket::ConnectedState &&
        socket->state() != QAbstractSocket::ConnectingState ) {
-    QString path = mConnectionSettings->value( QLatin1String( "Data/UnixPath" ), \
QDir::homePath() + QLatin1String( "/.akonadi/akonadiserver.socket" ) ).toString(); +  \
XdgBaseDirs baseDirs; +    QString defaultSocketDir = baseDirs.saveDir( "data", \
QLatin1String( "akonadi" ) ); +    QString path = mConnectionSettings->value( \
QLatin1String( "Data/UnixPath" ), defaultSocketDir + QLatin1String( \
"/akonadiserver.socket" ) ).toString();  socket->connectToPath( path );
   }
 #endif
@@ -141,8 +144,20 @@
   d->currentJob = 0;
   d->jobRunning = false;
 
-  d->mConnectionSettings = new QSettings( QDir::homePath() + \
QLatin1String("/.akonadi/akonadiconnectionrc"), QSettings::IniFormat ); +  \
XdgBaseDirs baseDirs;  
+  QString connectionConfigFile = baseDirs.findResourceFile( "config", QLatin1String( \
"akonadi/akonadiconnectionrc" ) ); +  if ( connectionConfigFile.isEmpty() ) {
+    qWarning() << "Akonadi Client Session: connection config file '"
+               << "akonadi/akonadiconnectionrc can not be found in '"
+               << baseDirs.homePath( "config" ) << "' nor in any of "
+               << baseDirs.systemPathList( "config" );
+
+    connectionConfigFile = baseDirs.saveDir( "config", QLatin1String( "akonadi" )) + \
QLatin1String( "/akonadiconnectionrc" ); +  }
+
+  d->mConnectionSettings = new QSettings( connectionConfigFile, QSettings::IniFormat \
); +
   // should check connection method
 #ifdef Q_OS_WIN
   d->socket = new QTcpSocket( this );
Index: libakonadi/agentbase.cpp
===================================================================
--- libakonadi/agentbase.cpp	(Revision 702576)
+++ libakonadi/agentbase.cpp	(Arbeitskopie)
@@ -27,6 +27,7 @@
 #include "agentadaptor.h"
 #include "monitor_p.h"
 #include "tracerinterface.h"
+#include "xdgbasedirs.h"
 
 #include <libakonadi/session.h>
 #include <libakonadi/monitor.h>
@@ -148,8 +149,10 @@
 
   d->mId = id;
 
-  d->mSettings = new QSettings( QString::fromLatin1( "%1/.akonadi/agent_config_%2" \
).arg( QDir::homePath(), id ), QSettings::IniFormat ); +  XdgBaseDirs baseDirs;
 
+  d->mSettings = new QSettings( QString::fromLatin1( "%1/agent_config_%2" ).arg( \
baseDirs.saveDir( "config", QLatin1String( "akonadi" ) ), id ), QSettings::IniFormat \
); +
   const QString name = d->mSettings->value( QLatin1String( "Agent/Name" ) \
).toString();  if ( !name.isEmpty() )
     d->mName = name;
Index: libakonadi/CMakeLists.txt
===================================================================
--- libakonadi/CMakeLists.txt	(Revision 702576)
+++ libakonadi/CMakeLists.txt	(Arbeitskopie)
@@ -72,6 +72,7 @@
 	searchcreatejob.cpp
 	session.cpp
 	transactionjobs.cpp
+	xdgbasedirs.cpp
 )
 
 qt4_generate_dbus_interface(resource.h org.kde.Akonadi.Resource.xml)
Index: libakonadi/resourcebase.cpp
===================================================================
--- libakonadi/resourcebase.cpp	(Revision 702576)
+++ libakonadi/resourcebase.cpp	(Arbeitskopie)
@@ -28,6 +28,7 @@
 #include "monitor_p.h"
 #include "resourcescheduler.h"
 #include "tracerinterface.h"
+#include "xdgbasedirs.h"
 
 #include <libakonadi/collectionlistjob.h>
 #include <libakonadi/itemfetchjob.h>
@@ -245,8 +246,10 @@
 
   d->mId = id;
 
-  d->mSettings = new QSettings( QString::fromLatin1( \
"%1/.akonadi/resource_config_%2" ).arg( QDir::homePath(), id ), QSettings::IniFormat \
); +  XdgBaseDirs baseDirs;
 
+  d->mSettings = new QSettings( QString::fromLatin1( "%1/resource_config_%2" ).arg( \
baseDirs.saveDir( "config", QLatin1String( "akonadi" ) ), id ), QSettings::IniFormat \
); +
   const QString name = d->mSettings->value( QLatin1String( "Resource/Name" ) \
).toString();  if ( !name.isEmpty() )
     d->mName = name;


["xdgbasedirs.h" (text/x-c++hdr)]

/***************************************************************************
 *   Copyright (C) 2007 by Kevin Krammer <kevin.krammer@gmx.at>            *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
 ***************************************************************************/

#ifndef XDGBASEDIRS_H
#define XDGBASEDIRS_H

#include "akonadi_export.h"

// forward declarations
class QString;
class QStringList;

namespace Akonadi {

class XdgBaseDirsPrivate;

class AKONADI_SERVER_EXPORT XdgBaseDirs
{
  public:
    XdgBaseDirs();

    ~XdgBaseDirs();

    QString homePath( const char *resource ) const;

    QStringList systemPathList( const char *resource ) const;

    QString findResourceFile( const char *resource, const QString &relPath ) const;

    QString findResourceDir( const char *resource, const QString &relPath ) const;

    QString saveDir( const char *resource, const QString &relPath ) const;

  private:
    XdgBaseDirsPrivate* const d;

  private:
    XdgBaseDirs( const XdgBaseDirs &);
    XdgBaseDirs &operator=( const XdgBaseDirs &);
};

};

#endif

["xdgbasedirs.cpp" (text/x-c++src)]

/***************************************************************************
 *   Copyright (C) 2007 by Kevin Krammer <kevin.krammer@gmx.at>            *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
 ***************************************************************************/

#include "xdgbasedirs.h"

#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>

#include <cstdlib>

namespace Akonadi {

class XdgBaseDirsPrivate
{
  public:
    XdgBaseDirsPrivate() {}

    ~XdgBaseDirsPrivate() {}

    QString homePath( const char *variable, const char *defaultSubDir );

    QStringList systemPathList( const char *variable, const char *defaultDirList );

  public:
    QString mConfigHome;
    QString mDataHome;

    QStringList mConfigDirs;
    QStringList mDataDirs;
};

};

using namespace Akonadi;

XdgBaseDirs::XdgBaseDirs() : d( new XdgBaseDirsPrivate() )
{
}

XdgBaseDirs::~XdgBaseDirs()
{
  delete d;
}

QString XdgBaseDirs::homePath( const char *resource ) const
{
  if ( qstrncmp( "data", resource, 4 ) == 0 ) {
    if ( d->mDataHome.isEmpty() ) {
      d->mDataHome = d->homePath( "XDG_DATA_HOME", ".local/share" );
    }
    return d->mDataHome;
  } else if ( qstrncmp( "config", resource, 6 ) == 0) {
    if ( d->mConfigHome.isEmpty() ) {
      d->mConfigHome = d->homePath( "XDG_CONFIG_HOME", ".config" );
    }
    return d->mConfigHome;
  }

  return QString();
}

QStringList XdgBaseDirs::systemPathList( const char *resource ) const
{
  if ( qstrncmp( "data", resource, 4 ) == 0 ) {
    if ( d->mDataDirs.isEmpty() ) {
      d->mDataDirs = d->systemPathList( "XDG_DATA_DIRS", "/usr/local/share:/usr/share" );
    }
    return d->mDataDirs;
  } else if ( qstrncmp( "config", resource, 6 ) == 0) {
    if ( d->mConfigDirs.isEmpty() ) {
      d->mConfigDirs = d->systemPathList( "XDG_CONFIG_DIRS", "/etc/xdg" );
    }
    return d->mConfigDirs;
  }

  return QStringList();
}

QString XdgBaseDirs::findResourceFile( const char *resource, const QString &relPath ) const
{
  QString fullPath = homePath( resource ) + QLatin1Char('/' ) + relPath;

  QFileInfo fileInfo( fullPath );
  if ( fileInfo.exists() && fileInfo.isFile() && fileInfo.isReadable() ) {
    return fullPath;
  }

  QStringList pathList = systemPathList( resource );

  QStringList::const_iterator it    = pathList.begin();
  QStringList::const_iterator endIt = pathList.end();
  for ( ; it != endIt; ++it ) {
    fileInfo = QFileInfo( *it + QLatin1Char('/' ) + relPath );
    if ( fileInfo.exists() && fileInfo.isFile() && fileInfo.isReadable() ) {
      return fileInfo.absoluteFilePath();
    }
  }

  return QString();
}

QString XdgBaseDirs::findResourceDir( const char *resource, const QString &relPath ) const
{
  QString fullPath = homePath( resource ) + QLatin1Char('/' ) + relPath;

  QFileInfo fileInfo( fullPath );
  if ( fileInfo.exists() && fileInfo.isDir() && fileInfo.isReadable() ) {
    return fullPath;
  }

  QStringList pathList = systemPathList( resource );

  QStringList::const_iterator it    = pathList.begin();
  QStringList::const_iterator endIt = pathList.end();
  for ( ; it != endIt; ++it ) {
    fileInfo = QFileInfo( *it + QLatin1Char('/' ) + relPath );
    if ( fileInfo.exists() && fileInfo.isDir() && fileInfo.isReadable() ) {
      return fileInfo.absoluteFilePath();
    }
  }

  return QString();
}

QString XdgBaseDirs::saveDir( const char *resource, const QString &relPath ) const
{
  QString fullPath = homePath( resource ) + QLatin1Char('/' ) + relPath;

  QFileInfo fileInfo( fullPath );
  if ( fileInfo.exists() ) {
    if ( fileInfo.isDir() ) {
      return fullPath;
    } else {
      qWarning() << "XdgBaseDirs::saveDir: '" << fileInfo.absoluteFilePath()
                 << "' exists but is not a directory";
    }
  } else {
    if ( !QDir::home().mkpath( fileInfo.absoluteFilePath() ) ) {
      qWarning() << "XdgBaseDirs::saveDir: failed to create directory '"
                 << fileInfo.absoluteFilePath() << "'";
    } else {
      return fullPath;
    }
  }

  return QString();
}

QString XdgBaseDirsPrivate::homePath( const char *variable, const char *defaultSubDir )
{
  char *env = std::getenv( variable );

  QString xdgPath;
  if ( env == 0 || *env == '\0' ) {
    xdgPath = QDir::homePath() + QLatin1Char( '/' ) + QLatin1String( defaultSubDir );
  } else if ( *env == '/' ) {
    xdgPath = QString::fromLocal8Bit( env );
  } else {
    xdgPath = QDir::homePath() + QLatin1Char( '/' ) + QString::fromLocal8Bit( env );
  }

  return xdgPath;
}

QStringList XdgBaseDirsPrivate::systemPathList( const char *variable, const char *defaultDirList )
{
  char *env = std::getenv( variable );

  QString xdgDirList;
  if ( env == 0 || *env == '\0' ) {
    xdgDirList = QLatin1String( defaultDirList );
  } else {
    xdgDirList = QString::fromLocal8Bit( env );
  }

  return xdgDirList.split( QLatin1Char( ':' ) );
}


["signature.asc" (application/pgp-signature)]

_______________________________________________
KDE PIM mailing list kde-pim@kde.org
https://mail.kde.org/mailman/listinfo/kde-pim
KDE PIM home page at http://pim.kde.org/

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic