#!/usr/bin/env python # -*- coding: utf-8 -*- # # Copyright (C) 2012 S. Daniel Francis # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. import os import logging logging.basicConfig(level=logging.DEBUG) from gi.repository import GLib import info logger = logging.getLogger(info.lower_name) appname = info.name # Some desktops like Gnome3-Shell show the Glib Prgname GLib.set_prgname(appname) GLib.set_application_name(appname) from gi.repository import Gtk from gi.repository import Gdk from options import Options from canvas import Canvas this_dir = os.path.split('__file__')[:-1] if len(this_dir) == 1 and this_dir[0] == '': this_dir = os.path.abspath('./') else: this_dir = os.path.join(this_dir) os.chdir(this_dir) from gettext import gettext as _ class UnfullscreenButton(Gtk.Window): def __init__(self): Gtk.Window.__init__(self) self.set_decorated(False) self.set_resizable(False) self.set_type_hint(Gdk.WindowTypeHint.DIALOG) self.set_border_width(0) self.props.accept_focus = False #Setup estimate of width, height w, h = Gtk.icon_size_lookup(Gtk.IconSize.LARGE_TOOLBAR) self._width = w self._height = h self.connect('size-request', self._size_request_cb) screen = self.get_screen() screen.connect('size-changed', self._screen_size_changed_cb) self._button = Gtk.Button(stock=Gtk.STOCK_LEAVE_FULLSCREEN) self._button.set_relief(Gtk.ReliefStyle.NONE) self._button.show() self.add(self._button) def connect_button_press(self, cb): self._button.connect('button-press-event', cb) def _reposition(self): x = gtk.gdk.screen_width() - self._width self.move(x, 0) def _size_request_cb(self, widget, req): self._width = req.width self._height = req.height self._reposition() def _screen_size_changed_cb(self, screen): self._reposition() class Application(Gtk.Window): def __init__(self): Gtk.Window.__init__(self) self.save_type = info.io_mode self.started = False self.file_path = None self.filter = Gtk.FileFilter() if info.file_filter_name: self.filter.set_name(info.file_filter_name) if info.file_filter_mime: self.filter.add_mime_type(info.file_filter_mime) if info.file_filter_pattern: self.filter.add_pattern(info.file_filter_pattern) else: self.filter.set_name(_('All')) self.filter.add_pattern('*') self.accel_group = Gtk.AccelGroup() self.add_accel_group(self.accel_group) self.set_title(appname) logger.debug(info.lower_name) self.set_icon_name('gtkslidy') self.connect('delete-event', lambda w, e: self.stop()) self.maximize() self._vbox = Gtk.VBox() self.options = Options(self) self.options.show() self._vbox.pack_start(self.options, False, True, 0) self.canvas = Canvas(self.options, self) self.canvas.show() self._vbox.pack_start(self.canvas, True, True, 0) self.add(self._vbox) self._vbox.show() self._is_fullscreen = False self.set_events(Gdk.EventMask.ALL_EVENTS_MASK) self.connect('motion-notify-event', self.motion_cb) self.canvas.connect('draw', self.expose_event) def expose_event(self, widget, context): #logger.debug('Exposing') if not self.started: if self.file_path != None: self.canvas.read_file(self.file_path) self.set_title(os.path.abspath('%s - %s' % (self.file_path, appname))) else: self.new() self.started = True def motion_cb(self, widget, event): if self._is_fullscreen: x, y, state = self.get_window().get_pointer() width, height = self.get_size() button_width, button_height = self._unfullscreen_button.get_size() if x >= width - button_width or y <= button_height: self._unfullscreen_button.show() else: self._unfullscreen_button.hide() def fullscreen(self): self.options.hide() self._is_fullscreen = True self._unfullscreen_button = UnfullscreenButton() self._unfullscreen_button.set_transient_for(self) self._unfullscreen_button.connect_button_press( lambda w, e: self.unfullscreen()) self._unfullscreen_button.show() gtk.Window.fullscreen(self) def unfullscreen(self): self.options.show() self._is_fullscreen = False self._unfullscreen_button.destroy() Gtk.Window.unfullscreen(self) def export(self, widget, data): format_name = data[3] filter_mime = data[2] mime_type = data[1] filechooser = Gtk.FileChooserDialog(_("Export..."), self, Gtk.FileChooserAction.SAVE, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OK, Gtk.ResponseType.OK)) file_filter = Gtk.FileFilter() file_filter.set_name(format_name) file_filter.add_mime_type(filter_mime) filechooser.add_filter(file_filter) filechooser.set_do_overwrite_confirmation(True) filechooser.run() file_path = filechooser.get_filename() filechooser.destroy() self.canvas.exports[mime_type](file_path) def new(self): self.file_path = None self.canvas.new() self.set_title(appname) def stop(self): if info.io_mode == info.CONFIG: self.file_path = os.path.join(os.environ['HOME'], '.' + info.lower_name) self.save() Gtk.main_quit() def open(self): filechooser = Gtk.FileChooserDialog(_('Open...'), self, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) filechooser.add_filter(self.filter) response = filechooser.run() self.file_path = filechooser.get_filename() filechooser.destroy() if response == Gtk.ResponseType.OK: logger.debug('Read file %s' % self.file_path) self.canvas.read_file(self.file_path) self.set_title('%s - %s' % (self.file_path, appname)) def save(self): if self.file_path == None: self.save_as() else: logger.debug('Write file %s' % self.file_path) self.canvas.write_file(self.file_path) def save_as(self): filechooser = Gtk.FileChooserDialog(_('Save...'), self, Gtk.FileChooserAction.SAVE, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OK, Gtk.ResponseType.OK)) filechooser.add_filter(self.filter) filechooser.set_do_overwrite_confirmation(True) response = filechooser.run() self.file_path = filechooser.get_filename() filechooser.destroy() if response == Gtk.ResponseType.OK: logger.debug('Save file as %s' % self.file_path) self.canvas.write_file(self.file_path) self.set_title('%s - %s' % (self.file_path, appname)) def start(): logger.debug('Initializing %s' % info.name) import sys if info.io_mode == info.DOCUMENT: if len(sys.argv) > 1: logger.debug('Open from args %s' % sys.argv[1]) if os.path.exists(sys.argv[1]): file_path = sys.argv[1] logger.debug('Found file') else: file_path = None logger.error('Could not find file') else: file_path = None logger.debug('Create new file') else: if os.path.exists(os.path.join(os.environ['HOME'], '.' + info.lower_name)): file_path = os.path.join(os.environ['HOME'], '.' + info.lower_name) else: file_path = None window = Application() window.file_path = file_path window.show() Gtk.main() logger.debug('Closing') exit() start()