Esempio n. 1
0
class SK1Application(wal.Application, UCApplication):

    appdata = None
    history = None

    actions = {}
    plugins = {}
    docs = []
    current_doc = None
    doc_counter = 0

    proxy = None
    insp = None
    mw = None
    default_cms = None
    artprovider = None
    cursors = None
    mdiarea = None
    plg_area = None
    print_data = None

    def __init__(self, path, cfgdir='~'):

        self.path = path

        wal.Application.__init__(self)
        UCApplication.__init__(self, path, cfgdir)

        if wal.is_winxp():
            msg = _('WindowsXP platform is obsolete and not supported!')
            dialogs.error_dialog(self.mw, 'sK1', msg)
            sys.exit()

        self.appdata = AppData(self, cfgdir)
        config.load(self.appdata.app_config)
        config.resource_dir = os.path.join(path_unicode(self.path), 'share')
        plg_dir = os.path.join(self.path, 'share', 'pd_plugins')
        custom_plg_dir = self.appdata.plugin_dir
        config.plugin_dirs = [plg_dir, custom_plg_dir]
        sys.path.insert(1, self.appdata.app_config)
        sys.path.insert(1, os.path.join(self.path, 'share'))
        config.app = self

        self.history = AppHistoryManager(self)

        self.artprovider = create_artprovider()
        self.cursors = modes.get_cursors()

        self.proxy = AppProxy(self)
        self.insp = AppInspector(self)
        self.plugins = app_plugins.scan_plugins(self)
        self.actions = app_actions.create_actions(self)

        self.default_cms = AppColorManager(self)
        self.palettes = AppPaletteManager(self)
        self.clipboard = AppClipboard(self)

        self.mw = AppMainWindow(self)
        self.mw.set_global_shortcuts(self.actions)

        self.proxy.update()
        self.insp.update()
        if wal.is_wx2(): events.emit(events.NO_DOCS)
        if config.make_font_cache_on_start: generate_fcache()

    def load_plugins(self):
        if config.active_plugins:
            for item in config.active_plugins:
                try:
                    self.mw.mdi.plg_area.show_plugin(item)
                except:
                    pass

    def call_after(self, *args):
        if self.docs: return
        if config.new_doc_on_start:
            self.load_plugins()
            self.new()
        else:
            txt = _('To start, create new document or open existing')
            events.emit(events.APP_STATUS, txt)
            self.load_plugins()
            if not wal.is_wx2(): events.emit(events.NO_DOCS)
        self.update_actions()

    def stub(self, *args):
        pass

    def update_config(self):
        config.resource_dir = ''
        w, h = self.mw.get_size()
        if wal.is_unity_16_04():
            h = max(h - 28, config.mw_min_size[1])
        config.mw_size = (w, h)
        config.mw_maximized = self.mw.is_maximized()
        if self.mw.is_maximized(): config.mw_size = config.mw_min_size
        plugins = []
        for item in self.mw.mdi.plg_area.plugins:
            plugins.append(item.pid)
        config.active_plugins = plugins
        config.save(self.appdata.app_config)

    def exit(self, *args):
        if not self.insp.is_any_doc_not_saved(): self.mw.hide()
        if self.close_all():
            self.update_config()
            self.mw.destroy()
            self.Exit()
            return True
        return False

    def get_new_docname(self):
        self.doc_counter += 1
        return _('Untitled') + ' ' + str(self.doc_counter)

    def set_current_doc(self, doc):
        self.current_doc = doc
        self.current_doc.set_title()
        self.mw.mdi.set_active(doc)
        self.current_doc.canvas.set_focus()
        events.emit(events.DOC_CHANGED, doc)
        events.emit(events.SNAP_CHANGED)
        events.emit(events.APP_STATUS, _('Document is changed'))

    def new(self):
        doc = PD_Presenter(self)
        self.docs.append(doc)
        self.set_current_doc(doc)
        events.emit(events.APP_STATUS, _('New document created'))

    def new_from_template(self):
        msg = _('Select Template')
        doc_file = dialogs.get_open_file_name(self.mw, self,
                                              config.template_dir, msg)
        if os.path.lexists(doc_file) and os.path.isfile(doc_file):
            try:
                doc = PD_Presenter(self, doc_file, template=True)
            except:
                msg = _('Cannot parse file:')
                msg = "%s\n'%s'" % (msg, doc_file) + '\n'
                msg += _('The file may be corrupted or not supported format')
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                self.print_stacktrace()
                return
            self.docs.append(doc)
            config.template_dir = str(os.path.dirname(doc_file))
            self.set_current_doc(doc)
            events.emit(events.APP_STATUS, _('New document from template'))

    def open(self, doc_file='', silent=False):
        if not doc_file:
            doc_file = dialogs.get_open_file_name(self.mw, self,
                                                  config.open_dir)
        if os.path.lexists(doc_file) and os.path.isfile(doc_file):
            try:
                doc = PD_Presenter(self, doc_file, silent)

            except RuntimeError:
                msg = _('Cannot open file:')
                msg = "%s\n'%s'" % (msg, doc_file) + '\n'
                msg += _('The file contains newer SK2 format.\n')
                msg += _(
                    'Try updating sK1 application from http://www.sk1project.net'
                )
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                self.print_stacktrace()
                return
            except:
                msg = _('Cannot open file:')
                msg = "%s\n'%s'" % (msg, doc_file) + '\n'
                msg += _('The file may be corrupted or not supported format')
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                self.print_stacktrace()
                return
            self.docs.append(doc)
            config.open_dir = str(os.path.dirname(doc_file))
            self.history.add_entry(doc_file)
            self.set_current_doc(doc)
            events.emit(events.APP_STATUS, _('Document opened'))

    def save(self, doc=''):
        if not doc:
            doc = self.current_doc
        if not doc.doc_file:
            return self.save_as()
        ext = os.path.splitext(self.current_doc.doc_file)[1]
        if not ext == "." + uc2const.FORMAT_EXTENSION[uc2const.SK2][0]:
            return self.save_as()
        if not os.path.lexists(os.path.dirname(self.current_doc.doc_file)):
            return self.save_as()

        try:
            self.make_backup(self.current_doc.doc_file)
            doc.save()
            self.history.add_entry(self.current_doc.doc_file, appconst.SAVED)
            events.emit(events.DOC_SAVED, doc)
        except:
            msg = _('Cannot save file:')
            msg = "%s\n'%s'" % (msg, self.current_doc.doc_file) + '\n'
            msg += _('Please check file write permissions')
            dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
            self.print_stacktrace()
            return False
        events.emit(events.APP_STATUS, _('Document saved'))
        return True

    def save_as(self):
        doc_file = '' + self.current_doc.doc_file
        if not doc_file:
            doc_file = '' + self.current_doc.doc_name
        if not os.path.splitext(doc_file)[1] == "." + \
           uc2const.FORMAT_EXTENSION[uc2const.SK2][0]:
            doc_file = os.path.splitext(doc_file)[0] + "." + \
              uc2const.FORMAT_EXTENSION[uc2const.SK2][0]
        if not os.path.lexists(os.path.dirname(doc_file)):
            doc_file = os.path.join(config.save_dir,
                                    os.path.basename(doc_file))
        doc_file = dialogs.get_save_file_name(self.mw,
                                              self,
                                              doc_file,
                                              path_only=True)
        if doc_file:
            old_file = self.current_doc.doc_file
            old_name = self.current_doc.doc_name
            self.current_doc.set_doc_file(doc_file)
            try:
                self.make_backup(doc_file)
                self.current_doc.save()
            except:
                self.current_doc.set_doc_file(old_file, old_name)
                first = _('Cannot save document:')
                msg = ("%s\n'%s'.") % (first, self.current_doc.doc_name) + '\n'
                msg += _('Please check file name and write permissions')
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                self.print_stacktrace()
                return False
            config.save_dir = str(os.path.dirname(doc_file))
            self.history.add_entry(doc_file, appconst.SAVED)
            events.emit(events.DOC_SAVED, self.current_doc)
            events.emit(events.APP_STATUS, _('Document saved'))
            return True
        else:
            return False

    def save_selected(self):
        doc_file = '' + self.current_doc.doc_file
        if not doc_file:
            doc_file = '' + self.current_doc.doc_name
        if not os.path.splitext(doc_file)[1] == "." + \
           uc2const.FORMAT_EXTENSION[uc2const.SK2][0]:
            doc_file = os.path.splitext(doc_file)[0] + "." + \
              uc2const.FORMAT_EXTENSION[uc2const.SK2][0]
        if not os.path.lexists(os.path.dirname(doc_file)):
            doc_file = os.path.join(config.save_dir,
                                    os.path.basename(doc_file))
        doc_file = dialogs.get_save_file_name(
            self.mw,
            self,
            doc_file,
            _('Save selected objects only as...'),
            path_only=True)
        if doc_file:
            try:
                self.make_backup(doc_file)
                self.current_doc.save_selected(doc_file)
                self.history.add_entry(doc_file, appconst.SAVED)
            except:
                first = _('Cannot save document:')
                msg = ("%s\n'%s'.") % (first, doc_file) + '\n'
                msg += _(
                    'Please check requested file format and write permissions')
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                self.print_stacktrace()

    def save_all(self):
        for doc in self.docs:
            if self.insp.is_doc_not_saved(doc):
                self.save(doc)

    def close(self, doc=None):
        if not self.docs: return
        if doc is None: doc = self.current_doc
        if not doc == self.current_doc: self.set_current_doc(doc)

        if self.insp.is_doc_not_saved(doc):
            msg = _("Document '%s' has been modified.") % (doc.doc_name) + '\n'
            msg += _('Do you want to save your changes?')
            ret = dialogs.ync_dialog(self.mw, self.appdata.app_name, msg)

            if ret is None: return False
            if ret:
                if not self.save(): return False

        if doc in self.docs:
            self.docs.remove(doc)
            doc.close()
            events.emit(events.DOC_CLOSED)
            if not len(self.docs):
                self.current_doc = None
                events.emit(events.NO_DOCS)
                msg = _('To start create new or open existing document')
                events.emit(events.APP_STATUS, msg)
                self.mw.set_title()
            else:
                self.set_current_doc(self.docs[-1])
        return True

    def close_all(self):
        result = True
        if self.docs:
            while self.docs:
                result = self.close(self.docs[0])
                if not result: break
        return result

    def import_file(self):
        doc_file = dialogs.get_open_file_name(self.mw, self, config.import_dir,
                                              _('Select file to import'))
        if os.path.lexists(doc_file) and os.path.isfile(doc_file):
            try:
                ret = self.current_doc.import_file(doc_file)
                if not ret:
                    msg = _('Cannot import graphics from file:')
                    msg = "%s\n'%s'" % (msg, doc_file) + '\n'
                    msg += _(
                        'It seems the document is empty or contains unsupported objects.'
                    )
                    dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                config.import_dir = str(os.path.dirname(doc_file))
            except:
                msg = _('Cannot import file:')
                msg = "%s\n'%s'" % (msg, doc_file) + '\n'
                msg += _('The file may be corrupted or not supported format')
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                self.print_stacktrace()

    def export_as(self):
        doc_file = '' + self.current_doc.doc_file
        if not doc_file:
            doc_file = '' + self.current_doc.doc_name
        doc_file = os.path.splitext(doc_file)[0]
        doc_file = os.path.join(config.export_dir, os.path.basename(doc_file))
        doc_file = dialogs.get_save_file_name(self.mw,
                                              self,
                                              doc_file,
                                              _('Export document As...'),
                                              file_types=SAVER_FORMATS[1:],
                                              path_only=True)
        if doc_file:
            try:
                self.make_backup(doc_file, True)
                self.current_doc.export_as(doc_file)
            except:
                first = _('Cannot save document:')
                msg = ("%s\n'%s'.") % (first, self.current_doc.doc_name) + '\n'
                msg += _('Please check file name and write permissions')
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                self.print_stacktrace()
                return
            config.export_dir = str(os.path.dirname(doc_file))
            events.emit(events.APP_STATUS,
                        _('Document is successfully exported'))

    def extract_bitmap(self):
        doc_file = 'image'
        doc_file = os.path.join(config.save_dir, doc_file)
        doc_file = dialogs.get_save_file_name(
            self.mw,
            self,
            doc_file,
            _('Extract selected bitmap as...'),
            file_types=[uc2const.PNG],
            path_only=True)
        if doc_file:
            try:
                pixmap = self.current_doc.selection.objs[0]
                libimg.extract_bitmap(pixmap, doc_file)
            except:
                first = _('Cannot save bitmap:')
                msg = ("%s\n'%s'.") % (first, doc_file) + '\n'
                msg += _('Please check file name and write permissions')
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                self.print_stacktrace()
                return
            config.save_dir = str(os.path.dirname(doc_file))
            events.emit(events.APP_STATUS,
                        _('Bitmap is successfully extracted'))

    def export_palette(self, palette, parent=None):
        if not parent: parent = self.mw
        doc_file = '' + palette.model.name
        doc_file = os.path.splitext(doc_file)[0]
        doc_file = os.path.join(config.export_dir, os.path.basename(doc_file))
        ret = dialogs.get_save_file_name(parent,
                                         self,
                                         doc_file,
                                         _('Export palette as...'),
                                         file_types=PALETTE_SAVERS)
        if not ret: return
        doc_file, index = ret
        saver_id = PALETTE_SAVERS[index]

        if doc_file:

            if not os.path.splitext(doc_file)[1] == "." + \
               uc2const.FORMAT_EXTENSION[saver_id][0]:
                doc_file = os.path.splitext(doc_file)[0] + "." + \
                  uc2const.FORMAT_EXTENSION[saver_id][0]

            try:
                saver = get_saver_by_id(saver_id)
                if saver is None:
                    raise IOError(
                        _('Unknown file format is requested for export!'),
                        doc_file)

                self.make_backup(doc_file, True)

                pd = dialogs.ProgressDialog(_('Exporting...'), parent)
                ret = pd.run(saver, [palette, doc_file, None, False, True],
                             False)
                if ret:
                    if not pd.error_info is None:
                        pd.destroy()
                        raise IOError(*pd.error_info)
                    pd.destroy()
                else:
                    pd.destroy()
                    raise IOError(_('Error while exporting'), doc_file)

            except IOError:
                raise IOError(*sys.exc_info())

            config.export_dir = str(os.path.dirname(doc_file))
            events.emit(events.APP_STATUS,
                        _('Palette is successfully exported'))

    def import_palette(self, parent=None):
        if not parent: parent = self.mw
        doc_file = dialogs.get_open_file_name(parent,
                                              self,
                                              config.import_dir,
                                              _('Select palette to import'),
                                              file_types=PALETTE_LOADERS)
        if os.path.lexists(doc_file) and os.path.isfile(doc_file):
            try:
                palette = None
                loader = get_loader(doc_file)
                pd = dialogs.ProgressDialog(_('Opening file...'), parent)
                ret = pd.run(loader,
                             [self.appdata, doc_file, None, False, True])
                if ret:
                    if pd.result is None:
                        pd.destroy()
                        raise IOError(*pd.error_info)

                    palette = pd.result
                    ret = True
                    pd.destroy()
                else:
                    pd.destroy()
                    raise IOError(_('Error while opening'), doc_file)

                if palette:
                    self.palettes.add_palette(palette)
                    config.import_dir = str(os.path.dirname(doc_file))
                    msg = _('Palette is successfully imported')
                    events.emit(events.APP_STATUS, msg)
                    return palette.model.name

            except:
                msg = _('Cannot import file:')
                msg = "%s\n'%s'" % (msg, doc_file) + '\n'
                msg += _('The file may be corrupted or not supported format')
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                self.print_stacktrace()
        return None

    def extract_pattern(self, parent, pattern, eps=False):
        img_file = 'image'
        img_file = os.path.join(config.save_dir, img_file)
        file_types = [uc2const.TIF]
        if eps: file_types = [uc2const.EPS]
        img_file = dialogs.get_save_file_name(parent,
                                              self,
                                              img_file,
                                              _('Save pattern as...'),
                                              file_types=file_types,
                                              path_only=True)
        if img_file:
            try:
                fobj = open(img_file, 'wb')
                fobj.write(b64decode(pattern))
                fobj.close()
            except:
                first = _('Cannot save pattern from:')
                msg = ("%s\n'%s'.") % (first, self.current_doc.doc_name) + '\n'
                msg += _('Please check file name and write permissions')
                dialogs.error_dialog(parent, self.appdata.app_name, msg)
                self.print_stacktrace()
                return
            config.save_dir = str(os.path.dirname(img_file))

    def import_pattern(self, parent=None):
        if not parent: parent = self.mw
        img_file = dialogs.get_open_file_name(parent,
                                              self,
                                              config.import_dir,
                                              _('Select pattern to load'),
                                              file_types=PATTERN_FORMATS)
        if os.path.lexists(img_file) and os.path.isfile(img_file):
            first = _('Cannot load pattern for:')
            msg = ("%s\n'%s'.") % (first, self.current_doc.doc_name) + '\n'
            msg += _('The file may be corrupted or not supported format')
            try:
                if libimg.check_image(img_file):
                    config.import_dir = str(os.path.dirname(img_file))
                    return img_file
                else:
                    dialogs.error_dialog(parent, self.appdata.app_name, msg)
                    self.print_stacktrace()
            except:
                dialogs.error_dialog(parent, self.appdata.app_name, msg)
                self.print_stacktrace()

        return None

    def make_backup(self, doc_file, export=False):
        if not export and not config.make_backup: return
        if export and not config.make_export_backup: return
        if os.path.lexists(doc_file):
            if os.path.lexists(doc_file + '~'):
                os.remove(doc_file + '~')
            os.rename(doc_file, doc_file + '~')

    def print_stacktrace(self):
        if config.print_stacktrace:
            print sys.exc_info()[1].__str__()
            print traceback.format_tb(sys.exc_info()[2])

    def open_url(self, url):
        webbrowser.open(url, new=1, autoraise=True)
        msg = _('Requested page is opened in default browser')
        events.emit(events.APP_STATUS, msg)
Esempio n. 2
0
class pdApplication(wal.Application, UCApplication):

	appdata = None
	history = None

	actions = {}
	plugins = {}
	docs = []
	current_doc = None
	doc_counter = 0

	proxy = None
	insp = None
	mw = None
	default_cms = None
	artprovider = None
	cursors = None
	mdiarea = None
	plg_area = None

	def __init__(self, path):

		self.path = path

		wal.Application.__init__(self)
		UCApplication.__init__(self, path)

		self.appdata = AppData(self)
		config.load(self.appdata.app_config)
		config.resource_dir = os.path.join(path_unicode(self.path), 'share')
		plg_dir = os.path.join(self.path, 'share', 'pd_plugins')
		custom_plg_dir = self.appdata.plugin_dir
		config.plugin_dirs = [plg_dir, custom_plg_dir]
		sys.path.insert(1, self.appdata.app_config)
		sys.path.insert(1, os.path.join(self.path, 'share'))
		config.app = self

		self.history = AppHistoryManager(self)

		self.artprovider = create_artprovider()
		self.cursors = modes.get_cursors()

		self.proxy = AppProxy(self)
		self.insp = AppInspector(self)
		self.plugins = app_plugins.scan_plugins(self)
		self.actions = app_actions.create_actions(self)

		self.default_cms = AppColorManager(self)
		self.palettes = AppPaletteManager(self)
		self.clipboard = AppClipboard(self)

		self.mw = AppMainWindow(self)
		self.mw.set_global_shortcuts(self.actions)

		self.proxy.update()
		self.insp.update()
		events.emit(events.NO_DOCS)

	def load_plugins(self):
		if config.active_plugins:
			for item in config.active_plugins:
				try:
					self.mw.mdi.plg_area.show_plugin(item)
				except: pass

	def call_after(self, *args):
		if self.docs: return
		if config.new_doc_on_start:
			self.load_plugins()
			self.new()
		else:
			txt = _('To start, create new document or open existing')
			events.emit(events.APP_STATUS, txt)
			self.load_plugins()

	def stub(self, *args):pass

	def update_config(self):
		config.resource_dir = ''
		config.mw_size = self.mw.get_size()
		config.mw_maximized = self.mw.is_maximized()
		if self.mw.is_maximized(): config.mw_size = config.mw_min_size
		plugins = []
		for item in self.mw.mdi.plg_area.plugins:
			plugins.append(item.pid)
		config.active_plugins = plugins
		config.save(self.appdata.app_config)

	def exit(self, *args):
		if not self.insp.is_any_doc_not_saved(): self.mw.hide()
		if self.close_all():
			self.update_config()
			self.mw.destroy()
			self.Exit()
			return True
		return False

	def get_new_docname(self):
		self.doc_counter += 1
		return _('Untitled') + ' ' + str(self.doc_counter)

	def set_current_doc(self, doc):
		self.current_doc = doc
		self.current_doc.set_title()
		self.mw.mdi.set_active(doc)
		self.current_doc.canvas.set_focus()
		events.emit(events.DOC_CHANGED, doc)
		events.emit(events.SNAP_CHANGED)
		events.emit(events.APP_STATUS, _('Document is changed'))

	def new(self):
		doc = PD_Presenter(self)
		self.docs.append(doc)
		self.set_current_doc(doc)
		events.emit(events.APP_STATUS, _('New document created'))

	def new_from_template(self):
		msg = _('Select Template')
		doc_file = dialogs.get_open_file_name(self.mw, self,
								config.template_dir, msg)
		if os.path.lexists(doc_file) and os.path.isfile(doc_file):
			try:
				doc = PD_Presenter(self, doc_file, template=True)
			except:
				msg = _('Cannot parse file')
				msg = "%s '%s'" % (msg, doc_file) + '\n'
				msg += _('The file may be corrupted or not supported format')
				dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
				self.print_stacktrace()
				return
			self.docs.append(doc)
			config.template_dir = str(os.path.dirname(doc_file))
			self.set_current_doc(doc)
			events.emit(events.APP_STATUS, _('New document from template'))

	def open(self, doc_file='', silent=False):
		if not doc_file:
			doc_file = dialogs.get_open_file_name(self.mw, self, config.open_dir)
		if os.path.lexists(doc_file) and os.path.isfile(doc_file):
			try:
				doc = PD_Presenter(self, doc_file, silent)
			except:
				msg = _('Cannot open file')
				msg = "%s '%s'" % (msg, doc_file) + '\n'
				msg += _('The file may be corrupted or not supported format')
				dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
				self.print_stacktrace()
				return
			self.docs.append(doc)
			config.open_dir = str(os.path.dirname(doc_file))
			self.history.add_entry(doc_file)
			self.set_current_doc(doc)
			events.emit(events.APP_STATUS, _('Document opened'))

	def save(self, doc=''):
		if not doc:
			doc = self.current_doc
		if not doc.doc_file:
			return self.save_as()
		ext = os.path.splitext(self.current_doc.doc_file)[1]
		if not ext == "." + uc2const.FORMAT_EXTENSION[uc2const.SK2][0]:
			return self.save_as()
		if not os.path.lexists(os.path.dirname(self.current_doc.doc_file)):
			return self.save_as()

		try:
			self.make_backup(self.current_doc.doc_file)
			doc.save()
			self.history.add_entry(self.current_doc.doc_file, appconst.SAVED)
			events.emit(events.DOC_SAVED, doc)
		except:
			msg = _('Cannot save file')
			msg = "%s '%s'" % (msg, self.current_doc.doc_file) + '\n'
			msg += _('Please check file write permissions')
			dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
			self.print_stacktrace()
			return False
		events.emit(events.APP_STATUS, _('Document saved'))
		return True

	def save_as(self):
		doc_file = '' + self.current_doc.doc_file
		if not doc_file:
			doc_file = '' + self.current_doc.doc_name
		if not os.path.splitext(doc_file)[1] == "." + \
					uc2const.FORMAT_EXTENSION[uc2const.SK2][0]:
			doc_file = os.path.splitext(doc_file)[0] + "." + \
					uc2const.FORMAT_EXTENSION[uc2const.SK2][0]
		if not os.path.lexists(os.path.dirname(doc_file)):
			doc_file = os.path.join(config.save_dir,
								os.path.basename(doc_file))
		doc_file = dialogs.get_save_file_name(self.mw, self, doc_file)[0]
		if doc_file:
			old_file = self.current_doc.doc_file
			old_name = self.current_doc.doc_name
			self.current_doc.set_doc_file(doc_file)
			try:
				self.make_backup(doc_file)
				self.current_doc.save()
			except:
				self.current_doc.set_doc_file(old_file, old_name)
				first = _('Cannot save document')
				msg = ("%s '%s'.") % (first, self.current_doc.doc_name) + '\n'
				msg += _('Please check file name and write permissions')
				dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
				self.print_stacktrace()
				return False
			config.save_dir = str(os.path.dirname(doc_file))
			self.history.add_entry(doc_file, appconst.SAVED)
			events.emit(events.DOC_SAVED, self.current_doc)
			events.emit(events.APP_STATUS, _('Document saved'))
			return True
		else:
			return False

	def save_selected(self):
		doc_file = '' + self.current_doc.doc_file
		if not doc_file:
			doc_file = '' + self.current_doc.doc_name
		if not os.path.splitext(doc_file)[1] == "." + \
					uc2const.FORMAT_EXTENSION[uc2const.SK2][0]:
			doc_file = os.path.splitext(doc_file)[0] + "." + \
					uc2const.FORMAT_EXTENSION[uc2const.SK2][0]
		if not os.path.lexists(os.path.dirname(doc_file)):
			doc_file = os.path.join(config.save_dir,
								os.path.basename(doc_file))
		doc_file = dialogs.get_save_file_name(self.mw, self, doc_file,
							_('Save selected objects only as...'))[0]
		if doc_file:
			try:
				self.make_backup(doc_file)
				self.current_doc.save_selected(doc_file)
				self.history.add_entry(doc_file, appconst.SAVED)
			except:
				first = _('Cannot save document')
				msg = ("%s '%s'.") % (first, doc_file) + '\n'
				msg += _('Please check requested file format and write permissions')
				dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
				self.print_stacktrace()

	def save_all(self):
		for doc in self.docs:
			if self.insp.is_doc_not_saved(doc):
				self.save(doc)

	def close(self, doc=None):
		if not self.docs: return
		if doc is None: doc = self.current_doc
		if not doc == self.current_doc: self.set_current_doc(doc)

		if self.insp.is_doc_not_saved(doc):
			msg = _("Document '%s' has been modified.") % (doc.doc_name) + '\n'
			msg += _('Do you want to save your changes?')
			ret = dialogs.ync_dialog(self.mw, self.appdata.app_name, msg)

			if ret is None: return False
			if ret:
				if not self.save(): return False

		if doc in self.docs:
			self.docs.remove(doc)
			doc.close()
			events.emit(events.DOC_CLOSED)
			if not len(self.docs):
				self.current_doc = None
				events.emit(events.NO_DOCS)
				msg = _('To start create new or open existing document')
				events.emit(events.APP_STATUS, msg)
				self.mw.set_title()
			else:
				self.set_current_doc(self.docs[-1])
		return True

	def close_all(self):
		result = True
		if self.docs:
			while self.docs:
				result = self.close(self.docs[0])
				if not result: break
		return result

	def import_file(self):
		doc_file = dialogs.get_open_file_name(self.mw, self, config.import_dir,
											_('Select file to import'))
		if os.path.lexists(doc_file) and os.path.isfile(doc_file):
			try:
				ret = self.current_doc.import_file(doc_file)
				if not ret:
					msg = _('Cannot import graphics from file:')
					msg = "%s\n'%s'" % (msg, doc_file) + '\n'
					msg += _('It seems the document is empty or contains unsupported objects.')
					dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
				config.import_dir = str(os.path.dirname(doc_file))
			except:
				msg = _('Cannot import file')
				msg = "%s '%s'" % (msg, doc_file) + '\n'
				msg += _('The file may be corrupted or not supported format')
				dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
				self.print_stacktrace()

	def export_as(self):
		doc_file = '' + self.current_doc.doc_file
		if not doc_file:
			doc_file = '' + self.current_doc.doc_name
		if os.path.splitext(doc_file)[1] == "." + \
					uc2const.FORMAT_EXTENSION[uc2const.SK2][0]:
			doc_file = os.path.splitext(doc_file)[0] + "." + \
					uc2const.FORMAT_EXTENSION[uc2const.PNG][0]
		doc_file = os.path.join(config.export_dir,
								os.path.basename(doc_file))
		doc_file = dialogs.get_save_file_name(self.mw, self, doc_file,
							_('Export document As...'),
							file_types=data.SAVER_FORMATS[1:])[0]
		if doc_file:
			try:
				self.make_backup(doc_file, True)
				self.current_doc.export_as(doc_file)
			except:
				first = _('Cannot save document')
				msg = ("%s '%s'.") % (first, self.current_doc.doc_name) + '\n'
				msg += _('Please check file name and write permissions')
				dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
				self.print_stacktrace()
				return
			config.export_dir = str(os.path.dirname(doc_file))
			events.emit(events.APP_STATUS, _('Document is successfully exported'))

	def extract_bitmap(self):
		doc_file = 'image.tiff'
		doc_file = os.path.join(config.save_dir, doc_file)
		doc_file = dialogs.get_save_file_name(self.mw, self, doc_file,
							_('Extract selected bitmap as...'),
							file_types=[data.TIF])[0]
		if doc_file:
			try:
				pixmap = self.current_doc.selection.objs[0]
				libimg.extract_bitmap(pixmap, doc_file)
			except:
				first = _('Cannot save document')
				msg = ("%s '%s'.") % (first, self.current_doc.doc_name) + '\n'
				msg += _('Please check file name and write permissions')
				dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
				self.print_stacktrace()
				return
			config.save_dir = str(os.path.dirname(doc_file))
			events.emit(events.APP_STATUS, _('Bitmap is successfully extracted'))

	def export_palette(self, palette, parent=None):
		if not parent: parent = self.mw
		doc_file = '' + palette.model.name
		doc_file = os.path.splitext(doc_file)[0] + "." + \
					uc2const.FORMAT_EXTENSION[uc2const.SKP][0]
		doc_file = os.path.join(config.export_dir,
								os.path.basename(doc_file))
		doc_file, index = dialogs.get_save_file_name(parent, self, doc_file,
							_('Export palette as...'),
							file_types=data.PALETTE_SAVERS)
		saver_id = data.PALETTE_SAVERS[index]

		if doc_file:

			if not os.path.splitext(doc_file)[1] == "." + \
						uc2const.FORMAT_EXTENSION[saver_id][0]:
				doc_file = os.path.splitext(doc_file)[0] + "." + \
						uc2const.FORMAT_EXTENSION[saver_id][0]

			try:
				saver = get_saver_by_id(saver_id)
				if saver is None:
					raise IOError(_('Unknown file format is requested for export!'),
								 doc_file)

				self.make_backup(doc_file, True)

				pd = dialogs.ProgressDialog(_('Exporting...'), parent)
				ret = pd.run(saver, [palette, doc_file, None, False, True], False)
				if ret:
					if not pd.error_info is None:
						pd.destroy()
						raise IOError(*pd.error_info)
					pd.destroy()
				else:
					pd.destroy()
					raise IOError(_('Error while exporting'), doc_file)

			except IOError:
				raise IOError(*sys.exc_info())

			config.export_dir = str(os.path.dirname(doc_file))
			events.emit(events.APP_STATUS, _('Palette is successfully exported'))

	def import_palette(self, parent=None):
		if not parent: parent = self.mw
		doc_file = dialogs.get_open_file_name(parent, self, config.import_dir,
											_('Select palette to import'),
											file_types=data.PALETTE_LOADERS)
		if os.path.lexists(doc_file) and os.path.isfile(doc_file):
			try:
				palette = None
				loader = get_loader(doc_file)
				pd = dialogs.ProgressDialog(_('Opening file...'), parent)
				ret = pd.run(loader, [self.appdata, doc_file, None, False, True])
				if ret:
					if pd.result is None:
						pd.destroy()
						raise IOError(*pd.error_info)

					palette = pd.result
					ret = True
					pd.destroy()
				else:
					pd.destroy()
					raise IOError(_('Error while opening'), doc_file)

				if palette:
					self.palettes.add_palette(palette)
					config.import_dir = str(os.path.dirname(doc_file))
					msg = _('Palette is successfully imported')
					events.emit(events.APP_STATUS, msg)
					return palette.model.name

			except:
				msg = _('Cannot import file')
				msg = "%s '%s'" % (msg, doc_file) + '\n'
				msg += _('The file may be corrupted or not supported format')
				dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
				self.print_stacktrace()
		return None

	def extract_pattern(self, parent, pattern, eps=False):
		img_file = 'image.tiff'
		if eps:img_file = 'image.eps'
		img_file = os.path.join(config.save_dir, img_file)
		file_types = [data.TIF]
		if eps: file_types = [data.EPS]
		img_file = dialogs.get_save_file_name(parent, self, img_file,
							_('Save pattern as...'),
							file_types=file_types)[0]
		if img_file:
			try:
				fobj = open(img_file, 'wb')
				fobj.write(b64decode(pattern))
				fobj.close()
			except:
				first = _('Cannot save pattern from')
				msg = ("%s '%s'.") % (first, self.current_doc.doc_name) + '\n'
				msg += _('Please check file name and write permissions')
				dialogs.error_dialog(parent, self.appdata.app_name, msg)
				self.print_stacktrace()
				return
			config.save_dir = str(os.path.dirname(img_file))

	def import_pattern(self, parent=None):
		if not parent: parent = self.mw
		img_file = dialogs.get_open_file_name(parent, self, config.import_dir,
				_('Select pattern to load'), file_types=data.PATTERN_FORMATS)
		if os.path.lexists(img_file) and os.path.isfile(img_file):
			first = _('Cannot load pattern for')
			msg = ("%s '%s'.") % (first, self.current_doc.doc_name) + '\n'
			msg += _('The file may be corrupted or not supported format')
			try:
				if libimg.check_image(img_file):
					config.import_dir = str(os.path.dirname(img_file))
					return img_file
				else:
					dialogs.error_dialog(parent, self.appdata.app_name, msg)
					self.print_stacktrace()
			except:
				dialogs.error_dialog(parent, self.appdata.app_name, msg)
				self.print_stacktrace()

		return None

	def make_backup(self, doc_file, export=False):
		if not export and not config.make_backup:return
		if export and not config.make_export_backup:return
		if os.path.lexists(doc_file):
			if os.path.lexists(doc_file + '~'):
				os.remove(doc_file + '~')
			os.rename(doc_file, doc_file + '~')

	def print_stacktrace(self):
		if config.print_stacktrace:
			print sys.exc_info()[1].__str__()
			print traceback.format_tb(sys.exc_info()[2])

	def open_url(self, url):
		webbrowser.open(url, new=1, autoraise=True)
		msg = _('Requested page is opened in default browser')
		events.emit(events.APP_STATUS, msg)
Esempio n. 3
0
class SK1Application(wal.Application, UCApplication):
    appdata = None
    history = None

    actions = None
    plugins = None
    docs = []
    current_doc = None
    doc_counter = 0

    proxy = None
    insp = None
    mw = None
    default_cms = None
    artprovider = None
    cursors = None
    mdiarea = None
    plg_area = None
    print_data = None
    log_filepath = None

    def __init__(self, path, cfgdir):

        self.path = path

        wal.Application.__init__(self)
        UCApplication.__init__(self, path, cfgdir, False)

        if wal.IS_WINXP:
            msg = _('WindowsXP platform is obsolete and not supported!')
            dialogs.error_dialog(self.mw, 'sK1', msg)
            sys.exit()

        self.appdata = AppData(self, cfgdir)
        log_level = config.log_level
        self.log_filepath = os.path.join(self.appdata.app_config_dir,
                                         'sk1.log')
        config_logging(get_sys_path(self.log_filepath), log_level)
        sys.stderr = StreamLogger()
        LOG.info('Logging started')

        self.update_wal()
        plg_dir = os.path.join(self.path, 'share', 'pd_plugins')
        custom_plg_dir = self.appdata.plugin_dir
        config.plugin_dirs = [plg_dir, custom_plg_dir]
        sys.path.insert(1, get_sys_path(self.appdata.app_config_dir))
        sys.path.insert(1, get_sys_path(os.path.join(self.path, 'share')))
        config.app = self
        LOG.info('Config is updated')

        self.history = AppHistoryManager(self)

        self.artprovider = create_artprovider()
        self.cursors = modes.get_cursors()

        self.proxy = AppProxy(self)
        self.insp = AppInspector(self)
        self.plugins = app_plugins.scan_plugins(self)
        self.actions = app_actions.create_actions(self)

        self.default_cms = AppColorManager(self)
        self.palettes = AppPaletteManager(self)
        self.clipboard = AppClipboard(self)

        self.mw = AppMainWindow(self)
        self.mw.set_global_shortcuts(self.actions)

        self.proxy.update()
        self.insp.update()
        LOG.info('Application is initialized')
        uc2.events.connect(uc2.events.MESSAGES, self.uc2_event_logging)
        events.connect(events.APP_STATUS, self.sk1_event_logging)

        if wal.IS_WX2:
            events.emit(events.NO_DOCS)
        if config.make_font_cache_on_start:
            generate_fcache()

    def load_plugins(self):
        if config.active_plugins:
            for item in config.active_plugins:
                try:
                    self.mw.mdi.plg_area.show_plugin(item)
                except Exception as e:
                    LOG.warn('Cannot load plugin <%s> %s', item, e)

    def call_after(self, *args):
        if self.docs:
            return
        if config.new_doc_on_start:
            self.load_plugins()
            self.new()
        else:
            txt = _('To start, create new document or open existing')
            events.emit(events.APP_STATUS, txt)
            self.load_plugins()
            if not wal.IS_WX2:
                events.emit(events.NO_DOCS)
        self.update_actions()

    def update_wal(self):
        wal.SPIN['overlay'] = config.spin_overlay
        wal.SPIN['sep'] = config.spin_sep
        if config.selected_text_bg:
            wal.UI_COLORS['selected_text_bg'] = () + config.selected_text_bg

    def update_config(self):
        config.resource_dir = ''
        w, h = self.mw.get_size()
        if wal.is_unity_16_04():
            h = max(h - 28, config.mw_min_size[1])
        config.mw_size = (w, h)
        config.mw_maximized = self.mw.is_maximized()
        if self.mw.is_maximized():
            config.mw_size = config.mw_min_size
        plugins = [item.pid for item in self.mw.mdi.plg_area.plugins]
        config.active_plugins = plugins
        if self.mw.mdi.plg_area.is_shown():
            w = self.mw.mdi.splitter.get_size()[0]
            val = self.mw.mdi.splitter.get_sash_position() - w
            if val < 0:
                config.sash_position = val
        config.save(self.appdata.app_config)

    def exit(self, *args):
        if self.close_all():
            self.mw.hide()
            self.update_config()
            self.mw.destroy()
            wal.Application.exit(self)
            LOG.info('Application terminated')
            return True
        return False

    def get_new_docname(self):
        self.doc_counter += 1
        doc_name = '%s %d' % (_('Untitled'), self.doc_counter)
        return doc_name

    def set_current_doc(self, doc):
        self.current_doc = doc
        if not self.mw.mdi.is_shown():
            self.mw.show_mdi(True)
        self.mw.mdi.set_active(doc)
        self.current_doc.set_title()
        events.emit(events.DOC_CHANGED, doc)
        events.emit(events.SNAP_CHANGED)
        events.emit(events.APP_STATUS, _('Document is changed'))

    def new(self):
        doc = SK1Presenter(self)
        self.docs.append(doc)
        self.set_current_doc(doc)
        events.emit(events.APP_STATUS, _('New document created'))

    def new_from_template(self):
        msg = _('Select Template')
        doc_file = dialogs.get_open_file_name(self.mw, config.template_dir,
                                              msg)
        if fsutils.lexists(doc_file) and fsutils.isfile(doc_file):
            try:
                doc = SK1Presenter(self, doc_file, template=True)
            except Exception as e:
                msg = _('Cannot parse file:')
                msg = "%s\n'%s'" % (msg, doc_file) + '\n'
                msg += _('The file may be corrupted or not supported format')
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                LOG.error('Cannot parse file <%s> %s', doc_file, e)
                return
            self.docs.append(doc)
            config.template_dir = str(os.path.dirname(doc_file))
            self.set_current_doc(doc)
            events.emit(events.APP_STATUS, _('New document from template'))

    def open(self, doc_file='', silent=False):
        doc_file = doc_file or \
                   dialogs.get_open_file_name(self.mw, config.open_dir)
        if doc_file and fsutils.lexists(doc_file) and fsutils.isfile(doc_file):
            try:
                doc = SK1Presenter(self, doc_file, silent)

            except RuntimeError:
                msg = _('Cannot open file:')
                msg = "%s\n'%s'" % (msg, doc_file) + '\n'
                msg += _('The file contains newer SK2 format.\n')
                msg += _('Try updating sK1 application from '
                         'http://www.sk1project.net')
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                LOG.error('Cannot open file <%s>: newer SK2 format.', doc_file)
                return
            except Exception as e:
                msg = _('Cannot open file:')
                msg = "%s\n'%s'" % (msg, doc_file) + '\n'
                msg += _('The file may be corrupted or not supported format.')
                msg += '\n'
                msg += _('Details see in application logs.')
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                LOG.error('Cannot open file <%s> %s', doc_file, e)
                return
            self.docs.append(doc)
            config.open_dir = str(os.path.dirname(doc_file))
            self.history.add_entry(doc_file)
            self.set_current_doc(doc)
            events.emit(events.APP_STATUS, _('Document opened'))

    def save(self, doc=None):
        doc = doc or self.current_doc
        if not doc.doc_file:
            return self.save_as()
        ext = os.path.splitext(self.current_doc.doc_file)[1]
        if not ext == "." + uc2const.FORMAT_EXTENSION[uc2const.SK2][0]:
            return self.save_as()
        if not fsutils.lexists(os.path.dirname(self.current_doc.doc_file)):
            return self.save_as()

        try:
            self.make_backup(self.current_doc.doc_file)
            doc.save()
            self.history.add_entry(self.current_doc.doc_file, appconst.SAVED)
            events.emit(events.DOC_SAVED, doc)
        except Exception as e:
            msg = _('Cannot save file:')
            msg = "%s\n'%s'" % (msg, self.current_doc.doc_file) + '\n'
            msg += _('Please check file write permissions')
            dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
            LOG.error('Cannot save file <%s> %s', self.current_doc.doc_file, e)
            return False
        events.emit(events.APP_STATUS, _('Document saved'))
        return True

    def save_as(self):
        doc_file = self.current_doc.doc_file
        doc_file = doc_file or self.current_doc.doc_name
        if os.path.splitext(doc_file)[1] != "." + \
                uc2const.FORMAT_EXTENSION[uc2const.SK2][0]:
            doc_file = os.path.splitext(doc_file)[0] + "." + \
                       uc2const.FORMAT_EXTENSION[uc2const.SK2][0]
        if not fsutils.lexists(os.path.dirname(doc_file)):
            doc_file = os.path.join(config.save_dir,
                                    os.path.basename(doc_file))
        doc_file = dialogs.get_save_file_name(self.mw,
                                              doc_file,
                                              path_only=True)
        if doc_file:
            old_file = self.current_doc.doc_file
            old_name = self.current_doc.doc_name
            self.current_doc.set_doc_file(doc_file)
            try:
                self.make_backup(doc_file)
                self.current_doc.save()
            except Exception as e:
                self.current_doc.set_doc_file(old_file, old_name)
                first = _('Cannot save document:')
                msg = "%s\n'%s'." % (first, self.current_doc.doc_name) + '\n'
                msg += _('Please check file name and write permissions')
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                LOG.error('Cannot save file <%s> %s', doc_file, e)
                return False
            config.save_dir = str(os.path.dirname(doc_file))
            self.history.add_entry(doc_file, appconst.SAVED)
            events.emit(events.DOC_SAVED, self.current_doc)
            events.emit(events.APP_STATUS, _('Document saved'))
            return True
        else:
            return False

    def save_selected(self):
        doc_file = self.current_doc.doc_file
        doc_file = doc_file or self.current_doc.doc_name
        if os.path.splitext(doc_file)[1] != "." + \
                uc2const.FORMAT_EXTENSION[uc2const.SK2][0]:
            doc_file = os.path.splitext(doc_file)[0] + "." + \
                       uc2const.FORMAT_EXTENSION[uc2const.SK2][0]
        if not fsutils.lexists(os.path.dirname(doc_file)):
            doc_file = os.path.join(config.save_dir,
                                    os.path.basename(doc_file))
        msg = _('Save selected objects only as...')
        doc_file = dialogs.get_save_file_name(self.mw,
                                              doc_file,
                                              msg,
                                              path_only=True)
        if doc_file:
            try:
                self.make_backup(doc_file)
                self.current_doc.save_selected(doc_file)
                self.history.add_entry(doc_file, appconst.SAVED)
            except Exception as e:
                first = _('Cannot save document:')
                msg = "%s\n'%s'." % (first, doc_file) + '\n'
                msg += _('Please check requested file format '
                         'and write permissions')
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                LOG.error('Cannot save file <%s> %s', doc_file, e)

    def save_all(self):
        for doc in self.docs:
            if self.insp.is_doc_not_saved(doc):
                self.save(doc)

    def close(self, doc=None):
        if not self.docs:
            return
        doc = doc or self.current_doc

        if self.insp.is_doc_not_saved(doc):
            if not doc == self.current_doc:
                self.set_current_doc(doc)

            msg = _("Document '%s' has been modified.") % doc.doc_name + '\n'
            msg += _('Do you want to save your changes?')
            ret = dialogs.ync_dialog(self.mw, self.appdata.app_name, msg)

            if ret is None:
                return False
            if ret:
                if not self.save():
                    return False

        if doc in self.docs:
            index = self.docs.index(doc)
            active = doc == self.current_doc
            self.docs.remove(doc)
            self.mdi.remove_doc(doc)
            doc.close()
            events.emit(events.DOC_CLOSED)
            if not len(self.docs):
                self.current_doc = None
                self.mw.show_mdi(False)
                events.emit(events.NO_DOCS)
                msg = _('To start create new or open existing document')
                events.emit(events.APP_STATUS, msg)
                self.mw.set_title()
            elif active:
                index = index if len(self.docs) > index else -1
                self.set_current_doc(self.docs[index])
        return True

    def close_others(self):
        docs = [] + self.docs
        docs.remove(self.current_doc)
        for doc in docs:
            if not self.close(doc):
                return False
        return True

    def close_all(self):
        if self.docs:
            while self.docs:
                if not self.close(self.docs[0]):
                    return False
        return True

    def import_file(self):
        doc_file = dialogs.get_open_file_name(self.mw, config.import_dir,
                                              _('Select file to import'))
        if fsutils.lexists(doc_file) and fsutils.isfile(doc_file):
            try:
                ret = self.current_doc.import_file(doc_file)
                if not ret:
                    msg = _('Cannot import graphics from file:')
                    msg = "%s\n'%s'" % (msg, doc_file) + '\n'
                    msg += _('It seems the document is empty or '
                             'contains unsupported objects.')
                    dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                    LOG.warn('Cannot import graphics from file <%s>', doc_file)
                config.import_dir = str(os.path.dirname(doc_file))
            except Exception as e:
                msg = _('Cannot import file:')
                msg = "%s\n'%s'" % (msg, doc_file) + '\n'
                msg += _('The file may be corrupted or not supported format.')
                msg += '\n'
                msg += _('Details see in application logs.')
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                LOG.warn('Cannot import file <%s>', doc_file, e)

    def export_as(self):
        doc_file = self.current_doc.doc_file
        doc_file = doc_file or self.current_doc.doc_name
        doc_file = os.path.splitext(doc_file)[0]
        doc_file = os.path.join(config.export_dir, os.path.basename(doc_file))
        ftype = uc2const.SAVER_FORMATS[1:]
        doc_file = dialogs.get_save_file_name(self.mw,
                                              doc_file,
                                              _('Export document As...'),
                                              file_types=ftype,
                                              path_only=True)
        if doc_file:
            try:
                self.make_backup(doc_file, True)
                self.current_doc.export_as(doc_file)
            except Exception as e:
                first = _('Cannot save document:')
                msg = "%s\n'%s'." % (first, self.current_doc.doc_name) + '\n'
                msg += _('Please check file name and write permissions')
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                LOG.warn('Cannot save file <%s>', doc_file, e)
                return
            config.export_dir = str(os.path.dirname(doc_file))
            msg = _('Document is successfully exported')
            events.emit(events.APP_STATUS, msg)

    def extract_bitmap(self):
        doc_file = 'image'
        doc_file = os.path.join(config.save_dir, doc_file)
        msg = _('Extract selected bitmap as...')
        doc_file = dialogs.get_save_file_name(self.mw,
                                              doc_file,
                                              msg,
                                              file_types=[uc2const.PNG],
                                              path_only=True)
        if doc_file:
            try:
                pixmap = self.current_doc.selection.objs[0]
                libimg.extract_bitmap(pixmap, doc_file)
            except Exception as e:
                first = _('Cannot save bitmap:')
                msg = "%s\n'%s'." % (first, doc_file) + '\n'
                msg += _('Please check file name and write permissions')
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                LOG.warn('Cannot save bitmap in <%s>', doc_file, e)
                return
            config.save_dir = str(os.path.dirname(doc_file))
            events.emit(events.APP_STATUS,
                        _('Bitmap is successfully extracted'))

    def export_palette(self, palette, parent=None):
        parent = parent or self.mw
        doc_file = palette.model.name
        doc_file = os.path.splitext(doc_file)[0]
        doc_file = os.path.join(config.export_dir, os.path.basename(doc_file))
        ret = dialogs.get_save_file_name(parent,
                                         doc_file,
                                         _('Export palette as...'),
                                         file_types=uc2const.PALETTE_SAVERS)
        if not ret:
            return
        doc_file, index = ret
        saver_id = uc2const.PALETTE_SAVERS[index]

        if doc_file:
            if not os.path.splitext(doc_file)[1] == "." + \
                   uc2const.FORMAT_EXTENSION[saver_id][0]:
                doc_file = os.path.splitext(doc_file)[0] + "." + \
                           uc2const.FORMAT_EXTENSION[saver_id][0]

            pd = dialogs.ProgressDialog(_('Exporting...'), parent)
            try:
                saver = get_saver_by_id(saver_id)
                if saver is None:
                    msg = _('Unknown file format is requested for export <%s>')
                    raise IOError(msg % doc_file)
                self.make_backup(doc_file, True)
                pd.run(saver, [palette, doc_file, None, False, True])
            except Exception as e:
                msg = _('Cannot export palette:')
                msg = "%s\n'%s'." % (msg, doc_file) + '\n'
                msg += _('Please check file name and write permissions')
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                LOG.error('Cannot save bitmap in <%s>', doc_file, e)
                return
            finally:
                pd.destroy()

            config.export_dir = str(os.path.dirname(doc_file))
            msg = _('Palette is successfully exported')
            events.emit(events.APP_STATUS, msg)

    def import_palette(self, parent=None):
        parent = parent or self.mw
        file_types = uc2const.PALETTE_LOADERS
        doc_file = dialogs.get_open_file_name(parent,
                                              config.import_dir,
                                              _('Select palette to import'),
                                              file_types=file_types)
        if fsutils.lexists(doc_file) and fsutils.isfile(doc_file):

            pd = dialogs.ProgressDialog(_('Opening file...'), parent)
            try:
                loader = get_loader(doc_file)
                if not loader:
                    raise IOError(_('Loader is not found for <%s>') % doc_file)
                palette = pd.run(loader,
                                 [self.appdata, doc_file, None, False, True])
                if not palette:
                    raise IOError(_('Error while opening'), doc_file)
                self.palettes.add_palette(palette)
                config.import_dir = str(os.path.dirname(doc_file))
                msg = _('Palette is successfully imported')
                events.emit(events.APP_STATUS, msg)
                return palette.model.name
            except Exception as e:
                msg = _('Cannot import file:')
                msg = "%s\n'%s'" % (msg, doc_file) + '\n'
                msg += _('The file may be corrupted or not supported format.')
                msg += '\n'
                msg += _('Details see in application logs.')
                dialogs.error_dialog(self.mw, self.appdata.app_name, msg)
                LOG.error('Cannot import file <%s> %s', doc_file, e)
            finally:
                pd.destroy()

    def extract_pattern(self, parent, pattern, eps=False):
        img_file = 'image'
        img_file = os.path.join(config.save_dir, img_file)
        file_types = [uc2const.EPS] if eps else [uc2const.TIF]
        img_file = dialogs.get_save_file_name(parent,
                                              img_file,
                                              _('Save pattern as...'),
                                              file_types=file_types,
                                              path_only=True)
        if img_file:
            try:
                fobj = fsutils.get_fileptr(img_file, True)
                fobj.write(b64decode(pattern))
                fobj.close()
            except Exception as e:
                first = _('Cannot save pattern from:')
                msg = "%s\n'%s'." % (first, self.current_doc.doc_name) + '\n'
                msg += _('Please check file name and write permissions')
                dialogs.error_dialog(parent, self.appdata.app_name, msg)
                LOG.error('Cannot save pattern in <%s> %s', img_file, e)
                return
            config.save_dir = str(os.path.dirname(img_file))

    def import_pattern(self, parent=None):
        parent = parent or self.mw
        file_types = uc2const.PATTERN_FORMATS
        img_file = dialogs.get_open_file_name(parent,
                                              config.import_dir,
                                              _('Select pattern to load'),
                                              file_types=file_types)
        if fsutils.lexists(img_file) and fsutils.isfile(img_file):
            first = _('Cannot load pattern for:')
            msg = "%s\n'%s'." % (first, self.current_doc.doc_name) + '\n'
            msg += _('The file may be corrupted or not supported format')
            msg += '\n'
            msg += _('Details see in application logs.')
            try:
                if libimg.check_image(img_file):
                    config.import_dir = str(os.path.dirname(img_file))
                    return img_file
                else:
                    dialogs.error_dialog(parent, self.appdata.app_name, msg)
                    LOG.error('Cannot load pattern <%s>', img_file)
            except Exception as e:
                dialogs.error_dialog(parent, self.appdata.app_name, msg)
                LOG.error('Cannot load pattern <%s> %s', img_file, e)

    def make_backup(self, doc_file, export=False):
        if not export and not config.make_backup:
            return
        if export and not config.make_export_backup:
            return
        if fsutils.lexists(doc_file):
            if fsutils.lexists(doc_file + '~'):
                os.remove(get_sys_path(doc_file + '~'))
            os.rename(get_sys_path(doc_file), get_sys_path(doc_file + '~'))

    def uc2_event_logging(self, *args):
        log_map = {
            msgconst.JOB: LOG.info,
            msgconst.INFO: LOG.info,
            msgconst.OK: LOG.info,
            msgconst.WARNING: LOG.warn,
            msgconst.ERROR: LOG.error,
            msgconst.STOP: LOG.critical,
        }
        log_map[args[0]](args[1])

    def sk1_event_logging(self, msg):
        LOG.info(msg)

    def open_url(self, url):
        webbrowser.open(url, new=1, autoraise=True)
        msg = _('Requested page is opened in default browser')
        events.emit(events.APP_STATUS, msg)