Skip to content

Commit

Permalink
ui: allow to use GUI themes
Browse files Browse the repository at this point in the history
Now the user can personalize GUI's appearance (#424).

There're 15 default themes, dark and light, that will help integrating
on some environments (#303, #335).

More themes can be added, by creating a new xml under
~/.config/opensnitch/themes/ or
/usr/lib/python3/dist-packages/opensnitch/

The lib used is https://github.com/UN-GCPDS/qt-material.
https://github.com/UN-GCPDS/qt-material#custom-colors
  • Loading branch information
gustavo-iniguez-goya committed Apr 6, 2022
1 parent caa8fac commit c20f1c1
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 67 deletions.
18 changes: 13 additions & 5 deletions ui/bin/opensnitch-ui
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ if dist_path not in sys.path:

from opensnitch.service import UIService
from opensnitch.config import Config
from opensnitch.utils import Themes
import opensnitch.version
import opensnitch.ui_pb2
from opensnitch.ui_pb2_grpc import add_UIServicer_to_server
Expand All @@ -40,6 +41,15 @@ def supported_qt_version(major, medium, minor):
q = QtCore.QT_VERSION_STR.split(".")
return int(q[0]) >= major and int(q[1]) >= medium and int(q[2]) >= minor

def load_translations():
locale = QtCore.QLocale.system()
i18n_path = os.path.dirname(os.path.realpath(opensnitch.__file__)) + "/i18n"
print("Loading translations:", i18n_path, "locale:", locale.name())
translator = QtCore.QTranslator()
translator.load(i18n_path + "/" + locale.name() + "/opensnitch-" + locale.name() + ".qm")

return translator

if __name__ == '__main__':
parser = argparse.ArgumentParser(description='OpenSnitch UI service.')
parser.add_argument("--socket", dest="socket", default="unix:///tmp/osui.sock", help="Path of the unix socket for the gRPC service (https://github.com/grpc/grpc/blob/master/doc/naming.md).", metavar="FILE")
Expand All @@ -55,13 +65,11 @@ if __name__ == '__main__':
except Exception:
pass

locale = QtCore.QLocale.system()
i18n_path = os.path.dirname(os.path.realpath(opensnitch.__file__)) + "/i18n"
print("Loading translations:", i18n_path, "locale:", locale.name())
translator = QtCore.QTranslator()
translator.load(i18n_path + "/" + locale.name() + "/opensnitch-" + locale.name() + ".qm")
translator = load_translations()
app = QtWidgets.QApplication(sys.argv)
app.installTranslator(translator)
thm = Themes.instance()
thm.load_theme(app)

service = UIService(app, on_exit)
# @doc: https://grpc.github.io/grpc/python/grpc.html#server-object
Expand Down
2 changes: 1 addition & 1 deletion ui/opensnitch/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class Config:
POPUP_TOP_LEFT = 3
POPUP_BOTTOM_LEFT = 4

DEFAULT_THEME = "global/theme"
DEFAULT_DISABLE_POPUPS = "global/disable_popups"
DEFAULT_TIMEOUT_KEY = "global/default_timeout"
DEFAULT_ACTION_KEY = "global/default_action"
Expand All @@ -65,7 +66,6 @@ class Config:
NOTIFICATION_TYPE_SYSTEM = 0
NOTIFICATION_TYPE_QT = 1


STATS_GEOMETRY = "statsDialog/geometry"
STATS_LAST_TAB = "statsDialog/last_tab"
STATS_FILTER_TEXT = "statsDialog/general_filter_text"
Expand Down
39 changes: 34 additions & 5 deletions ui/opensnitch/dialogs/preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from opensnitch.config import Config
from opensnitch.nodes import Nodes
from opensnitch.database import Database
from opensnitch.utils import Message, QuickHelp
from opensnitch.utils import Message, QuickHelp, Themes
from opensnitch.notifications import DesktopNotifications

from opensnitch import ui_pb2
Expand All @@ -32,6 +32,9 @@ class PreferencesDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
def __init__(self, parent=None, appicon=None):
QtWidgets.QDialog.__init__(self, parent, QtCore.Qt.WindowStaysOnTopHint)

self._themes = Themes.instance()
self._saved_theme = ""

self._cfg = Config.get()
self._nodes = Nodes.instance()
self._db = Database.instance()
Expand Down Expand Up @@ -115,10 +118,28 @@ def showEvent(self, event):
# True when any node option changes
self._node_needs_update = False

def _load_themes(self):
theme_idx, self._saved_theme = self._themes.get_saved_theme()

self.labelThemeError.setVisible(False)
self.labelThemeError.setText("")
self.comboUITheme.clear()
self.comboUITheme.addItem(QC.translate("preferences", "System"))
if self._themes.available():
themes = self._themes.list_themes()
self.comboUITheme.addItems(themes)
else:
self._saved_theme = ""
self.labelThemeError.setStyleSheet('color: red')
self.labelThemeError.setVisible(True)
self.labelThemeError.setText(QC.translate("preferences", "Themes not available. Install qt-material: pip3 install qt-material"))

self.comboUITheme.setCurrentIndex(theme_idx)

def _load_settings(self):
self._default_action = self._cfg.getInt(self._cfg.DEFAULT_ACTION_KEY)
self._default_target = self._cfg.getSettings(self._cfg.DEFAULT_TARGET_KEY)
self._default_timeout = self._cfg.getSettings(self._cfg.DEFAULT_TIMEOUT_KEY)
self._default_target = self._cfg.getInt(self._cfg.DEFAULT_TARGET_KEY, 0)
self._default_timeout = self._cfg.getInt(self._cfg.DEFAULT_TIMEOUT_KEY, 15)
self._disable_popups = self._cfg.getBool(self._cfg.DEFAULT_DISABLE_POPUPS)

if self._cfg.hasKey(self._cfg.DEFAULT_DURATION_KEY):
Expand All @@ -140,8 +161,8 @@ def _load_settings(self):
)

self.comboUIAction.setCurrentIndex(self._default_action)
self.comboUITarget.setCurrentIndex(int(self._default_target))
self.spinUITimeout.setValue(int(self._default_timeout))
self.comboUITarget.setCurrentIndex(self._default_target)
self.spinUITimeout.setValue(self._default_timeout)
self.spinUITimeout.setEnabled(not self._disable_popups)
self.popupsCheck.setChecked(self._disable_popups)

Expand Down Expand Up @@ -171,6 +192,7 @@ def _load_settings(self):
self.spinDBMaxDays.setValue(dbMaxDays)
self.spinDBPurgeInterval.setValue(dbPurgeInterval)

self._load_themes()
self._load_node_settings()
self._load_ui_columns_config()

Expand Down Expand Up @@ -360,6 +382,13 @@ def _save_ui_config(self):
self._cfg.setSettings(self._cfg.NOTIFICATIONS_TYPE,
int(Config.NOTIFICATION_TYPE_SYSTEM if self.radioSysNotifs.isChecked() else Config.NOTIFICATION_TYPE_QT))

self._themes.save_theme(self.comboUITheme.currentIndex(), self.comboUITheme.currentText())
if self._themes.available() and self._saved_theme != self.comboUITheme.currentText():
Message.ok(
QC.translate("preferences", "UI theme changed"),
QC.translate("preferences", "Restart the GUI in order to apply the new theme"),
QtWidgets.QMessageBox.Warning)

# this is a workaround for not display pop-ups.
# see #79 for more information.
if self.popupsCheck.isChecked():
Expand Down
59 changes: 41 additions & 18 deletions ui/opensnitch/res/preferences.ui
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>626</width>
<height>405</height>
<height>442</height>
</rect>
</property>
<property name="windowTitle">
Expand Down Expand Up @@ -472,21 +472,7 @@
<string>UI</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="1">
<widget class="QComboBox" name="comboUIRules">
<item>
<property name="text">
<string>any temporary rules</string>
</property>
</item>
<item>
<property name="text">
<string>once</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<item row="2" column="0">
<widget class="QCheckBox" name="checkUIRules">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;When this option is selected, the rules of the selected duration won't be added to the list of temporary rules in the GUI.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Temporary rules will still be valid, and you can use them when prompted to allow/deny a new connection.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
Expand All @@ -496,7 +482,7 @@
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<item row="3" column="0" colspan="2">
<widget class="QGroupBox" name="groupNotifs">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
Expand Down Expand Up @@ -577,7 +563,16 @@
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<item row="0" column="1">
<widget class="QComboBox" name="comboUITheme">
<item>
<property name="text">
<string>System</string>
</property>
</item>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
Expand Down Expand Up @@ -704,6 +699,34 @@
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_21">
<property name="text">
<string>Theme</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboUIRules">
<item>
<property name="text">
<string>any temporary rules</string>
</property>
</item>
<item>
<property name="text">
<string>once</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="labelThemeError">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
Expand Down
47 changes: 10 additions & 37 deletions ui/opensnitch/res/stats.ui
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@
<iconset theme="edit-clear-all">
<normaloff>../../../../../../../../../../../../../../../../../../../../../../../../../../.designer/backup</normaloff>../../../../../../../../../../../../../../../../../../../../../../../../../../.designer/backup</iconset>
</property>
<property name="autoDefault">
<bool>false</bool>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
Expand Down Expand Up @@ -279,13 +279,7 @@
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="QToolButton" name="saveButton">
<property name="minimumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<widget class="QPushButton" name="saveButton">
<property name="toolTip">
<string>Save to CSV.</string>
</property>
Expand All @@ -299,54 +293,39 @@
<property name="shortcut">
<string>Ctrl+S</string>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonFollowStyle</enum>
</property>
<property name="autoRaise">
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="prefsButton">
<widget class="QPushButton" name="prefsButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset theme="preferences-system">
<normaloff>../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../.designer/backup</normaloff>../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../.designer/backup</iconset>
</property>
<property name="autoRaise">
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="newRuleButton">
<widget class="QPushButton" name="newRuleButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>32</horstretch>
<verstretch>32</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="toolTip">
<string>Create a new rule</string>
</property>
Expand All @@ -357,7 +336,7 @@
<iconset theme="document-new">
<normaloff>../../../../../../../../.designer/backup</normaloff>../../../../../../../../.designer/backup</iconset>
</property>
<property name="autoRaise">
<property name="flat">
<bool>true</bool>
</property>
</widget>
Expand Down Expand Up @@ -453,13 +432,7 @@
</widget>
</item>
<item>
<widget class="QToolButton" name="startButton">
<property name="minimumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<widget class="QPushButton" name="startButton">
<property name="toolTip">
<string>Start or Stop interception</string>
</property>
Expand All @@ -476,7 +449,7 @@
<property name="checked">
<bool>false</bool>
</property>
<property name="autoRaise">
<property name="flat">
<bool>true</bool>
</property>
</widget>
Expand Down
Loading

0 comments on commit c20f1c1

Please sign in to comment.