def __init__(self, wiface='wlan0', socket_id=0, no_confirm_ether=False): self.wiface = wiface self.network_list = [] self.no_confirm_ether = no_confirm_ether # Default basic styling apply_common_to_screen() # Attach specific styling apply_styling_to_screen(self.CSS_PATH) # Set window base_class.__init__( self, _("Kano WiFi"), self.width, self.height, socket_id ) self.top_bar = TopBar(_("Kano WiFi")) self.top_bar.set_prev_callback(self.refresh_networks) self.top_bar.set_close_callback(Gtk.main_quit) self.prev_handler = None self.connect('delete-event', Gtk.main_quit) self.set_keep_above(True) self.set_icon_name('kano-settings') self.set_decorated(True) if self._base_name == "Window": self.set_titlebar(self.top_bar) self._launch_application()
def __init__(self, screen_number=None, screen_name=None, socket_id=0, onescreen=False): # Check for internet, if screen is 12 means no internet if screen_number == 12 or screen_name == 'no-internet': common.has_internet = False else: common.has_internet = is_internet() # Set combobox styling to the screen # Is done here so we don't attach the styling multiple times when # switching screens apply_styling_to_screen(self.CSS_PATH) apply_common_to_screen() KanoComboBox.apply_styling_to_screen() ScrolledWindow.apply_styling_to_screen(wide=True) # Set window base_class.__init__(self, _("Settings"), self.width, self.height, socket_id) self.set_decorated(True) self.top_bar = TopBar(_("Settings")) self.top_bar.set_close_callback(self.close_window) self.prev_handler = None self.set_icon_name('kano-settings') if self._base_name == "Window": self.set_titlebar(self.top_bar) self._onescreen = onescreen self.connect('delete-event', Gtk.main_quit) # In case we are called from kano-world-launcher, terminate splash os.system('kano-stop-splash') # Init to Home Screen HomeScreen(self, screen_number=screen_number, screen_name=screen_name)
def __init__(self): apply_common_to_screen() self.a = self.b = self.c = 0 self.switching = 0 ApplicationWindow.__init__(self, _('Login'), self.WIDTH, self.HEIGHT) self.connect("delete-event", Gtk.main_quit) # Create a new LightDM.Greeter instance which will be used by the 2 views self.greeter = GreeterWindow.greeter.new() # Create the two views: one for normal Login, the other to create a new account self.password_view = PasswordView(None, self.greeter) self.newuser_view = NewUserView(self.greeter) self.login_with_kw_view = LoginWithKanoWorldView(self.greeter) self.grid = Gtk.Grid() self.set_main_widget(self.grid) self.grid.set_column_spacing(30) self.grid.set_row_spacing(30) self.top_bar = TopBar(_('Login')) self._remove_top_bar_buttons() self.top_bar.set_size_request(self.WIDTH, -1) self.grid.attach(self.top_bar, 0, 0, 3, 1) self.grid.attach(Gtk.Label(), 0, 3, 3, 1) self.top_bar.set_prev_callback(self._back_cb) self.user_list = UserListView() self.go_to_users() cursor = Gdk.Cursor.new(Gdk.CursorType.ARROW) self.get_root_window().set_cursor(cursor)
def __init__(self, install=None, icon_only=False, tutorial=False): ApplicationWindow.__init__(self, 'Apps', 755, 588) self._install = install self._tutorial = tutorial self._icon_only = icon_only self._last_page = 0 self.connect("show", self._app_loaded) # Destructor self.connect('delete-event', Gtk.main_quit) self.set_icon_from_file("/usr/share/kano-desktop/icons/apps.png") # Styling screen = Gdk.Screen.get_default() specific_css_provider = Gtk.CssProvider() specific_css_provider.load_from_path(Media.media_dir() + 'css/style.css') specific_style_context = Gtk.StyleContext() specific_style_context.add_provider_for_screen( screen, specific_css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) style = self.get_style_context() style.add_class('main_window') # Setup widgets self.set_decorated(True) self._top_bar = TopBar(_("Apps"), self._win_width, False) self._top_bar.set_close_callback(Gtk.main_quit) self.set_titlebar(self._top_bar) self._contents = Contents(self) self.set_main_widget(self._contents) self.show_apps_view()
def __init__(self, install=None, icon_only=False, tutorial=False): ApplicationWindow.__init__(self, 'Apps', 755, 588) self._install = install self._tutorial = tutorial self._icon_only = icon_only self._last_page = 0 self.connect("show", self._app_loaded) # Destructor self.connect('delete-event', Gtk.main_quit) self.set_icon_from_file("/usr/share/kano-desktop/icons/apps.png") # Styling screen = Gdk.Screen.get_default() specific_css_provider = Gtk.CssProvider() specific_css_provider.load_from_path(Media.media_dir() + 'css/style.css') specific_style_context = Gtk.StyleContext() specific_style_context.add_provider_for_screen( screen, specific_css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER ) style = self.get_style_context() style.add_class('main_window') # Setup widgets self.set_decorated(True) self._top_bar = TopBar(_("Apps"), self._win_width, False) self._top_bar.set_close_callback(Gtk.main_quit) self.set_titlebar(self._top_bar) self._contents = Contents(self) self.set_main_widget(self._contents) self.show_apps_view()
class MainWindow(ApplicationWindow): def __init__(self, install=None, icon_only=False, tutorial=False): ApplicationWindow.__init__(self, 'Apps', 755, 588) self._install = install self._tutorial = tutorial self._icon_only = icon_only self._last_page = 0 self.connect("show", self._app_loaded) # Destructor self.connect('delete-event', Gtk.main_quit) self.set_icon_from_file("/usr/share/kano-desktop/icons/apps.png") # Styling screen = Gdk.Screen.get_default() specific_css_provider = Gtk.CssProvider() specific_css_provider.load_from_path(Media.media_dir() + 'css/style.css') specific_style_context = Gtk.StyleContext() specific_style_context.add_provider_for_screen( screen, specific_css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER ) style = self.get_style_context() style.add_class('main_window') # Setup widgets self.set_decorated(True) self._top_bar = TopBar(_("Apps"), self._win_width, False) self._top_bar.set_close_callback(Gtk.main_quit) self.set_titlebar(self._top_bar) self._contents = Contents(self) self.set_main_widget(self._contents) self.show_apps_view() def get_main_area(self): return self._contents def get_last_page(self): return self._last_page def set_last_page(self, last_page_num): self._last_page = last_page_num def show_apps_view(self, button=None, event=None): self._top_bar.disable_prev() self._apps = apps = Apps(get_applications(), self) self.get_main_area().set_contents(apps) def refresh(self, category=None): for app in get_applications(): if self._apps.has_app(app): self._apps.update_app(app) else: self._apps.add_app(app) def _app_loaded(self, widget): if self._install is not None: self._install_apps() elif self._tutorial: self._show_icon_tutorial() def _show_icon_tutorial(self): if load_app_state_variable('kano-apps', 'icon-tutorial-shown'): return else: save_app_state_variable('kano-apps', 'icon-tutorial-shown', True) kdialog = KanoDialog( _("Add more apps to the desktop"), _( "Click the '+' button to the right of the app name to " "make it appear on the desktop. You can remove it again " "by clicking on 'x'." ), { _("OK, GOT IT"): { "return_value": 0, "color": "green" } }, parent_window=self ) kdialog.set_action_background("grey") kdialog.title.description.set_max_width_chars(40) kdialog.run() def _install_apps(self): pw = None for app in self._install: inst = AppInstaller(app, self._apps, pw, self) inst.set_check_if_installed(True) inst.set_icon_only(self._icon_only) inst.install() pw = inst.get_sudo_pw() self.set_last_page(0) refresh_package_list() self.refresh()
class MainWindow(ApplicationWindow): def __init__(self, install=None, icon_only=False, tutorial=False): ApplicationWindow.__init__(self, 'Apps', 755, 588) self._install = install self._tutorial = tutorial self._icon_only = icon_only self._last_page = 0 self.connect("show", self._app_loaded) # Destructor self.connect('delete-event', Gtk.main_quit) self.set_icon_from_file("/usr/share/kano-desktop/icons/apps.png") # Styling screen = Gdk.Screen.get_default() specific_css_provider = Gtk.CssProvider() specific_css_provider.load_from_path(Media.media_dir() + 'css/style.css') specific_style_context = Gtk.StyleContext() specific_style_context.add_provider_for_screen( screen, specific_css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) style = self.get_style_context() style.add_class('main_window') # Setup widgets self.set_decorated(True) self._top_bar = TopBar(_("Apps"), self._win_width, False) self._top_bar.set_close_callback(Gtk.main_quit) self.set_titlebar(self._top_bar) self._contents = Contents(self) self.set_main_widget(self._contents) self.show_apps_view() def get_main_area(self): return self._contents def get_last_page(self): return self._last_page def set_last_page(self, last_page_num): self._last_page = last_page_num def show_apps_view(self, button=None, event=None): self._top_bar.disable_prev() self._apps = apps = Apps(get_applications(), self) self.get_main_area().set_contents(apps) def refresh(self, category=None): for app in get_applications(): if self._apps.has_app(app): self._apps.update_app(app) else: self._apps.add_app(app) def _app_loaded(self, widget): if self._install is not None: self._install_apps() elif self._tutorial: self._show_icon_tutorial() def _show_icon_tutorial(self): try: from kano_profile.apps import save_app_state_variable, load_app_state_variable if load_app_state_variable('kano-apps', 'icon-tutorial-shown'): return else: save_app_state_variable('kano-apps', 'icon-tutorial-shown', True) except ImportError: # ignore problems importing kano_profile, as we don't want it to # be a dependency pass kdialog = KanoDialog( _("Add more apps to the desktop"), _("Click the '+' button to the right of the app name to " "make it appear on the desktop. You can remove it again " "by clicking on 'x'."), {_("OK, GOT IT"): { "return_value": 0, "color": "green" }}, parent_window=self) kdialog.set_action_background("grey") kdialog.title.description.set_max_width_chars(40) kdialog.run() def _install_apps(self): pw = None for app in self._install: inst = AppInstaller(app, self._apps, pw, self) inst.set_check_if_installed(True) inst.set_icon_only(self._icon_only) inst.install() pw = inst.get_sudo_pw() self.set_last_page(0) refresh_package_list() self.refresh()
class MainWindow(base_class): state = 0 last_level_visited = 0 width = 680 height = 405 CSS_PATH = os.path.join(common.css_dir, 'style.css') def __init__(self, screen_number=None, screen_name=None, socket_id=0, onescreen=False): # Check for internet, if screen is 12 means no internet if screen_number == 12 or screen_name == 'no-internet': common.has_internet = False else: common.has_internet = is_internet() # Set combobox styling to the screen # Is done here so we don't attach the styling multiple times when # switching screens apply_styling_to_screen(self.CSS_PATH) apply_common_to_screen() KanoComboBox.apply_styling_to_screen() ScrolledWindow.apply_styling_to_screen(wide=True) # Set window base_class.__init__(self, _("Settings"), self.width, self.height, socket_id) self.set_decorated(True) self.top_bar = TopBar(_("Settings")) self.top_bar.set_close_callback(self.close_window) self.prev_handler = None self.set_icon_name('kano-settings') if self._base_name == "Window": self.set_titlebar(self.top_bar) self._onescreen = onescreen self.connect('delete-event', Gtk.main_quit) # In case we are called from kano-world-launcher, terminate splash os.system('kano-stop-splash') # Init to Home Screen HomeScreen(self, screen_number=screen_number, screen_name=screen_name) def clear_win(self): self.remove_main_widget() def go_to_home(self, widget=None, event=None): self.clear_win() if self._onescreen: sys.exit(0) HomeScreen(self) def change_prev_callback(self, callback): # first time, no event attached self.remove_prev_callback() self.prev_handler = self.top_bar.prev_button.connect( 'button-release-event', callback ) def remove_prev_callback(self): if self.prev_handler: self.top_bar.prev_button.disconnect(self.prev_handler) self.prev_handler = None def _trigger_tracking_event(self): """ Generate a tracker event with some hardware settings. This will send a track_date event called 'user-settings' with the audio setting, parental lock level and display configuration. """ track_data('user-settings', { 'audio': 'hdmi' if is_HDMI() else 'analog', 'parental-lock-level': get_setting('Parental-level'), 'display': get_status() }) # On closing window, will alert if any of the listed booleans are True def close_window(self, button, event): if common.need_reboot: kdialog = KanoDialog( _("Reboot?"), _("Your Kano needs to reboot for changes to apply"), [ { 'label': _("LATER"), 'color': 'grey', 'return_value': False }, { 'label': _("REBOOT NOW"), 'color': 'orange', 'return_value': True } ], parent_window=self.get_toplevel() ) kdialog.set_action_background('grey') do_reboot_now = kdialog.run() if do_reboot_now: os.system("sudo systemctl reboot") self._trigger_tracking_event() Gtk.main_quit()
class FeedbackWindow(MainWindow): CLOSE_FEEDBACK = 0 KEEP_OPEN = 1 LAUNCH_WIFI = 2 WIDTH = 400 def __init__(self, bug_report=False): ''' Initialises the window, creating a report or contact window ''' MainWindow.__init__(self, subject='Kano Desktop Feedback Widget') self.bug_report = bug_report if self.bug_report: self.report_window() else: self.contact_window() def contact_window(self): ''' Contact Us window Contains text view and a Send button ''' # delete the directory containing all the info we'll send, and recreate delete_tmp_dir() create_tmp_dir() ApplicationWindow.__init__( self, _('Contact Us'), # noqa: F821 self.WIDTH, 0.35 ) screen = Gdk.Screen.get_default() specific_provider = Gtk.CssProvider() specific_provider.load_from_path(Media.media_dir() + 'css/style.css') style_context = Gtk.StyleContext() style_context.add_provider_for_screen(screen, specific_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) # Make sure this window has no icon in the task bar # so it plays nice with kdesk-blur self.set_property('skip-taskbar-hint', True) self._grid = Gtk.Grid() # Create top bar self._top_bar = TopBar( title=_("Contact Us"), # noqa: F821 window_width=self.WIDTH, has_buttons=False ) self._top_bar.set_close_callback(Gtk.main_quit) self.set_decorated(True) self.set_titlebar(self._top_bar) # Create Text view self._text = Gtk.TextView() self._text.set_editable(True) self._text.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) self._text.set_size_request(self.WIDTH, -1) self._textbuffer = self._text.get_buffer() self._textbuffer.set_text( _("Type your feedback here!") # noqa: F821 ) self._clear_buffer_handler_id = self._textbuffer.connect( "insert-text", self.clear_buffer ) scrolledwindow = ScrolledWindow() scrolledwindow.set_vexpand(True) scrolledwindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolledwindow.apply_styling_to_widget() scrolledwindow.add(self._text) scrolledwindow.set_margin_left(2) scrolledwindow.set_margin_right(2) scrolledwindow.set_margin_top(2) scrolledwindow.set_margin_bottom(2) # Very hacky way to get a border: create a grey event box # which is a little bigger than the widget below border = Gtk.EventBox() border.get_style_context().add_class("grey") border.add(scrolledwindow) self._grid.attach(border, 0, 0, 1, 1) border.set_margin_left(20) border.set_margin_right(20) border.set_margin_top(10) border.set_margin_bottom(20) # Create send button self._send_button = KanoButton( _("SEND") # noqa: F821 ) self._send_button.set_sensitive(False) self._send_button.connect("button_press_event", self.send_feedback) self._send_button.pack_and_align() self._send_button.align.set_padding(10, 10, 0, 0) bottom_background = Gtk.EventBox() bottom_background.get_style_context().add_class("grey") bottom_background.add(self._send_button.align) self._grid.attach(bottom_background, 0, 1, 1, 1) self._grid.set_row_spacing(0) self.set_main_widget(self._grid) # kano-profile stat collection try: from kano_profile.badges import \ increment_app_state_variable_with_dialog increment_app_state_variable_with_dialog( 'kano-feedback', 'starts', 1 ) except Exception: pass def report_window(self): ''' Report window Contains 2 text views and Take Screenshot, Add Image and Send buttons ''' ApplicationWindow.__init__( self, _('Report a Problem'), # noqa: F821 self.WIDTH, 0.35 ) screen = Gdk.Screen.get_default() specific_provider = Gtk.CssProvider() specific_provider.load_from_path(Media.media_dir() + 'css/style.css') style_context = Gtk.StyleContext() style_context.add_provider_for_screen(screen, specific_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) self.set_icon_name("feedback") self._grid = Gtk.Grid() # Create top bar self._top_bar = TopBar( title=_("Report a Problem"), # noqa: F821 window_width=self.WIDTH, has_buttons=False ) self._top_bar.set_close_callback(Gtk.main_quit) self.set_decorated(True) self.set_titlebar(self._top_bar) self.entry = Gtk.Entry() self.entry.props.placeholder_text = \ _("Add subject (optional)") # noqa: F821 self.entry.set_margin_left(20) self.entry.set_margin_right(20) self.entry.set_margin_top(20) self.entry.set_margin_bottom(10) self._grid.attach(self.entry, 0, 0, 1, 1) # Create Text view self._text = Gtk.TextView() self._text.set_editable(True) self._text.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) self._text.set_size_request(self.WIDTH, -1) self._textbuffer = self._text.get_buffer() self._textbuffer.set_text( _("Type your problem here!") # noqa: F821 ) self._clear_buffer_handler_id = self._textbuffer.connect( "insert-text", self.clear_buffer ) scrolledwindow = ScrolledWindow() scrolledwindow.set_vexpand(True) scrolledwindow.set_policy( Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC ) scrolledwindow.apply_styling_to_widget() scrolledwindow.add(self._text) scrolledwindow.set_margin_left(2) scrolledwindow.set_margin_right(2) scrolledwindow.set_margin_top(2) scrolledwindow.set_margin_bottom(2) # Very hacky way to get a border: create a grey event box # which is a little bigger than the widget below border = Gtk.EventBox() border.get_style_context().add_class("grey") border.add(scrolledwindow) self._grid.attach(border, 0, 1, 1, 1) border.set_margin_left(20) border.set_margin_right(20) border.set_margin_top(10) border.set_margin_bottom(20) # Create take screenshot button self._screenshot_button = KanoButton( _("TAKE SCREENSHOT"), # noqa: F821 "blue" ) self._screenshot_button.set_sensitive(True) self._screenshot_button.connect("button_press_event", self.screenshot_clicked) # Create attach screenshot button self._attach_button = KanoButton( _("ADD IMAGE"), # noqa: F821 "blue" ) self._attach_button.set_sensitive(True) self._attach_button.connect("button_press_event", self.attach_clicked) # Create send button self._send_button = KanoButton( _("SEND") # noqa: F821 ) self._send_button.set_sensitive(False) self._send_button.connect("button_press_event", self.send_feedback) self._send_button.pack_and_align() self._send_button.set_margin(10, 0, 10, 0) self.screenshot_box = Gtk.ButtonBox() self.screenshot_box.set_layout(Gtk.ButtonBoxStyle.CENTER) self.screenshot_box.set_spacing(20) self.pack_screenshot_buttons() self.screenshot_box.set_margin_bottom(20) self._grid.attach(self.screenshot_box, 0, 2, 1, 1) # Create grey box to put the button in self.bottom_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.bottom_box.pack_start(self._send_button.align, False, False, 0) bottom_background = Gtk.EventBox() bottom_background.get_style_context().add_class("grey") bottom_background.add(self.bottom_box) self._grid.attach(bottom_background, 0, 3, 1, 1) self._grid.set_row_spacing(0) self.set_main_widget(self._grid) # kano-profile stat collection try: from kano_profile.badges import increment_app_state_variable_with_dialog increment_app_state_variable_with_dialog( 'kano-feedback', 'starts', 1 ) except Exception: pass def screenshot_clicked(self, button=None, event=None): ''' Takes a screenshot while minimising the window ''' # minimise the window self.iconify() take_screenshot() self.include_screenshot() # restore the window self.deiconify() def attach_clicked(self, button=None, event=None): ''' Opens the File Chooser Dialog. If image selected then copy it to the feedback folder ''' screenshot = None # Open file manager dialog = Gtk.FileChooserDialog( _("Please choose a file"), # noqa: F821 self, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK) ) self.add_filters(dialog) response = dialog.run() if response == Gtk.ResponseType.OK: screenshot = dialog.get_filename() dialog.destroy() # Copy image file into feedback folder if screenshot is not None: copy_screenshot(screenshot) self.include_screenshot() def add_filters(self, dialog): ''' Add image type filters Used for the File Chooser Dialog ''' # Image filter filter_images = Gtk.FileFilter() filter_images.set_name("Images") filter_images.add_mime_type("image/png") filter_images.add_mime_type("image/jpeg") filter_images.add_mime_type("image/gif") filter_images.add_pattern("*.png") filter_images.add_pattern("*.jpg") filter_images.add_pattern("*.gif") filter_images.add_pattern("*.tif") filter_images.add_pattern("*.xpm") dialog.add_filter(filter_images) # Any file filter filter_any = Gtk.FileFilter() filter_any.set_name("Any files") filter_any.add_pattern("*") dialog.add_filter(filter_any) def include_screenshot(self): ''' This is the box containing the filename of the screenshot, and the option to display it or remove it ''' if not hasattr(self, "screenshot"): # We pack the buttons into an event box with styling # so that we can have a container with a border radius # without having ugly gaps between the buttons. self.screenshot = Gtk.EventBox() self.screenshot.get_style_context().add_class("kano_button") self.screenshot.get_style_context().add_class("blue_background") remove_screenshot = Gtk.Button() attach_cursor_events(remove_screenshot) remove_icon = Gtk.Image.new_from_file("/usr/share/kano-feedback/media/icons/close.png") remove_screenshot.add(remove_icon) remove_screenshot.connect("button-release-event", self.remove_screenshot) remove_screenshot.get_style_context().add_class("blue_background") show_screenshot = Gtk.Button() attach_cursor_events(show_screenshot) show_icon = Gtk.Image() show_icon.set_from_file("/usr/share/kano-feedback/media/icons/preview.png") show_screenshot.add(show_icon) show_screenshot.connect("button-release-event", self.show_screenshot) show_screenshot.get_style_context().add_class("blue_background") label = Gtk.Label(SCREENSHOT_NAME.upper()) label.set_padding(10, 0) box = Gtk.Box() box.pack_start(label, False, False, 0) box.pack_end(remove_screenshot, False, False, 0) box.pack_end(show_screenshot, False, False, 0) self.screenshot.add(box) self.screenshot_box.remove(self._screenshot_button) self.screenshot_box.remove(self._attach_button) self.screenshot_box.pack_start(self.screenshot, False, False, 0) def remove_screenshot(self, widget, event): ''' Remove screenshot button action ''' delete_screenshot() self.screenshot_box.remove(self.screenshot) self.pack_screenshot_buttons() self.show_all() def show_screenshot(self, widget, event): ''' Creates and displays a dialog with the screenshot image ''' height = Gdk.Screen().get_default().get_height() width = Gdk.Screen().get_default().get_width() pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(SCREENSHOT_PATH, width * 0.5, height * 0.5) image = Gtk.Image.new_from_pixbuf(pixbuf) dialog = KanoDialog( _("Screenshot"), # noqa: F821 widget=image ) dialog.run() def pack_screenshot_buttons(self): ''' Pack the screenshot buttons into a box ''' self.screenshot_box.pack_start(self._screenshot_button, False, False, 0) self.screenshot_box.set_child_non_homogeneous(self._screenshot_button, True) self.screenshot_box.pack_start(self._attach_button, False, False, 0) self.screenshot_box.set_child_non_homogeneous(self._attach_button, True)
class KanoWifiGui(base_class): CSS_PATH = os.path.join(css_dir, 'kano_wifi_gui.css') width = 350 height = 450 def __init__(self, wiface='wlan0', socket_id=0, no_confirm_ether=False): self.wiface = wiface self.network_list = [] self.no_confirm_ether = no_confirm_ether # Default basic styling apply_common_to_screen() # Attach specific styling apply_styling_to_screen(self.CSS_PATH) # Set window base_class.__init__( self, _("Kano WiFi"), self.width, self.height, socket_id ) self.top_bar = TopBar(_("Kano WiFi")) self.top_bar.set_prev_callback(self.refresh_networks) self.top_bar.set_close_callback(Gtk.main_quit) self.prev_handler = None self.connect('delete-event', Gtk.main_quit) self.set_keep_above(True) self.set_icon_name('kano-settings') self.set_decorated(True) if self._base_name == "Window": self.set_titlebar(self.top_bar) self._launch_application() def _launch_application(self, widget=None): # Decide whether application prompts user to plug in WiFi dongle # or tell them they have ethernet. # Don't want to call this function more than once self.wiface = get_wlan_device() has_internet = is_internet() ethernet_plugged = is_ethernet_plugged() dongle_is_plugged_in = is_device(self.wiface) if has_internet and ethernet_plugged and self.no_confirm_ether: sys.exit(0) # For testing # dongle_is_plugged_in = False # ethernet_plugged = True # has_internet = False if has_internet and ethernet_plugged: self._you_are_connected_via_ethernet() elif dongle_is_plugged_in: if has_internet: self._you_have_internet_screen(self.wiface) else: # Refresh the networks list self.refresh_networks() else: self._plug_in_wifi_dongle() def refresh_networks(self, widget=None, event=None): RefreshNetworks(self) def _plug_in_wifi_dongle(self): self.remove_main_widget() title = _("You don't seem to have a WiFi dongle\nplugged in.") description = _("Plug one in and try again") buttons = [ { 'label': "" }, { 'label': _("TRY AGAIN"), 'color': 'green', 'callback': self._launch_application, 'type': 'KanoButton', 'focus': True }, { 'label': _("Skip"), 'callback': Gtk.main_quit, 'type': 'OrangeButton' } ] img_path = os.path.join(img_dir, "dongle2.png") screen = Template( title, description, buttons, self.is_plug(), img_path ) self.set_main_widget(screen) screen.button_grab_focus() screen.show_all() def _you_are_connected_via_ethernet(self): self.remove_main_widget() title = _("You are already connected via ethernet.") description = _("Do you still want to connect with WiFi?") # Decide which callback to use depending on if wifi dongle is # plugged in buttons = [ { 'label': _("NO"), 'color': 'red', 'callback': Gtk.main_quit, 'type': 'KanoButton' }, { 'label': _("YES"), 'color': 'green', 'callback': self._ethernet_next_step, 'type': 'KanoButton', 'focus': True } ] img_path = os.path.join(img_dir, "ethernet-2.png") screen = Template( title, description, buttons, self.is_plug(), img_path ) self.set_main_widget(screen) screen.button_grab_focus() screen.show_all() def _ethernet_next_step(self, widget=None): dongle_is_plugged_in = is_device(self.wiface) if dongle_is_plugged_in: self.refresh_networks() else: self._plug_in_wifi_dongle() def _you_have_internet_screen(self, wiface): self.remove_main_widget() title = _("You already have internet!") description = _("Do you want to change network?") buttons = [ { 'label': _("NO"), 'color': 'red', 'callback': Gtk.main_quit, 'type': 'KanoButton' }, { 'label': _("YES"), 'color': 'green', 'callback': self.refresh_networks, 'type': 'KanoButton', 'focus': True } ] img_path = os.path.join(img_dir, "internet.png") screen = Template( title, description, buttons, self.is_plug(), img_path ) self.set_main_widget(screen) screen.button_grab_focus() screen.show_all() def _decide(self): if is_device(self.wiface): self.refresh_networks() else: self._plug_in_wifi_dongle()
def contact_window(self): ''' Contact Us window Contains text view and a Send button ''' # delete the directory containing all the info we'll send, and recreate delete_tmp_dir() create_tmp_dir() ApplicationWindow.__init__( self, _('Contact Us'), # noqa: F821 self.WIDTH, 0.35) screen = Gdk.Screen.get_default() specific_provider = Gtk.CssProvider() specific_provider.load_from_path(Media.media_dir() + 'css/style.css') style_context = Gtk.StyleContext() style_context.add_provider_for_screen(screen, specific_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) # Make sure this window has no icon in the task bar # so it plays nice with kdesk-blur self.set_property('skip-taskbar-hint', True) self._grid = Gtk.Grid() # Create top bar self._top_bar = TopBar( title=_("Contact Us"), # noqa: F821 window_width=self.WIDTH, has_buttons=False) self._top_bar.set_close_callback(Gtk.main_quit) self.set_decorated(True) self.set_titlebar(self._top_bar) # Create Text view self._text = Gtk.TextView() self._text.set_editable(True) self._text.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) self._text.set_size_request(self.WIDTH, -1) self._text.set_sensitive(self._pii_allowed()) self._textbuffer = self._text.get_buffer() if self._pii_allowed(): self._textbuffer.set_text( _("Type your feedback here!")) # noqa: F821 else: self._textbuffer.set_text( _("Want to send us more information? Ask your parent to check their email." )) # noqa: F821 self._clear_buffer_handler_id = self._textbuffer.connect( "insert-text", self.clear_buffer) scrolledwindow = ScrolledWindow() scrolledwindow.set_vexpand(True) scrolledwindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolledwindow.apply_styling_to_widget() scrolledwindow.add(self._text) scrolledwindow.set_margin_left(2) scrolledwindow.set_margin_right(2) scrolledwindow.set_margin_top(2) scrolledwindow.set_margin_bottom(2) # Very hacky way to get a border: create a grey event box # which is a little bigger than the widget below border = Gtk.EventBox() border.get_style_context().add_class("grey") border.add(scrolledwindow) self._grid.attach(border, 0, 0, 1, 1) border.set_margin_left(20) border.set_margin_right(20) border.set_margin_top(10) border.set_margin_bottom(20) # Create send button self._send_button = KanoButton(_("SEND") # noqa: F821 ) self._send_button.set_sensitive(not self._pii_allowed()) self._send_button.connect("button_press_event", self.send_feedback) self._send_button.pack_and_align() self._send_button.align.set_padding(10, 10, 0, 0) bottom_background = Gtk.EventBox() bottom_background.get_style_context().add_class("grey") bottom_background.add(self._send_button.align) self._grid.attach(bottom_background, 0, 1, 1, 1) self._grid.set_row_spacing(0) self.set_main_widget(self._grid) # kano-profile stat collection try: from kano_profile.badges import \ increment_app_state_variable_with_dialog increment_app_state_variable_with_dialog('kano-feedback', 'starts', 1) except Exception: pass
class FeedbackWindow(MainWindow): CLOSE_FEEDBACK = 0 KEEP_OPEN = 1 LAUNCH_WIFI = 2 WIDTH = 400 def __init__(self, bug_report=False): ''' Initialises the window, creating a report or contact window ''' MainWindow.__init__(self, subject='Kano Desktop Feedback Widget') self.kano_world_client = KanoWorld() self.bug_report = bug_report if self.bug_report: self.report_window() else: self.contact_window() def contact_window(self): ''' Contact Us window Contains text view and a Send button ''' # delete the directory containing all the info we'll send, and recreate delete_tmp_dir() create_tmp_dir() ApplicationWindow.__init__( self, _('Contact Us'), # noqa: F821 self.WIDTH, 0.35) screen = Gdk.Screen.get_default() specific_provider = Gtk.CssProvider() specific_provider.load_from_path(Media.media_dir() + 'css/style.css') style_context = Gtk.StyleContext() style_context.add_provider_for_screen(screen, specific_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) # Make sure this window has no icon in the task bar # so it plays nice with kdesk-blur self.set_property('skip-taskbar-hint', True) self._grid = Gtk.Grid() # Create top bar self._top_bar = TopBar( title=_("Contact Us"), # noqa: F821 window_width=self.WIDTH, has_buttons=False) self._top_bar.set_close_callback(Gtk.main_quit) self.set_decorated(True) self.set_titlebar(self._top_bar) # Create Text view self._text = Gtk.TextView() self._text.set_editable(True) self._text.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) self._text.set_size_request(self.WIDTH, -1) self._text.set_sensitive(self._pii_allowed()) self._textbuffer = self._text.get_buffer() if self._pii_allowed(): self._textbuffer.set_text( _("Type your feedback here!")) # noqa: F821 else: self._textbuffer.set_text( _("Want to send us more information? Ask your parent to check their email." )) # noqa: F821 self._clear_buffer_handler_id = self._textbuffer.connect( "insert-text", self.clear_buffer) scrolledwindow = ScrolledWindow() scrolledwindow.set_vexpand(True) scrolledwindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolledwindow.apply_styling_to_widget() scrolledwindow.add(self._text) scrolledwindow.set_margin_left(2) scrolledwindow.set_margin_right(2) scrolledwindow.set_margin_top(2) scrolledwindow.set_margin_bottom(2) # Very hacky way to get a border: create a grey event box # which is a little bigger than the widget below border = Gtk.EventBox() border.get_style_context().add_class("grey") border.add(scrolledwindow) self._grid.attach(border, 0, 0, 1, 1) border.set_margin_left(20) border.set_margin_right(20) border.set_margin_top(10) border.set_margin_bottom(20) # Create send button self._send_button = KanoButton(_("SEND") # noqa: F821 ) self._send_button.set_sensitive(not self._pii_allowed()) self._send_button.connect("button_press_event", self.send_feedback) self._send_button.pack_and_align() self._send_button.align.set_padding(10, 10, 0, 0) bottom_background = Gtk.EventBox() bottom_background.get_style_context().add_class("grey") bottom_background.add(self._send_button.align) self._grid.attach(bottom_background, 0, 1, 1, 1) self._grid.set_row_spacing(0) self.set_main_widget(self._grid) # kano-profile stat collection try: from kano_profile.badges import \ increment_app_state_variable_with_dialog increment_app_state_variable_with_dialog('kano-feedback', 'starts', 1) except Exception: pass def report_window(self): ''' Report window Contains 2 text views and Take Screenshot, Add Image and Send buttons ''' ApplicationWindow.__init__( self, _('Report a Problem'), # noqa: F821 self.WIDTH, 0.35) screen = Gdk.Screen.get_default() specific_provider = Gtk.CssProvider() specific_provider.load_from_path(Media.media_dir() + 'css/style.css') style_context = Gtk.StyleContext() style_context.add_provider_for_screen(screen, specific_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) self.set_icon_name("feedback") self._grid = Gtk.Grid() # Create top bar self._top_bar = TopBar( title=_("Report a Problem"), # noqa: F821 window_width=self.WIDTH, has_buttons=False) self._top_bar.set_close_callback(Gtk.main_quit) self.set_decorated(True) self.set_titlebar(self._top_bar) self.entry = Gtk.Entry() if self._pii_allowed(): self.entry.props.placeholder_text = _( "Add subject (optional)") # noqa: F821 else: self.entry.props.placeholder_text = _( "Want to send us more information?") # noqa: F821 self.entry.set_margin_left(20) self.entry.set_margin_right(20) self.entry.set_margin_top(20) self.entry.set_margin_bottom(10) self.entry.set_sensitive(self._pii_allowed()) self._grid.attach(self.entry, 0, 0, 1, 1) # Create Text view self._text = Gtk.TextView() self._text.set_editable(True) self._text.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) self._text.set_size_request(self.WIDTH, -1) self._text.set_sensitive(self._pii_allowed()) self._textbuffer = self._text.get_buffer() if self._pii_allowed(): self._textbuffer.set_text( _("Type your problem here!")) # noqa: F821 else: self._textbuffer.set_text( _("Ask your parent to check their email.")) # noqa: F821 self._clear_buffer_handler_id = self._textbuffer.connect( "insert-text", self.clear_buffer) scrolledwindow = ScrolledWindow() scrolledwindow.set_vexpand(True) scrolledwindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolledwindow.apply_styling_to_widget() scrolledwindow.add(self._text) scrolledwindow.set_margin_left(2) scrolledwindow.set_margin_right(2) scrolledwindow.set_margin_top(2) scrolledwindow.set_margin_bottom(2) # Very hacky way to get a border: create a grey event box # which is a little bigger than the widget below border = Gtk.EventBox() border.get_style_context().add_class("grey") border.add(scrolledwindow) self._grid.attach(border, 0, 1, 1, 1) border.set_margin_left(20) border.set_margin_right(20) border.set_margin_top(10) border.set_margin_bottom(20) # Create take screenshot button self._screenshot_button = KanoButton( _("TAKE SCREENSHOT"), # noqa: F821 "blue") self._screenshot_button.set_sensitive(self._pii_allowed()) self._screenshot_button.connect("button_press_event", self.screenshot_clicked) # Create attach screenshot button self._attach_button = KanoButton( _("ADD IMAGE"), # noqa: F821 "blue") self._attach_button.set_sensitive(self._pii_allowed()) self._attach_button.connect("button_press_event", self.attach_clicked) # Create send button self._send_button = KanoButton(_("SEND") # noqa: F821 ) self._send_button.set_sensitive(not self._pii_allowed()) self._send_button.connect("button_press_event", self.send_feedback) self._send_button.pack_and_align() self._send_button.set_margin(10, 0, 10, 0) self.screenshot_box = Gtk.ButtonBox() self.screenshot_box.set_layout(Gtk.ButtonBoxStyle.CENTER) self.screenshot_box.set_spacing(20) self.pack_screenshot_buttons() self.screenshot_box.set_margin_bottom(20) self._grid.attach(self.screenshot_box, 0, 2, 1, 1) # Create grey box to put the button in self.bottom_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.bottom_box.pack_start(self._send_button.align, False, False, 0) bottom_background = Gtk.EventBox() bottom_background.get_style_context().add_class("grey") bottom_background.add(self.bottom_box) self._grid.attach(bottom_background, 0, 3, 1, 1) self._grid.set_row_spacing(0) self.set_main_widget(self._grid) # kano-profile stat collection try: from kano_profile.badges import increment_app_state_variable_with_dialog increment_app_state_variable_with_dialog('kano-feedback', 'starts', 1) except Exception: pass def screenshot_clicked(self, button=None, event=None): ''' Takes a screenshot while minimising the window ''' # minimise the window self.iconify() take_screenshot() self.include_screenshot() # restore the window self.deiconify() def attach_clicked(self, button=None, event=None): ''' Opens the File Chooser Dialog. If image selected then copy it to the feedback folder ''' screenshot = None # Open file manager dialog = Gtk.FileChooserDialog( _("Please choose a file"), # noqa: F821 self, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) self.add_filters(dialog) response = dialog.run() if response == Gtk.ResponseType.OK: screenshot = dialog.get_filename() dialog.destroy() # Copy image file into feedback folder if screenshot is not None: copy_screenshot(screenshot) self.include_screenshot() def add_filters(self, dialog): ''' Add image type filters Used for the File Chooser Dialog ''' # Image filter filter_images = Gtk.FileFilter() filter_images.set_name("Images") filter_images.add_mime_type("image/png") filter_images.add_mime_type("image/jpeg") filter_images.add_mime_type("image/gif") filter_images.add_pattern("*.png") filter_images.add_pattern("*.jpg") filter_images.add_pattern("*.gif") filter_images.add_pattern("*.tif") filter_images.add_pattern("*.xpm") dialog.add_filter(filter_images) # Any file filter filter_any = Gtk.FileFilter() filter_any.set_name("Any files") filter_any.add_pattern("*") dialog.add_filter(filter_any) def include_screenshot(self): ''' This is the box containing the filename of the screenshot, and the option to display it or remove it ''' if not hasattr(self, "screenshot"): # We pack the buttons into an event box with styling # so that we can have a container with a border radius # without having ugly gaps between the buttons. self.screenshot = Gtk.EventBox() self.screenshot.get_style_context().add_class("kano_button") self.screenshot.get_style_context().add_class("blue_background") remove_screenshot = Gtk.Button() attach_cursor_events(remove_screenshot) remove_icon = Gtk.Image.new_from_file( "/usr/share/kano-feedback/media/icons/close.png") remove_screenshot.add(remove_icon) remove_screenshot.connect("button-release-event", self.remove_screenshot) remove_screenshot.get_style_context().add_class("blue_background") show_screenshot = Gtk.Button() attach_cursor_events(show_screenshot) show_icon = Gtk.Image() show_icon.set_from_file( "/usr/share/kano-feedback/media/icons/preview.png") show_screenshot.add(show_icon) show_screenshot.connect("button-release-event", self.show_screenshot) show_screenshot.get_style_context().add_class("blue_background") label = Gtk.Label(SCREENSHOT_NAME.upper()) label.set_padding(10, 0) box = Gtk.Box() box.pack_start(label, False, False, 0) box.pack_end(remove_screenshot, False, False, 0) box.pack_end(show_screenshot, False, False, 0) self.screenshot.add(box) self.screenshot_box.remove(self._screenshot_button) self.screenshot_box.remove(self._attach_button) self.screenshot_box.pack_start(self.screenshot, False, False, 0) def remove_screenshot(self, widget, event): ''' Remove screenshot button action ''' delete_screenshot() self.screenshot_box.remove(self.screenshot) self.pack_screenshot_buttons() self.show_all() def show_screenshot(self, widget, event): ''' Creates and displays a dialog with the screenshot image ''' height = Gdk.Screen().get_default().get_height() width = Gdk.Screen().get_default().get_width() pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size( SCREENSHOT_PATH, width * 0.5, height * 0.5) image = Gtk.Image.new_from_pixbuf(pixbuf) dialog = KanoDialog( _("Screenshot"), # noqa: F821 widget=image) dialog.run() def pack_screenshot_buttons(self): ''' Pack the screenshot buttons into a box ''' self.screenshot_box.pack_start(self._screenshot_button, False, False, 0) self.screenshot_box.set_child_non_homogeneous(self._screenshot_button, True) self.screenshot_box.pack_start(self._attach_button, False, False, 0) self.screenshot_box.set_child_non_homogeneous(self._attach_button, True) def _pii_allowed(self): """ Helper to check whether or not users are allowed to send us text, screenshots, images. """ return (self.kano_world_client.is_logged_in() and self.kano_world_client.get_account_verified())
def report_window(self): ''' Report window Contains 2 text views and Take Screenshot, Add Image and Send buttons ''' ApplicationWindow.__init__( self, _('Report a Problem'), # noqa: F821 self.WIDTH, 0.35) screen = Gdk.Screen.get_default() specific_provider = Gtk.CssProvider() specific_provider.load_from_path(Media.media_dir() + 'css/style.css') style_context = Gtk.StyleContext() style_context.add_provider_for_screen(screen, specific_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) self.set_icon_name("feedback") self._grid = Gtk.Grid() # Create top bar self._top_bar = TopBar( title=_("Report a Problem"), # noqa: F821 window_width=self.WIDTH, has_buttons=False) self._top_bar.set_close_callback(Gtk.main_quit) self.set_decorated(True) self.set_titlebar(self._top_bar) self.entry = Gtk.Entry() if self._pii_allowed(): self.entry.props.placeholder_text = _( "Add subject (optional)") # noqa: F821 else: self.entry.props.placeholder_text = _( "Want to send us more information?") # noqa: F821 self.entry.set_margin_left(20) self.entry.set_margin_right(20) self.entry.set_margin_top(20) self.entry.set_margin_bottom(10) self.entry.set_sensitive(self._pii_allowed()) self._grid.attach(self.entry, 0, 0, 1, 1) # Create Text view self._text = Gtk.TextView() self._text.set_editable(True) self._text.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) self._text.set_size_request(self.WIDTH, -1) self._text.set_sensitive(self._pii_allowed()) self._textbuffer = self._text.get_buffer() if self._pii_allowed(): self._textbuffer.set_text( _("Type your problem here!")) # noqa: F821 else: self._textbuffer.set_text( _("Ask your parent to check their email.")) # noqa: F821 self._clear_buffer_handler_id = self._textbuffer.connect( "insert-text", self.clear_buffer) scrolledwindow = ScrolledWindow() scrolledwindow.set_vexpand(True) scrolledwindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolledwindow.apply_styling_to_widget() scrolledwindow.add(self._text) scrolledwindow.set_margin_left(2) scrolledwindow.set_margin_right(2) scrolledwindow.set_margin_top(2) scrolledwindow.set_margin_bottom(2) # Very hacky way to get a border: create a grey event box # which is a little bigger than the widget below border = Gtk.EventBox() border.get_style_context().add_class("grey") border.add(scrolledwindow) self._grid.attach(border, 0, 1, 1, 1) border.set_margin_left(20) border.set_margin_right(20) border.set_margin_top(10) border.set_margin_bottom(20) # Create take screenshot button self._screenshot_button = KanoButton( _("TAKE SCREENSHOT"), # noqa: F821 "blue") self._screenshot_button.set_sensitive(self._pii_allowed()) self._screenshot_button.connect("button_press_event", self.screenshot_clicked) # Create attach screenshot button self._attach_button = KanoButton( _("ADD IMAGE"), # noqa: F821 "blue") self._attach_button.set_sensitive(self._pii_allowed()) self._attach_button.connect("button_press_event", self.attach_clicked) # Create send button self._send_button = KanoButton(_("SEND") # noqa: F821 ) self._send_button.set_sensitive(not self._pii_allowed()) self._send_button.connect("button_press_event", self.send_feedback) self._send_button.pack_and_align() self._send_button.set_margin(10, 0, 10, 0) self.screenshot_box = Gtk.ButtonBox() self.screenshot_box.set_layout(Gtk.ButtonBoxStyle.CENTER) self.screenshot_box.set_spacing(20) self.pack_screenshot_buttons() self.screenshot_box.set_margin_bottom(20) self._grid.attach(self.screenshot_box, 0, 2, 1, 1) # Create grey box to put the button in self.bottom_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.bottom_box.pack_start(self._send_button.align, False, False, 0) bottom_background = Gtk.EventBox() bottom_background.get_style_context().add_class("grey") bottom_background.add(self.bottom_box) self._grid.attach(bottom_background, 0, 3, 1, 1) self._grid.set_row_spacing(0) self.set_main_widget(self._grid) # kano-profile stat collection try: from kano_profile.badges import increment_app_state_variable_with_dialog increment_app_state_variable_with_dialog('kano-feedback', 'starts', 1) except Exception: pass
def contact_window(self): ''' Contact Us window Contains text view and a Send button ''' # delete the directory containing all the info we'll send, and recreate delete_tmp_dir() create_tmp_dir() ApplicationWindow.__init__( self, _('Contact Us'), # noqa: F821 self.WIDTH, 0.35 ) screen = Gdk.Screen.get_default() specific_provider = Gtk.CssProvider() specific_provider.load_from_path(Media.media_dir() + 'css/style.css') style_context = Gtk.StyleContext() style_context.add_provider_for_screen(screen, specific_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) # Make sure this window has no icon in the task bar # so it plays nice with kdesk-blur self.set_property('skip-taskbar-hint', True) self._grid = Gtk.Grid() # Create top bar self._top_bar = TopBar( title=_("Contact Us"), # noqa: F821 window_width=self.WIDTH, has_buttons=False ) self._top_bar.set_close_callback(Gtk.main_quit) self.set_decorated(True) self.set_titlebar(self._top_bar) # Create Text view self._text = Gtk.TextView() self._text.set_editable(True) self._text.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) self._text.set_size_request(self.WIDTH, -1) self._textbuffer = self._text.get_buffer() self._textbuffer.set_text( _("Type your feedback here!") # noqa: F821 ) self._clear_buffer_handler_id = self._textbuffer.connect( "insert-text", self.clear_buffer ) scrolledwindow = ScrolledWindow() scrolledwindow.set_vexpand(True) scrolledwindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolledwindow.apply_styling_to_widget() scrolledwindow.add(self._text) scrolledwindow.set_margin_left(2) scrolledwindow.set_margin_right(2) scrolledwindow.set_margin_top(2) scrolledwindow.set_margin_bottom(2) # Very hacky way to get a border: create a grey event box # which is a little bigger than the widget below border = Gtk.EventBox() border.get_style_context().add_class("grey") border.add(scrolledwindow) self._grid.attach(border, 0, 0, 1, 1) border.set_margin_left(20) border.set_margin_right(20) border.set_margin_top(10) border.set_margin_bottom(20) # Create send button self._send_button = KanoButton( _("SEND") # noqa: F821 ) self._send_button.set_sensitive(False) self._send_button.connect("button_press_event", self.send_feedback) self._send_button.pack_and_align() self._send_button.align.set_padding(10, 10, 0, 0) bottom_background = Gtk.EventBox() bottom_background.get_style_context().add_class("grey") bottom_background.add(self._send_button.align) self._grid.attach(bottom_background, 0, 1, 1, 1) self._grid.set_row_spacing(0) self.set_main_widget(self._grid) # kano-profile stat collection try: from kano_profile.badges import \ increment_app_state_variable_with_dialog increment_app_state_variable_with_dialog( 'kano-feedback', 'starts', 1 ) except Exception: pass
class GreeterWindow(ApplicationWindow): WIDTH = 400 HEIGHT = -1 greeter = LightDM.Greeter def __init__(self): apply_common_to_screen() self.a = self.b = self.c = 0 self.switching = 0 ApplicationWindow.__init__(self, _('Login'), self.WIDTH, self.HEIGHT) self.connect("delete-event", Gtk.main_quit) # Create a new LightDM.Greeter instance which will be used by the 2 views self.greeter = GreeterWindow.greeter.new() # Create the two views: one for normal Login, the other to create a new account self.password_view = PasswordView(None, self.greeter) self.newuser_view = NewUserView(self.greeter) self.login_with_kw_view = LoginWithKanoWorldView(self.greeter) self.grid = Gtk.Grid() self.set_main_widget(self.grid) self.grid.set_column_spacing(30) self.grid.set_row_spacing(30) self.top_bar = TopBar(_('Login')) self._remove_top_bar_buttons() self.top_bar.set_size_request(self.WIDTH, -1) self.grid.attach(self.top_bar, 0, 0, 3, 1) self.grid.attach(Gtk.Label(), 0, 3, 3, 1) self.top_bar.set_prev_callback(self._back_cb) self.user_list = UserListView() self.go_to_users() cursor = Gdk.Cursor.new(Gdk.CursorType.ARROW) self.get_root_window().set_cursor(cursor) def _remove_top_bar_buttons(self): self.top_bar.box.remove(self.top_bar.close_button) self.top_bar.box.remove(self.top_bar.next_button) def set_main(self, wdg): child = self.grid.get_child_at(1, 1) if child: self.grid.remove(child) self.grid.attach(wdg, 1, 1, 1, 1) self.show_all() def go_to_users(self): self.set_main(self.user_list) self.top_bar.disable_prev() def go_to_password(self, user): self.set_main(self.password_view) self.top_bar.enable_prev() if not self.switching == 1: self.greeter.disconnect(self.a) self.greeter.disconnect(self.b) self.greeter.disconnect(self.c) self.greeter = GreeterWindow.greeter.new() self.password_view.greeter = self.greeter (self.a, self.b, self.c) = self.password_view._reset_greeter() self.switching = 1 self.password_view.grab_focus(user) def go_to_newuser(self): self.set_main(self.newuser_view) self.top_bar.enable_prev() if not self.switching == 2: self.greeter.disconnect(self.a) self.greeter.disconnect(self.b) self.greeter.disconnect(self.c) self.greeter = GreeterWindow.greeter.new() self.newuser_view.greeter = self.greeter # FIXME: We do not reset the greeter in the newuser view # It will be done only when the local user account has been forced # so as to avoid LightDM freezes # (self.a, self.b, self.c) = self.newuser_view._reset_greeter() self.switching = 2 def go_to_login_with_kw(self): self.set_main(self.login_with_kw_view) self.top_bar.enable_prev() if not self.switching == 3: self.greeter.disconnect(self.a) self.greeter.disconnect(self.b) self.greeter.disconnect(self.c) self.greeter = GreeterWindow.greeter.new() self.login_with_kw_view.greeter = self.greeter # FIXME: We do not reset the greeter in the newuser view # It will be done only when the local user account has been forced # so as to avoid LightDM freezes # (self.a, self.b, self.c) = self.login_with_kw_view._reset_greeter() self.switching = 3 self.login_with_kw_view.grab_focus() def _back_cb(self, event, button): self.go_to_users()
def report_window(self): ''' Report window Contains 2 text views and Take Screenshot, Add Image and Send buttons ''' ApplicationWindow.__init__( self, _('Report a Problem'), # noqa: F821 self.WIDTH, 0.35 ) screen = Gdk.Screen.get_default() specific_provider = Gtk.CssProvider() specific_provider.load_from_path(Media.media_dir() + 'css/style.css') style_context = Gtk.StyleContext() style_context.add_provider_for_screen(screen, specific_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) self.set_icon_name("feedback") self._grid = Gtk.Grid() # Create top bar self._top_bar = TopBar( title=_("Report a Problem"), # noqa: F821 window_width=self.WIDTH, has_buttons=False ) self._top_bar.set_close_callback(Gtk.main_quit) self.set_decorated(True) self.set_titlebar(self._top_bar) self.entry = Gtk.Entry() self.entry.props.placeholder_text = \ _("Add subject (optional)") # noqa: F821 self.entry.set_margin_left(20) self.entry.set_margin_right(20) self.entry.set_margin_top(20) self.entry.set_margin_bottom(10) self._grid.attach(self.entry, 0, 0, 1, 1) # Create Text view self._text = Gtk.TextView() self._text.set_editable(True) self._text.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) self._text.set_size_request(self.WIDTH, -1) self._textbuffer = self._text.get_buffer() self._textbuffer.set_text( _("Type your problem here!") # noqa: F821 ) self._clear_buffer_handler_id = self._textbuffer.connect( "insert-text", self.clear_buffer ) scrolledwindow = ScrolledWindow() scrolledwindow.set_vexpand(True) scrolledwindow.set_policy( Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC ) scrolledwindow.apply_styling_to_widget() scrolledwindow.add(self._text) scrolledwindow.set_margin_left(2) scrolledwindow.set_margin_right(2) scrolledwindow.set_margin_top(2) scrolledwindow.set_margin_bottom(2) # Very hacky way to get a border: create a grey event box # which is a little bigger than the widget below border = Gtk.EventBox() border.get_style_context().add_class("grey") border.add(scrolledwindow) self._grid.attach(border, 0, 1, 1, 1) border.set_margin_left(20) border.set_margin_right(20) border.set_margin_top(10) border.set_margin_bottom(20) # Create take screenshot button self._screenshot_button = KanoButton( _("TAKE SCREENSHOT"), # noqa: F821 "blue" ) self._screenshot_button.set_sensitive(True) self._screenshot_button.connect("button_press_event", self.screenshot_clicked) # Create attach screenshot button self._attach_button = KanoButton( _("ADD IMAGE"), # noqa: F821 "blue" ) self._attach_button.set_sensitive(True) self._attach_button.connect("button_press_event", self.attach_clicked) # Create send button self._send_button = KanoButton( _("SEND") # noqa: F821 ) self._send_button.set_sensitive(False) self._send_button.connect("button_press_event", self.send_feedback) self._send_button.pack_and_align() self._send_button.set_margin(10, 0, 10, 0) self.screenshot_box = Gtk.ButtonBox() self.screenshot_box.set_layout(Gtk.ButtonBoxStyle.CENTER) self.screenshot_box.set_spacing(20) self.pack_screenshot_buttons() self.screenshot_box.set_margin_bottom(20) self._grid.attach(self.screenshot_box, 0, 2, 1, 1) # Create grey box to put the button in self.bottom_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.bottom_box.pack_start(self._send_button.align, False, False, 0) bottom_background = Gtk.EventBox() bottom_background.get_style_context().add_class("grey") bottom_background.add(self.bottom_box) self._grid.attach(bottom_background, 0, 3, 1, 1) self._grid.set_row_spacing(0) self.set_main_widget(self._grid) # kano-profile stat collection try: from kano_profile.badges import increment_app_state_variable_with_dialog increment_app_state_variable_with_dialog( 'kano-feedback', 'starts', 1 ) except Exception: pass