findInFiles #1

Merged
andi merged 6 commits from findInFiles into master 2022-08-23 11:52:02 +00:00
17 changed files with 417 additions and 88 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

@@ -5,80 +5,104 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: RavenLog\n" "Project-Id-Version: RavenLog\n"
"POT-Creation-Date: 2022-02-12 10:14+0100\n" "POT-Creation-Date: 2022-08-21 09:51+0200\n"
"PO-Revision-Date: 2022-02-12 10:17+0100\n" "PO-Revision-Date: 2022-08-21 09:58+0200\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
"Language: de\n" "Language: de\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 2.3\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 3.0.1\n"
#: src/mainwindow.py:39 src/plugins/krowlog/aboutdialog.py:23 #: src/mainwindow.py:34 src/plugins/krowlog/aboutdialog.py:24
#: src/plugins/krowlogplugin.py:85 #: src/plugins/krowlogplugin.py:85
msgid "KrowLog" msgid "KrowLog"
msgstr "KrowLog" msgstr "KrowLog"
#: src/mainwindow.py:47 src/plugins/openfileplugin.py:29 #: src/mainwindow.py:42 src/plugins/openfileplugin.py:30
msgid "Open &Recent" msgid "Open &Recent"
msgstr "Zu&letzt geöffnete Dateien" msgstr "Zu&letzt geöffnete Dateien"
#: src/mainwindow.py:66 #: src/mainwindow.py:64
msgid "&File" msgid "&File"
msgstr "&Datei" msgstr "&Datei"
#: src/mainwindow.py:67 #: src/mainwindow.py:65
msgid "&Settings" msgid "&Settings"
msgstr "&Einstellungen" msgstr "&Einstellungen"
#: src/mainwindow.py:68 #: src/mainwindow.py:66
msgid "&Window" msgid "&Window"
msgstr "&Fenster" msgstr "&Fenster"
#: src/mainwindow.py:69 #: src/mainwindow.py:67
msgid "&Help" msgid "&Help"
msgstr "&Hilfe" msgstr "&Hilfe"
#: src/mainwindow.py:101 src/ui/bigtext/bigtext.py:187 #: src/mainwindow.py:99 src/ui/bigtext/bigtext.py:188
msgid "&Highlighter" msgid "&Highlighter"
msgstr "&Hervorhebungen" msgstr "&Hervorhebungen"
#: src/mainwindow.py:108 #: src/mainwindow.py:106
msgid "Highlight &Searches" msgid "Highlight &Searches"
msgstr "&Suchtreffer Hervorheben" msgstr "&Suchtreffer Hervorheben"
#: src/mainwindow.py:116 #: src/mainwindow.py:114
msgid "Open Tab on Save As File" msgid "Open Tab on Save As File"
msgstr "Öffne neues Tab wenn Selektion als neue Datei gespeichert wird" msgstr "Öffne neues Tab wenn Selektion als neue Datei gespeichert wird"
#: src/plugins/krowlog/aboutdialog.py:18 #: src/plugins/findInFiles/findinfileswidget.py:37
msgid "Focus on current file"
msgstr "Auf aktuelle Datei fokussieren"
#: src/plugins/findInFiles/findinfileswidget.py:40
msgid "Folder:"
msgstr "Ordner:"
#: src/plugins/findInFiles/findinfileswidget.py:45
msgid "Filter:"
msgstr "Filter:"
#: src/plugins/findInFiles/findinfileswidget.py:83
msgid "Open Directory"
msgstr "Ordner öffnen"
#: src/plugins/findinfilesplugin.py:31
msgid "&Find In Files"
msgstr "In &Dateien Suchen"
#: src/plugins/findinfilesplugin.py:37
msgid "Find In Files"
msgstr "In Dateien Suchen"
#: src/plugins/krowlog/aboutdialog.py:19
msgid "About KrowLog" msgid "About KrowLog"
msgstr "Über KrowLog" msgstr "Über KrowLog"
#: src/plugins/krowlog/aboutdialog.py:28 #: src/plugins/krowlog/aboutdialog.py:29
msgid "Version: {0}" msgid "Version: {0}"
msgstr "Version: {0}" msgstr "Version: {0}"
#: src/plugins/krowlog/aboutdialog.py:43 #: src/plugins/krowlog/aboutdialog.py:44
msgid "About" msgid "About"
msgstr "Über KrowLog" msgstr "Über KrowLog"
#: src/plugins/krowlog/aboutdialog.py:44 #: src/plugins/krowlog/aboutdialog.py:45
msgid "License" msgid "License"
msgstr "Lizenz" msgstr "Lizenz"
#: src/plugins/krowlog/aboutdialog.py:57 #: src/plugins/krowlog/aboutdialog.py:58
msgid "Log file viewer" msgid "Log file viewer"
msgstr "Betrachter für Logdateien" msgstr "Betrachter für Logdateien"
#: src/plugins/krowlog/aboutdialog.py:58 #: src/plugins/krowlog/aboutdialog.py:59
msgid "(c) 2022 Andreas Huber" msgid "(c) 2022 Andreas Huber"
msgstr "(c) 2022 Andreas Huber" msgstr "(c) 2022 Andreas Huber"
#: src/plugins/krowlog/aboutdialog.py:59 #: src/plugins/krowlog/aboutdialog.py:60
msgid "License: LGPL v3" msgid "License: LGPL v3"
msgstr "Lizenz: LGPL v3" msgstr "Lizenz: LGPL v3"
@@ -122,71 +146,75 @@ msgstr "&Über KrowLog"
msgid "E&xit" msgid "E&xit"
msgstr "&Beenden" msgstr "&Beenden"
#: src/plugins/logfile/filterwidget.py:134 #: src/plugins/logfile/filterwidget.py:137
msgid "Cancel" msgid "Cancel"
msgstr "Abbrechen" msgstr "Abbrechen"
#: src/plugins/logfile/filterwidget.py:138 #: src/plugins/logfile/filterwidget.py:143
msgid "save query"
msgstr "suche speichern"
#: src/plugins/logfile/filterwidget.py:148
msgid "ignore case" msgid "ignore case"
msgstr "Groß-/Kleinschreibung ignorieren" msgstr "Groß-/Kleinschreibung ignorieren"
#: src/plugins/logfile/filterwidget.py:142 #: src/plugins/logfile/filterwidget.py:152
msgid "regex" msgid "regex"
msgstr "RegExp" msgstr "RegExp"
#: src/plugins/logfileplugin.py:25 #: src/plugins/logfileplugin.py:26
msgid "File not found" msgid "File not found"
msgstr "Datei nicht gefunden" msgstr "Datei nicht gefunden"
#: src/plugins/logfileplugin.py:26 #: src/plugins/logfileplugin.py:27
msgid "'{0}' is not a file or cannot be opened" msgid "'{0}' is not a file or cannot be opened"
msgstr "'{0}' ist keine Datei oder kann nicht geöffnet werden" msgstr "'{0}' ist keine Datei oder kann nicht geöffnet werden"
#: src/plugins/notesplugin.py:25 #: src/plugins/notesplugin.py:24
msgid "Add &Notes" msgid "&Notes"
msgstr "&Notizen Hinzufügen" msgstr "&Notizen"
#: src/plugins/notesplugin.py:33 #: src/plugins/notesplugin.py:32
msgid "Notes {0}" msgid "Notes {0}"
msgstr "Notizen {0}" msgstr "Notizen {0}"
#: src/plugins/openfileplugin.py:24 #: src/plugins/openfileplugin.py:25
msgid "&Open..." msgid "&Open..."
msgstr "&Öffnen..." msgstr "&Öffnen..."
#: src/plugins/openfileplugin.py:45 #: src/plugins/openfileplugin.py:46
msgid "Open File" msgid "Open File"
msgstr "Öffne Datei" msgstr "Öffne Datei"
#: src/ui/bigtext/bigtext.py:170 #: src/ui/bigtext/bigtext.py:171
msgid "&Copy to Clipboard" msgid "&Copy to Clipboard"
msgstr "In Zwischenablage &Kopieren" msgstr "In Zwischenablage &Kopieren"
#: src/ui/bigtext/bigtext.py:176 #: src/ui/bigtext/bigtext.py:177
msgid "Copy to &File" msgid "Copy to &File"
msgstr "In &Datei Kopieren" msgstr "In &Datei Kopieren"
#: src/ui/bigtext/bigtext.py:181 #: src/ui/bigtext/bigtext.py:182
msgid "Select &All" msgid "Select &All"
msgstr "&Alles Selektieren" msgstr "&Alles Selektieren"
#: src/ui/bigtext/bigtext.py:331 #: src/ui/bigtext/bigtext.py:332
msgid "data selection" msgid "data selection"
msgstr "selektion" msgstr "selektion"
#: src/ui/bigtext/bigtext.py:332 #: src/ui/bigtext/bigtext.py:333
msgid "You have selected <b>{0}</b> of data." msgid "You have selected <b>{0}</b> of data."
msgstr "Du hast <b>{0}</b> selektiert." msgstr "Du hast <b>{0}</b> selektiert."
#: src/ui/bigtext/bigtext.py:335 #: src/ui/bigtext/bigtext.py:336
msgid "Copy {0} to Clipboard" msgid "Copy {0} to Clipboard"
msgstr "Kopiere {0} in die Zwischenablage" msgstr "Kopiere {0} in die Zwischenablage"
#: src/ui/bigtext/bigtext.py:337 #: src/ui/bigtext/bigtext.py:338
msgid "Write to File" msgid "Write to File"
msgstr "Schreibe in Datei" msgstr "Schreibe in Datei"
#: src/ui/bigtext/bigtext.py:359 #: src/ui/bigtext/bigtext.py:360
msgid "Save File" msgid "Save File"
msgstr "Speichere Datei" msgstr "Speichere Datei"

View File

@@ -5,7 +5,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2022-02-12 10:14+0100\n" "POT-Creation-Date: 2022-08-21 09:51+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -15,68 +15,92 @@ msgstr ""
"Generated-By: pygettext.py 1.5\n" "Generated-By: pygettext.py 1.5\n"
#: src/mainwindow.py:39 src/plugins/krowlog/aboutdialog.py:23 #: src/mainwindow.py:34 src/plugins/krowlog/aboutdialog.py:24
#: src/plugins/krowlogplugin.py:85 #: src/plugins/krowlogplugin.py:85
msgid "KrowLog" msgid "KrowLog"
msgstr "" msgstr ""
#: src/mainwindow.py:47 src/plugins/openfileplugin.py:29 #: src/mainwindow.py:42 src/plugins/openfileplugin.py:30
msgid "Open &Recent" msgid "Open &Recent"
msgstr "" msgstr ""
#: src/mainwindow.py:66 #: src/mainwindow.py:64
msgid "&File" msgid "&File"
msgstr "" msgstr ""
#: src/mainwindow.py:67 #: src/mainwindow.py:65
msgid "&Settings" msgid "&Settings"
msgstr "" msgstr ""
#: src/mainwindow.py:68 #: src/mainwindow.py:66
msgid "&Window" msgid "&Window"
msgstr "" msgstr ""
#: src/mainwindow.py:69 #: src/mainwindow.py:67
msgid "&Help" msgid "&Help"
msgstr "" msgstr ""
#: src/mainwindow.py:101 src/ui/bigtext/bigtext.py:187 #: src/mainwindow.py:99 src/ui/bigtext/bigtext.py:188
msgid "&Highlighter" msgid "&Highlighter"
msgstr "" msgstr ""
#: src/mainwindow.py:108 #: src/mainwindow.py:106
msgid "Highlight &Searches" msgid "Highlight &Searches"
msgstr "" msgstr ""
#: src/mainwindow.py:116 #: src/mainwindow.py:114
msgid "Open Tab on Save As File" msgid "Open Tab on Save As File"
msgstr "" msgstr ""
#: src/plugins/krowlog/aboutdialog.py:18 #: src/plugins/findInFiles/findinfileswidget.py:37
msgid "Focus on current file"
msgstr ""
#: src/plugins/findInFiles/findinfileswidget.py:40
msgid "Folder:"
msgstr ""
#: src/plugins/findInFiles/findinfileswidget.py:45
msgid "Filter:"
msgstr ""
#: src/plugins/findInFiles/findinfileswidget.py:83
msgid "Open Directory"
msgstr ""
#: src/plugins/findinfilesplugin.py:31
msgid "&Find In Files"
msgstr ""
#: src/plugins/findinfilesplugin.py:37
msgid "Find In Files"
msgstr ""
#: src/plugins/krowlog/aboutdialog.py:19
msgid "About KrowLog" msgid "About KrowLog"
msgstr "" msgstr ""
#: src/plugins/krowlog/aboutdialog.py:28 #: src/plugins/krowlog/aboutdialog.py:29
msgid "Version: {0}" msgid "Version: {0}"
msgstr "" msgstr ""
#: src/plugins/krowlog/aboutdialog.py:43 #: src/plugins/krowlog/aboutdialog.py:44
msgid "About" msgid "About"
msgstr "" msgstr ""
#: src/plugins/krowlog/aboutdialog.py:44 #: src/plugins/krowlog/aboutdialog.py:45
msgid "License" msgid "License"
msgstr "" msgstr ""
#: src/plugins/krowlog/aboutdialog.py:57 #: src/plugins/krowlog/aboutdialog.py:58
msgid "Log file viewer" msgid "Log file viewer"
msgstr "" msgstr ""
#: src/plugins/krowlog/aboutdialog.py:58 #: src/plugins/krowlog/aboutdialog.py:59
msgid "(c) 2022 Andreas Huber" msgid "(c) 2022 Andreas Huber"
msgstr "" msgstr ""
#: src/plugins/krowlog/aboutdialog.py:59 #: src/plugins/krowlog/aboutdialog.py:60
msgid "License: LGPL v3" msgid "License: LGPL v3"
msgstr "" msgstr ""
@@ -116,71 +140,79 @@ msgstr ""
msgid "E&xit" msgid "E&xit"
msgstr "" msgstr ""
#: src/plugins/logfile/filterwidget.py:134 #: src/plugins/logfile/filterwidget.py:137
msgid "Cancel" msgid "Cancel"
msgstr "" msgstr ""
#: src/plugins/logfile/filterwidget.py:138 #: src/plugins/logfile/filterwidget.py:143
msgid "save query"
msgstr ""
#: src/plugins/logfile/filterwidget.py:148
msgid "ignore case" msgid "ignore case"
msgstr "" msgstr ""
#: src/plugins/logfile/filterwidget.py:142 #: src/plugins/logfile/filterwidget.py:152
msgid "regex" msgid "regex"
msgstr "" msgstr ""
#: src/plugins/logfileplugin.py:25 #: src/plugins/logfileplugin.py:26
msgid "File not found" msgid "File not found"
msgstr "" msgstr ""
#: src/plugins/logfileplugin.py:26 #: src/plugins/logfileplugin.py:27
msgid "'{0}' is not a file or cannot be opened" msgid "'{0}' is not a file or cannot be opened"
msgstr "" msgstr ""
#: src/plugins/notesplugin.py:25 #: src/plugins/notesplugin.py:24
msgid "Add &Notes" msgid "&Notes"
msgstr "" msgstr ""
#: src/plugins/notesplugin.py:33 #: src/plugins/notesplugin.py:32
msgid "Notes {0}" msgid "Notes {0}"
msgstr "" msgstr ""
#: src/plugins/openfileplugin.py:24 #: src/plugins/openfileplugin.py:25
msgid "&Open..." msgid "&Open..."
msgstr "" msgstr ""
#: src/plugins/openfileplugin.py:45 #: src/plugins/openfileplugin.py:46
msgid "Open File" msgid "Open File"
msgstr "" msgstr ""
#: src/ui/bigtext/bigtext.py:170 #: src/plugins/timediffplugin.py:17
msgid ""
msgstr ""
#: src/ui/bigtext/bigtext.py:171
msgid "&Copy to Clipboard" msgid "&Copy to Clipboard"
msgstr "" msgstr ""
#: src/ui/bigtext/bigtext.py:176 #: src/ui/bigtext/bigtext.py:177
msgid "Copy to &File" msgid "Copy to &File"
msgstr "" msgstr ""
#: src/ui/bigtext/bigtext.py:181 #: src/ui/bigtext/bigtext.py:182
msgid "Select &All" msgid "Select &All"
msgstr "" msgstr ""
#: src/ui/bigtext/bigtext.py:331 #: src/ui/bigtext/bigtext.py:332
msgid "data selection" msgid "data selection"
msgstr "" msgstr ""
#: src/ui/bigtext/bigtext.py:332 #: src/ui/bigtext/bigtext.py:333
msgid "You have selected <b>{0}</b> of data." msgid "You have selected <b>{0}</b> of data."
msgstr "" msgstr ""
#: src/ui/bigtext/bigtext.py:335 #: src/ui/bigtext/bigtext.py:336
msgid "Copy {0} to Clipboard" msgid "Copy {0} to Clipboard"
msgstr "" msgstr ""
#: src/ui/bigtext/bigtext.py:337 #: src/ui/bigtext/bigtext.py:338
msgid "Write to File" msgid "Write to File"
msgstr "" msgstr ""
#: src/ui/bigtext/bigtext.py:359 #: src/ui/bigtext/bigtext.py:360
msgid "Save File" msgid "Save File"
msgstr "" msgstr ""

View File

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

View File

@@ -1,5 +1,5 @@
pip==22.1.2 pip==22.2.2
PySide6==6.3.1 PySide6==6.3.1
setuptools==62.1.0 setuptools==62.1.0
urllib3==1.26.9 urllib3==1.26.11
watchdog==2.1.9 watchdog==2.1.9

View File

@@ -33,18 +33,50 @@ def sort_menu_contributions(menu_contributions: [MenuContribution]) -> [MenuCont
result = [] result = []
items = _sort_by_action_id(menu_contributions[:]) 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: for item in items:
mc: MenuContribution = item 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: if not mc.after:
result.append(mc) result.append(mc)
items.remove(mc) items.remove(mc)

View File

@@ -40,6 +40,39 @@ class MyTestCase(unittest.TestCase):
ordered_ids = ordered_ids + a.action_id ordered_ids = ordered_ids + a.action_id
self.assertEqual("ab", ordered_ids) 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__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

View File

@@ -0,0 +1,119 @@
import os
import sys
from pathlib import Path
from PySide6.QtCore import QDir, QModelIndex
from PySide6.QtGui import QIcon
from src.pluginregistry import PluginRegistry
from src.plugins.krowlog.Tab import Tab
from PySide6.QtWidgets import QVBoxLayout, QLabel, QLineEdit, QPushButton, QFileDialog, QTreeView, \
QFileSystemModel
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("folder"), "")
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(self._settings.get_session("findInFiles", "filter", fallback="*.log"))
self._filter.textChanged.connect(self._filter_changed)
form.addRow(QLabel(_("Filter:")), self._filter)
self._model = QFileSystemModel()
self._model.setRootPath(self._base_dir.text())
self._model.setFilter(QDir.AllDirs | QDir.NoDotAndDotDot | QDir.AllEntries)
self._model.setNameFilters([self._filter.text()])
self._model.setNameFilterDisables(False)
self._view = QTreeView()
self._view.setModel(self._model)
self._view.setRootIndex(self._model.index(self._base_dir.text()))
self._view.hideColumn(2) # hide type column
self._view.show()
self.layout.addWidget(self._view)
self._view.doubleClicked.connect(self._open_file)
# icons: /snap/gtk-common-themes/1534/share/icons/
# folder, document, text-css, text-xml, text-x-python
#
def _open_file(self, index: QModelIndex):
path = []
i = index
while i.isValid():
path.append(i.data())
i = i.parent()
path.reverse()
file = Path()
for s in path:
file = file / s
if file.is_file():
PluginRegistry.execute_single("open_file", f"{file}")
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 _filter_changed(self, filter):
self._settings.set_session("findInFiles", "filter", filter)
self._model.setNameFilters([filter])
def _base_dir_changed(self, base_dir):
if os.path.isdir(base_dir):
self._settings.set_session("findInFiles", "folder", base_dir)
self._model.setRootPath(base_dir)
self._view.setRootIndex(self._model.index(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):
find_in_files = FindInFilesWidget(
"find_in_files",
_("Find In Files"),
self.settings
)
PluginRegistry.execute_single("add_dock", Qt.DockWidgetArea.LeftDockWidgetArea, find_in_files)

View File

@@ -21,7 +21,7 @@ class NotesPlugin(PluginBase):
] ]
def _add_notes_tab_action(self) -> RAction: 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") icon_from_theme="filenew")
return open_file return open_file

View File

@@ -14,7 +14,7 @@ class TimeDiffPlugin(PluginBase):
def __init__(self): def __init__(self):
super(TimeDiffPlugin, self).__init__() super(TimeDiffPlugin, self).__init__()
self.time_diff_state = False self.time_diff_state = False
self.time_diff_action = RAction(_(""), lambda: self._toggle_time_diff(), self.time_diff_action = RAction("", lambda: self._toggle_time_diff(),
icon_file="icons/ionicons/stopwatch-outline.svg", checkable=True) icon_file="icons/ionicons/stopwatch-outline.svg", checkable=True)
self.time_diff_hook = TimeDiffPreProcessLinesHook() self.time_diff_hook = TimeDiffPreProcessLinesHook()

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)