Add support for config options hints
This commit is contained in:
parent
ba73bb975b
commit
bc9ae26787
7 changed files with 208 additions and 130 deletions
|
|
@ -231,9 +231,9 @@
|
|||
</action-widgets>
|
||||
</object>
|
||||
<object class="GtkWindow" id="mainWindow">
|
||||
<signal name="destroy" handler="gtk_main_quit" swapped="no"/>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Tuned Manager</property>
|
||||
<signal name="destroy" handler="gtk_main_quit" swapped="no"/>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
|
|
@ -258,12 +258,12 @@
|
|||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="imagemenuitemQuit">
|
||||
<signal name="activate" handler="gtk_main_quit" swapped="no"/>
|
||||
<property name="label">gtk-quit</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="gtk_main_quit" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
@ -282,12 +282,12 @@
|
|||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="imagemenuitemAbout">
|
||||
<signal name="activate" handler="execute_about" swapped="no"/>
|
||||
<property name="label">gtk-about</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="execute_about" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
@ -342,8 +342,6 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="switchTunedStartStop">
|
||||
<signal name="notify::active" handler="execute_switch_tuned" swapped="no"/>
|
||||
<property name="active">True</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="halign">start</property>
|
||||
|
|
@ -351,6 +349,8 @@
|
|||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="active">True</property>
|
||||
<signal name="notify::active" handler="execute_switch_tuned" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
|
|
@ -359,7 +359,6 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="switchTunedStartupStartStop">
|
||||
<signal name="notify::active" handler="execute_switch_tuned" swapped="no"/>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="halign">start</property>
|
||||
|
|
@ -367,6 +366,7 @@
|
|||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="hexpand">True</property>
|
||||
<signal name="notify::active" handler="execute_switch_tuned" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
|
|
@ -405,12 +405,12 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="switchTunedAdminFunctions">
|
||||
<signal name="notify::active" handler="execute_switch_tuned_admin_functions" swapped="no"/>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
<signal name="notify::active" handler="execute_switch_tuned_admin_functions" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
|
|
@ -583,13 +583,13 @@
|
|||
<property name="margin_bottom">20</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="buttonCreateProfile">
|
||||
<signal name="clicked" handler="execute_create_profile" swapped="no"/>
|
||||
<property name="label" translatable="yes">Create New Profile</property>
|
||||
<property name="width_request">200</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="margin_right">120</property>
|
||||
<signal name="clicked" handler="execute_create_profile" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
|
|
@ -598,14 +598,14 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="buttonUpadteSelectedProfile">
|
||||
<signal name="clicked" handler="execute_update_profile" swapped="no"/>
|
||||
<property name="label" translatable="yes">Update</property>
|
||||
<property name="label" translatable="yes">Edit</property>
|
||||
<property name="width_request">200</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="margin_right">10</property>
|
||||
<property name="resize_mode">queue</property>
|
||||
<signal name="clicked" handler="execute_update_profile" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
|
|
@ -614,7 +614,6 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="buttonDeleteSelectedProfile">
|
||||
<signal name="clicked" handler="execute_remove_profile" swapped="no"/>
|
||||
<property name="label" translatable="yes">Delete</property>
|
||||
<property name="width_request">200</property>
|
||||
<property name="visible">True</property>
|
||||
|
|
@ -623,6 +622,7 @@
|
|||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="image_position">right</property>
|
||||
<signal name="clicked" handler="execute_remove_profile" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
|
|
@ -686,9 +686,9 @@
|
|||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="comboboxMainPlugins">
|
||||
<signal name="changed" handler="on_changed_combobox_plugins" swapped="no"/>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<signal name="changed" handler="on_changed_combobox_plugins" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
|
@ -716,11 +716,19 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTextView" id="textviewPluginAvaibleText">
|
||||
<property name="editable">False</property>
|
||||
<property name="height_request">100</property>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<property name="min_content_height">200</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="textviewPluginAvaibleText">
|
||||
<property name="height_request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
|
@ -743,11 +751,19 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTextView" id="textviewPluginDocumentationText">
|
||||
<property name="editable">False</property>
|
||||
<property name="height_request">250</property>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<property name="min_content_height">200</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="textviewPluginDocumentationText">
|
||||
<property name="height_request">250</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
|
@ -951,11 +967,11 @@
|
|||
<property name="margin_bottom">2</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="buttonFastChangeProfile">
|
||||
<signal name="clicked" handler="execute_change_profile" swapped="no"/>
|
||||
<property name="label" translatable="yes">Change Profile</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="execute_change_profile" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
|
|
@ -990,7 +1006,6 @@
|
|||
<object class="GtkSpinner" id="spinnerFastChangeProfile">
|
||||
<property name="width_request">20</property>
|
||||
<property name="height_request">20</property>
|
||||
<property name="visible">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
|
|
@ -1080,10 +1095,10 @@
|
|||
</object>
|
||||
<object class="GtkTreeStore" id="treestoreActualPlugins"/>
|
||||
<object class="GtkTreeView" id="treeviewActualPlugins">
|
||||
<signal name="row-activated" handler="on_treeview_click" swapped="no"/>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="model">treestoreActualPlugins</property>
|
||||
<signal name="row-activated" handler="on_treeview_click" swapped="no"/>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="treeview-selection2"/>
|
||||
</child>
|
||||
|
|
@ -1119,11 +1134,11 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="cancel_button">
|
||||
<signal name="clicked" handler="HideTunedDaemonExceptionDialog" swapped="no"/>
|
||||
<property name="label" translatable="yes">Exit</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="HideTunedDaemonExceptionDialog" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
|
@ -1160,10 +1175,10 @@
|
|||
</action-widgets>
|
||||
</object>
|
||||
<object class="GtkWindow" id="windowProfileEditor">
|
||||
<signal name="delete-event" handler="on_delete_event" swapped="no"/>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Profile Editor</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<signal name="delete-event" handler="on_delete_event" swapped="no"/>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
|
|
@ -1196,7 +1211,6 @@
|
|||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="buttonAddPlugin">
|
||||
<signal name="clicked" handler="execute_add_plugin_to_notebook" swapped="no"/>
|
||||
<property name="label" translatable="yes">Add Plugin</property>
|
||||
<property name="width_request">160</property>
|
||||
<property name="visible">True</property>
|
||||
|
|
@ -1206,6 +1220,7 @@
|
|||
<property name="margin_right">20</property>
|
||||
<property name="margin_top">12</property>
|
||||
<property name="margin_bottom">13</property>
|
||||
<signal name="clicked" handler="execute_add_plugin_to_notebook" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
|
|
@ -1215,7 +1230,6 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="buttonRemovePlugin">
|
||||
<signal name="clicked" handler="execute_remove_plugin_from_notebook" swapped="no"/>
|
||||
<property name="label" translatable="yes">Remove Plugin</property>
|
||||
<property name="width_request">160</property>
|
||||
<property name="visible">True</property>
|
||||
|
|
@ -1223,6 +1237,7 @@
|
|||
<property name="receives_default">True</property>
|
||||
<property name="margin_left">20</property>
|
||||
<property name="margin_right">20</property>
|
||||
<signal name="clicked" handler="execute_remove_plugin_from_notebook" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
|
|
@ -1252,7 +1267,6 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="buttonOpenRaw">
|
||||
<signal name="clicked" handler="execute_open_raw_button" swapped="no"/>
|
||||
<property name="label" translatable="yes">Raw Editor</property>
|
||||
<property name="width_request">160</property>
|
||||
<property name="visible">True</property>
|
||||
|
|
@ -1261,6 +1275,7 @@
|
|||
<property name="halign">center</property>
|
||||
<property name="margin_top">10</property>
|
||||
<property name="margin_bottom">10</property>
|
||||
<signal name="clicked" handler="execute_open_raw_button" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
|
|
@ -1288,7 +1303,6 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="buttonConfirmProfileCreate">
|
||||
<signal name="clicked" handler="on_click_button_confirm_profile_create" swapped="no"/>
|
||||
<property name="label" translatable="yes">Confirm</property>
|
||||
<property name="width_request">160</property>
|
||||
<property name="visible">True</property>
|
||||
|
|
@ -1298,6 +1312,7 @@
|
|||
<property name="margin_right">20</property>
|
||||
<property name="margin_top">20</property>
|
||||
<property name="margin_bottom">20</property>
|
||||
<signal name="clicked" handler="on_click_button_confirm_profile_create" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
|
|
@ -1307,7 +1322,6 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="buttonConfirmProfileUpdate">
|
||||
<signal name="clicked" handler="on_click_button_confirm_profile_update" swapped="no"/>
|
||||
<property name="label" translatable="yes">Confirm</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
|
|
@ -1316,6 +1330,7 @@
|
|||
<property name="margin_right">20</property>
|
||||
<property name="margin_top">20</property>
|
||||
<property name="margin_bottom">20</property>
|
||||
<signal name="clicked" handler="on_click_button_confirm_profile_update" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
|
|
@ -1325,7 +1340,6 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="buttonCancel">
|
||||
<signal name="clicked" handler="execute_cancel_window_profile_editor" swapped="no"/>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="width_request">160</property>
|
||||
<property name="visible">True</property>
|
||||
|
|
@ -1335,6 +1349,7 @@
|
|||
<property name="margin_right">20</property>
|
||||
<property name="margin_bottom">20</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="execute_cancel_window_profile_editor" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
|
|
@ -1477,8 +1492,8 @@
|
|||
</child>
|
||||
</object>
|
||||
<object class="GtkWindow" id="windowProfileEditorRaw">
|
||||
<signal name="delete-event" handler="on_delete_event" swapped="no"/>
|
||||
<property name="can_focus">False</property>
|
||||
<signal name="delete-event" handler="on_delete_event" swapped="no"/>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
|
|
@ -1508,7 +1523,6 @@
|
|||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="textviewProfileConfigRaw">
|
||||
<property name="editable">True</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="margin_left">5</property>
|
||||
|
|
@ -1531,7 +1545,6 @@
|
|||
<property name="halign">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="buttonApply">
|
||||
<signal name="clicked" handler="execute_apply_window_profile_editor_raw" swapped="no"/>
|
||||
<property name="label">gtk-apply</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
|
|
@ -1541,6 +1554,7 @@
|
|||
<property name="margin_top">10</property>
|
||||
<property name="margin_bottom">10</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="execute_apply_window_profile_editor_raw" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
|
|
@ -1549,7 +1563,6 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="buttonCancelRaw">
|
||||
<signal name="clicked" handler="execute_cancel_window_profile_editor_raw" swapped="no"/>
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
|
|
@ -1559,6 +1572,7 @@
|
|||
<property name="margin_top">10</property>
|
||||
<property name="margin_bottom">10</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="execute_cancel_window_profile_editor_raw" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
|
|
|
|||
60
tuned-gui.py
60
tuned-gui.py
|
|
@ -50,8 +50,8 @@ import os
|
|||
import time
|
||||
import configobj
|
||||
import inspect
|
||||
|
||||
import subprocess
|
||||
|
||||
import tuned.logs
|
||||
import tuned.consts as consts
|
||||
import tuned.version as version
|
||||
|
|
@ -144,7 +144,7 @@ class Base(object):
|
|||
GObject.TYPE_STRING)
|
||||
self.treestore_plugins = Gtk.ListStore(GObject.TYPE_STRING)
|
||||
for plugin_class in self.plugin_loader.plugins:
|
||||
plugin_name = os.path.basename(inspect.getfile(plugin_class))[7:].replace('.py','')
|
||||
plugin_name = self.plugin_loader.get_plugin_name(plugin_class)
|
||||
self.treestore_plugins.append([plugin_name])
|
||||
|
||||
self._gobj('comboboxPlugins').set_model(self.treestore_plugins)
|
||||
|
|
@ -331,8 +331,11 @@ class Base(object):
|
|||
self._gobj('textviewPluginDocumentationText').get_buffer().set_text(''
|
||||
)
|
||||
return
|
||||
options = '\n'.join('%s = %r' % (key, val) for (key, val) in
|
||||
plugin._get_config_options().items())
|
||||
|
||||
options = ''
|
||||
for (key, val) in plugin._get_config_options().items():
|
||||
options += '%s = %r\n' % (key, val)
|
||||
options += '%s\n' % (plugin.get_config_options_hints().get(key, ''))
|
||||
|
||||
self._gobj('textviewPluginAvaibleText').get_buffer().set_text(options)
|
||||
self._gobj('textviewPluginDocumentationText').get_buffer().set_text(plugin.__doc__)
|
||||
|
|
@ -387,7 +390,9 @@ class Base(object):
|
|||
plugin_name = self._gobj('comboboxPlugins').get_active_text()
|
||||
plugin_to_tab = None
|
||||
for plugin in self.plugin_loader.plugins:
|
||||
cur_plugin_name = os.path.basename(inspect.getfile(plugin))[7:].replace('.py','')
|
||||
cur_plugin_name = self.plugin_loader.get_plugin_name(
|
||||
plugin
|
||||
)
|
||||
if cur_plugin_name == plugin_name:
|
||||
for children in self._gobj('notebookPlugins'):
|
||||
if plugin_name \
|
||||
|
|
@ -396,7 +401,7 @@ class Base(object):
|
|||
+ ' is already in profile.', '')
|
||||
return
|
||||
plugin_to_tab = plugin
|
||||
self._gobj('notebookPlugins').append_page_menu(self.treeview_for_data(plugin_to_tab._get_config_options()),
|
||||
self._gobj('notebookPlugins').append_page_menu(self.treeview_for_data(plugin_to_tab._get_config_options(), cur_plugin_name),
|
||||
Gtk.Label(cur_plugin_name),
|
||||
Gtk.Label(cur_plugin_name)
|
||||
)
|
||||
|
|
@ -595,12 +600,12 @@ class Base(object):
|
|||
# load all values not just normal
|
||||
|
||||
for (name, unit) in list(profile.units.items()):
|
||||
self._gobj('notebookPlugins').append_page_menu(self.treeview_for_data(unit.options),
|
||||
self._gobj('notebookPlugins').append_page_menu(self.treeview_for_data(unit.options, unit.name),
|
||||
Gtk.Label(unit.name), Gtk.Label(unit.name))
|
||||
self._gobj('notebookPlugins').show_all()
|
||||
self._gobj('windowProfileEditor').show()
|
||||
|
||||
def treeview_for_data(self, data):
|
||||
def treeview_for_data(self, data, plugin_name):
|
||||
"""
|
||||
This prepare treestore and treeview for data and return treeview
|
||||
"""
|
||||
|
|
@ -619,6 +624,20 @@ class Base(object):
|
|||
treeview.enable_grid_lines = True
|
||||
treeview.connect('row-activated', self.change_value_dialog)
|
||||
treeview.connect('button_press_event', self.on_treeview_click)
|
||||
treeview.set_property('has-tooltip',True)
|
||||
model = treeview.get_model()
|
||||
treeview.connect(
|
||||
'query-tooltip',
|
||||
lambda widget, x, y, keyboard_mode, tooltip:
|
||||
self.on_option_tooltip(widget,
|
||||
x,
|
||||
y,
|
||||
keyboard_mode,
|
||||
tooltip,
|
||||
plugin_name,
|
||||
model
|
||||
)
|
||||
)
|
||||
return treeview
|
||||
|
||||
def execute_change_profile(self, button):
|
||||
|
|
@ -822,6 +841,31 @@ class Base(object):
|
|||
rc = subprocess.call(args)
|
||||
return rc
|
||||
|
||||
def on_option_tooltip(self, widget, x, y, keyboard_mode, tooltip, plugin_name, model):
|
||||
path = widget.get_path_at_pos(x, y)
|
||||
plugin_class = self.plugin_loader.get_plugin(plugin_name)
|
||||
if plugin_class is None:
|
||||
return False
|
||||
config_option_hints = plugin_class.get_config_options_hints()
|
||||
if not path:
|
||||
row_count = model.iter_n_children(None)
|
||||
if (row_count == 0):
|
||||
return False
|
||||
iterator = model.get_iter(row_count - 1)
|
||||
option_name = model.get_value(iterator, 1)
|
||||
elif int(str(path[0])) < 1:
|
||||
return False
|
||||
else:
|
||||
iterator = model.get_iter(int(str(path[0])) -1)
|
||||
option_name = model.get_value(iterator, 1)
|
||||
path = model.get_path(iterator)
|
||||
hint = config_option_hints.get(option_name, None)
|
||||
if not hint:
|
||||
return False
|
||||
tooltip.set_text(hint)
|
||||
widget.set_tooltip_row(tooltip, path)
|
||||
return True
|
||||
|
||||
def gtk_main_quit(self, sender):
|
||||
Gtk.main_quit()
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ FUNCTION_PREFIX = "function_"
|
|||
ENV_PREFIX = "TUNED_"
|
||||
|
||||
# tuned-gui
|
||||
PREFIX_PROFILE_FACTORY = "Factory"
|
||||
PREFIX_PROFILE_FACTORY = "System"
|
||||
PREFIX_PROFILE_USER = "User"
|
||||
|
||||
CFG_DAEMON = "daemon"
|
||||
|
|
|
|||
|
|
@ -90,8 +90,14 @@ class GuiPluginLoader(PluginLoader):
|
|||
|
||||
def get_plugin(self, plugin_name):
|
||||
for plugin in self._plugins:
|
||||
if plugin_name == os.path.basename(inspect.getfile(plugin))[7:].replace('.py',''):
|
||||
if plugin_name == self.get_plugin_name(plugin):
|
||||
return plugin
|
||||
return None
|
||||
|
||||
def get_plugin_name(self, plugin):
|
||||
return os.path.splitext(
|
||||
os.path.basename(inspect.getfile(plugin))[7:]
|
||||
)[0]
|
||||
|
||||
def _load_global_config(self, file_name=consts.GLOBAL_CONFIG_FILE):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -57,6 +57,11 @@ class Plugin(object):
|
|||
"""Default configuration options for the plugin."""
|
||||
return {}
|
||||
|
||||
@classmethod
|
||||
def get_config_options_hints(cls):
|
||||
"""Explanation of each config option function"""
|
||||
return {}
|
||||
|
||||
@classmethod
|
||||
def _get_config_options_used_by_dynamic(self):
|
||||
"""List of config options used by dynamic tuning. Their previous values will be automatically saved and restored."""
|
||||
|
|
|
|||
|
|
@ -48,6 +48,14 @@ class AudioPlugin(base.Plugin):
|
|||
"reset_controller": False,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def get_config_options_hints(cls):
|
||||
"""Explanation of each config option function"""
|
||||
return {
|
||||
"timeout": "just a timeout explanation",
|
||||
"reset_controller": "how to reset pls",
|
||||
}
|
||||
|
||||
def _timeout_path(self, device):
|
||||
return "/sys/module/%s/parameters/power_save" % device
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ except:
|
|||
have_syspurpose = False
|
||||
|
||||
import tuned.consts as consts
|
||||
import tuned.logs
|
||||
from tuned.utils.commands import commands
|
||||
|
||||
log = tuned.logs.get()
|
||||
|
|
@ -28,96 +29,96 @@ class ProfileRecommender:
|
|||
self._commands = commands()
|
||||
|
||||
def recommend(self, hardcoded = False):
|
||||
profile = consts.DEFAULT_PROFILE
|
||||
if hardcoded:
|
||||
return profile
|
||||
matching = self.process_config(consts.RECOMMEND_CONF_FILE)
|
||||
if matching is not None:
|
||||
return matching
|
||||
files = {}
|
||||
for directory in consts.RECOMMEND_DIRECTORIES:
|
||||
contents = []
|
||||
try:
|
||||
contents = os.listdir(directory)
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOENT:
|
||||
log.error("error accessing %s: %s" % (directory, e))
|
||||
for name in contents:
|
||||
path = os.path.join(directory, name)
|
||||
files[name] = path
|
||||
for name in sorted(files.keys()):
|
||||
path = files[name]
|
||||
matching = self.process_config(path)
|
||||
profile = consts.DEFAULT_PROFILE
|
||||
if hardcoded:
|
||||
return profile
|
||||
matching = self.process_config(consts.RECOMMEND_CONF_FILE)
|
||||
if matching is not None:
|
||||
return matching
|
||||
return profile
|
||||
files = {}
|
||||
for directory in consts.RECOMMEND_DIRECTORIES:
|
||||
contents = []
|
||||
try:
|
||||
contents = os.listdir(directory)
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOENT:
|
||||
log.error("error accessing %s: %s" % (directory, e))
|
||||
for name in contents:
|
||||
path = os.path.join(directory, name)
|
||||
files[name] = path
|
||||
for name in sorted(files.keys()):
|
||||
path = files[name]
|
||||
matching = self.process_config(path)
|
||||
if matching is not None:
|
||||
return matching
|
||||
return profile
|
||||
|
||||
def process_config(self, fname):
|
||||
matching_profile = None
|
||||
try:
|
||||
if not os.path.isfile(fname):
|
||||
return None
|
||||
config = ConfigObj(fname, list_values = False, interpolation = False)
|
||||
for section in list(config.keys()):
|
||||
match = True
|
||||
for option in list(config[section].keys()):
|
||||
value = config[section][option]
|
||||
if value == "":
|
||||
value = r"^$"
|
||||
if option == "virt":
|
||||
if not re.match(value,
|
||||
self._commands.execute("virt-what")[1], re.S):
|
||||
match = False
|
||||
elif option == "system":
|
||||
if not re.match(value,
|
||||
self._commands.read_file(
|
||||
consts.SYSTEM_RELEASE_FILE), re.S):
|
||||
match = False
|
||||
elif option[0] == "/":
|
||||
if not os.path.exists(option) or not re.match(value,
|
||||
self._commands.read_file(option), re.S):
|
||||
match = False
|
||||
elif option[0:7] == "process":
|
||||
ps = procfs.pidstats()
|
||||
ps.reload_threads()
|
||||
if len(ps.find_by_regex(re.compile(value))) == 0:
|
||||
match = False
|
||||
elif option == "chassis_type":
|
||||
if have_dmidecode:
|
||||
for chassis in dmidecode.chassis().values():
|
||||
chassis_type = chassis["data"]["Type"].decode(
|
||||
"ascii")
|
||||
if re.match(value, chassis_type, re.IGNORECASE):
|
||||
break
|
||||
matching_profile = None
|
||||
try:
|
||||
if not os.path.isfile(fname):
|
||||
return None
|
||||
config = ConfigObj(fname, list_values = False, interpolation = False)
|
||||
for section in list(config.keys()):
|
||||
match = True
|
||||
for option in list(config[section].keys()):
|
||||
value = config[section][option]
|
||||
if value == "":
|
||||
value = r"^$"
|
||||
if option == "virt":
|
||||
if not re.match(value,
|
||||
self._commands.execute("virt-what")[1], re.S):
|
||||
match = False
|
||||
elif option == "system":
|
||||
if not re.match(value,
|
||||
self._commands.read_file(
|
||||
consts.SYSTEM_RELEASE_FILE), re.S):
|
||||
match = False
|
||||
elif option[0] == "/":
|
||||
if not os.path.exists(option) or not re.match(value,
|
||||
self._commands.read_file(option), re.S):
|
||||
match = False
|
||||
elif option[0:7] == "process":
|
||||
ps = procfs.pidstats()
|
||||
ps.reload_threads()
|
||||
if len(ps.find_by_regex(re.compile(value))) == 0:
|
||||
match = False
|
||||
elif option == "chassis_type":
|
||||
if have_dmidecode:
|
||||
for chassis in dmidecode.chassis().values():
|
||||
chassis_type = chassis["data"]["Type"].decode(
|
||||
"ascii")
|
||||
if re.match(value, chassis_type, re.IGNORECASE):
|
||||
break
|
||||
else:
|
||||
match = False
|
||||
else:
|
||||
match = False
|
||||
else:
|
||||
log.debug("Ignoring 'chassis_type' in '%s',\
|
||||
dmidecode is not available." % fname)
|
||||
elif option == "syspurpose_role":
|
||||
if have_syspurpose:
|
||||
s = syspurpose.files.SyspurposeStore(
|
||||
syspurpose.files.USER_SYSPURPOSE,
|
||||
raise_on_error = True)
|
||||
role = ""
|
||||
try:
|
||||
s.read_file()
|
||||
role = s.contents["role"]
|
||||
except (IOError, OSError, KeyError) as e:
|
||||
if hasattr(e, "errno") and e.errno != errno.ENOENT:
|
||||
log.error("Failed to load the syspurpose\
|
||||
file: %s" % e)
|
||||
if re.match(value, role, re.IGNORECASE) is None:
|
||||
match = False
|
||||
else:
|
||||
log.error("Failed to process 'syspurpose_role' in '%s'\
|
||||
, the syspurpose module is not available" % fname)
|
||||
log.debug("Ignoring 'chassis_type' in '%s',\
|
||||
dmidecode is not available." % fname)
|
||||
elif option == "syspurpose_role":
|
||||
if have_syspurpose:
|
||||
s = syspurpose.files.SyspurposeStore(
|
||||
syspurpose.files.USER_SYSPURPOSE,
|
||||
raise_on_error = True)
|
||||
role = ""
|
||||
try:
|
||||
s.read_file()
|
||||
role = s.contents["role"]
|
||||
except (IOError, OSError, KeyError) as e:
|
||||
if hasattr(e, "errno") and e.errno != errno.ENOENT:
|
||||
log.error("Failed to load the syspurpose\
|
||||
file: %s" % e)
|
||||
if re.match(value, role, re.IGNORECASE) is None:
|
||||
match = False
|
||||
else:
|
||||
log.error("Failed to process 'syspurpose_role' in '%s'\
|
||||
, the syspurpose module is not available" % fname)
|
||||
|
||||
if match:
|
||||
# remove the ",.*" suffix
|
||||
r = re.compile(r",[^,]*$")
|
||||
matching_profile = r.sub("", section)
|
||||
break
|
||||
except (IOError, OSError, ConfigObjError) as e:
|
||||
log.error("error processing '%s', %s" % (fname, e))
|
||||
return matching_profile
|
||||
if match:
|
||||
# remove the ",.*" suffix
|
||||
r = re.compile(r",[^,]*$")
|
||||
matching_profile = r.sub("", section)
|
||||
break
|
||||
except (IOError, OSError, ConfigObjError) as e:
|
||||
log.error("error processing '%s', %s" % (fname, e))
|
||||
return matching_profile
|
||||
|
|
|
|||
Loading…
Reference in a new issue