#!/usr/bin/python3 -EsI
#
# system-config-selinux.py - GUI for SELinux Config tool in system-config-selinux
#
# Dan Walsh <dwalsh@redhat.com>
#
# Copyright 2006-2009 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
import os
import signal
import sys
import gi
gi.require_version('Gtk', '3.0')
try:
    from gi.repository import Gtk
except RuntimeError as e:
    print("system-config-selinux:", e)
    print("This is a graphical application and requires DISPLAY to be set.")
    sys.exit(1)

sys.path.append('/usr/share/system-config-selinux')

from gi.repository import GObject
import statusPage
import booleansPage
import loginsPage
import usersPage
import portsPage
import modulesPage
import domainsPage
import fcontextPage
import selinux
##
## I18N
##
PROGNAME = "selinux-gui"
try:
    import gettext
    kwargs = {}
    if sys.version_info < (3,):
        kwargs['unicode'] = True
    t = gettext.translation(PROGNAME,
                    localedir="/usr/share/locale",
                    **kwargs,
                    fallback=True)
    _ = t.gettext
except:
    try:
        import builtins
        builtins.__dict__['_'] = str
    except ImportError:
        import __builtin__
        __builtin__.__dict__['_'] = unicode

version = "1.0"


##
## Pull in the Glade file
##
xml = Gtk.Builder()
xml.set_translation_domain(PROGNAME)
if os.access("system-config-selinux.ui", os.F_OK):
    xml.add_from_file("system-config-selinux.ui")
else:
    xml.add_from_file("/usr/share/system-config-selinux/system-config-selinux.ui")


class childWindow:

    def __init__(self):
        self.tabs = []
        self.xml = xml
        xml.connect_signals({
            "on_quit_activate": self.destroy,
            "on_delete_clicked": self.delete,
            "on_add_clicked": self.add,
            "on_properties_clicked": self.properties,
            "on_local_clicked": self.on_local_clicked,
            "on_policy_activate": self.policy,
            "on_logging_activate": self.logging,
            "on_about_activate": self.on_about_activate,
        })
        self.add_page(statusPage.statusPage(xml))
        if selinux.is_selinux_enabled() > 0:
            try:
                self.add_page(booleansPage.booleansPage(xml))
                self.add_page(fcontextPage.fcontextPage(xml))
                self.add_page(loginsPage.loginsPage(xml))
                self.add_page(usersPage.usersPage(xml))
                self.add_page(portsPage.portsPage(xml))
                self.add_page(modulesPage.modulesPage(xml))  # modules
                self.add_page(domainsPage.domainsPage(xml))  # domains
            except ValueError as e:
                self.error(e.message)

        self.add_menu = xml.get_object("add_menu_item")
        self.properties_menu = xml.get_object("properties_menu_item")
        self.delete_menu = xml.get_object("delete_menu_item")

    def error(self, message):
        dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR,
                                Gtk.ButtonsType.CLOSE,
                                message)
        dlg.set_position(Gtk.WindowPosition.MOUSE)
        dlg.show_all()
        dlg.run()
        dlg.destroy()

    def add_page(self, page):
        self.tabs.append(page)

    def policy(self, args):
        os.spawnl(os.P_NOWAIT, "/usr/share/system-config-selinux/semanagegui.py")

    def logging(self, args):
        os.spawnl(os.P_NOWAIT, "/usr/bin/seaudit")

    def delete(self, args):
        self.tabs[self.notebook.get_current_page()].deleteDialog()

    def add(self, args):
        self.tabs[self.notebook.get_current_page()].addDialog()

    def properties(self, args):
        self.tabs[self.notebook.get_current_page()].propertiesDialog()

    def on_local_clicked(self, button):
        self.tabs[self.notebook.get_current_page()].on_local_clicked(button)

    def on_about_activate(self, args):
        dlg = xml.get_object("aboutWindow")
        dlg.run()
        dlg.hide()

    def destroy(self, args):
        Gtk.main_quit()

    def use_menus(self, use_menus):
        self.add_menu.set_sensitive(use_menus)
        self.properties_menu.set_sensitive(use_menus)
        self.delete_menu.set_sensitive(use_menus)

    def itemSelected(self, selection):
        store, rows = selection.get_selected_rows()
        if store != None and len(rows) > 0:
            self.notebook.set_current_page(rows[0][0])
            self.use_menus(self.tabs[rows[0][0]].use_menus())
        else:
            self.notebook.set_current_page(0)
            self.use_menus(self.tabs[0].use_menus())

    def setupScreen(self):
        # Bring in widgets from glade file.
        self.mainWindow = self.xml.get_object("mainWindow")
        self.notebook = self.xml.get_object("notebook")
        self.view = self.xml.get_object("selectView")
        self.view.get_selection().connect("changed", self.itemSelected)
        self.store = Gtk.ListStore(GObject.TYPE_STRING)
        self.view.set_model(self.store)
        col = Gtk.TreeViewColumn("", Gtk.CellRendererText(), text=0)
        col.set_resizable(True)
        self.view.append_column(col)

        for page in self.tabs:
            iter = self.store.append()
            self.store.set_value(iter, 0, page.get_description())
        self.view.get_selection().select_path((0,))

    def stand_alone(self):
        desktopName = _("Configure SELinux")

        self.setupScreen()

        self.mainWindow.connect("destroy", self.destroy)

        self.mainWindow.show_all()
        Gtk.main()

if __name__ == "__main__":
    signal.signal(signal.SIGINT, signal.SIG_DFL)

    app = childWindow()
    app.stand_alone()
