rewrite to use submodules

This commit is contained in:
arcan1s 2014-08-26 16:06:13 +04:00
parent eb3753ab25
commit 5ed704e676
15 changed files with 20 additions and 732 deletions

12
.gitmodules vendored Normal file
View File

@ -0,0 +1,12 @@
[submodule "sources/3rdparty/task"]
path = sources/3rdparty/task
url = git@github.com:arcan1s/qtadds-taskadds-qprocess.git
[submodule "sources/3rdparty/tasks"]
path = sources/3rdparty/tasks
url = https://github.com/mhogomchungu/tasks.git
[submodule "sources/3rdparty/language"]
path = sources/3rdparty/language
url = git@github.com:arcan1s/qtadds-language.git
[submodule "sources/3rdparty/pdebug"]
path = sources/3rdparty/pdebug
url = git@github.com:arcan1s/qtadds-pdebug.git

View File

@ -12,7 +12,7 @@ url="http://arcanis.name/projects/netctl-gui"
license=('GPL3') license=('GPL3')
makedepends=('automoc4' 'cmake' 'kdelibs' 'qt5-base' 'qt5-tools') makedepends=('automoc4' 'cmake' 'kdelibs' 'qt5-base' 'qt5-tools')
source=("https://github.com/arcan1s/netctl-gui/releases/download/V.${pkgver}/${pkgbase}-${pkgver}-src.tar.xz") source=("https://github.com/arcan1s/netctl-gui/releases/download/V.${pkgver}/${pkgbase}-${pkgver}-src.tar.xz")
md5sums=('9b56b04258855258ed30549f1039b8f8') md5sums=('b5c8fbff66bf5b8374dbe1fa72eb787d')
prepare() { prepare() {

View File

@ -3,10 +3,12 @@
ARCHIVE="netctl-gui" ARCHIVE="netctl-gui"
SRCDIR="sources" SRCDIR="sources"
FILES="AUTHORS CHANGELOG COPYING README.md" FILES="AUTHORS CHANGELOG COPYING README.md"
IGNORELIST="build en.qm ru.qm netctl-gui.qm *.cppcheck" IGNORELIST="build *.qm *.cppcheck .git*"
VERSION=$(grep -m1 PROJECT_VERSION_MAJOR sources/CMakeLists.txt | awk '{print $3}' | cut -c 1).\ VERSION=$(grep -m1 PROJECT_VERSION_MAJOR sources/CMakeLists.txt | awk '{print $3}' | cut -c 1).\
$(grep -m1 PROJECT_VERSION_MINOR sources/CMakeLists.txt | awk '{print $3}' | cut -c 1).\ $(grep -m1 PROJECT_VERSION_MINOR sources/CMakeLists.txt | awk '{print $3}' | cut -c 1).\
$(grep -m1 PROJECT_VERSION_PATCH sources/CMakeLists.txt | awk '{print $3}' | cut -c 1) $(grep -m1 PROJECT_VERSION_PATCH sources/CMakeLists.txt | awk '{print $3}' | cut -c 1)
# update submodules
git submodule update --init --recursive
# create archive # create archive
[[ -e ${ARCHIVE}-${VERSION}-src.tar.xz ]] && rm -f "${ARCHIVE}-${VERSION}-src.tar.xz" [[ -e ${ARCHIVE}-${VERSION}-src.tar.xz ]] && rm -f "${ARCHIVE}-${VERSION}-src.tar.xz"
[[ -d ${ARCHIVE} ]] && rm -rf "${ARCHIVE}" [[ -d ${ARCHIVE} ]] && rm -rf "${ARCHIVE}"

1
sources/3rdparty/language vendored Submodule

@ -0,0 +1 @@
Subproject commit fe15282d970a65737a26685080910c149ae9856e

View File

@ -1,12 +0,0 @@
#ifndef LANGUAGE_CONFIG_H
#define LANGUAGE_CONFIG_H
// put your languages here comma separated
// the first language is default language
#define LANGUAGES "en,ru"
// language key in the configuration file
#define LANGUAGE_KEY "LANGUAGE"
#endif /* LANGUAGE_CONFIG_H */

View File

@ -1,114 +0,0 @@
/***************************************************************************
* Copyright (C) 2014 Evgeniy Alekseev *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 3.0 of the License, or (at your option) any later version. *
* *
* This library 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 *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library. *
***************************************************************************/
#include "language.h"
#include <QFile>
#include <QLocale>
#include "config.h"
Language::Language()
{
}
QString Language::checkLanguage(const QString language)
{
QStringList availableLanguages = getAvailableLanguages();
if (availableLanguages.count() == 0) return QString();
for (int i=0; i<availableLanguages.count(); i++)
if (language == availableLanguages[i])
return availableLanguages[i];
for (int i=0; i<availableLanguages.count(); i++)
if (language.contains(availableLanguages[i] + QChar('_')))
return availableLanguages[i];
return availableLanguages[0];
}
QString Language::defineLanguage(const QString configPath, const QString options)
{
QMap<QString, QString> optionsDict = parseOptions(options);
if (optionsDict.contains(QString(LANGUAGE_KEY)))
if (getAvailableLanguages().contains(optionsDict[QString(LANGUAGE_KEY)]))
return optionsDict[QString(LANGUAGE_KEY)];
QString language;
language = defineLanguageFromFile(configPath);
if (language.isEmpty())
language = defineLanguageFromLocale();
language = checkLanguage(language);
return language;
}
QString Language::defineLanguageFromFile(const QString configPath)
{
QMap<QString, QString> settings;
if (configPath.isEmpty())
return QString("");
QFile configFile(configPath);
QString fileStr;
if (!configFile.open(QIODevice::ReadOnly))
return QString("");
while (true) {
fileStr = QString(configFile.readLine()).trimmed();
if ((fileStr.isEmpty()) && (!configFile.atEnd())) continue;
if ((fileStr[0] == QChar('#')) && (!configFile.atEnd())) continue;
if ((fileStr[0] == QChar(';')) && (!configFile.atEnd())) continue;
if (fileStr.contains(QChar('=')))
settings[fileStr.split(QChar('='))[0]] = fileStr.split(QChar('='))[1];
if (configFile.atEnd()) break;
}
configFile.close();
if (settings.contains(QString(LANGUAGE_KEY)))
return settings[QString(LANGUAGE_KEY)];
else
return QString("");
}
QString Language::defineLanguageFromLocale()
{
return QLocale::system().name();
}
QStringList Language::getAvailableLanguages()
{
return QString(LANGUAGES).split(QChar(','));
}
QMap<QString, QString> Language::parseOptions(const QString options)
{
QMap<QString, QString> optionsDict;
for (int i=0; i<options.split(QChar(',')).count(); i++) {
if (options.split(QChar(','))[i].split(QChar('=')).count() < 2)
continue;
optionsDict[options.split(QChar(','))[i].split(QChar('='))[0]] =
options.split(QChar(','))[i].split(QChar('='))[1];
}
return optionsDict;
}

View File

@ -1,42 +0,0 @@
/***************************************************************************
* Copyright (C) 2014 Evgeniy Alekseev *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 3.0 of the License, or (at your option) any later version. *
* *
* This library 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 *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library. *
***************************************************************************/
#ifndef LANGUAGE_H
#define LANGUAGE_H
#include <QStringList>
class Language : public QObject
{
Q_OBJECT
public:
explicit Language();
static QString checkLanguage(const QString language);
static QString defineLanguage(const QString configPath,
const QString options = QString("OPTIONS"));
static QString defineLanguageFromFile(const QString configPath);
static QString defineLanguageFromLocale();
static QStringList getAvailableLanguages();
private:
static QMap<QString, QString> parseOptions(const QString options);
};
#endif /* LANGUAGE_H */

1
sources/3rdparty/pdebug vendored Submodule

@ -0,0 +1 @@
Subproject commit 294a590bb966fd79eb2e93a7b02377ca57731cd5

View File

@ -1,45 +0,0 @@
/***************************************************************************
* Copyright (C) 2014 Evgeniy Alekseev *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 3.0 of the License, or (at your option) any later version. *
* *
* This library 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 *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library. *
***************************************************************************/
#ifndef PRETTY_DEBUG_H
#define PRETTY_DEBUG_H
inline const char *pDebug(const std::string prettyFunction)
{
return prettyFunction.c_str();
}
inline std::string pFuncInfo(const std::string prettyFunction)
{
size_t colons = prettyFunction.find("::");
// workaround for functions which are not belong to any class
if (colons == std::string::npos)
colons = prettyFunction.rfind("(");
size_t begin = prettyFunction.substr(0, colons).rfind(" ") + 1;
size_t end = prettyFunction.rfind("(") - begin;
return "[" + prettyFunction.substr(begin, end) + "]";
}
#define PDEBUG pDebug(pFuncInfo(__PRETTY_FUNCTION__))
#endif /* PRETTY_DEBUG_H */

1
sources/3rdparty/task vendored Submodule

@ -0,0 +1 @@
Subproject commit d2798204a1a84a23a9510aeda73d5b9b75d2c8eb

View File

@ -1,41 +0,0 @@
Asynchronous programming in Qt/C++ using tasks,continuations and resumable functions.
This project is inspired by this[1] video on channel9.
The project seeks to do async based programming in Qt/C++ using modern C++ with lambdas.
The project has two sets of APIs.
1. Task::run().then() API provides async based programming with continuation[4].
2. Task::await() API provides the first API presented in a different way[5].
Under certain use cases,they can be used interchangeably, and in others,only one or the other can be used.Some of the problems
the first API causes and solved by the second API are discussed in this[7] youtube video.
Example use case for the Task::run().then() API can be found here[0]. Additional example is [2] where an API is
declared and [3] where the declared API is used.
Example use case of the Task::await() API is here[6] where a function call "blocks" waiting for a result without "hanging" the entire GUI application.
A short tutorial on task/async/await as implemented in C# can be viewed from this[8] link.
[0] https://github.com/mhogomchungu/tasks/blob/master/example.cpp
[1] http://channel9.msdn.com/Blogs/Charles/Asynchronous-Programming-for-C-Developers-PPL-Tasks-and-Windows-8
[2] https://github.com/mhogomchungu/zuluCrypt/blob/d0439a4e36521e42fa9392b82dcefd3224d53334/zuluMount-gui/zulumounttask.h#L61
[3] https://github.com/mhogomchungu/zuluCrypt/blob/d0439a4e36521e42fa9392b82dcefd3224d53334/zuluMount-gui/mainwindow.cpp#L812
[4] Disscussion about this can be found on the following link among other places: http://isocpp.org/files/papers/N3558.pdf
[5] Disscussion about this can be found on the following link among other places: http://isocpp.org/files/papers/N3564.pdf
[6] https://github.com/mhogomchungu/zuluCrypt/blob/7123e3c3a7c8c5b3b3b6958464fd92a7f780d827/zuluMount-gui/keydialog.cpp#L511
[7] https://www.youtube.com/watch?v=Y475RshtAHA
[8] http://www.youtube.com/watch?v=DqjIQiZ_ql4

View File

@ -1,385 +0,0 @@
/*
* copyright: 2014
* name : mhogo mchungu
* email: mhogomchungu@gmail.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef __TASK_H_INCLUDED__
#define __TASK_H_INCLUDED__
#include <utility>
#include <future>
#include <functional>
#include <QThread>
#include <QEventLoop>
/*
*
* Examples on how to use the library are at the end of this file.
*
*/
namespace Task
{
class Thread : public QThread
{
Q_OBJECT
public:
Thread()
{
connect( this,SIGNAL( finished() ),this,SLOT( deleteLater() ) ) ;
}
protected:
virtual ~Thread()
{
}
private:
virtual void run( void )
{
}
};
template< typename T >
class future
{
public:
future() : m_function( []( T t ){ Q_UNUSED( t ) ; } )
{
}
void setActions( std::function< void( void ) > start,
std::function< void( void ) > cancel,
std::function< T ( void ) > get )
{
m_start = std::move( start ) ;
m_cancel = std::move( cancel ) ;
m_get = std::move( get ) ;
}
void then( std::function< void( T ) > function )
{
m_function = std::move( function ) ;
m_start() ;
}
T get()
{
return m_get() ;
}
T await()
{
QEventLoop p ;
T q ;
m_function = [ & ]( T r ){ q = std::move( r ) ; p.exit() ; } ;
m_start() ;
p.exec() ;
return q ;
}
void start()
{
m_start() ;
}
void cancel()
{
m_cancel() ;
}
void run( T r )
{
m_function( std::move( r ) ) ;
}
private:
std::function< void( T ) > m_function ;
std::function< void( void ) > m_start ;
std::function< void( void ) > m_cancel ;
std::function< T ( void ) > m_get ;
};
template< typename T >
class ThreadHelper : public Thread
{
public:
ThreadHelper( std::function< T ( void ) >&& function ) : m_function( std::move( function ) )
{
}
future<T>& Future( void )
{
m_future.setActions( [ this ](){ this->start() ; },
[ this ](){ this->deleteLater() ; },
[ this ](){ T r = m_function() ; this->deleteLater() ; return r ; } ) ;
return m_future ;
}
private:
~ThreadHelper()
{
m_future.run( std::move( m_cargo ) ) ;
}
void run( void )
{
m_cargo = m_function() ;
}
std::function< T ( void ) > m_function ;
future<T> m_future ;
T m_cargo ;
};
class future_1
{
public:
future_1() : m_function( [](){} )
{
}
void setActions( std::function< void( void ) > start,
std::function< void( void ) > cancel,
std::function< void( void ) > get )
{
m_start = std::move( start ) ;
m_cancel = std::move( cancel ) ;
m_get = std::move( get ) ;
}
void then( std::function< void( void ) > function )
{
m_function = std::move( function ) ;
m_start() ;
}
void get()
{
m_get() ;
}
void await()
{
QEventLoop p ;
m_function = [ & ](){ p.exit() ; } ;
m_start() ;
p.exec() ;
}
void start()
{
m_start() ;
}
void run()
{
m_function() ;
}
void cancel()
{
m_cancel() ;
}
private:
std::function< void( void ) > m_function ;
std::function< void( void ) > m_start ;
std::function< void( void ) > m_cancel ;
std::function< void( void ) > m_get ;
};
class ThreadHelper_1 : public Thread
{
public:
ThreadHelper_1( std::function< void ( void ) >&& function ) : m_function( std::move( function ) )
{
}
future_1& Future( void )
{
m_future.setActions( [ this ](){ this->start() ; },
[ this ](){ this->deleteLater() ; },
[ this ](){ m_function() ; this->deleteLater() ; } ) ;
return m_future ;
}
private:
~ThreadHelper_1()
{
m_future.run() ;
}
void run( void )
{
m_function() ;
}
std::function< void ( void ) > m_function ;
future_1 m_future ;
};
/*
* Below APIs runs two tasks,the first one will run in a different thread and
* the second one will be run on the original thread after the completion of the
* first one.
*/
template< typename T >
future<T>& run( std::function< T ( void ) > function )
{
auto t = new ThreadHelper<T>( std::move( function ) ) ;
return t->Future() ;
}
static inline future_1& run( std::function< void( void ) > function )
{
auto t = new ThreadHelper_1( std::move( function ) ) ;
return t->Future() ;
}
static inline void exec( std::function< void( void ) > function )
{
Task::run( std::move( function ) ).start() ;
}
/*
* Below APIs implements resumable functions where a function will be "blocked"
* waiting for the function to return without "hanging" the current thread.
*
* recommending reading up on C#'s await keyword to get a sense of what is being
* discussed below.
*/
static inline void await( Task::future_1& e )
{
e.await() ;
}
static inline void await( std::function< void( void ) > function )
{
Task::run( std::move( function ) ).await() ;
}
template< typename T >
T await( std::function< T ( void ) > function )
{
return Task::run<T>( std::move( function ) ).await() ;
}
template< typename T >
T await( Task::future<T>& e )
{
return e.await() ;
}
template< typename T >
T await( std::future<T>&& t )
{
return Task::await<T>( [ & ](){ return t.get() ; } ) ;
}
}
#if 0
/*
* Examples on how to use the library
*/
/*
* templated version that passes a return value of one function to another function
*/
auto _a = [](){
/*
* task _a does what task _a does here.
*
* This function body will run on a different thread
*/
return 0 ;
}
auto _b = []( int r ){
/*
*
* task _b does what task _b does here.
*
* r is a const reference to a value returned by _a
*
* This function body will run on the original thread
*/
}
Task::run<int>( _a ).then( _b ) ;
alternatively,
Task::future<int>& e = Task::run( _a ) ;
e.then( _b ) ;
/*
* Non templated version that does not pass around return value
*/
auto _c = [](){
/*
* task _a does what task _a does here.
*
* This function body will run on a different thread
*/
}
auto _d = [](){
/*
* task _b does what task _b does here.
*
* r is a const reference to a value returned by _a
*
* This function body will run on the original thread
*/
}
Task::run( _c ).then( _d ) ;
/*
* if no continuation
*/
Task::exec( _c ) ;
/*
* Task::await() is used to "block" without "hanging" the calling thread until the function returns.
*
* Its use case is to do sync programming without hanging the calling thread.
*
* example use case for it is to "block" on function in a GUI thread withough blocking the GUI thread
* hanging the application.
*/
/*
* await example when the called function return no result
*/
Task::await( _c ) ;
/*
* await example when the called function return a result
*/
int r = Task::await<int>( _a ) ;
alternatively,
Task::future<int>& e = Task::run<int>( _a ) ;
int r = e.await() ;
alternatively,
int r = Task::run<int>( _a ).await() ;
#endif
#endif //__TASK_H_INCLUDED__

View File

@ -1,44 +0,0 @@
/***************************************************************************
* This file is part of netctl-gui *
* *
* netctl-gui 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. *
* *
* netctl-gui 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 General Public License *
* along with netctl-gui. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "taskadds.h"
TaskResult runTask(const QString cmd, const bool useSuid)
{
return Task::await<TaskResult>( [ & ]() {
TaskResult r;
if (useSuid) {
RootProcess command;
command.start(cmd);
command.waitForFinished(-1);
r.exitCode = command.exitCode();
r.output = command.readAllStandardOutput();
r.error = command.readAllStandardError();
} else {
QProcess command;
command.start(cmd);
command.waitForFinished(-1);
r.exitCode = command.exitCode();
r.output = command.readAllStandardOutput();
r.error = command.readAllStandardError();
}
return r;
});
}

View File

@ -1,47 +0,0 @@
/***************************************************************************
* This file is part of netctl-gui *
* *
* netctl-gui 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. *
* *
* netctl-gui 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 General Public License *
* along with netctl-gui. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef TASKADDS_H
#define TASKADDS_H
#include <QProcess>
#include <unistd.h>
#include "task.h"
class RootProcess : public QProcess
{
protected:
void setupChildProcess()
{
::setuid(0);
};
};
struct TaskResult
{
int exitCode;
QByteArray error;
QByteArray output;
};
TaskResult runTask(const QString cmd, const bool useSuid = true);
#endif /* TASKADDS_H */

1
sources/3rdparty/tasks vendored Submodule

@ -0,0 +1 @@
Subproject commit f78c18d38156e8f7dd0d342d9f8779bed8b7f84e