(C++) WtSelectFileDialog
January 25, 2018 · View on GitHub
(C++) WtSelectFileDialog



WtSelectFileDialog is a Wt class to let a user select a file from the server. To let a user select a file from his/her computer, the Wt::WFileUpload class might be convenient.
TestSelectFileDialog is a tool to test the WtSelectFileDialog class.
Technical facts
./CppWtSelectFileDialog/CppWtSelectFileDialog.pri
INCLUDEPATH += \ ../../Classes/CppWtSelectFileDialog SOURCES += \ ../../Classes/CppWtSelectFileDialog/wtselectfiledialog.cpp HEADERS += \ ../../Classes/CppWtSelectFileDialog/wtselectfiledialog.h OTHER_FILES += \ ../../Classes/CppWtSelectFileDialog/Licence.txt
./CppWtSelectFileDialog/wtselectfiledialog.h
//--------------------------------------------------------------------------- /* WtSelectFileDialog, Wt dialog for selecting a file Copyright 2011-2015 Richel Bilderbeek This program 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. 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 General Public License along with this program.If not, see <http://www.gnu.org/licenses/>. */ //--------------------------------------------------------------------------- //From http://www.richelbilderbeek.nl/CppWtSelectFileDialog.htm //--------------------------------------------------------------------------- #ifndef WTSELECTFILEDIALOG_H #define WTSELECTFILEDIALOG_H #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" #pragma GCC diagnostic ignored "-Wunused-local-typedefs" #pragma GCC diagnostic ignored "-Wunused-but-set-variable" #include <boost/signals2.hpp> #include <Wt/WContainerWidget> #pragma GCC diagnostic pop namespace Wt { struct WLineEdit; struct WPushButton; struct WSelectionBox; } namespace ribi { ///WtSelectFileDialog is a Wt dialog to select a file struct WtSelectFileDialog : public Wt::WContainerWidget { WtSelectFileDialog(); WtSelectFileDialog(const WtSelectFileDialog&) = delete; WtSelectFileDialog& operator=(const WtSelectFileDialog&) = delete; virtual ~WtSelectFileDialog() {} ///Check the folder for files again void DoRefresh(); ///Get the path in which this class will look for files static const std::string& GetPath() { return m_path; } ///Get the currently selected file std::string GetSelectedFile() const; ///Get the version of this class static std::string GetVersion(); ///Get the version history of this class static std::vector<std::string> GetVersionHistory(); ///Set the regex filter filenames are selected for void SetFilter(const std::string& filename_filter); ///Set if the regex filter is readonly void SetFilterReadOnly(const bool readonly); ///Set the path in which this class will look for files static void SetPath(const std::string& path); ///The signal that is emitted when a file is selected boost::signals2::signal<void ()> m_signal_selected; protected: ///The path this dialog starts at static std::string m_path; ///The user interface of this class struct Ui { Ui(); Ui(const Ui&) = delete; Ui& operator=(const Ui&) = delete; Wt::WLineEdit * const m_edit_filter; Wt::WLabel * const m_label_filter; Wt::WSelectionBox * const m_selection_box; } m_ui; ///Get all the files in a folder //From http://www.richelbilderbeek.nl/CppGetFilesInFolder.htm //static std::vector<std::string> GetFilesInFolder(const std::string& folder); ///\brief ///The member function how to select files from a folder /// ///default behavior: select all files in the folder m_path that match the regex in m_edit_filter virtual std::vector<std::string> SelectFiles() const noexcept; ///\brief ///OnUpdateDialog updates the list of filenames in the m_selection_box /// ///OnUpdateDialog is called automatically when the selection filter is changed void OnUpdateDialog(); private: ///OnSelect is called when a client selected a file void OnSelect(); }; } //~namespace ribi #endif // WTSELECTFILEDIALOG_H
./CppWtSelectFileDialog/wtselectfiledialog.cpp
//--------------------------------------------------------------------------- /* WtSelectFileDialog, Wt dialog for selecting a file Copyright 2011-2015 Richel Bilderbeek This program 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. 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 General Public License along with this program.If not, see <http://www.gnu.org/licenses/>. */ //--------------------------------------------------------------------------- //From http://www.richelbilderbeek.nl/CppWtSelectFileDialog.htm //--------------------------------------------------------------------------- #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" #pragma GCC diagnostic ignored "-Wunused-local-typedefs" #pragma GCC diagnostic ignored "-Wunused-but-set-variable" #include "wtselectfiledialog.h" #include <boost/xpressive/xpressive.hpp> #include <Wt/WBreak> #include <Wt/WLabel> #include <Wt/WLineEdit> #include <Wt/WSelectionBox> #include "fileio.h" #include "trace.h" #pragma GCC diagnostic pop ///The path this dialog starts at std::string ribi::WtSelectFileDialog::m_path = ""; ribi::WtSelectFileDialog::Ui::Ui() : m_edit_filter(new Wt::WLineEdit(".*")), m_label_filter(new Wt::WLabel("File filter: ")), m_selection_box(new Wt::WSelectionBox) { } ribi::WtSelectFileDialog::WtSelectFileDialog() : m_signal_selected{}, m_ui{} { assert(!m_path.empty() && "Path must be set from argv[0]:" && "ribi::WtSelectFileDialog::SetPath(boost::filesystem::path(argv[0]).parent_path().string());"); clear(); setContentAlignment(Wt::AlignCenter); this->addWidget(m_ui.m_selection_box); this->addWidget(new Wt::WBreak); this->addWidget(m_ui.m_label_filter); this->addWidget(m_ui.m_edit_filter); m_ui.m_edit_filter->changed().connect(this, &ribi::WtSelectFileDialog::OnUpdateDialog); m_ui.m_edit_filter->enterPressed().connect(this, &ribi::WtSelectFileDialog::OnUpdateDialog); m_ui.m_edit_filter->keyWentUp().connect(this, &ribi::WtSelectFileDialog::OnUpdateDialog); m_ui.m_selection_box->activated().connect(this, &ribi::WtSelectFileDialog::OnSelect); m_ui.m_selection_box->clicked().connect(this, &ribi::WtSelectFileDialog::OnSelect); m_ui.m_selection_box->doubleClicked().connect(this, &ribi::WtSelectFileDialog::OnSelect); m_ui.m_selection_box->setSelectionMode(Wt::SingleSelection); m_ui.m_selection_box->resize(400,Wt::WLength::Auto); OnUpdateDialog(); } void ribi::WtSelectFileDialog::DoRefresh() { OnUpdateDialog(); } //const std::vector<std::string> ribi::WtSelectFileDialog::GetFilesInFolder(const std::string& folder) //{ // assert(!m_path.empty() && "Path must be set from argv[0]"); // return fileio::FileIo().GetFilesInFolder(m_path); //} std::string ribi::WtSelectFileDialog::GetSelectedFile() const { if (m_ui.m_selection_box->currentIndex() == -1) return std::string(); return m_ui.m_selection_box->itemText(m_ui.m_selection_box->currentIndex()).toUTF8(); } std::string ribi::WtSelectFileDialog::GetVersion() { return "1.5"; } std::vector<std::string> ribi::WtSelectFileDialog::GetVersionHistory() { return { "2011-07-01: version 1.0: initial version", "2011-07-01: version 1.1: added support for setting the regex filter", "2011-07-03: version 1.2: added support for setting the regex filter to readonly", "2011-07-15: version 1.3: added GetPath member function, removed \'Select\' Wt::WPushButton", "2011-10-16: version 1.4: put UI elements in Ui struct, added virtual SelectFiles member function (for Hometrainer)", "2011-10-24: version 1.5: added DoRefresh member function" }; } void ribi::WtSelectFileDialog::OnUpdateDialog() { m_ui.m_selection_box->clear(); const std::vector<std::string> v = SelectFiles(); for(const auto s: v) { m_ui.m_selection_box->addItem(s.c_str()); } } void ribi::WtSelectFileDialog::OnSelect() { if (m_ui.m_selection_box->currentIndex() == -1) return; m_signal_selected(); } std::vector<std::string> ribi::WtSelectFileDialog::SelectFiles() const noexcept { try { boost::xpressive::sregex::compile(m_ui.m_edit_filter->text().toUTF8()); } catch(boost::xpressive::regex_error& e) { return std::vector<std::string>(); } catch (...) { assert(!"Should not get here"); } //Get all filenames const std::vector<std::string> v = fileio::FileIo().GetFilesInFolder(m_path); //Create the regex for a correct text file const boost::xpressive::sregex txt_file_regex = boost::xpressive::sregex::compile(m_ui.m_edit_filter->text().toUTF8()); std::vector<std::string> w; //Copy_if(v.begin(),v.end(), // std::back_inserter(w), // boost::regex_match(boost::bind(boost::lambda::_1),txt_file_regex)); //Copy all filenames matching the regex in the resulting std::vector for(const auto s: v) { if (boost::xpressive::regex_match(s,txt_file_regex)) { w.push_back(s); } } std::sort(w.begin(),w.end()); return w; } void ribi::WtSelectFileDialog::SetFilter(const std::string& filename_filter) { m_ui.m_edit_filter->setText(filename_filter.c_str()); OnUpdateDialog(); } void ribi::WtSelectFileDialog::SetFilterReadOnly(const bool readonly) { m_ui.m_edit_filter->setReadOnly(readonly); } void ribi::WtSelectFileDialog::SetPath(const std::string& path) { m_path = path; }