update wt to 4.0.2
This commit is contained in:
parent
adb280d30c
commit
73f4b636fb
@ -14,7 +14,8 @@ set(HUNTER_BUILD_SHARED_LIBS TRUE)
|
||||
include(cmake/Compiler.cmake)
|
||||
include(cmake/FindAllRequirements.cmake)
|
||||
|
||||
include_directories(${CMAKE_BINARY_DIR}/external/include)
|
||||
include_directories(${CMAKE_BINARY_DIR}/external/include SYSTEM)
|
||||
include_directories(${CMAKE_BINARY_DIR}/external/include/date SYSTEM)
|
||||
|
||||
add_subdirectory(src)
|
||||
#add_subdirectory(tests)
|
||||
|
||||
@ -60,8 +60,8 @@ find_package(spdlog CONFIG REQUIRED)
|
||||
hunter_add_package(range-v3)
|
||||
find_package(range-v3 CONFIG REQUIRED)
|
||||
|
||||
#hunter_add_package(PostgreSQL)
|
||||
#find_package(PostgreSQL REQUIRED)
|
||||
hunter_add_package(PostgreSQL)
|
||||
find_package(PostgreSQL REQUIRED)
|
||||
|
||||
set(EXTERNAL_INSTALL_LOCATION ${CMAKE_BINARY_DIR}/lib CACHE STRING "external libs root path")
|
||||
set(EXTERNAL_LOCATION ${CMAKE_BINARY_DIR}/external CACHE STRING "external sources root path")
|
||||
@ -88,8 +88,8 @@ build_external_project(project_wt wt
|
||||
-DENABLE_FIREBIRD=OFF
|
||||
-DENABLE_MYSQL=OFF
|
||||
-DENABLE_MSSQLSERVER=OFF
|
||||
-DENABLE_LIBWTDBO=TRUE
|
||||
-DENABLE_QT4=OFF
|
||||
-DENABLE_LIBWTDBO=OFF
|
||||
-DENABLE_OPENGL=OFF
|
||||
-DENABLE_UNWIND=OFF
|
||||
-DCONNECTOR_FCGI=OFF
|
||||
@ -104,10 +104,11 @@ set_target_properties(wthttp PROPERTIES IMPORTED_LOCATION ${EXTERNAL_LOCATION}/l
|
||||
add_dependencies(wthttp project_wt)
|
||||
|
||||
LIST(APPEND CMAKE_MODULE_PATH "${EXTERNAL_LOCATION}")
|
||||
#LIST(APPEND CMAKE_MODULE_PATH "${_HUNTER_ROOT}/lib")
|
||||
|
||||
build_external_project(project_hhdate date
|
||||
https://github.com/HowardHinnant/date.git
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||
-DCMAKE_INSTALL_PREFIX=${EXTERNAL_LOCATION}
|
||||
-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH_ALT_SEP}
|
||||
-DTZ_CXX_STANDARD=14
|
||||
@ -118,6 +119,8 @@ add_dependencies(date project_hhdate)
|
||||
|
||||
build_external_project(project_sqlpp sqlpp
|
||||
https://github.com/rbock/sqlpp11.git
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||
-DCMAKE_INSTALL_PREFIX=${EXTERNAL_LOCATION}
|
||||
-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH_ALT_SEP}
|
||||
-DENABLE_TESTS=FALSE
|
||||
@ -126,7 +129,8 @@ build_external_project(project_sqlpp sqlpp
|
||||
add_library(sqlpp INTERFACE IMPORTED)
|
||||
add_dependencies(sqlpp project_sqlpp)
|
||||
|
||||
link_directories(${_HUNTER_ROOT}/lib)
|
||||
link_directories(${_HUNTER_ROOT}/lib GLOBAL)
|
||||
link_directories(${EXTERNAL_LOCATION}/lib GLOBAL)
|
||||
|
||||
find_library(wt REQUIRED)
|
||||
find_library(wthttp REQUIRED)
|
||||
@ -134,10 +138,11 @@ find_library(sqlpp REQUIRED)
|
||||
|
||||
build_external_project(project_sqlpp_connector sqlpp_connector
|
||||
https://github.com/matthijs/sqlpp11-connector-postgresql.git
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||
-DCMAKE_INSTALL_PREFIX=${EXTERNAL_LOCATION}
|
||||
-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH_ALT_SEP}
|
||||
-DENABLE_TESTS=FALSE
|
||||
-DDATE_INCLUDE_DIR=${EXTERNAL_LOCATION}/include/date
|
||||
-DSQLPP11_INCLUDE_DIR=${EXTERNAL_LOCATION}/include
|
||||
)
|
||||
|
||||
|
||||
@ -1,20 +1,17 @@
|
||||
set(SOURCES
|
||||
main.cpp)
|
||||
|
||||
#INCLUDE_DIRECTORIES(${PostgreSQL_INCLUDE_DIRS})
|
||||
|
||||
|
||||
add_executable(eedb ${SOURCES} )
|
||||
|
||||
|
||||
target_link_libraries(eedb
|
||||
wthttp # or {Wt_HTTP_DEBUG_LIBRARY}
|
||||
wt # or {Wt_DEBUG_LIBRARY}
|
||||
eedb_db
|
||||
auth
|
||||
Boost::system
|
||||
Boost::filesystem
|
||||
Boost::thread
|
||||
Boost::program_options
|
||||
z
|
||||
# eedb_db auth
|
||||
)
|
||||
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
//#include <eedb/EEDB.hpp>
|
||||
//#include <eedb/Session.hpp>
|
||||
#include <eedb/EEDB.hpp>
|
||||
#include <eedb/Session.hpp>
|
||||
|
||||
//#include <eedb/auth/PgUserAuth.hpp>
|
||||
//#include <eedb/auth/Services.hpp>
|
||||
#include <eedb/auth/PgUserAuth.hpp>
|
||||
#include <eedb/auth/Services.hpp>
|
||||
|
||||
//#include <eedb/db/config.hpp>
|
||||
//#include <eedb/db/connection.hpp>
|
||||
#include <eedb/db/config.hpp>
|
||||
#include <eedb/db/connection.hpp>
|
||||
|
||||
//#include <eedb/widgets/DefaultAuthPage.hpp>
|
||||
//#include <eedb/widgets/DefaultHomePage.hpp>
|
||||
@ -15,28 +15,28 @@
|
||||
#include <Wt/WServer.h>
|
||||
|
||||
Wt::WApplication * createApplication(const Wt::WEnvironment & env) {
|
||||
// using std::make_unique;
|
||||
// using std::move;
|
||||
// using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
using std::move;
|
||||
using std::unique_ptr;
|
||||
|
||||
// auto dbConfig = make_unique< eedb::db::PgConfig >(env);
|
||||
// auto dbConnection = make_unique< eedb::db::PgConnection >(move(dbConfig));
|
||||
// auto session = unique_ptr< eedb::Session >(make_unique< eedb::WebSession >(move(dbConnection), env));
|
||||
auto dbConfig = make_unique< eedb::db::PgConfig >(env);
|
||||
// auto dbConnection = make_unique< eedb::db::PgConnection >(move(dbConfig));
|
||||
// auto session = unique_ptr< eedb::Session >(make_unique< eedb::WebSession >(move(dbConnection), env));
|
||||
|
||||
// auto authPageFactory = [_session = session.get()]()->std::unique_ptr< eedb::AuthPage > {
|
||||
// auto userDatabase = make_unique< eedb::auth::PgUserAuth >(_session->db(), _session->enviroment());
|
||||
// auto services = eedb::auth::Services();
|
||||
// auto & login = _session->login();
|
||||
// auto authPageFactory = [_session = session.get()]()->std::unique_ptr< eedb::AuthPage > {
|
||||
// auto userDatabase = make_unique< eedb::auth::PgUserAuth >(_session->db(), _session->enviroment());
|
||||
// auto services = eedb::auth::Services();
|
||||
// auto & login = _session->login();
|
||||
|
||||
// return make_unique< eedb::DefaultAuthPage >(services, std::move(userDatabase), login);
|
||||
// };
|
||||
// return make_unique< eedb::DefaultAuthPage >(services, std::move(userDatabase), login);
|
||||
// };
|
||||
|
||||
// auto homePageFactory = [_session = session.get()]()->std::unique_ptr< eedb::HomePage > {
|
||||
// auto navigationBar = std::make_unique< eedb::DefaultNavigationBar >();
|
||||
// return make_unique< eedb::DefaultHomePage >(*_session, std::move(navigationBar));
|
||||
// };
|
||||
// auto homePageFactory = [_session = session.get()]()->std::unique_ptr< eedb::HomePage > {
|
||||
// auto navigationBar = std::make_unique< eedb::DefaultNavigationBar >();
|
||||
// return make_unique< eedb::DefaultHomePage >(*_session, std::move(navigationBar));
|
||||
// };
|
||||
|
||||
// return new eedb::EEDB{std::move(session), authPageFactory, homePageFactory};
|
||||
// return new eedb::EEDB{std::move(session), authPageFactory, homePageFactory};
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
|
||||
@ -1,17 +1,16 @@
|
||||
file(GLOB SOURCE
|
||||
# EEDB.cpp
|
||||
# Session.cpp
|
||||
EEDB.cpp
|
||||
Session.cpp
|
||||
|
||||
# auth/PgUserAuth.cpp
|
||||
# auth/Services.cpp
|
||||
# data/*
|
||||
# widgets/*
|
||||
# model/*
|
||||
auth/PgUserAuth.cpp
|
||||
auth/Services.cpp
|
||||
data/*
|
||||
widgets/*
|
||||
model/*
|
||||
)
|
||||
|
||||
#add_subdirectory(db)
|
||||
#include_directories( ${PostgreSQL_INCLUDE_DIRS} )
|
||||
|
||||
#add_library(auth STATIC ${SOURCE})
|
||||
#target_link_libraries( auth eedb_db )
|
||||
include_directories( ${PostgreSQL_INCLUDE_DIRS} )
|
||||
add_subdirectory(db)
|
||||
|
||||
add_library(auth STATIC ${SOURCE})
|
||||
target_link_libraries( auth eedb_db )
|
||||
|
||||
@ -39,7 +39,7 @@ EEDB::EEDB(std::unique_ptr< Session > session, AuthPageFactory authPageFactory,
|
||||
root()->addStyleClass("container");
|
||||
useStyleSheet("/resources/style.css");
|
||||
|
||||
setTheme(_theme->create(this));
|
||||
setTheme(_theme->create());
|
||||
|
||||
_authPage = _authPageFactory();
|
||||
_authPage->registerNeedVerification([] {});
|
||||
|
||||
@ -18,17 +18,14 @@
|
||||
#include <random>
|
||||
#include <string>
|
||||
|
||||
#include <Wt/Auth/AuthService>
|
||||
#include <Wt/Auth/Dbo/AuthInfo>
|
||||
#include <Wt/WEnvironment>
|
||||
#include <Wt/WLogger>
|
||||
#include <Wt/Auth/AuthService.h>
|
||||
#include <Wt/Auth/Dbo/AuthInfo.h>
|
||||
#include <Wt/WEnvironment.h>
|
||||
#include <Wt/WLogger.h>
|
||||
|
||||
#include <tao/json.hh>
|
||||
#include <tao/json/value.hh>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using namespace sqlpp;
|
||||
using namespace Wt::Auth;
|
||||
using namespace std::string_literals;
|
||||
|
||||
// enum LoginActions { Login, Logout };
|
||||
// static std::array< std::string_view, 2 > UserActionNames = {{"login", "logout"}};
|
||||
@ -56,7 +53,8 @@ struct TransactionGuard : public Wt::Auth::AbstractUserDatabase::Transaction {
|
||||
_c.native()->commit_transaction();
|
||||
}
|
||||
void rollback() override {
|
||||
_c.native()->rollback_transaction();
|
||||
///FIXME
|
||||
// _c.native()->rollback_transaction();
|
||||
}
|
||||
|
||||
private:
|
||||
@ -85,7 +83,7 @@ namespace {
|
||||
.from(t_user_action) //
|
||||
.where(t_user_action.name == "logout") //
|
||||
.limit(1u);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
PgUserAuth::~PgUserAuth() {}
|
||||
|
||||
@ -108,7 +106,7 @@ User PgUserAuth::findWithId(const std::string & id) const {
|
||||
|
||||
User PgUserAuth::findWithIdentity(const std::string & provider, const Wt::WString & identity) const {
|
||||
auto _identity = identity.toUTF8();
|
||||
if(_authService && _authService->identityPolicy() == EmailAddressIdentity) {
|
||||
if(_authService && _authService->identityPolicy() == Wt::Auth::IdentityPolicy::EmailAddress ) {
|
||||
std::transform(_identity.begin(), _identity.end(), _identity.begin(), ::tolower);
|
||||
}
|
||||
|
||||
@ -302,7 +300,7 @@ User PgUserAuth::findWithEmail(const std::string & address) const {
|
||||
return {std::to_string(ret.front().user_uid), *this};
|
||||
}
|
||||
|
||||
void PgUserAuth::setEmailToken(const User & user, const Token & token, User::EmailTokenRole role) {
|
||||
void PgUserAuth::setEmailToken(const User & user, const Token & token, EmailTokenRole role) {
|
||||
auto exp = ::date::floor<::std::chrono::milliseconds >(std::chrono::system_clock::from_time_t(token.expirationTime().toTime_t()));
|
||||
db(update(t_info) //
|
||||
.set( //
|
||||
@ -325,14 +323,14 @@ Token PgUserAuth::emailToken(const User & user) const {
|
||||
return {ret.front().email_token, exp};
|
||||
}
|
||||
|
||||
User::EmailTokenRole PgUserAuth::emailTokenRole(const User & user) const {
|
||||
EmailTokenRole PgUserAuth::emailTokenRole(const User & user) const {
|
||||
auto ret = db(select(t_info.email_token_role) //
|
||||
.from(t_info) //
|
||||
.where(t_info.user_uid == std::atoi(user.id().c_str())));
|
||||
if(ret.empty())
|
||||
throw std::exception();
|
||||
auto val = ret.front().email_token_role;
|
||||
return static_cast< User::EmailTokenRole >(val.value());
|
||||
return static_cast< EmailTokenRole >(val.value());
|
||||
}
|
||||
|
||||
User PgUserAuth::findWithEmailToken(const std::string & hash) const {
|
||||
@ -378,6 +376,7 @@ User PgUserAuth::findWithAuthToken(const std::string & hash) const {
|
||||
int PgUserAuth::updateAuthToken(const User & user, const std::string & oldhash, const std::string & newhash) {
|
||||
// method called only after successful login
|
||||
using namespace std::chrono;
|
||||
using namespace std::string_literals;
|
||||
const auto identity_id = db(select(t_info.id) //
|
||||
.from(t_info) //
|
||||
.where(t_info.user_uid == std::atoi(user.id().c_str())));
|
||||
@ -392,7 +391,7 @@ int PgUserAuth::updateAuthToken(const User & user, const std::string & oldhash,
|
||||
if(expires.empty())
|
||||
return 0;
|
||||
|
||||
const tao::json::value data{
|
||||
const nlohmann::json data = {
|
||||
{"status"s, "success"}, //
|
||||
{"method"s, "token"}, //
|
||||
{"user_address"s, _env.clientAddress()}, //
|
||||
@ -405,7 +404,7 @@ int PgUserAuth::updateAuthToken(const User & user, const std::string & oldhash,
|
||||
db(insert_into(t_user_history)
|
||||
.set(t_user_history.user_id = std::atoi(user.id().c_str()),
|
||||
t_user_history.action_id = select_login_action_id, //
|
||||
t_user_history.data = tao::json::to_string(data)));
|
||||
t_user_history.data = data.dump()));
|
||||
|
||||
const auto now = system_clock::now();
|
||||
const auto diff = expires.front().expires.value() - now;
|
||||
@ -413,9 +412,10 @@ int PgUserAuth::updateAuthToken(const User & user, const std::string & oldhash,
|
||||
}
|
||||
|
||||
void PgUserAuth::setFailedLoginAttempts(const User & user, int count) {
|
||||
using namespace std::string_literals;
|
||||
const auto getStatus = [count]() { return count ? "failed"s : "success"s; };
|
||||
|
||||
const tao::json::value data{
|
||||
const nlohmann::json data = {
|
||||
{"status"s, getStatus()}, //
|
||||
{"method"s, "password"}, //
|
||||
{"user_address"s, _env.clientAddress()}, //
|
||||
@ -428,13 +428,15 @@ void PgUserAuth::setFailedLoginAttempts(const User & user, int count) {
|
||||
db(insert_into(t_user_history)
|
||||
.set(t_user_history.user_id = std::atoi(user.id().c_str()),
|
||||
t_user_history.action_id = select_login_action_id, //
|
||||
t_user_history.data = tao::json::to_string(data)));
|
||||
t_user_history.data = data.dump()));
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
inline std::string name_of(const T &) {
|
||||
static_assert(sqlpp::is_column_t< T >::value, "T should by a calumn");
|
||||
return std::string{sqlpp::name_of< typename T::_table >::char_ptr()} + '.' + sqlpp::name_of< T >::char_ptr();
|
||||
return {};
|
||||
/// FIXME
|
||||
// static_assert(sqlpp::is_column_t< T >::value, "T should by a calumn");
|
||||
// return std::string{sqlpp::name_of< typename T::_table >::char_ptr()} + '.' + sqlpp::name_of< T >::char_ptr();
|
||||
}
|
||||
|
||||
int PgUserAuth::failedLoginAttempts(const User & user) const {
|
||||
@ -474,15 +476,16 @@ Wt::WDateTime PgUserAuth::lastLoginAttempt(const User & user) const {
|
||||
}
|
||||
|
||||
void PgUserAuth::logout(const User & user) {
|
||||
const tao::json::value data{{"status"s, "success"}};
|
||||
using namespace std::string_literals;
|
||||
const nlohmann::json data = {{"status"s, "success"}};
|
||||
|
||||
db(insert_into(t_user_history)
|
||||
.set(t_user_history.user_id = std::atoi(user.id().c_str()),
|
||||
t_user_history.action_id = select_logout_action_id, //
|
||||
t_user_history.data = tao::json::to_string(data)));
|
||||
t_user_history.data = data.dump()));
|
||||
}
|
||||
|
||||
AbstractUserDatabase::Transaction * PgUserAuth::startTransaction() {
|
||||
return new TransactionGuard< decltype(db) >(db);
|
||||
}
|
||||
}
|
||||
} // namespace eedb::auth
|
||||
|
||||
@ -48,9 +48,9 @@ class PgUserAuth : public Wt::Auth::AbstractUserDatabase {
|
||||
void setUnverifiedEmail(const Wt::Auth::User & user, const std::string & address) override;
|
||||
std::string unverifiedEmail(const Wt::Auth::User & user) const override;
|
||||
|
||||
void setEmailToken(const Wt::Auth::User & user, const Wt::Auth::Token & token, Wt::Auth::User::EmailTokenRole role) override;
|
||||
void setEmailToken(const Wt::Auth::User & user, const Wt::Auth::Token & token, Wt::Auth::EmailTokenRole role) override;
|
||||
Wt::Auth::Token emailToken(const Wt::Auth::User & user) const override;
|
||||
Wt::Auth::User::EmailTokenRole emailTokenRole(const Wt::Auth::User & user) const override;
|
||||
Wt::Auth::EmailTokenRole emailTokenRole(const Wt::Auth::User & user) const override;
|
||||
|
||||
void addAuthToken(const Wt::Auth::User & user, const Wt::Auth::Token & token) override;
|
||||
void removeAuthToken(const Wt::Auth::User &, const std::string & hash) override;
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
#include <eedb/auth/Services.hpp>
|
||||
|
||||
#include <Wt/Auth/PasswordService>
|
||||
#include <Wt/Auth/PasswordStrengthValidator>
|
||||
#include <Wt/Auth/PasswordVerifier>
|
||||
#include <Wt/Auth/PasswordService.h>
|
||||
#include <Wt/Auth/PasswordStrengthValidator.h>
|
||||
#include <Wt/Auth/PasswordVerifier.h>
|
||||
|
||||
#include <Wt/Auth/AuthService>
|
||||
#include <Wt/Auth/AuthWidget>
|
||||
#include <Wt/Auth/Dbo/AuthInfo>
|
||||
#include <Wt/Auth/Dbo/UserDatabase>
|
||||
#include <Wt/Auth/FacebookService>
|
||||
#include <Wt/Auth/GoogleService>
|
||||
#include <Wt/Auth/HashFunction>
|
||||
#include <Wt/Auth/Login>
|
||||
#include <Wt/Auth/AuthService.h>
|
||||
#include <Wt/Auth/AuthWidget.h>
|
||||
#include <Wt/Auth/Dbo/AuthInfo.h>
|
||||
#include <Wt/Auth/Dbo/UserDatabase.h>
|
||||
#include <Wt/Auth/FacebookService.h>
|
||||
#include <Wt/Auth/GoogleService.h>
|
||||
#include <Wt/Auth/HashFunction.h>
|
||||
#include <Wt/Auth/Login.h>
|
||||
|
||||
namespace {
|
||||
|
||||
@ -45,12 +45,14 @@ void Services::configureAuth() {
|
||||
myAuthService.setAuthTokensEnabled(true, "logincookie");
|
||||
myAuthService.setEmailVerificationEnabled(true);
|
||||
myAuthService.setEmailVerificationRequired(true);
|
||||
{
|
||||
auto verifier = std::unique_ptr<Wt::Auth::PasswordVerifier>();
|
||||
verifier->addHashFunction(std::make_unique< Wt::Auth::BCryptHashFunction >(7));
|
||||
myPasswordService.setVerifier(std::move(verifier));
|
||||
}
|
||||
|
||||
Wt::Auth::PasswordVerifier * verifier = new Wt::Auth::PasswordVerifier();
|
||||
verifier->addHashFunction(new Wt::Auth::BCryptHashFunction(7));
|
||||
myPasswordService.setVerifier(verifier);
|
||||
myPasswordService.setAttemptThrottlingEnabled(true);
|
||||
myPasswordService.setStrengthValidator(new Wt::Auth::PasswordStrengthValidator());
|
||||
myPasswordService.setStrengthValidator(std::make_unique< Wt::Auth::PasswordStrengthValidator >());
|
||||
|
||||
if(Wt::Auth::GoogleService::configured())
|
||||
myOAuthServices.push_back(new Wt::Auth::GoogleService(myAuthService));
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#include <Wt/WStandardItem>
|
||||
#include <Wt/WStandardItemModel>
|
||||
#include <Wt/WStandardItem.h>
|
||||
#include <Wt/WStandardItemModel.h>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
@ -9,22 +9,22 @@ auto secondLevelRows = 300;
|
||||
namespace eedb {
|
||||
class CategoriesModel final : public Wt::WStandardItemModel {
|
||||
public:
|
||||
CategoriesModel(Wt::WObject * parent) : Wt::WStandardItemModel(parent) {
|
||||
CategoriesModel(Wt::WObject * parent) : Wt::WStandardItemModel() {
|
||||
auto model = this;
|
||||
auto root = model->invisibleRootItem();
|
||||
for(int row = 0; row < topLevelRows; ++row) {
|
||||
Wt::WStandardItem * topLevel = new Wt::WStandardItem();
|
||||
auto topLevel = std::make_unique< Wt::WStandardItem >();
|
||||
topLevel->setText("Item " + boost::lexical_cast< std::string >(row));
|
||||
for(int row2 = 0; row2 < secondLevelRows; ++row2) {
|
||||
Wt::WStandardItem * item = new Wt::WStandardItem();
|
||||
auto item = std::make_unique< Wt::WStandardItem >();
|
||||
item->setToolTip("this is a tooltip");
|
||||
item->setText("Item " + boost::lexical_cast< std::string >(row) + ": " + boost::lexical_cast< std::string >(row2));
|
||||
topLevel->appendRow(item);
|
||||
topLevel->appendRow(std::move(item));
|
||||
}
|
||||
root->appendRow(topLevel);
|
||||
root->appendRow(std::move(topLevel));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
}
|
||||
} // namespace eedb
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
#include <eedb/model/user.h>
|
||||
#include <eedb/model/user_audit.h>
|
||||
|
||||
#include <Wt/WString>
|
||||
#include <Wt/WString.h>
|
||||
|
||||
#include <boost/spirit/home/support/char_class.hpp>
|
||||
|
||||
|
||||
@ -1,12 +1,9 @@
|
||||
set(SOURCE
|
||||
connection.cpp
|
||||
config.cpp
|
||||
)
|
||||
|
||||
find_package(Sqlpp11 REQUIRED)
|
||||
find_package(PostgreSQL REQUIRED)
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES( ${PostgreSQL_INCLUDE_DIRS} )
|
||||
|
||||
add_library(eedb_db ${SOURCE})
|
||||
target_link_libraries( eedb_db sqlpp-postgresql )
|
||||
target_link_libraries( eedb_db wt sqlpp-postgresql )
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#include <eedb/db/config.hpp>
|
||||
|
||||
#include <Wt/WEnvironment>
|
||||
#include <Wt/WServer>
|
||||
#include <Wt/WEnvironment.h>
|
||||
#include <Wt/WServer.h>
|
||||
|
||||
namespace eedb::db {
|
||||
PgConfig::PgConfig(const Wt::WEnvironment & env) {
|
||||
@ -36,4 +36,4 @@ PgConfig::PgConfig(const Wt::WEnvironment & env) {
|
||||
readInt("db_port", port, 5432);
|
||||
readBool("db_debug", debug, true);
|
||||
}
|
||||
}
|
||||
} // namespace eedb::db
|
||||
|
||||
@ -4,12 +4,12 @@
|
||||
|
||||
namespace Wt {
|
||||
class WEnvironment;
|
||||
}
|
||||
} // namespace Wt
|
||||
|
||||
namespace eedb::db {
|
||||
|
||||
class PgConfig : public sqlpp::postgresql::connection_config {
|
||||
public:
|
||||
PgConfig(const Wt::WEnvironment & env);
|
||||
explicit PgConfig(const Wt::WEnvironment & env);
|
||||
};
|
||||
}
|
||||
} // namespace eedb::db
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
#include <eedb/widgets/BootstrapTheme.hpp>
|
||||
|
||||
#include <Wt/WBootstrapTheme>
|
||||
#include <Wt/WBootstrapTheme.h>
|
||||
|
||||
namespace eedb {
|
||||
|
||||
Wt::WTheme * BootstrapTheme::create(Wt::WObject * parent) const {
|
||||
auto theme = new Wt::WBootstrapTheme(parent);
|
||||
theme->setVersion(Wt::WBootstrapTheme::Version2);
|
||||
std::shared_ptr<Wt::WTheme> BootstrapTheme::create() const {
|
||||
auto theme = std::shared_ptr<Wt::WBootstrapTheme>();
|
||||
theme->setVersion(Wt::WBootstrapTheme::Version::v3);
|
||||
// theme->setResponsive(true);
|
||||
return theme;
|
||||
}
|
||||
|
||||
@ -9,6 +9,6 @@ class BootstrapTheme final : public Theme {
|
||||
BootstrapTheme(Theme &&) {}
|
||||
BootstrapTheme(const Theme &) {}
|
||||
|
||||
Wt::WTheme * create(Wt::WObject * parent) const override;
|
||||
std::shared_ptr< Wt::WTheme > create() const override;
|
||||
};
|
||||
}
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
#include <eedb/auth/Services.hpp>
|
||||
#include <eedb/widgets/DefaultAuthPage.hpp>
|
||||
|
||||
#include <Wt/Auth/AbstractUserDatabase>
|
||||
#include <Wt/Auth/AuthWidget>
|
||||
#include <Wt/WContainerWidget>
|
||||
#include <Wt/Auth/AbstractUserDatabase.h>
|
||||
#include <Wt/Auth/AuthWidget.h>
|
||||
#include <Wt/WContainerWidget.h>
|
||||
|
||||
namespace std {
|
||||
|
||||
@ -15,7 +15,7 @@ struct default_delete< Wt::Auth::AuthWidget > {
|
||||
delete ptr;
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace std
|
||||
|
||||
namespace eedb {
|
||||
|
||||
@ -23,7 +23,7 @@ struct DefaultAuthPage::DefaultAuthPagePriv {
|
||||
DefaultAuthPagePriv(const auth::Services & baseAuth,
|
||||
std::unique_ptr< Wt::Auth::AbstractUserDatabase > userDatabase,
|
||||
Wt::Auth::Login & _login)
|
||||
: _authWidget(std::make_unique< Wt::Auth::AuthWidget >(*baseAuth.authService(), *userDatabase.get(), _login, nullptr)),
|
||||
: _authWidget(std::make_unique< Wt::Auth::AuthWidget >(*baseAuth.authService(), *userDatabase.get(), _login)),
|
||||
_userDatabase(std::move(userDatabase)) {
|
||||
_authWidget->model()->addPasswordAuth(eedb::auth::Services::passwordService());
|
||||
_authWidget->model()->addOAuth(eedb::auth::Services::oAuthServices());
|
||||
@ -43,17 +43,18 @@ DefaultAuthPage::DefaultAuthPage(const auth::Services & baseAuth,
|
||||
std::unique_ptr< Wt::Auth::AbstractUserDatabase > userDatabase,
|
||||
Wt::Auth::Login & _login)
|
||||
: _priv(std::make_unique< DefaultAuthPagePriv >(baseAuth, std::move(userDatabase), _login)) {
|
||||
_priv->_authWidget->login().changed().connect([this](auto...) {
|
||||
if(_priv->_authWidget->login().state() == Wt::Auth::LoginState::StrongLogin) {
|
||||
this->notifyUserStrongLogin();
|
||||
} else if(_priv->_authWidget->login().state() == Wt::Auth::LoginState::WeakLogin) {
|
||||
this->notifyUserWeakLogin();
|
||||
} else if(_priv->_authWidget->login().state() == Wt::Auth::LoginState::DisabledLogin) {
|
||||
this->notifyNeedEmailVerification();
|
||||
} else {
|
||||
this->notifyUserLogout();
|
||||
}
|
||||
});
|
||||
///FIXME
|
||||
// _priv->_authWidget->login().changed().connect([this](auto...) {
|
||||
// if(_priv->_authWidget->login().state() == Wt::Auth::LoginState::Strong) {
|
||||
// this->notifyUserStrongLogin();
|
||||
// } else if(_priv->_authWidget->login().state() == Wt::Auth::LoginState::Weak) {
|
||||
// this->notifyUserWeakLogin();
|
||||
// } else if(_priv->_authWidget->login().state() == Wt::Auth::LoginState::Disabled) {
|
||||
// this->notifyNeedEmailVerification();
|
||||
// } else {
|
||||
// this->notifyUserLogout();
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
DefaultAuthPage::DefaultAuthPage(DefaultAuthPage && rhs) : _priv(std::move(rhs._priv)) {}
|
||||
@ -65,7 +66,7 @@ DefaultAuthPage & DefaultAuthPage::operator=(DefaultAuthPage && rhs) {
|
||||
|
||||
DefaultAuthPage::~DefaultAuthPage() = default;
|
||||
void DefaultAuthPage::attachTo(Wt::WContainerWidget * parent) {
|
||||
parent->addWidget(_priv->_authWidget.get());
|
||||
parent->addWidget(std::move(_priv->_authWidget));
|
||||
}
|
||||
|
||||
void DefaultAuthPage::detach() {
|
||||
@ -79,19 +80,19 @@ void DefaultAuthPage::processEnvironment() {
|
||||
}
|
||||
|
||||
void DefaultAuthPage::registerNeedVerification(std::function< void() > f) {
|
||||
_priv->_onNeedEmailVerification.connect([=](auto...) { f(); });
|
||||
_priv->_onNeedEmailVerification.connect([=]() { f(); });
|
||||
}
|
||||
|
||||
void DefaultAuthPage::registerOnUserWeakLogin(std::function< void() > f) {
|
||||
_priv->_onUserWeakLogin.connect([=](auto...) { f(); });
|
||||
_priv->_onUserWeakLogin.connect([=]() { f(); });
|
||||
}
|
||||
|
||||
void DefaultAuthPage::registerOnUserStrongLogin(std::function< void() > f) {
|
||||
_priv->_onUserStrongLogin.connect([=](auto...) { f(); });
|
||||
_priv->_onUserStrongLogin.connect([=]() { f(); });
|
||||
}
|
||||
|
||||
void DefaultAuthPage::registerOnUserLogout(std::function< void() > f) {
|
||||
_priv->_onUserLogout.connect([=](auto...) { f(); });
|
||||
_priv->_onUserLogout.connect([=]() { f(); });
|
||||
}
|
||||
|
||||
void DefaultAuthPage::notifyUserStrongLogin() const {
|
||||
@ -109,4 +110,4 @@ void DefaultAuthPage::notifyNeedEmailVerification() const {
|
||||
void DefaultAuthPage::notifyUserLogout() const {
|
||||
_priv->_onUserLogout.emit();
|
||||
}
|
||||
}
|
||||
} // namespace eedb
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
|
||||
#include <eedb/data/Category.hpp>
|
||||
|
||||
#include <Wt/WContainerWidget>
|
||||
#include <Wt/WTreeView>
|
||||
#include <Wt/WContainerWidget.h>
|
||||
#include <Wt/WTreeView.h>
|
||||
|
||||
namespace std {
|
||||
|
||||
@ -30,7 +30,7 @@ DefaultCategoriesTree::DefaultCategoriesTree() : _priv(std::make_unique< Default
|
||||
DefaultCategoriesTree::~DefaultCategoriesTree() = default;
|
||||
|
||||
void DefaultCategoriesTree::attachTo(Wt::WContainerWidget * parent) {
|
||||
parent->addWidget(_priv->tree.get());
|
||||
parent->addWidget(std::move(_priv->tree));
|
||||
}
|
||||
|
||||
void DefaultCategoriesTree::registerOnCategoryChanged(std::function< void(const Category &) >) {}
|
||||
|
||||
@ -1,23 +1,23 @@
|
||||
#include <eedb/widgets/DefaultHomePage.hpp>
|
||||
|
||||
#include <Wt/Auth/Login>
|
||||
#include <Wt/WContainerWidget>
|
||||
#include <Wt/WEnvironment>
|
||||
#include <Wt/WLineEdit>
|
||||
#include <Wt/WMessageBox>
|
||||
#include <Wt/WServer>
|
||||
#include <Wt/WStackedWidget>
|
||||
#include <Wt/WText>
|
||||
#include <Wt/WTextArea>
|
||||
#include <Wt/Auth/Login.h>
|
||||
#include <Wt/WContainerWidget.h>
|
||||
#include <Wt/WEnvironment.h>
|
||||
#include <Wt/WLineEdit.h>
|
||||
#include <Wt/WMessageBox.h>
|
||||
#include <Wt/WServer.h>
|
||||
#include <Wt/WStackedWidget.h>
|
||||
#include <Wt/WText.h>
|
||||
#include <Wt/WTextArea.h>
|
||||
|
||||
#include <Wt/WIconPair>
|
||||
#include <Wt/WLogger>
|
||||
#include <Wt/WText>
|
||||
#include <Wt/WTreeNode>
|
||||
#include <Wt/WTreeView>
|
||||
#include <Wt/WIconPair.h>
|
||||
#include <Wt/WLogger.h>
|
||||
#include <Wt/WText.h>
|
||||
#include <Wt/WTreeNode.h>
|
||||
#include <Wt/WTreeView.h>
|
||||
|
||||
#include <Wt/WHBoxLayout>
|
||||
#include <Wt/WVBoxLayout>
|
||||
#include <Wt/WHBoxLayout.h>
|
||||
#include <Wt/WVBoxLayout.h>
|
||||
|
||||
#include <eedb/Session.hpp>
|
||||
#include <eedb/data/CategoriesModel.hpp>
|
||||
@ -26,15 +26,15 @@
|
||||
namespace eedb {
|
||||
|
||||
auto make_tree() {
|
||||
auto tree = new Wt::WTreeView();
|
||||
auto tree = std::make_unique< Wt::WTreeView >();
|
||||
|
||||
Wt::WAbstractItemModel * model = new eedb::CategoriesModel(tree);
|
||||
tree->setModel(model);
|
||||
auto model = std::unique_ptr<eedb::CategoriesModel>();
|
||||
tree->setModel(std::move(model));
|
||||
|
||||
tree->setColumnResizeEnabled(true);
|
||||
tree->setSortingEnabled(false);
|
||||
tree->setSelectionMode(Wt::SingleSelection);
|
||||
tree->setEditTriggers(Wt::WAbstractItemView::NoEditTrigger);
|
||||
tree->setSelectionMode(Wt::SelectionMode::Single);
|
||||
tree->setEditTriggers(Wt::EditTrigger::None);
|
||||
|
||||
return tree;
|
||||
}
|
||||
@ -45,25 +45,26 @@ eedb::DefaultHomePage::DefaultHomePage(Session & session, std::unique_ptr< eedb:
|
||||
DefaultHomePage::~DefaultHomePage() = default;
|
||||
|
||||
void DefaultHomePage::attachTo(Wt::WContainerWidget * container) {
|
||||
auto stackedWidget = new Wt::WStackedWidget();
|
||||
auto stackedWidget = std::make_unique<Wt::WStackedWidget>();
|
||||
|
||||
_navigationBar->attachTo(stackedWidget);
|
||||
_navigationBar->attachTo(stackedWidget.get());
|
||||
_navigationBar->registerLogoutAction([=]() { this->_session.login().logout(); });
|
||||
|
||||
Wt::WVBoxLayout * vbox = new Wt::WVBoxLayout();
|
||||
container->setLayout(vbox);
|
||||
vbox->addWidget(stackedWidget, 0);
|
||||
auto vbox = std::make_unique< Wt::WVBoxLayout >();
|
||||
container->setLayout(std::move(vbox));
|
||||
vbox->addWidget(std::move(stackedWidget), 0);
|
||||
|
||||
Wt::WHBoxLayout * hbox = new Wt::WHBoxLayout();
|
||||
vbox->addLayout(hbox, 10);
|
||||
auto hbox = std::unique_ptr<Wt::WHBoxLayout>();
|
||||
vbox->addLayout(std::move(hbox), 10);
|
||||
|
||||
Wt::WStackedWidget * contents = new Wt::WStackedWidget();
|
||||
auto contents = std::unique_ptr< Wt::WStackedWidget>();
|
||||
|
||||
_categoryTree = make_tree();
|
||||
_categoryTree->clicked().connect([=](auto...) { Wt::log("notice") << "Item selection changed"; });
|
||||
auto tree=make_tree();
|
||||
_categoryTree = tree.get();
|
||||
_categoryTree->clicked().connect([](Wt::WModelIndex, Wt::WMouseEvent) { Wt::log("notice") << "Item selection changed"; });
|
||||
|
||||
hbox->addWidget(_categoryTree, 1);
|
||||
hbox->addWidget(contents, 2);
|
||||
hbox->addWidget(std::move(tree), 1);
|
||||
hbox->addWidget(std::move(contents), 2);
|
||||
hbox->setResizable(0, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,20 +1,9 @@
|
||||
#include <eedb/widgets/DefaultNavigationBar.hpp>
|
||||
|
||||
#include <Wt/WMenu>
|
||||
#include <Wt/WNavigationBar>
|
||||
#include <Wt/WPopupMenu>
|
||||
#include <Wt/WStackedWidget>
|
||||
|
||||
namespace std {
|
||||
|
||||
template <>
|
||||
struct default_delete< Wt::WNavigationBar > {
|
||||
void operator()(Wt::WNavigationBar * ptr) {
|
||||
if(ptr && !ptr->parent())
|
||||
delete ptr;
|
||||
}
|
||||
};
|
||||
}
|
||||
#include <Wt/WMenu.h>
|
||||
#include <Wt/WNavigationBar.h>
|
||||
#include <Wt/WPopupMenu.h>
|
||||
#include <Wt/WStackedWidget.h>
|
||||
|
||||
namespace eedb {
|
||||
|
||||
@ -25,33 +14,34 @@ struct DefaultNavigationBar::DefaultNavigationBarPriv {
|
||||
return;
|
||||
|
||||
// Setup a Left-aligned menu.
|
||||
auto mainTabs = new Wt::WMenu();
|
||||
auto mainTabs = std::make_unique< Wt::WMenu >();
|
||||
auto homeItem = mainTabs->addItem("Home");
|
||||
homeItem->setObjectName("navigation_bar.home_menu");
|
||||
homeItem->triggered().connect([=](auto...) {});
|
||||
///FIXME
|
||||
// homeItem->triggered().connect([=](auto...) {});
|
||||
|
||||
// Setup a Right-aligned menu.
|
||||
// Create a popup submenu for the Help menu.
|
||||
auto sessionMenuPopup = new Wt::WPopupMenu();
|
||||
auto sessionMenuPopup = std::make_unique< Wt::WPopupMenu >();
|
||||
sessionMenuPopup->setObjectName("navigation_bar.session_menu_popup");
|
||||
|
||||
auto logoutItem = sessionMenuPopup->addItem("Logout");
|
||||
Wt::WMenuItem * logoutItem = sessionMenuPopup->addItem("Logout");
|
||||
logoutItem->setObjectName("navigation_bar.session_menu.logout");
|
||||
logoutItem->triggered().connect([=](auto...) { this->onLogin.emit(); });
|
||||
logoutItem->triggered().connect([=](Wt::WMenuItem *) { this->onLogin.emit(); });
|
||||
|
||||
auto sessionItem = new Wt::WMenuItem("Session");
|
||||
sessionItem->setMenu(sessionMenuPopup);
|
||||
auto sessionItem = std::make_unique< Wt::WMenuItem >("Session");
|
||||
sessionItem->setMenu(std::move(sessionMenuPopup));
|
||||
|
||||
auto sessionMenu = new Wt::WMenu();
|
||||
auto sessionMenu = std::make_unique< Wt::WMenu >();
|
||||
sessionMenu->setObjectName("navigation_bar.session_menu");
|
||||
sessionMenu->addItem(sessionItem);
|
||||
sessionMenu->addItem(std::move(sessionItem));
|
||||
|
||||
_bar = std::make_unique< Wt::WNavigationBar >();
|
||||
_bar->setObjectName("navigation_bar");
|
||||
_bar->setTitle("eedb", "http://eedb.pl");
|
||||
_bar->setResponsive(true);
|
||||
_bar->addMenu(mainTabs, Wt::AlignLeft);
|
||||
_bar->addMenu(sessionMenu, Wt::AlignRight);
|
||||
_bar->addMenu(std::move(mainTabs), Wt::AlignmentFlag::Left);
|
||||
_bar->addMenu(std::move(sessionMenu), Wt::AlignmentFlag::Right);
|
||||
}
|
||||
|
||||
Wt::Signal<> onLogin;
|
||||
@ -72,7 +62,7 @@ DefaultNavigationBar::~DefaultNavigationBar() = default;
|
||||
|
||||
void DefaultNavigationBar::attachTo(Wt::WContainerWidget * container) {
|
||||
_priv->create();
|
||||
container->addWidget(_priv->_bar.get());
|
||||
container->addWidget(std::move(_priv->_bar));
|
||||
}
|
||||
|
||||
void DefaultNavigationBar::detach() {
|
||||
@ -82,6 +72,6 @@ void DefaultNavigationBar::detach() {
|
||||
}
|
||||
|
||||
void DefaultNavigationBar::registerLogoutAction(std::function< void() > f) {
|
||||
_priv->onLogin.connect([f](auto...) { f(); });
|
||||
}
|
||||
_priv->onLogin.connect([f]() { f(); });
|
||||
}
|
||||
} // namespace eedb
|
||||
|
||||
@ -1,45 +1,42 @@
|
||||
#include "MenuTree.hpp"
|
||||
|
||||
#include <sqlpp11/postgresql/connection.h>
|
||||
#include <eedb/db/connection.hpp>
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
#include <eedb/model/auth_info.h>
|
||||
#include <eedb/model/category.h>
|
||||
#include <sqlpp11/postgresql/connection.h>
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
void eedb::MenuTree::createTree()
|
||||
{
|
||||
void eedb::MenuTree::createTree() {
|
||||
using namespace eedb::db;
|
||||
using namespace sqlpp;
|
||||
// using namespace sqlpp;
|
||||
|
||||
Wt::WTree *tree = new Wt::WTree();
|
||||
Wt::WTree * tree = new Wt::WTree();
|
||||
|
||||
tree->setSelectionMode(Wt::ExtendedSelection);
|
||||
tree->setSelectionMode(Wt::SelectionMode::Extended);
|
||||
|
||||
Wt::WIconPair *folderIcon
|
||||
= new Wt::WIconPair("icons/yellow-folder-closed.png",
|
||||
"icons/yellow-folder-open.png", false);
|
||||
auto folderIcon = std::make_unique< Wt::WIconPair >("icons/yellow-folder-closed.png", "icons/yellow-folder-open.png", false);
|
||||
|
||||
Wt::WTreeNode *node = new Wt::WTreeNode("Categories", folderIcon);
|
||||
auto node = std::make_unique< Wt::WTreeNode >("Categories", std::move(folderIcon));
|
||||
|
||||
tree->setTreeRoot(node);
|
||||
node->label()->setTextFormat(Wt::PlainText);
|
||||
node->setLoadPolicy(Wt::WTreeNode::NextLevelLoading);
|
||||
tree->setTreeRoot(std::move(node));
|
||||
node->label()->setTextFormat(Wt::TextFormat::Plain);
|
||||
node->setLoadPolicy(Wt::ContentLoading::Lazy);
|
||||
///FIXME
|
||||
// const eedb::category cat;
|
||||
|
||||
const eedb::category cat;
|
||||
// auto r = _db(sqlpp::select(sqlpp::all_of(cat)).from(cat).where(cat.parent_path < 'root'));
|
||||
|
||||
auto r = _db(sqlpp::select( sqlpp::all_of(cat) ).from(cat).where(cat.parent_path < 'root') );
|
||||
// for(const auto & row : r) {
|
||||
// node->addChildNode(new Wt::WTreeNode(row.Name));
|
||||
// }
|
||||
|
||||
for (const auto & row: r){\
|
||||
node->addChildNode(new Wt::WTreeNode(row.Name));
|
||||
}
|
||||
|
||||
// if (_db.is_open()){
|
||||
// auto sql = "SELECT * FROM category WHERE parent_path <@ 'root'";
|
||||
// nontransaction N(C);
|
||||
// result R( N.exec( sql ));
|
||||
|
||||
// for (auto r = R.begin(); r<R.end(); r++)
|
||||
// node->addChildNode(new Wt::WTreeNode(r[1].as<std::string>()));
|
||||
// if (_db.is_open()){
|
||||
// auto sql = "SELECT * FROM category WHERE parent_path <@ 'root'";
|
||||
// nontransaction N(C);
|
||||
// result R( N.exec( sql ));
|
||||
|
||||
// for (auto r = R.begin(); r<R.end(); r++)
|
||||
// node->addChildNode(new Wt::WTreeNode(r[1].as<std::string>()));
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <Wt/WIconPair>
|
||||
#include <Wt/WText>
|
||||
#include <Wt/WTree>
|
||||
#include <Wt/WTreeNode>
|
||||
#include <Wt/WIconPair.h>
|
||||
#include <Wt/WText.h>
|
||||
#include <Wt/WTree.h>
|
||||
#include <Wt/WTreeNode.h>
|
||||
|
||||
namespace eedb::db {
|
||||
class PgConnection;
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Wt {
|
||||
class WTheme;
|
||||
class WObject;
|
||||
}
|
||||
|
||||
namespace eedb {
|
||||
@ -13,7 +14,7 @@ class Theme {
|
||||
|
||||
virtual ~Theme();
|
||||
|
||||
virtual Wt::WTheme * create(Wt::WObject * parent) const = 0;
|
||||
virtual std::shared_ptr<Wt::WTheme> create() const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user