Skip to content

Commit

Permalink
Merge pull request #37 from Tom94/regex
Browse files Browse the repository at this point in the history
Add regex toggle for more advanced image filtering
  • Loading branch information
Tom94 authored Mar 12, 2018
2 parents 8dd6a48 + 2965720 commit b128755
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 29 deletions.
2 changes: 1 addition & 1 deletion include/tev/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ std::string toUpper(std::string str);

bool endsWith(const std::string& str, const std::string& ending);

bool matches(std::string text, std::string filter);
bool matches(std::string text, std::string filter, bool isRegex);

void drawTextWithShadow(NVGcontext* ctx, float x, float y, std::string text, float shadowAlpha = 1.0f);

Expand Down
4 changes: 4 additions & 0 deletions include/tev/ImageViewer.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ class ImageViewer : public nanogui::Screen {
void resizeToFitAllImages();
bool setFilter(const std::string& filter);

bool useRegex();
void setUseRegex(bool value);

void maximize();
bool isMaximized();
void toggleMaximized();
Expand Down Expand Up @@ -168,6 +171,7 @@ class ImageViewer : public nanogui::Screen {
MultiGraph* mHistogram;

nanogui::TextBox* mFilter;
nanogui::Button* mRegexButton;

// Buttons which require a current image to be meaningful.
std::vector<nanogui::Button*> mCurrentImageButtons;
Expand Down
50 changes: 32 additions & 18 deletions src/Common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <algorithm>
#include <cctype>
#include <map>
#include <regex>

#ifdef _WIN32
# include <Shlobj.h>
Expand Down Expand Up @@ -52,31 +53,44 @@ bool endsWith(const string& str, const string& ending) {
return str.rfind(ending) == str.length() - ending.length();
}

bool matches(string text, string filter) {
if (filter.empty()) {
return true;
}
bool matches(string text, string filter, bool isRegex) {
auto matchesFuzzy = [](string text, string filter) {
if (filter.empty()) {
return true;
}

// Perform matching on lowercase strings
text = toLower(text);
filter = toLower(filter);
// Perform matching on lowercase strings
text = toLower(text);
filter = toLower(filter);

auto words = split(filter, ", ");
// We don't want people entering multiple spaces in a row to match everything.
words.erase(remove(begin(words), end(words), ""), end(words));
auto words = split(filter, ", ");
// We don't want people entering multiple spaces in a row to match everything.
words.erase(remove(begin(words), end(words), ""), end(words));

if (words.empty()) {
return true;
}
if (words.empty()) {
return true;
}

// Match every word of the filter separately.
for (const auto& word : words) {
if (text.find(word) != string::npos) {
// Match every word of the filter separately.
for (const auto& word : words) {
if (text.find(word) != string::npos) {
return true;
}
}

return false;
};

auto matchesRegex = [](string text, string filter) {
if (filter.empty()) {
return true;
}
}

return false;
regex searchRegex{filter, std::regex_constants::ECMAScript | std::regex_constants::icase};
return regex_search(text, searchRegex);
};

return isRegex ? matchesRegex(text, filter) : matchesFuzzy(text, filter);
}

void drawTextWithShadow(NVGcontext* ctx, float x, float y, string text, float shadowAlpha) {
Expand Down
6 changes: 3 additions & 3 deletions src/Image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ void Image::readStbi() {

for (auto& channel : channels) {
string name = channel.name();
if (matches(name, mChannelSelector)) {
if (matches(name, mChannelSelector, false)) {
mChannels.emplace(move(name), move(channel));
}
}
Expand Down Expand Up @@ -238,7 +238,7 @@ void Image::readExr() {
const Imf::ChannelList& imfChannels = part.header().channels();

for (Imf::ChannelList::ConstIterator c = imfChannels.begin(); c != imfChannels.end(); ++c) {
if (matches(c.name(), mChannelSelector)) {
if (matches(c.name(), mChannelSelector, false)) {
partIdx = i;
goto l_foundPart;
}
Expand Down Expand Up @@ -326,7 +326,7 @@ void Image::readExr() {
set<string> layerNames;

for (Imf::ChannelList::ConstIterator c = imfChannels.begin(); c != imfChannels.end(); ++c) {
if (matches(c.name(), mChannelSelector)) {
if (matches(c.name(), mChannelSelector, false)) {
rawChannels.emplace_back(c.name(), c.channel().type);
layerNames.insert(Channel::head(c.name()));
}
Expand Down
33 changes: 26 additions & 7 deletions src/ImageViewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ ImageViewer::ImageViewer(shared_ptr<Ipc> ipc, shared_ptr<SharedQueue<ImageAdditi
// Fuzzy filter of open images
{
panel = new Widget{mSidebarLayout};
panel->setLayout(new BoxLayout{Orientation::Vertical, Alignment::Fill, 5});
panel->setLayout(new GridLayout{Orientation::Horizontal, 2, Alignment::Fill, 5, 2});

mFilter = new TextBox{panel, ""};
mFilter->setEditable(true);
Expand All @@ -267,14 +267,23 @@ ImageViewer::ImageViewer(shared_ptr<Ipc> ipc, shared_ptr<SharedQueue<ImageAdditi
return setFilter(filter);
});

mFilter->setPlaceholder("Enter text to filter images");
mFilter->setPlaceholder("Find");
mFilter->setTooltip(tfm::format(
"Filters visible images and layers according to a supplied string. "
"The string must have the format 'image:layer'. "
"Only images whose name contains 'image' and layers whose name contains 'layer' will be visible.\n\n"
"Keyboard shortcut:\n%s+P",
HelpWindow::COMMAND
));

mRegexButton = new Button{panel, "", ENTYPO_ICON_SEARCH};
mRegexButton->setTooltip("Treat filter as regular expression");
mRegexButton->setPushed(false);
mRegexButton->setFlags(Button::ToggleButton);
mRegexButton->setFontSize(15);
mRegexButton->setChangeCallback([this](bool value) {
setUseRegex(value);
});
}

// Playback controls
Expand Down Expand Up @@ -1136,6 +1145,15 @@ bool ImageViewer::setFilter(const string& filter) {
return true;
}

bool ImageViewer::useRegex() {
return mRegexButton->pushed();
}

void ImageViewer::setUseRegex(bool value) {
mRegexButton->setPushed(value);
mRequiresFilterUpdate = true;
}

void ImageViewer::maximize() {
glfwMaximizeWindow(mGLFWWindow);
}
Expand Down Expand Up @@ -1270,11 +1288,11 @@ void ImageViewer::updateFilter() {
// This is the case if the image name matches the image part
// and at least one of the image's layers matches the layer part.
auto doesImageMatch = [&](const shared_ptr<Image>& image) {
bool doesMatch = matches(image->name(), imagePart);
bool doesMatch = matches(image->name(), imagePart, useRegex());
if (doesMatch) {
bool anyLayersMatch = false;
for (const auto& layer : image->layers()) {
if (matches(layer, layerPart)) {
if (matches(layer, layerPart, useRegex())) {
anyLayersMatch = true;
break;
}
Expand Down Expand Up @@ -1350,7 +1368,7 @@ void ImageViewer::updateFilter() {
selectImage(nthVisibleImage(0));
}

if (mCurrentReference && !matches(mCurrentReference->name(), imagePart)) {
if (mCurrentReference && !matches(mCurrentReference->name(), imagePart, useRegex())) {
selectReference(nullptr);
}
}
Expand All @@ -1362,13 +1380,13 @@ void ImageViewer::updateFilter() {
const auto& buttons = mLayerButtonContainer->children();
for (Widget* button : buttons) {
ImageButton* ib = dynamic_cast<ImageButton*>(button);
ib->setVisible(matches(ib->caption(), layerPart));
ib->setVisible(matches(ib->caption(), layerPart, useRegex()));
if (ib->visible()) {
ib->setId(id++);
}
}

if (!matches(mCurrentLayer, layerPart)) {
if (!matches(mCurrentLayer, layerPart, useRegex())) {
selectLayer(nthVisibleLayer(0));
}
}
Expand All @@ -1383,6 +1401,7 @@ void ImageViewer::updateLayout() {
mSidebar->setFixedHeight(mSize.y() - footerHeight);

mHelpButton->setPosition(Vector2i{mSidebar->fixedWidth() - 38, 5});
mFilter->setFixedWidth(mSidebar->fixedWidth() - 50);
mSidebarLayout->setFixedWidth(mSidebar->fixedWidth());

mVerticalScreenSplit->setFixedSize(mSize);
Expand Down

0 comments on commit b128755

Please sign in to comment.