diff --git a/.gitignore b/.gitignore deleted file mode 120000 index 913762c..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.hgignore \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ed8f8a7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,50 @@ +*.swp + +*.orig +*.org + +*.log + +*.so* +*.a +*.o +*.*~ + +build +debug +release + +DEBIAN +debian/files +*.deb +*.debhelper +*.substvars + +doc +doc-source + +usr +include + +examples/*.wt +examples/*.ex +examples/all.cpp +examples/all.cpp.in +examples/swfstore.cpp +locales-test.1 +Doxyfile +config.hpp + +locales-test/setup.py +locales-test/locales-test + +CMakeFiles +CMakeCache.txt +CMakeDoxygenDefaults.cmake +CMakeDoxyfile.in +Makefile +CTestTestfile.cmake +cmake_install.cmake +install_manifest.txt +CTestCostData.txt + diff --git a/.hgignore b/.hgignore index 2748f7d..6c39a37 100644 --- a/.hgignore +++ b/.hgignore @@ -13,6 +13,7 @@ syntax: glob *.so* *.a *.o +*.*~ build/ debug/ diff --git a/CMakeLists.txt b/CMakeLists.txt index cc42e5f..2bfd69d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,9 @@ set(SONAME 12) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) +# We need the deprecated binding boost::bind global placeholders +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBOOST_BIND_GLOBAL_PLACEHOLDERS") + set(local_include_dir ${PROJECT_BINARY_DIR}/include) set(local_headers_dir ${local_include_dir}/Wt/Wc) @@ -17,7 +20,7 @@ set(Boost_USE_STATIC_LIBS OFF CACHE BOOL "Use static boost libs") set(Boost_USE_MULTITHREADED ON CACHE BOOL "Use multithreaded boost libs") set(Boost_USE_STATIC_RUNTIME OFF CACHE BOOL "Use boost libs linked with static C++ standard library") -set(boost_libs filesystem thread signals system program_options) +set(boost_libs filesystem thread system program_options) find_package(Boost 1.42.0 COMPONENTS ${boost_libs} REQUIRED) set(WT_LIB_SUFFIX "" CACHE STRING "Wt lib suffix (empty or 'd')") diff --git a/INSTALL b/INSTALL index d6f290b..d54241d 100644 --- a/INSTALL +++ b/INSTALL @@ -2,8 +2,13 @@ wt-classes, utility classes used by Wt applications ------------------------------------------ Compile and install wt-classes library: -$ cmake . -$ make install + + $ cmake -B build -S . # create a cmake build directory under the + # top-level directory and configure it + $ cd build # move to the new build directory + $ make # build wt-classes + $ sudo make install # install as root user + Read about cmake for more information Dependencies: @@ -12,7 +17,6 @@ Dependencies: * libboost >= 1.42 * boost_filesystem (version 2 or 3) * boost_system - * boost_signals * boost_thread * boost_date_time * headers: @@ -26,6 +30,7 @@ Dependencies: * boost/format.hpp * boost/function.hpp * boost/shared_ptr.hpp + * boost/signals2.hpp Recommendations: * YUI library >= 2.8.0 for SWFStore diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 7d23bf0..df78e04 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -33,7 +33,11 @@ if(NOT WC_HAVE_PAGER) list(REMOVE_ITEM examples_sources ${CMAKE_CURRENT_SOURCE_DIR}/pager.cpp) endif() -include(FindPythonInterp) +if(NOT WC_HAVE_SPINBOX) + list(REMOVE_ITEM examples_sources ${CMAKE_CURRENT_SOURCE_DIR}/wnoref.cpp) +endif() + +include(FindPython3) list(REMOVE_DUPLICATES examples_sources) diff --git a/examples/filetreeexample.cpp b/examples/filetreeexample.cpp new file mode 100644 index 0000000..15d679b --- /dev/null +++ b/examples/filetreeexample.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium. + * + * See the LICENSE file for terms of use. + */ + +#include +#include +#include +#include + +#include "Wt/Wc/FileTreeTable.hpp" + +using namespace Wt; + +WApplication *createApplication(const WEnvironment& env) +{ + WApplication *app = new WApplication(env); + app->setTitle("File explorer example"); + app->useStyleSheet("filetree.css"); + + Wc::FileTreeTable *treeTable = new Wc::FileTreeTable("."); + treeTable->resize(500, 300); + treeTable->tree()->setSelectionMode(ExtendedSelection); + treeTable->treeRoot()->setNodeVisible(false); + treeTable->treeRoot()->setChildCountPolicy(WTreeNode::Enabled); + + app->root()->addWidget(treeTable); + + return app; +} + +int main(int argc, char **argv) +{ + return WRun(argc, argv, &createApplication); +} + diff --git a/examples/icons/document.png b/examples/icons/document.png new file mode 100644 index 0000000..208908a Binary files /dev/null and b/examples/icons/document.png differ diff --git a/examples/icons/yellow-folder-closed.png b/examples/icons/yellow-folder-closed.png new file mode 100644 index 0000000..0215874 Binary files /dev/null and b/examples/icons/yellow-folder-closed.png differ diff --git a/examples/icons/yellow-folder-open.png b/examples/icons/yellow-folder-open.png new file mode 100644 index 0000000..97ce9f8 Binary files /dev/null and b/examples/icons/yellow-folder-open.png differ diff --git a/examples/launch_filetree b/examples/launch_filetree new file mode 100755 index 0000000..ea89330 --- /dev/null +++ b/examples/launch_filetree @@ -0,0 +1,3 @@ +#!/bin/sh +./filetreeexample.wt --docroot=$PROJ_DIR/UI_Server/docroot \ +--http-address=0.0.0 --http-port=8080 diff --git a/examples/url-sitemap.cpp b/examples/url-sitemap.cpp index 4aeed68..9d99775 100644 --- a/examples/url-sitemap.cpp +++ b/examples/url-sitemap.cpp @@ -131,7 +131,7 @@ class UrlSitemapApp : public WApplication { new WText("Items:", contents_); for (int i = 0; i < 10; ++i) { new WBreak(contents_); - int id = abs(rr()); + int id = rr(); WAnchor* user = new WAnchor(contents_); user->setRefInternalPath(user_profile_->get_full_path(id)); user->setText(user_profile_->get_full_path(id)); diff --git a/examples/url.cpp b/examples/url.cpp index 62b38f7..ec414c3 100644 --- a/examples/url.cpp +++ b/examples/url.cpp @@ -84,7 +84,7 @@ class UrlApp : public WApplication { new WText("Items:", contents_); for (int i = 0; i < 10; ++i) { new WBreak(contents_); - int id = abs(rr()); + int id = rr(); WAnchor* user = new WAnchor(contents_); user->setRefInternalPath(user_profile_->get_full_path(id)); user->setText(user_profile_->get_full_path(id)); diff --git a/features/Features.cmake b/features/Features.cmake index 8498c73..c9394b4 100644 --- a/features/Features.cmake +++ b/features/Features.cmake @@ -2,7 +2,7 @@ include(CheckCXXSourceCompiles) include(FindOpenSSL) set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} - wt boost_filesystem boost_system boost_signals) + wt boost_filesystem boost_system) check_cxx_source_compiles("#include \n int main() { Wt::WLink l; }" WC_HAVE_WLINK) diff --git a/locales/CMakeLists.txt b/locales/CMakeLists.txt index 1fd10f6..54bcdd4 100644 --- a/locales/CMakeLists.txt +++ b/locales/CMakeLists.txt @@ -3,7 +3,7 @@ set(LOCALES_DIR ${WT_DIR}/Wc/locales CACHE PATH "L9N XML installation dir") install(DIRECTORY ./ DESTINATION ${LOCALES_DIR} FILES_MATCHING PATTERN "*.xml") -include(FindPythonInterp) +include(FindPython3) if(PYTHONINTERP_FOUND) execute_process(COMMAND ${PYTHON_EXECUTABLE} diff --git a/src/EtagStore.cpp b/src/EtagStore.cpp index d7f7324..ec06fd4 100644 --- a/src/EtagStore.cpp +++ b/src/EtagStore.cpp @@ -27,7 +27,7 @@ EtagStoreResource::EtagStoreResource(const std::string& cookie_name, setDispositionType(WResource::Inline); } -static const char EMPTY_GIF[] = { +static const unsigned char EMPTY_GIF[] = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00, 0x80, 0x00, 0x00, 0xdb, 0xdf, 0xef, 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, @@ -42,7 +42,8 @@ void EtagStoreResource::handleRequest(const Http::Request& request, handle_etag(request, response); response.setMimeType("image/gif"); response.addHeader("Content-Length", TO_S(EMPTY_GIF_SIZE)); - response.out().write(EMPTY_GIF, EMPTY_GIF_SIZE); + response.out().write( reinterpret_cast(EMPTY_GIF), +EMPTY_GIF_SIZE); } void EtagStoreResource::handle_etag(const Http::Request& request, diff --git a/src/FileTreeTable.cpp b/src/FileTreeTable.cpp new file mode 100644 index 0000000..4e008ce --- /dev/null +++ b/src/FileTreeTable.cpp @@ -0,0 +1,34 @@ +// This may look like C code, but it's really -*- C++ -*- +/* + * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium. + * + * See the LICENSE file for terms of use. + */ + +#include "FileTreeTable.hpp" +#include "FileTreeTableNode.hpp" + +#include + +namespace Wt { +namespace Wc { + + + FileTreeTable::FileTreeTable(const boost::filesystem::path& path, + const std::string &suffix, + WContainerWidget *parent) + : WTreeTable(parent) +{ + addColumn("Size", 80); + addColumn("Modified", 110); + + header(1)->setStyleClass("fsize"); + header(2)->setStyleClass("date"); + + setTreeRoot(new FileTreeTableNode(path, suffix), "File"); + + treeRoot()->setImagePack("icons/"); + treeRoot()->expand(); +} +} +} diff --git a/src/FileTreeTable.hpp b/src/FileTreeTable.hpp new file mode 100644 index 0000000..9fd8f2e --- /dev/null +++ b/src/FileTreeTable.hpp @@ -0,0 +1,56 @@ +// This may look like C code, but it's really -*- C++ -*- +/* + * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium. + * + * See the LICENSE file for terms of use. + */ +#ifndef FILETREETABLE_H_ +#define FILETREETABLE_H_ + +#include +#include +#include +#include + +#include +namespace Wt { +namespace Wc { + +/** + * \defgroup FileTreeTable widget that displays a file system tree + */ +/*@{*/ + +/*! \brief A tree table that displays a file tree. + * + * The table allows one to browse a path, and all its subdirectories, + * using a tree table. In addition to the file name, it shows file size + * and modification date. + * + * The table use FileTreeTableNode objects to display the actual content + * of the table. + * + * The tree table uses the LazyLoading strategy of WTreeNode to dynamically + * load contents for the tree. + * + * This widget was adapted from the %Wt File Explorer example. + */ +class FileTreeTable : public Wt::WTreeTable +{ +public: + /*! \brief Construct a new FileTreeTable. + * + * Create a new FileTreeTable to browse the given path. + * \param path directory to display + * \param suffix if non-empty, only display files with this suffix + * \param parent optional Parent widget + */ + FileTreeTable(const boost::filesystem::path& path, const std::string &suffix="", + Wt::WContainerWidget *parent=0); +}; +} +} + +/*@}*/ + +#endif // FILETREETABLE_H_ diff --git a/src/FileTreeTableNode.cpp b/src/FileTreeTableNode.cpp new file mode 100644 index 0000000..5d5e8b8 --- /dev/null +++ b/src/FileTreeTableNode.cpp @@ -0,0 +1,111 @@ +// This may look like C code, but it's really -*- C++ -*- +/* + * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium. + * + * See the LICENSE file for terms of use. + */ + +#include "FileTreeTableNode.hpp" + +#include +#include +#include +#include + +#include +#include +#include + +namespace Wt { +namespace Wc { + +FileTreeTableNode::FileTreeTableNode(const boost::filesystem::path& path, + const std::string &suffix) +#if BOOST_FILESYSTEM_VERSION < 3 +#ifndef WT_NO_STD_WSTRING + : WTreeTableNode(Wt::widen(path.leaf()), createIcon(path)), +#else + : WTreeTableNode(path.leaf(), createIcon(path)), +#endif +#else + : WTreeTableNode(path.leaf().string(), createIcon(path)), +#endif + path_(path) ,suffix_(suffix) +{ + label()->setTextFormat(PlainText); + + if (boost::filesystem::exists(path)) { + if (!boost::filesystem::is_directory(path)) { + int fsize = (int)boost::filesystem::file_size(path); + setColumnWidget(1, new WText(boost::lexical_cast(fsize))); + columnWidget(1)->setStyleClass("fsize"); + } else + setSelectable(false); + + std::time_t t = boost::filesystem::last_write_time(path); + struct tm ttm; +#if WIN32 + ttm=*localtime(&t); +#else + localtime_r(&t, &ttm); +#endif + + char c[100]; + strftime(c, 100, "%b %d %Y", &ttm); + + setColumnWidget(2, new WText(c)); + columnWidget(2)->setStyleClass("date"); + } +} + +WIconPair *FileTreeTableNode::createIcon(const boost::filesystem::path& path) +{ + if (boost::filesystem::exists(path) + && boost::filesystem::is_directory(path)) + return new WIconPair("icons/yellow-folder-closed.png", + "icons/yellow-folder-open.png", false); + else + return new WIconPair("icons/document.png", + "icons/yellow-folder-open.png", false); +} + +void FileTreeTableNode::populate() +{ + if (boost::filesystem::is_directory(path_)) { + std::set paths; + boost::filesystem::directory_iterator end_itr; + + for (boost::filesystem::directory_iterator i(path_); i != end_itr; ++i) + try { +#ifdef NOTDEF + std::cerr << "path = " << i->path().filename() << std::endl << + "\textension = " << boost::filesystem::extension(i->path().filename()) + << std::endl; +#endif + if ( (suffix_ == "") || + boost::filesystem::extension(i->path().filename()) == suffix_ ) { + paths.insert(*i); + } + } catch (boost::filesystem::filesystem_error& e) { + std::cerr << e.what() << std::endl; + } + + for (std::set::iterator i = paths.begin(); + i != paths.end(); ++i) + try { + addChildNode(new FileTreeTableNode(*i)); + } catch (boost::filesystem::filesystem_error& e) { + std::cerr << e.what() << std::endl; + } + } +} + +bool FileTreeTableNode::expandable() +{ + if (!populated()) { + return boost::filesystem::is_directory(path_); + } else + return WTreeTableNode::expandable(); +} +} +} diff --git a/src/FileTreeTableNode.hpp b/src/FileTreeTableNode.hpp new file mode 100644 index 0000000..2a6168b --- /dev/null +++ b/src/FileTreeTableNode.hpp @@ -0,0 +1,63 @@ +// This may look like C code, but it's really -*- C++ -*- +/* + * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium. + * + * See the LICENSE file for terms of use. + */ +#ifndef FILETREETABLENODE_H_ +#define FILETREETABLENODE_H_ + +#include + +#include +namespace Wt { +namespace Wc { +/** + * @addtogroup fileexplorer + */ +/*@{*/ + +/*! \brief A single node in a file tree table. + * + * The node manages the details about one file, and if the file is a + * directory, populates a subtree with nodes for every directory item. + * + * If a non-empty suffix is passed, only files with that suffix are displayed + * + * The tree node reimplements Wt::WTreeTableNode::populate() to populate + * a directory node only when the node is expanded. In this way, only + * directories that are actually browsed are loaded from disk. + */ +class FileTreeTableNode : public Wt::WTreeTableNode +{ +public: + /*! \brief Construct a new node for the given file. + * \param path directory to display + * \param suffix if non-empty, only display files with this suffix + */ + FileTreeTableNode(const boost::filesystem::path& path, + + const std::string &suffix=""); + +private: + //! The path. + boost::filesystem::path path_; + + //! The suffix + const std::string& suffix_; + + //! Reimplements WTreeNode::populate to read files within a directory. + virtual void populate(); + + //! Reimplements WTreeNode::expandable + virtual bool expandable(); + + //! Create the iconpair for representing the path. + static Wt::WIconPair *createIcon(const boost::filesystem::path& path); +}; +} +} + +/*@}*/ + +#endif // FILETREETABLENODE_H_ diff --git a/src/MapImage.cpp b/src/MapImage.cpp index 2221a12..7d86d84 100644 --- a/src/MapImage.cpp +++ b/src/MapImage.cpp @@ -79,15 +79,15 @@ class MapResource : public WResource { WApplication* app_; }; -void emit_clicked(MapImage::ClickSignal* signal, WMouseEvent& event) { - signal->emit(event.widget()); +void emit_clicked(MapImage::ClickSignal& signal, const WMouseEvent& event) { + signal.emit(event.widget()); } MapImage::MapImage(WImage* image, WContainerWidget* parent): WCompositeWidget(parent) { if (wApp->environment().ajax()) { setImplementation(image); - image->clicked().connect(boost::bind(emit_clicked, &clicked_, _1)); + image->clicked().connect(boost::bind(emit_clicked, boost::ref(clicked_), _1)); } else { std::string url = wApp->bookmarkUrl(); char join = url.find('?') == std::string::npos ? '?' : '&'; diff --git a/src/TimeDuration.cpp b/src/TimeDuration.cpp index 09665f0..48b1f09 100644 --- a/src/TimeDuration.cpp +++ b/src/TimeDuration.cpp @@ -44,7 +44,7 @@ TimeDuration TimeDuration::operator -() const { } TimeDuration TimeDuration::operator /(const double& b) const { - return ptime::milliseconds(double(total_milliseconds()) / b); + return ptime::milliseconds(long(total_milliseconds() / b)); } TimeDuration TimeDuration::operator /(int b) const { @@ -52,7 +52,7 @@ TimeDuration TimeDuration::operator /(int b) const { } TimeDuration TimeDuration::operator *(const double& b) const { - return ptime::milliseconds(double(total_milliseconds()) * b); + return ptime::milliseconds(long(total_milliseconds() * b)); } TimeDuration TimeDuration::operator *(int b) const { diff --git a/src/util.cpp b/src/util.cpp index e07a996..2971148 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -382,7 +382,7 @@ void schedule_action(const td::TimeDuration& wait, WIOService& io = WServer::instance()->ioService(); io.schedule(ms, func); #else - TimerPtr timer = boost::make_shared(boost::ref(wc_io.io), wait); + TimerPtr timer = boost::make_shared(wc_io.io, wait); timer->async_wait(boost::bind(handle_timeout, timer, func, boost::asio::placeholders::error)); #endif @@ -588,6 +588,7 @@ bool stop_ioservice(WServer& server) { #ifdef WC_HAVE_WIOSERVICE server.ioService().boost::asio::io_service::stop(); #endif + return 0; } int wrun_stop_ioservice(int argc, char** argv, ApplicationCreator creator) {