add findInFiles plugin

This commit is contained in:
2022-07-30 09:17:08 +02:00
parent 1a4006ca8f
commit 14c059e5aa
12 changed files with 247 additions and 11 deletions

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512">
<title>ionicons-v5-f</title>
<path d="M256,64C150.13,64,64,150.13,64,256s86.13,192,192,192,192-86.13,192-192S361.87,64,256,64Zm91.31,283.31a16,16,0,0,1-22.62,0l-42.84-42.83a88.08,88.08,0,1,1,22.63-22.63l42.83,42.84A16,16,0,0,1,347.31,347.31Z"/>
<circle cx="232" cy="232" r="56"/>
</svg>

After

Width:  |  Height:  |  Size: 386 B

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512">
<title>ionicons-v5-f</title>
<path d="M221.09,64A157.09,157.09,0,1,0,378.18,221.09,157.1,157.1,0,0,0,221.09,64Z"
style="fill:none;stroke:#000;stroke-miterlimit:10;stroke-width:32px"/>
<line x1="338.29" y1="338.29" x2="448" y2="448"
style="fill:none;stroke:#000;stroke-linecap:round;stroke-miterlimit:10;stroke-width:32px"/>
</svg>

After

Width:  |  Height:  |  Size: 450 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512">
<title>ionicons-v5-f</title>
<path d="M464,428,339.92,303.9a160.48,160.48,0,0,0,30.72-94.58C370.64,120.37,298.27,48,209.32,48S48,120.37,48,209.32s72.37,161.32,161.32,161.32a160.48,160.48,0,0,0,94.58-30.72L428,464ZM209.32,319.69A110.38,110.38,0,1,1,319.69,209.32,110.5,110.5,0,0,1,209.32,319.69Z"/>
</svg>

After

Width:  |  Height:  |  Size: 400 B

13
icons/myicons/target.svg Normal file
View File

@@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512">
<title>ionicons-v5-m</title>
<path d="M448,256c0-106-86-192-192-192S64,150,64,256s86,192,192,192S448,362,448,256Z"
style="fill:none;stroke:#000;stroke-miterlimit:10;stroke-width:32px"/>
<line x1="70" y1="256" x2="170" y2="256"
style="fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:40px"/>
<line x1="342" y1="256" x2="442" y2="256"
style="fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:40px"/>
<line x1="256" y1="70" x2="256" y2="170"
style="fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:40px"/>
<line x1="256" y1="342" x2="256" y2="442"
style="fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:40px"/>
</svg>

After

Width:  |  Height:  |  Size: 893 B

View File

@@ -55,6 +55,7 @@ if __name__ == "__main__":
PluginRegistry.load_plugin("LogFilePlugin")
PluginRegistry.load_plugin("NotesPlugin")
PluginRegistry.load_plugin("TimeDiffPlugin")
PluginRegistry.load_plugin("FindInFilesPlugin")
window = PluginRegistry.execute_single("create_main_window")
window.show()

View File

@@ -33,18 +33,50 @@ def sort_menu_contributions(menu_contributions: [MenuContribution]) -> [MenuCont
result = []
items = _sort_by_action_id(menu_contributions[:])
_recursive_half_order_adder(result, items)
# add remaining items to the end (ordered by their action_id)
# This resolves cycles.
for item in items:
result.append(item)
return result
def _recursive_half_order_adder(result: [MenuContribution], items: [MenuContribution]):
for item in items:
mc: MenuContribution = item
if not mc.after:
result.append(mc)
items.remove(mc)
result = result + _new_recursive(mc.action_id, items)
# _recursive_half_order_adder(result, items)
# add remaining items to the end (ordered by their action_id)
# This resolves cycles.
for item in items:
if result.count(item) == 0:
result.append(item)
return result
def _new_recursive(current_action_id: str, items: [MenuContribution]) -> [MenuContribution]:
result = []
for item in items:
mc: MenuContribution = item
print("%s checking %s" % (current_action_id, mc.action_id))
if mc.after == current_action_id:
print("%s adding %s" % (current_action_id, mc.action_id))
result.append(mc)
result = result + _new_recursive(mc.action_id, items)
return result
def _recursive_half_order_adder(result: [MenuContribution], items: [MenuContribution]):
print("%s -- %s" % ([mc.action_id for mc in result], [mc.action_id for mc in items]))
for item in items:
mc: MenuContribution = item
if mc.after:
index = 0
for r in result:
index = index + 1
mc_in_result: MenuContribution = r
if mc.after == mc_in_result.action_id:
result.insert(index, mc)
items.remove(mc)
_recursive_half_order_adder(result, items)
if not mc.after:
result.append(mc)
items.remove(mc)

View File

@@ -40,6 +40,39 @@ class MyTestCase(unittest.TestCase):
ordered_ids = ordered_ids + a.action_id
self.assertEqual("ab", ordered_ids)
def test_sort_with_non_consecutive_action_ids(self):
items = [
MenuContribution("menuId", action_id="The", after=None),
MenuContribution("menuId", action_id="quick", after="The"),
MenuContribution("menuId", action_id="brown", after="quick"),
MenuContribution("menuId", action_id="fox", after="brown"),
MenuContribution("menuId", action_id="jumped", after="fox"),
]
shuffle(items)
actual = sort_menu_contributions(items)
ordered_ids = ""
for a in actual:
ordered_ids = ordered_ids + a.action_id
self.assertEqual("Thequickbrownfoxjumped", ordered_ids)
def test_sort_with_multiple_equal_after_values(self):
items = [
MenuContribution("menuId", action_id="Tanja", after=None),
MenuContribution("menuId", action_id="jumps", after="Tanja"),
MenuContribution("menuId", action_id="over", after="Tanja"),
MenuContribution("menuId", action_id="the", after="Tanja"),
MenuContribution("menuId", action_id="yellow", after="Tanja"),
MenuContribution("menuId", action_id="Zebra", after=None),
]
shuffle(items)
actual = sort_menu_contributions(items)
ordered_ids = ""
for a in actual:
ordered_ids = ordered_ids + a.action_id
self.assertEqual("TanjajumpsovertheyellowZebra", ordered_ids)
if __name__ == '__main__':
unittest.main()

View File

View File

@@ -0,0 +1,86 @@
import os
import sys
from pathlib import Path
from PySide6.QtGui import QIcon
from src.pluginregistry import PluginRegistry
from src.plugins.krowlog.Tab import Tab
from PySide6.QtWidgets import QTextEdit, QVBoxLayout, QLabel, QLineEdit, QPushButton, QFileDialog
from src.i18n import _
from src.settings.settings import Settings
from src.ui.formgrid import FormGrid
from src.ui.hbox import HBox
class FindInFilesWidget(Tab):
def __init__(self, unique_id: str, title: str, settings: Settings):
super(FindInFilesWidget, self).__init__(unique_id, title)
self._settings = settings
self.layout = QVBoxLayout(self)
self.layout.setContentsMargins(0, 0, 0, 0)
form = FormGrid();
self.layout.addWidget(form)
self._base_dir = QLineEdit(self._initialFolder())
self._base_dir.textChanged.connect(self._base_dir_changed)
btn_select_base_dir = QPushButton(QIcon.fromTheme("document-open"), "")
btn_select_base_dir.pressed.connect(self._select_base_dir)
btn_base_dir_for_current_file = QPushButton(QIcon("icons/myicons/target.svg"), "")
btn_base_dir_for_current_file.setToolTip(_("Focus on current file"))
btn_base_dir_for_current_file.pressed.connect(self._select_btn_base_dir_for_current_file)
form.addRow(QLabel(_("Folder:")),
HBox(self._base_dir, btn_select_base_dir, btn_base_dir_for_current_file))
self._filter = QLineEdit("*.log")
form.addRow(QLabel(_("Filter:")), self._filter)
self._btn_search = QPushButton(QIcon("icons/ionicons/search-outline.svg"), _("Search"))
self._btn_search.pressed.connect(self._search)
self.layout.addWidget(self._btn_search)
self.layout.addWidget(QTextEdit())
def _search(self):
pass
def _select_base_dir(self):
dialog = QFileDialog()
selected_dir = dialog.getExistingDirectory(
caption=_("Open Directory"),
dir=self._base_dir.text()
)
if selected_dir:
self._base_dir.setText(selected_dir)
def _select_btn_base_dir_for_current_file(self):
dir = self._get_base_dir_for_current_file()
self._base_dir.setText(dir)
def _base_dir_changed(self, base_dir):
if os.path.isdir(base_dir):
self._settings.set_session("findInFiles", "folder", base_dir)
def _initialFolder(self) -> str:
folder = self._settings.get_session("findInFiles", "folder", fallback=None)
if folder is None or not os.path.isdir(folder):
folder = self._get_base_dir_for_current_file()
return folder
def _get_base_dir_for_current_file(self):
current_file = PluginRegistry.execute_single("current_file")
folder = os.path.dirname(current_file) if current_file else None
if not os.path.isdir(folder):
if sys.platform == 'win32' or sys.platform == 'cygwin':
folder = "C:\\"
else:
folder = os.path.join(Path.home())
return folder

View File

@@ -0,0 +1,40 @@
from PySide6.QtCore import Qt
from src.pluginbase import PluginBase
from src.pluginregistry import PluginRegistry
from src.plugins.domain.menucontribution import MenuContribution
from src.plugins.domain.raction import RAction
from src.plugins.findInFiles.findinfileswidget import FindInFilesWidget
from src.plugins.notes.noteswidget import NotesWidget
from src.i18n import _
from src.settings.settings import Settings
class FindInFilesPlugin(PluginBase):
def __init__(self):
super(FindInFilesPlugin, self).__init__()
self.settings = None
def set_settings(self, settings: Settings):
self.settings = settings
if not self.settings.session.has_section("findInFiles"):
self.settings.session.add_section("findInFiles")
def get_menu_contributions(self) -> [MenuContribution]:
return [
MenuContribution("window", action=self._add_find_in_files_tab_action(), action_id="add find in files tab",
after="add notes tab"),
]
def _add_find_in_files_tab_action(self) -> RAction:
return RAction(_("&Find In Files"), self._add_notes_tab, shortcut='Ctrl+Shift+F',
icon_file="icons/ionicons/search-outline.svg")
def _add_notes_tab(self):
findInFiles = FindInFilesWidget(
"find_in_files",
_("Find In Files"),
self.settings
)
PluginRegistry.execute_single("add_dock", Qt.DockWidgetArea.LeftDockWidgetArea, findInFiles)

View File

@@ -21,7 +21,7 @@ class NotesPlugin(PluginBase):
]
def _add_notes_tab_action(self) -> RAction:
open_file = RAction(_("Add &Notes"), self._add_notes_tab, shortcut='Ctrl+Shift+N',
open_file = RAction(_("&Notes"), self._add_notes_tab, shortcut='Ctrl+Shift+N',
icon_from_theme="filenew")
return open_file

15
src/ui/formgrid.py Normal file
View File

@@ -0,0 +1,15 @@
from PySide6.QtWidgets import QWidget, QGridLayout, QLabel
class FormGrid(QWidget):
def __init__(self):
super(FormGrid, self).__init__()
self.layout = QGridLayout(self)
self.row = -1
def addRow(self, *widgets: QWidget):
self.row = self.row + 1
col = -1
for widget in widgets:
col = col + 1
self.layout.addWidget(widget, self.row, col)