Ejemplo n.º 1
0
    def run(self):
        """
        Shows the settings dialog and processes settings changes. Doesn't return anything.
        """
        gtk_settings = Gtk.Settings.get_default()

        # Discord enabled state
        discord_enabled_previous = self.settings.get_integration_discord_enabled()
        settings_discord_enable = self.builder.get_object('setting_discord_enable')
        settings_discord_enable.set_active(discord_enabled_previous)

        # Gtk Theme
        if not sys.platform.startswith('linux'):
            store: Gtk.ListStore = Gtk.ListStore.new([str])
            cb: Gtk.ComboBox = self.builder.get_object('setting_gtk_theme')
            active = None
            for id, theme in enumerate(self._list_gtk_themes()):
                store.append([theme])
                if theme == gtk_settings.get_property("gtk-theme-name"):
                    active = id
            cb.set_model(store)
            if active is not None:
                cb.set_active(active)
        else:
            self.builder.get_object('frame_setting_gtk_theme').hide()

        # Languages
        cb: Gtk.ComboBox = self.builder.get_object('setting_language')
        store: Gtk.ListStore = self.builder.get_object('lang_store')
        store.clear()
        active = None
        for id, (code, name) in enumerate(LANGS):
            store.append([code, name])
            if code == self.settings.get_locale():
                active = id
        if active is not None:
            cb.set_active(active)

        response = self.window.run()

        have_to_restart = False
        if response == Gtk.ResponseType.ACCEPT:

            # Discord enabled state
            discord_enabled = settings_discord_enable.get_active()
            if discord_enabled != discord_enabled_previous:
                self.settings.set_integration_discord_enabled(discord_enabled)
                have_to_restart = True

            # Gtk Theme
            if not sys.platform.startswith('linux'):
                cb: Gtk.ComboBox = self.builder.get_object('setting_gtk_theme')
                iter = cb.get_active_iter()
                if (iter != None):
                    theme_name = cb.get_model()[iter][0]
                    gtk_settings.set_property("gtk-theme-name", theme_name)
                    self.settings.set_gtk_theme(theme_name)

            # Languages
            cb: Gtk.ComboBox = self.builder.get_object('setting_language')
            lang_name = cb.get_model()[cb.get_active_iter()][0]
            before = self.settings.get_locale()
            if before != lang_name:
                self.settings.set_locale(lang_name)
                have_to_restart = True

        self.window.hide()

        if have_to_restart:
            md = SkyTempleMessageDialog(self.parent_window,
                                        Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.INFO,
                                        Gtk.ButtonsType.OK, _("You need to restart SkyTemple to "
                                                              "apply some of the settings."),
                                        title="SkyTemple")
            md.run()
            md.destroy()
Ejemplo n.º 2
0
    def on_import_clicked(self, *args):
        md = SkyTempleMessageDialog(
            MainController.window(),
            Gtk.DialogFlags.DESTROY_WITH_PARENT,
            Gtk.MessageType.INFO,
            Gtk.ButtonsType.OK,
            _("To import, select a directory to import from. Files with the pattern 'XX.png'\n"
              "will be imported, where XX is a number between 0 and 99. The image dimensions must be a multiple of 8."
              ),
            title=_("Import Images"))
        md.run()
        md.destroy()
        dialog = Gtk.FileChooserNative.new(_("Import images from PNGs..."),
                                           MainController.window(),
                                           Gtk.FileChooserAction.SELECT_FOLDER,
                                           None, None)

        response = dialog.run()
        fn = dialog.get_filename()
        dialog.destroy()

        if response == Gtk.ResponseType.ACCEPT:
            r = re.compile(rf"(\d+)\.png", re.IGNORECASE)
            imgs_dict = {
                int(match[1]): name
                for match, name in self._try_match_import(r, os.listdir(fn))
                if match is not None
            }
            imgs = []
            # Convert imgs to list
            for i in range(0, len(imgs_dict)):
                if i not in imgs_dict:
                    display_error(
                        None,
                        f(
                            _('Failed importing image "{i}":\nImage for number {i} missing.'
                              )), _('Image for number {i} missing.'))
                    return
                imgs.append(imgs_dict[i])
            if len(imgs) == 0:
                display_error(None, _('No images found.'),
                              _("No images found."))
                return
            for index, image_fn in enumerate(imgs):
                try:
                    with open(os.path.join(fn, image_fn), 'rb') as file:
                        image = Image.open(file)
                        if len(self.w16) > index:
                            # Existing image, update
                            self.w16[index].set(image)
                        else:
                            self.w16.append(
                                W16AtImage.new(W16TocEntry(0, 0, 0, 0), image))
                except Exception as err:
                    logger.error(f(_("Failed importing image '{index}'.")),
                                 exc_info=err)
                    display_error(
                        sys.exc_info(),
                        f(_('Failed importing image "{index}":\n{err}')),
                        f(_("Error for '{index}'.")))
            # Re-render
            self._reset()
            for draw in self._draws:
                draw.queue_draw()
            # Mark as modified
            self.module.mark_w16_as_modified(self.item_id)
Ejemplo n.º 3
0
    def convert(self, *args):

        mode_cb: Gtk.ComboBox = self.builder.get_object('tq_mode')
        mode = ImageConversionMode(
            mode_cb.get_model()[mode_cb.get_active_iter()][0])
        dither_level = self.builder.get_object('tq_dither_level').get_value()
        has_first_image = self.builder.get_object(
            'tq_input_file').get_filename() is not None
        has_second_image = self.builder.get_object(
            'tq_second_file').get_filename() is not None

        if not has_first_image:
            self.error(_("Please select an input image."))
            return
        if has_second_image:
            md = SkyTempleMessageDialog(
                self.window, Gtk.DialogFlags.DESTROY_WITH_PARENT,
                Gtk.MessageType.INFO, Gtk.ButtonsType.OK,
                _("Since you selected two images to convert, you will be "
                  "asked for both images where to save them to."))
            md.run()
            md.destroy()

        dialog = Gtk.FileChooserNative.new(_("Save first image as (PNG)..."),
                                           self.window,
                                           Gtk.FileChooserAction.SAVE, None,
                                           None)
        if self._previous_output_image is not None:
            dialog.set_filename(self._previous_output_image)

        add_dialog_png_filter(dialog)

        response = dialog.run()
        output_image = dialog.get_filename()
        if '.' not in output_image:
            output_image += '.png'
        self._previous_output_image = output_image
        dialog.destroy()
        if response != Gtk.ResponseType.ACCEPT:
            return

        if has_second_image:
            dialog = Gtk.FileChooserNative.new(
                _("Save second image as (PNG)..."), self.window,
                Gtk.FileChooserAction.SAVE, None, None)
            if self._previous_second_output_image is not None:
                dialog.set_filename(self._previous_second_output_image)
            else:
                dialog.set_filename(output_image)

            add_dialog_png_filter(dialog)

            response = dialog.run()
            second_output_image = dialog.get_filename()
            if '.' not in second_output_image:
                second_output_image += '.png'
            self._previous_second_output_image = second_output_image
            dialog.destroy()
            if response != Gtk.ResponseType.ACCEPT:
                return

        try:
            num_pals = int(
                self.builder.get_object('tq_number_palettes').get_text())
            input_image = self.builder.get_object(
                'tq_input_file').get_filename()
            second_input_file = self.builder.get_object(
                'tq_second_file').get_filename()
            transparent_color = self.builder.get_object(
                'tq_transparent_color').get_color()
            transparent_color = (int(transparent_color.red_float * 255),
                                 int(transparent_color.green_float * 255),
                                 int(transparent_color.blue_float * 255))
        except ValueError:
            self.error(_("You entered invalid numbers."))
        else:
            if not os.path.exists(input_image):
                self.error(_("The input image does not exist."))
                return
            if has_second_image and not os.path.exists(second_input_file):
                self.error(_("The second input image does not exist."))
                return
            with open(input_image, 'rb') as input_file:
                try:
                    if not has_second_image:
                        # Only one image
                        image = Image.open(input_file)
                    else:
                        # Two images: Merge them.
                        image1 = Image.open(input_file)
                        image2 = Image.open(second_input_file)
                        image = Image.new('RGBA',
                                          (max(image1.width, image2.width),
                                           image1.height + image2.height),
                                          transparent_color)
                        image.paste(image1, (0, 0))
                        image.paste(image2, (0, image1.height))
                except OSError:
                    self.error(_("The input image is not a supported format."))
                    return
                try:
                    img = self._convert(image, transparent_color, mode,
                                        num_pals, dither_level)
                    if not has_second_image:
                        # Only one image
                        img.save(output_image)
                    else:
                        # Two images: Un-merge them.
                        img.crop((0, 0, image1.width,
                                  image1.height)).save(output_image)
                        img.crop(
                            (0, image1.height, image2.width, image1.height +
                             image2.height)).save(second_output_image)
                except BaseException as err:
                    logger.error("Tilequant error.", exc_info=err)
                    self.error(str(err))
                else:
                    md = SkyTempleMessageDialog(
                        self.window,
                        Gtk.DialogFlags.DESTROY_WITH_PARENT,
                        Gtk.MessageType.INFO,
                        Gtk.ButtonsType.OK,
                        _("Image was converted."),
                        is_success=True)
                    md.run()
                    md.destroy()
Ejemplo n.º 4
0
from skytemple.core.ui_utils import make_builder

try:
    gi.require_foreign("cairo")
except ImportError:
    from gi.repository import Gtk

    md = SkyTempleMessageDialog(
        None,
        Gtk.DialogFlags.DESTROY_WITH_PARENT,
        Gtk.MessageType.ERROR,
        Gtk.ButtonsType.OK,
        _("PyGObject compiled without Cairo support. Can't start!"),
        title=_("SkyTemple - Error!"))
    md.set_position(Gtk.WindowPosition.CENTER)
    md.run()
    md.destroy()
    exit(1)

from gi.repository import Gtk, Gdk, GLib
from gi.repository.Gtk import Window
from skytemple.controller.main import MainController
SKYTEMPLE_LOGLEVEL = logging.INFO


def run_main(settings: SkyTempleSettingsStore):
    # TODO: Gtk.Application: https://python-gtk-3-tutorial.readthedocs.io/en/latest/application.html
    path = os.path.abspath(os.path.dirname(__file__))

    if sys.platform.startswith('win'):
        # Load theming under Windows