Skip to content

Commit

Permalink
Add saving and changing commit log filters
Browse files Browse the repository at this point in the history
  • Loading branch information
ArekPiekarz committed Aug 9, 2022
1 parent cebf8d4 commit 0302c5e
Show file tree
Hide file tree
Showing 16 changed files with 653 additions and 49 deletions.
9 changes: 4 additions & 5 deletions src/commit_log_author_filter_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl CommitLogAuthorFilterEntry
{
let widget = guiElementProvider.get::<gtk::Entry>("Commit log author filter entry");
let cssProvider = setupCss(&widget);
connectWidget(&widget, sender.clone());
connectEntry(&widget, sender.clone());
setupCaseSensitivityButton(guiElementProvider, sender.clone());
setupRegexButton(guiElementProvider, sender);
Self{widget, cssProvider}
Expand All @@ -65,12 +65,11 @@ fn setupCss<WidgetType>(widget: &WidgetType) -> gtk::CssProvider
cssProvider
}

fn connectWidget(widget: &gtk::Entry, sender: Sender)
fn connectEntry(entry: &gtk::Entry, sender: Sender)
{
widget.connect_changed(move |widget| {
sender.send((Source::CommitLogAuthorFilterEntry, Event::TextEntered(widget.text().into()))).unwrap();
entry.connect_changed(move |entry| {
sender.send((Source::CommitLogAuthorFilterEntry, Event::TextEntered(entry.text().into()))).unwrap();
});

}

fn setupCaseSensitivityButton(guiElementProvider: &GuiElementProvider, sender: Sender)
Expand Down
162 changes: 162 additions & 0 deletions src/commit_log_filters.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
use crate::config::{AuthorFilter, CommitLogFilter, Config};
use crate::event::{Event, FilterIndex, handleUnknown, IEventHandler, Sender, Source};

use itertools::Itertools;


pub(crate) struct CommitLogFilters
{
currentFilter: CurrentFilter,
filters: Vec<CommitLogFilter>,
sender: Sender
}

impl IEventHandler for CommitLogFilters
{
fn handle(&mut self, source: Source, event: &Event)
{
use Source as S;
use Event as E;
match (source, event) {
(S::CommitLogAuthorFilterCaseButton, E::Toggled(isEnabled)) => self.onCaseButtonToggled(*isEnabled),
(S::CommitLogAuthorFilterRegexButton, E::Toggled(isEnabled)) => self.onRegexButtonToggled(*isEnabled),
(_, E::ActiveFilterChosen(index)) => self.onActiveFilterChosen(*index),
(_, E::FilterNameChosen(name)) => self.onFilterNameChosen(name),
(_, E::TextEntered(text)) => self.onTextEntered(text),
_ => handleUnknown(source, event)
}
}
}

impl CommitLogFilters
{
pub fn new(config: &Config, sender: Sender) -> Self
{
let newSelf = Self{
currentFilter: CurrentFilter::new(config.commitLogFilters.active),
filters: config.commitLogFilters.filters.clone(),
sender
};
newSelf.notifyActiveFilterSwitched();
newSelf
}

fn onActiveFilterChosen(&mut self, index: usize)
{
if self.currentFilter.index == index {
return;
}
self.currentFilter = CurrentFilter::new(index);
self.notifyActiveFilterSwitched();
self.notifyFiltersUpdated();
}

fn onCaseButtonToggled(&mut self, isEnabled: bool)
{
if self.filters[self.currentFilter.index].authorFilter.caseSensitive == isEnabled {
self.currentFilter.authorFilterChanges.caseSensitive = None;
} else {
self.currentFilter.authorFilterChanges.caseSensitive = Some(isEnabled);
}
}

fn onRegexButtonToggled(&mut self, isEnabled: bool)
{
if self.filters[self.currentFilter.index].authorFilter.usesRegex == isEnabled {
self.currentFilter.authorFilterChanges.usesRegex = None;
} else {
self.currentFilter.authorFilterChanges.usesRegex = Some(isEnabled);
}
}

fn onFilterNameChosen(&mut self, name: &str)
{
match self.filters.iter().find_position(|filter| filter.name == name)
{
Some((_index, _filter)) => unimplemented!(),
None => {
self.addFilter(name);
self.notifyFilterAdded(name);
self.notifyFiltersUpdated();
}
}
}

fn onTextEntered(&mut self, text: &str)
{
if self.filters[self.currentFilter.index].authorFilter.pattern == text {
self.currentFilter.authorFilterChanges.pattern = None;
} else {
self.currentFilter.authorFilterChanges.pattern = Some(text.into());
}
}

fn addFilter(&mut self, name: &str)
{
let newFilter = CommitLogFilter{name: name.into(), authorFilter: self.mergeOriginalAndChangedFilter()};
self.filters.push(newFilter);
self.currentFilter = CurrentFilter::new(self.filters.len()-1);
}

fn mergeOriginalAndChangedFilter(&self) -> AuthorFilter
{
let baseFilter = &self.filters[self.currentFilter.index].authorFilter;
let authorFilterChanges = &self.currentFilter.authorFilterChanges;
AuthorFilter{
pattern: authorFilterChanges.pattern.as_ref().unwrap_or(&baseFilter.pattern).into(),
caseSensitive: authorFilterChanges.caseSensitive.unwrap_or(baseFilter.caseSensitive),
usesRegex: authorFilterChanges.usesRegex.unwrap_or(baseFilter.usesRegex)
}
}

fn notifyFilterAdded(&self, name: &str)
{
self.sender.send((Source::CommitLogFilters, Event::FilterAdded(name.into()))).unwrap();
}

fn notifyFiltersUpdated(&self)
{
self.sender.send((
Source::CommitLogFilters,
Event::FiltersUpdated(
crate::config::CommitLogFilters{active: self.currentFilter.index, filters: self.filters.clone()})))
.unwrap();
}

fn notifyActiveFilterSwitched(&self)
{
self.sender.send((
Source::CommitLogFilters,
Event::ActiveFilterSwitched(self.filters[self.currentFilter.index].authorFilter.clone())))
.unwrap();
}
}

struct CurrentFilter
{
index: usize,
authorFilterChanges: AuthorFilterChanges
}

impl CurrentFilter
{
fn new(index: FilterIndex) -> Self
{
Self{index, authorFilterChanges: AuthorFilterChanges::new()}
}
}

struct AuthorFilterChanges
{
pattern: Option<String>,
caseSensitive: Option<bool>,
usesRegex: Option<bool>
}

impl AuthorFilterChanges
{
fn new() -> Self
{
Self{pattern: None, caseSensitive: None, usesRegex: None}
}
}
56 changes: 56 additions & 0 deletions src/commit_log_filters_combo_box.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use crate::config::Config;
use crate::event::{Event, handleUnknown, IEventHandler, Sender, Source};
use crate::gui_element_provider::GuiElementProvider;

use gtk::prelude::ComboBoxExtManual;
use gtk::traits::{ComboBoxExt, ComboBoxTextExt};
use itertools::Itertools;
use to_trait::To;


pub(crate) struct CommitLogFiltersComboBox
{
widget: gtk::ComboBoxText,
filterNames: Vec<String>
}

impl IEventHandler for CommitLogFiltersComboBox
{
fn handle(&mut self, source: Source, event: &Event)
{
match event {
Event::FilterAdded(name) => self.onFilterAdded(name),
_ => handleUnknown(source, event)
}
}
}

impl CommitLogFiltersComboBox
{
pub fn new(guiElementProvider: &GuiElementProvider, config: &Config, sender: Sender) -> Self
{
let widget = guiElementProvider.get::<gtk::ComboBoxText>("Commit log filters combo box text");
let activeFilter = config.commitLogFilters.active;
let filterNames = config.commitLogFilters.filters.iter().map(|filter| filter.name.clone()).collect_vec();
for name in &filterNames {
widget.append_text(name);
}
widget.connect_changed(
move |comboBox|
if let Some(index) = comboBox.active() {
sender.send((
Source::CommitLogFiltersComboBox,
Event::ActiveFilterChosen(index.try_into().unwrap())))
.unwrap();
});
widget.set_active(Some(activeFilter.try_into().unwrap()));
Self{widget, filterNames}
}

fn onFilterAdded(&mut self, name: &str)
{
self.filterNames.push(name.into());
self.widget.append_text(name);
self.widget.set_active(Some(self.filterNames.len().try_to::<u32>().unwrap()-1))
}
}
27 changes: 21 additions & 6 deletions src/commit_log_filters_view.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
use crate::config::AuthorFilter;
use crate::event::{Event, handleUnknown, IEventHandler, Source};
use crate::gui_element_provider::GuiElementProvider;

use gtk::traits::WidgetExt;
use gtk::traits::{EntryExt, ToggleButtonExt, WidgetExt};


pub(crate) struct CommitLogFiltersView
{
widget: gtk::Grid
grid: gtk::Grid,
entry: gtk::Entry,
caseButton: gtk::ToggleButton,
regexButton: gtk::ToggleButton,
}

impl IEventHandler for CommitLogFiltersView
{
fn handle(&mut self, source: Source, event: &Event)
{
match event {
Event::Toggled(isEnabled) => self.onToggled(*isEnabled),
Event::ActiveFilterSwitched(filter) => self.onActiveFilterSwitched(filter),
Event::Toggled(isEnabled) => self.onToggled(*isEnabled),
_ => handleUnknown(source, event)
}
}
Expand All @@ -24,12 +29,22 @@ impl CommitLogFiltersView
{
pub(crate) fn new(guiElementProvider: &GuiElementProvider) -> Self
{
let widget = guiElementProvider.get::<gtk::Grid>("Commit log filters grid");
Self{widget}
let grid = guiElementProvider.get::<gtk::Grid>("Commit log filters grid");
let entry = guiElementProvider.get::<gtk::Entry>("Commit log author filter entry");
let caseButton = guiElementProvider.get::<gtk::ToggleButton>("Commit log author filter case button");
let regexButton = guiElementProvider.get::<gtk::ToggleButton>("Commit log author filter regex button");
Self{grid, entry, caseButton, regexButton}
}

fn onActiveFilterSwitched(&self, filter: &AuthorFilter)
{
self.entry.set_text(&filter.pattern);
self.caseButton.set_active(filter.caseSensitive);
self.regexButton.set_active(filter.usesRegex);
}

fn onToggled(&self, isEnabled: bool)
{
self.widget.set_visible(isEnabled);
self.grid.set_visible(isEnabled);
}
}
12 changes: 12 additions & 0 deletions src/commit_log_save_filter_button.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use crate::event::{Event, Sender, Source};
use crate::gui_element_provider::GuiElementProvider;

use gtk::traits::ToolButtonExt;


pub(crate) fn setupCommitLogSaveFilterButton(guiElementProvider: &GuiElementProvider, sender: Sender)
{
let button = guiElementProvider.get::<gtk::ToolButton>("Commit log save filter button");
button.connect_clicked(
move |_button| sender.send((Source::CommitLogSaveFilterButton, Event::OpenDialogRequested)).unwrap());
}
Loading

0 comments on commit 0302c5e

Please sign in to comment.