diff --git a/README.md b/README.md index f26a6bd..10149dc 100644 --- a/README.md +++ b/README.md @@ -16,4 +16,5 @@ sudo apt-get install python3.8 python3-setproctitle python3-gi # Images ![1 BulkR clean slate. ](images/pic1.png) -![2 BulkR loaded dir and some actions. ](images/pic2.png) +![2 BulkR actions collection without set dir. ](images/pic2.png) +![3 BulkR loaded dir and some actions. ](images/pic3.png) diff --git a/images/pic1.png b/images/pic1.png index 5de477d..89d0bd3 100644 Binary files a/images/pic1.png and b/images/pic1.png differ diff --git a/images/pic2.png b/images/pic2.png index 19c5f84..b537393 100644 Binary files a/images/pic2.png and b/images/pic2.png differ diff --git a/images/pic3.png b/images/pic3.png new file mode 100644 index 0000000..b7a908e Binary files /dev/null and b/images/pic3.png differ diff --git a/src/Window.py b/src/Window.py index c06b4f9..108673c 100644 --- a/src/Window.py +++ b/src/Window.py @@ -21,7 +21,7 @@ class Window(Gtk.Window, Builtins): self.add(Controller(args)) self.connect("delete-event", Gtk.main_quit) - self.set_default_size(800, 600) + self.set_default_size(850, 600) self.set_title(f"{app_name}") self.set_icon_from_file("/usr/share/bulkr/bulkr.png") self.set_gravity(5) # 5 = CENTER diff --git a/src/controller/ChangeView.py b/src/controller/ChangeView.py index e3d6d2f..09cdf4c 100644 --- a/src/controller/ChangeView.py +++ b/src/controller/ChangeView.py @@ -7,10 +7,10 @@ gi.require_version('Gdk', '3.0') from gi.repository import Gtk, Gdk # Application imports -from mixins import CommonActionsMixin +from mixins import CommonWidgetGeneratorMixin, CommonActionsMixin -class ChangeView(Gtk.Box, CommonActionsMixin): +class ChangeView(Gtk.Box, CommonWidgetGeneratorMixin, CommonActionsMixin): def __init__(self): super(ChangeView, self).__init__() diff --git a/src/controller/Controller.py b/src/controller/Controller.py index 00ac263..eb6911b 100644 --- a/src/controller/Controller.py +++ b/src/controller/Controller.py @@ -8,7 +8,7 @@ from gi.repository import Gtk from gi.repository import GLib # Application imports -from mixins import CommonActionsMixin +from mixins import CommonWidgetGeneratorMixin from . import ChangeView from .widgets import * @@ -19,7 +19,7 @@ def threaded(fn): return wrapper -class Controller(Gtk.Box, CommonActionsMixin): +class Controller(Gtk.Box, CommonWidgetGeneratorMixin): def __init__(self, args): super(Controller, self).__init__() @@ -60,6 +60,9 @@ class Controller(Gtk.Box, CommonActionsMixin): actions_scroll_label = Gtk.Label(label="Actions:") actions_scroll_label.set_xalign(-20) actions_scroll_view, self.actions_list_view = self._create_listBox_widget() + actions_scroll_view.set_vexpand(True) + + self.copy_window = Gtk.Box() self.set_spacing(20) self.set_margin_top(5) @@ -111,14 +114,31 @@ class Controller(Gtk.Box, CommonActionsMixin): self.change_view.update_to_list() return - for action in self.action_collection: + for i, action in enumerate(self.action_collection): if action == target: + if type == "move-up": + if i > 0: + parent = target.get_parent() + parent.remove(target) + parent.destroy() + self.actions_list_view.insert(target, (i - 1)) + self.action_collection[i-1], self.action_collection[i] = self.action_collection[i], self.action_collection[i - 1] + if type == "move-down": + if i < len(self.action_collection): + parent = target.get_parent() + parent.remove(target) + parent.destroy() + self.actions_list_view.insert(target, (i + 1)) + self.action_collection[i+1], self.action_collection[i] = self.action_collection[i], self.action_collection[i + 1] + if type == "delete": self.action_collection.remove(target) target.delete() if type == "run": target.run() + break + def _add_action(self, widget): itr = self.combo_box.get_active_iter() @@ -165,3 +185,8 @@ class Controller(Gtk.Box, CommonActionsMixin): def _str_to_class(self, class_name): return getattr(sys.modules[__name__], class_name)() + + # NOTE: Yes, this exists in CommonActionsMixin. But, I don't want to add a while mixin just for one method + def _has_method(self, obj, name): + ''' Checks if a given method exists. ''' + return callable(getattr(obj, name, None)) diff --git a/src/controller/widgets/Case.py b/src/controller/widgets/Case.py index ddfe5f7..3b263fb 100644 --- a/src/controller/widgets/Case.py +++ b/src/controller/widgets/Case.py @@ -6,20 +6,19 @@ gi.require_version('Gtk', '3.0') from gi.repository import Gtk # Application imports -from mixins import CommonActionsMixin +from mixins import CommonWidgetGeneratorMixin, CommonActionsMixin -class Case(Gtk.Box, CommonActionsMixin): +class Case(Gtk.Box, CommonWidgetGeneratorMixin, CommonActionsMixin): def __init__(self): super(Case, self).__init__() - label = Gtk.Label(label="Case") data = ["Title Case", "UPPER", "lower", "InVert CaSe --> iNvERT cAsE"] self.store, self.combo_box = self._create_combobox_widget(data) - label.set_hexpand(True) + self.combo_box.set_hexpand(True) - self.add_widgets([label, self.combo_box]) + self.add_widgets([self.combo_box]) self.set_spacing(20) self.show_all() diff --git a/src/controller/widgets/Insert.py b/src/controller/widgets/Insert.py index 97afb68..7ce660e 100644 --- a/src/controller/widgets/Insert.py +++ b/src/controller/widgets/Insert.py @@ -7,14 +7,13 @@ gi.require_version('Gtk', '3.0') from gi.repository import Gtk # Application imports -from mixins import CommonActionsMixin +from mixins import CommonWidgetGeneratorMixin, CommonActionsMixin -class Insert(Gtk.Box, CommonActionsMixin): +class Insert(Gtk.Box, CommonWidgetGeneratorMixin, CommonActionsMixin): def __init__(self): super(Insert, self).__init__() - label = Gtk.Label(label="Insert: ") self.insert_entry = Gtk.Entry() self.insert_entry.set_hexpand(True) self.insert_entry.set_placeholder_text("Insert...") @@ -24,7 +23,7 @@ class Insert(Gtk.Box, CommonActionsMixin): self.spin_button = self._create_spinbutton_widget() - self.add_widgets([label, self.insert_entry, self.combo_box, self.spin_button]) + self.add_widgets([self.insert_entry, self.combo_box, self.spin_button]) self.set_spacing(20) self.show_all() diff --git a/src/controller/widgets/Remove.py b/src/controller/widgets/Remove.py index fe7b38b..e2649c5 100644 --- a/src/controller/widgets/Remove.py +++ b/src/controller/widgets/Remove.py @@ -6,14 +6,13 @@ gi.require_version('Gtk', '3.0') from gi.repository import Gtk # Application imports -from mixins import CommonActionsMixin +from mixins import CommonWidgetGeneratorMixin, CommonActionsMixin -class Remove(Gtk.Box, CommonActionsMixin): +class Remove(Gtk.Box, CommonWidgetGeneratorMixin, CommonActionsMixin): def __init__(self): super(Remove, self).__init__() - label = Gtk.Label(label="Remove: ") self.entry_from = Gtk.Entry() data = ["All", "Word Start", "Word End", "First Instance", "Last Instance", "RegEx"] @@ -22,7 +21,7 @@ class Remove(Gtk.Box, CommonActionsMixin): self.entry_from.set_hexpand(True) self.entry_from.set_placeholder_text("Remove...") - self.add_widgets([label, self.entry_from, self.combo_box]) + self.add_widgets([self.entry_from, self.combo_box]) self.set_spacing(20) self.show_all() diff --git a/src/controller/widgets/RemoveFromTo.py b/src/controller/widgets/RemoveFromTo.py index ebd1fbb..b0a13ea 100644 --- a/src/controller/widgets/RemoveFromTo.py +++ b/src/controller/widgets/RemoveFromTo.py @@ -6,23 +6,22 @@ gi.require_version('Gtk', '3.0') from gi.repository import Gtk # Application imports -from mixins import CommonActionsMixin +from mixins import CommonWidgetGeneratorMixin, CommonActionsMixin -class RemoveFromTo(Gtk.Box, CommonActionsMixin): +class RemoveFromTo(Gtk.Box, CommonWidgetGeneratorMixin, CommonActionsMixin): def __init__(self): super(RemoveFromTo, self).__init__() - label = Gtk.Label(label="Remove From / To: ") self.entry_from = Gtk.Entry() self.entry_to = Gtk.Entry() self.entry_from.set_hexpand(True) self.entry_to.set_hexpand(True) - self.entry_from.set_placeholder_text("From...") - self.entry_to.set_placeholder_text("To...") + self.entry_from.set_placeholder_text("Remove From...") + self.entry_to.set_placeholder_text("Remove To...") - self.add_widgets([label, self.entry_from, self.entry_to]) + self.add_widgets([self.entry_from, self.entry_to]) self.set_spacing(20) self.show_all() diff --git a/src/controller/widgets/Replace.py b/src/controller/widgets/Replace.py index 821d131..c127223 100644 --- a/src/controller/widgets/Replace.py +++ b/src/controller/widgets/Replace.py @@ -6,23 +6,22 @@ gi.require_version('Gtk', '3.0') from gi.repository import Gtk # Application imports -from mixins import CommonActionsMixin +from mixins import CommonWidgetGeneratorMixin, CommonActionsMixin -class Replace(Gtk.Box, CommonActionsMixin): +class Replace(Gtk.Box, CommonWidgetGeneratorMixin, CommonActionsMixin): def __init__(self): super(Replace, self).__init__() - label = Gtk.Label(label="Replace With: ") self.entry_from = Gtk.Entry() self.entry_to = Gtk.Entry() self.entry_from.set_hexpand(True) self.entry_to.set_hexpand(True) - self.entry_from.set_placeholder_text("From...") - self.entry_to.set_placeholder_text("To...") + self.entry_from.set_placeholder_text("Replace From...") + self.entry_to.set_placeholder_text("Replace To...") - self.add_widgets([label, self.entry_from, self.entry_to]) + self.add_widgets([self.entry_from, self.entry_to]) self.set_spacing(20) self.show_all() diff --git a/src/mixins/CommonActionsMixin.py b/src/mixins/CommonActionsMixin.py index f8afbee..0755493 100644 --- a/src/mixins/CommonActionsMixin.py +++ b/src/mixins/CommonActionsMixin.py @@ -14,33 +14,47 @@ class CommonActionsMixin: for widget in widgets: self.add(widget) - remove_button = Gtk.Button(label="X") test_button = Gtk.Button(label="Test") + remove_button = Gtk.Button(label="X") + up_button = Gtk.Button() + down_button = Gtk.Button() + up_button.set_image(Gtk.Image.new_from_icon_name("up", 4)) + down_button.set_image(Gtk.Image.new_from_icon_name("down", 4)) + + up_button.set_size_request(32, 32) + down_button.set_size_request(32, 32) + remove_button.set_size_request(32, 32) + test_button.set_size_request(96, 32) + + up_button.connect("clicked", self._move_up) + down_button.connect("clicked", self._move_down) remove_button.connect("clicked", self._remove_self) test_button.connect("clicked", self._do_run) - remove_button.set_size_request(120, 32) - test_button.set_size_request(120, 32) - self.add(test_button) + self.add(up_button) + self.add(down_button) self.add(remove_button) def delete(self): self.get_parent().destroy() + def _move_up(self, widget): + event_system.push_gui_event(["move-up", self, ()]) + def _move_down(self, widget): + event_system.push_gui_event(["move-down", self, ()]) + def _has_method(self, obj, name): + ''' Checks if a given method exists. ''' + return callable(getattr(obj, name, None)) def get_file_parts(self, name): file_extension = pathlib.Path(name).suffix base = name.split(file_extension)[0] return base, file_extension - def _has_method(self, obj, name): - ''' Checks if a given method exists. ''' - return callable(getattr(obj, name, None)) - def _replace_last(self, string, find, replace): reversed = string[::-1] replaced = reversed.replace(find[::-1], replace[::-1], 1) @@ -54,71 +68,3 @@ class CommonActionsMixin: def _do_run(self, widget): event_system.push_gui_event(["run", self, ()]) - - - def _create_spinbutton_widget(self): - spin_button = Gtk.SpinButton() - spin_button.set_numeric(True) - spin_button.set_wrap(True) - spin_button.set_digits(0) - spin_button.set_increments(1.0, 1.0) - spin_button.set_range(1, 1000000) - spin_button.set_sensitive(False) - - return spin_button - - def _create_combobox_widget(self, data): - cell = Gtk.CellRendererText() - store = Gtk.ListStore(str) - - for row in data: - store.append([row]) - - combo_box = Gtk.ComboBox() - combo_box.set_model(store) - combo_box.pack_start(cell, True) - combo_box.add_attribute(cell, 'text', 0) - combo_box.set_active(0) - - if self._has_method(self, "_combo_box_changed"): - combo_box.connect("changed", self._combo_box_changed) - - return store, combo_box - - def _create_treeview_widget(self, title = "Not Set"): - scroll = Gtk.ScrolledWindow() - grid = Gtk.TreeView() - store = Gtk.ListStore(str) - column = Gtk.TreeViewColumn(title) - name = Gtk.CellRendererText() - selec = grid.get_selection() - - grid.set_model(store) - selec.set_mode(2) - - column.pack_start(name, True) - column.add_attribute(name, "text", 0) - column.set_expand(False) - - grid.append_column(column) - grid.set_search_column(0) - grid.set_headers_visible(True) - grid.set_enable_tree_lines(False) - - grid.show_all() - scroll.add(grid) - grid.columns_autosize() - scroll.set_size_request(360, 240) - return scroll, store - - def _create_listBox_widget(self,): - scroll = Gtk.ScrolledWindow() - grid = Gtk.ListBox() - viewport = Gtk.Viewport() - - grid.show_all() - viewport.add(grid) - scroll.add(viewport) - - scroll.set_size_request(360, 200) - return scroll, grid diff --git a/src/mixins/CommonWidgetGeneratorMixin.py b/src/mixins/CommonWidgetGeneratorMixin.py new file mode 100644 index 0000000..80d8710 --- /dev/null +++ b/src/mixins/CommonWidgetGeneratorMixin.py @@ -0,0 +1,78 @@ +# Python imports +import pathlib + +# lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports + + +class CommonWidgetGeneratorMixin: + def _create_spinbutton_widget(self): + spin_button = Gtk.SpinButton() + spin_button.set_numeric(True) + spin_button.set_wrap(True) + spin_button.set_digits(0) + spin_button.set_increments(1.0, 1.0) + spin_button.set_range(1, 1000000) + spin_button.set_sensitive(False) + + return spin_button + + def _create_combobox_widget(self, data): + cell = Gtk.CellRendererText() + store = Gtk.ListStore(str) + + for row in data: + store.append([row]) + + combo_box = Gtk.ComboBox() + combo_box.set_model(store) + combo_box.pack_start(cell, True) + combo_box.add_attribute(cell, 'text', 0) + combo_box.set_active(0) + + if self._has_method(self, "_combo_box_changed"): + combo_box.connect("changed", self._combo_box_changed) + + return store, combo_box + + def _create_treeview_widget(self, title = "Not Set"): + scroll = Gtk.ScrolledWindow() + grid = Gtk.TreeView() + store = Gtk.ListStore(str) + column = Gtk.TreeViewColumn(title) + name = Gtk.CellRendererText() + selec = grid.get_selection() + + grid.set_model(store) + selec.set_mode(2) + + column.pack_start(name, True) + column.add_attribute(name, "text", 0) + column.set_expand(False) + + grid.append_column(column) + grid.set_search_column(0) + grid.set_headers_visible(True) + grid.set_enable_tree_lines(False) + + grid.show_all() + scroll.add(grid) + grid.columns_autosize() + scroll.set_size_request(360, 240) + return scroll, store + + def _create_listBox_widget(self,): + scroll = Gtk.ScrolledWindow() + grid = Gtk.ListBox() + viewport = Gtk.Viewport() + + grid.show_all() + viewport.add(grid) + scroll.add(viewport) + + scroll.set_size_request(360, 200) + return scroll, grid diff --git a/src/mixins/__init__.py b/src/mixins/__init__.py index 55cf9b4..49ca33f 100644 --- a/src/mixins/__init__.py +++ b/src/mixins/__init__.py @@ -1 +1,2 @@ from .CommonActionsMixin import CommonActionsMixin +from .CommonWidgetGeneratorMixin import CommonWidgetGeneratorMixin