Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduced Sequence::Item class, to replace Frame in sequences #164

Merged
merged 8 commits into from
May 10, 2020
106 changes: 106 additions & 0 deletions src/libs/possumwood_sdk/datatypes/filenames.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#include "filenames.h"

#include <possumwood_sdk/app.h>

namespace possumwood {

Filenames::Filenames(std::initializer_list<std::string> extensions) : m_extensions(extensions) {
}

Filenames::Filenames(const Filenames& fn) : m_filenames(fn.m_filenames), m_extensions(fn.m_extensions) {
}

const std::vector<boost::filesystem::path> Filenames::filenames(bool makeAbsolute) const {
if(!makeAbsolute)
return m_filenames;
else {
auto result = m_filenames;
for(auto& f : result)
f = App::instance().expandPath(f);
std::sort(result.begin(), result.end());
return result;
}
}

bool Filenames::empty() const {
return m_filenames.empty();
}

void Filenames::addFilename(const boost::filesystem::path& filename) {
m_filenames.push_back(filename);
}

void Filenames::clear() {
m_filenames.clear();
}

const std::set<std::string>& Filenames::extensions() const {
return m_extensions;
}

Filenames& Filenames::operator = (const Filenames& fn) {
// only assign a value if the m_extension array is empty
// -> allows to keep the extensions list while allowing to change
// the filename value in the UI / serialization
if(m_extensions.empty())
m_extensions = fn.m_extensions;

m_filenames = fn.m_filenames;

return *this;
}

bool Filenames::operator == (const Filenames& fn) const {
return m_filenames == fn.m_filenames && m_extensions == fn.m_extensions;
}

bool Filenames::operator != (const Filenames& fn) const {
return m_filenames != fn.m_filenames || m_extensions != fn.m_extensions;
}

std::ostream& operator << (std::ostream& out, const Filenames& f) {
out << f.filenames().size() << " filename(s)" << std::endl;

for(auto& fi : f.filenames())
out << " - " << fi.string() << std::endl;

return out;
}

/////////////////

namespace {

void toJson(::possumwood::io::json& json, const Filenames& value) {
if(value.empty())
json = "";
else {
auto fn = value.filenames(false);
if(fn.size() == 1)
json = fn[0].string();
else {
for(auto& fff : fn)
json.push_back(fff.string());
}
}
}

void fromJson(const ::possumwood::io::json& json, Filenames& value) {
value.clear();

if(!json.empty()) {
if(json.is_string())
value.addFilename(json.get<std::string>());
else {
assert(json.is_array());
for(std::size_t i=0; i<json.size(); ++i)
value.addFilename(json[i].get<std::string>());
}
}
}

}

IO<Filenames> Traits<Filenames>::io(&toJson, &fromJson);

}
49 changes: 49 additions & 0 deletions src/libs/possumwood_sdk/datatypes/filenames.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#pragma once

#include <string>
#include <set>

#include <boost/filesystem/path.hpp>

#include <dependency_graph/data_traits.h>

#include "actions/io.h"
#include "actions/traits.h"

namespace possumwood {

class Filenames {
public:
Filenames(std::initializer_list<std::string> extensions = std::initializer_list<std::string>());

const std::vector<boost::filesystem::path> filenames(bool makeAbsolute = true) const;

bool empty() const;
void addFilename(const boost::filesystem::path& filename);
void clear();

const std::set<std::string>& extensions() const;

Filenames(const Filenames& fn);
Filenames& operator = (const Filenames& fn);

bool operator == (const Filenames& fn) const;
bool operator != (const Filenames& fn) const;

private:
std::vector<boost::filesystem::path> m_filenames;
std::set<std::string> m_extensions;
};

template<>
struct Traits<Filenames> {
static IO<Filenames> io;

static constexpr std::array<float, 3> colour() {
return std::array<float, 3>{{1, 1, 0.5}};
}
};

std::ostream& operator << (std::ostream& out, const Filenames& f);

}
106 changes: 106 additions & 0 deletions src/libs/possumwood_sdk/ui/filenames.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#include "filenames.h"

#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/predicate.hpp>

#include <QHBoxLayout>
#include <QStyle>
#include <QFileDialog>
#include <QAction>
#include <QApplication>
#include <QMainWindow>
#include <QSizePolicy>

#include <possumwood_sdk/app.h>

filenames_ui::filenames_ui() {
m_widget = new QWidget(NULL);

QHBoxLayout* layout = new QHBoxLayout(m_widget);
layout->setContentsMargins(0,0,0,0);

m_textEdit = new QTextEdit();

QSizePolicy sp = m_textEdit->sizePolicy();
sp.setVerticalPolicy(QSizePolicy::MinimumExpanding);
m_textEdit->setSizePolicy(sp);

m_textEdit->setLineWrapMode(QTextEdit::NoWrap);

layout->addWidget(m_textEdit, 1);

m_textEditConnection = QObject::connect(
m_textEdit,
&QTextEdit::textChanged,
[this]() -> void {
callValueChangedCallbacks();
}
);

m_browseButton = new QToolButton();
m_browseButton->setIcon(m_browseButton->style()->standardIcon(QStyle::SP_DialogOpenButton));
layout->addWidget(m_browseButton);

m_buttonConnection = QObject::connect(
m_browseButton,
&QToolButton::released,
[this]() -> void {
// starting directory
QStringList paths = m_textEdit->toPlainText().split('\n');
for(auto& p : paths)
p = possumwood::App::instance().expandPath(p.toStdString()).string().c_str();

QString parentPath = possumwood::App::instance().filename().parent_path().string().c_str();
if(paths.size() > 0)
parentPath = boost::filesystem::path(paths[0].toStdString()).parent_path().string().c_str();

// run the file dialog
paths = QFileDialog::getOpenFileNames(
possumwood::App::instance().mainWindow(),
"Select input files...",
parentPath,
boost::algorithm::join(m_value.extensions(), ";;").c_str()
);

for(auto& p : paths)
p = possumwood::App::instance().shrinkPath(p.toStdString()).string().c_str();

m_textEdit->setText(paths.join('\n'));
}
);
}

filenames_ui::~filenames_ui() {
QObject::disconnect(m_textEditConnection);
QObject::disconnect(m_buttonConnection);
}

void filenames_ui::get(possumwood::Filenames& value) const {
value.clear();

for(auto& s : m_textEdit->toPlainText().split('\n'))
value.addFilename(s.toStdString());
}

void filenames_ui::set(const possumwood::Filenames& value) {
m_value = value;

QString content;
for(auto& f : value.filenames())
content = content + (f.string() + "\n").c_str();
content = content.trimmed();

const bool bs = m_textEdit->blockSignals(true);
m_textEdit->setText(content);
m_textEdit->blockSignals(bs);
}

QWidget* filenames_ui::widget() {
return m_widget;
}

void filenames_ui::onFlagsChanged(unsigned flags) {
assert((!(flags & kOutput)) && "Filename should never be used as an output.");

m_browseButton->setDisabled(flags & kDisabled);
}
31 changes: 31 additions & 0 deletions src/libs/possumwood_sdk/ui/filenames.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include "datatypes/filenames.h"

#include <possumwood_sdk/properties/property.h>

#include <QTextEdit>
#include <QToolButton>

class filenames_ui : public possumwood::properties::property<possumwood::Filenames, filenames_ui> {
public:
filenames_ui();
virtual ~filenames_ui();

virtual void get(possumwood::Filenames& value) const override;
virtual void set(const possumwood::Filenames& value) override;

virtual QWidget* widget() override;

protected:
virtual void onFlagsChanged(unsigned flags) override;

private:
QWidget* m_widget;
QTextEdit* m_textEdit;
QToolButton* m_browseButton;

possumwood::Filenames m_value;

QMetaObject::Connection m_textEditConnection, m_buttonConnection;
};
Loading