def _iterAction(self):
    '''
    Iterate to the next sequence step.
    '''
    if len(self.steps) <= self._current_step:
      if self._loop is not None:
        self._loop.quit()
      return
    action = self.steps[self._current_step]
    if self._verbose:
      print _('SEQUENCE: %s') % action

    try:
      next_action = self.steps[self._current_step + 1]
    except IndexError:
      next_action = None

    pyatspi.Registry.deregisterEventListener(self._onAnticipatedEvent,
                                             *self._anticipated_event_types)
    if isinstance(next_action, WaitAction):
      self._anticipated_event_types = next_action.wait_for
    else:
      self._anticipated_event_types = []
    pyatspi.Registry.registerEventListener(self._onAnticipatedEvent,
                                           *self._anticipated_event_types)
    self._current_handler = action.connect('done', self._onStepDone)

    GObject.timeout_add(action.delta_time, self._doAction, action)
Exemple #2
0
 def arm (self, manager):
   self.manager = manager
   props = dict(obj=self.remote.path, name=self.remote.item.name, expected=self.when.isoformat( ), **self.remote.item.fields)
   self.props = props
   new_path = PATH + '/Scheduler/Armed/' + self.hashed
   delay_ms = (self.when - datetime.datetime.now( )).total_seconds( ) * 1000
   self.remote.bus.add_signal_receiver(self.cleanup, "Remove", dbus_interface=Trigger.OWN_IFACE, bus_name=BUS, path=new_path)
   # manager.bus.add_signal_receiver(self.attrs, ack=self.on_success, error=self.on_error)
   trigger = None
   try:
     trigger = Trigger(new_path, manager, props, self)
     if trigger:
       trigger.Armed( )
       self.manager.Trigger("Arming", trigger.path)
       self.trigger = trigger
       print "DELAYING", delay_ms
       gobject.timeout_add(delay_ms, trigger.Fire)
       manager.InterfacesAdded(trigger.path, { Trigger.OWN_IFACE: props })
       self.manager.Trigger("Armed", trigger.path)
   except:
     print "already exited?"
     raise
   finally:
     pass
   return trigger
Exemple #3
0
def clear_token_from_ubuntu_sso_sync(appname):
    """ send a dbus signal to the com.ubuntu.sso service to clear
        the credentials for the given appname, e.g. _("Ubuntu Software Center")
        and wait for it to finish (or 2s)
    """
    from ubuntu_sso import (
        DBUS_BUS_NAME,
        DBUS_CREDENTIALS_IFACE,
        DBUS_CREDENTIALS_PATH,
        )
    # clean
    loop = GObject.MainLoop()
    bus = dbus.SessionBus()
    obj = bus.get_object(bus_name=DBUS_BUS_NAME,
                         object_path=DBUS_CREDENTIALS_PATH,
                         follow_name_owner_changes=True)
    proxy = dbus.Interface(object=obj,
                           dbus_interface=DBUS_CREDENTIALS_IFACE)
    proxy.connect_to_signal("CredentialsCleared", loop.quit)
    proxy.connect_to_signal("CredentialsNotFound", loop.quit)
    proxy.connect_to_signal("CredentialsError", loop.quit)
    proxy.clear_credentials(appname, {})
    # ensure we don't hang forever here
    GObject.timeout_add_seconds(2, loop.quit)
    # run the mainloop until the credentials are clear
    loop.run()
 def __load_previous_file(self, scroll_to_end=True):
     if self._sub_file_number > 0:
         self.__load_file(self._sub_file_number - 1)
         if scroll_to_end is True:
             GObject.timeout_add(100, self.__scroll_to_end_of_loaded_file)
         else:
             self._previous_file_loaded = True
Exemple #5
0
def main():
    for opt in sys.argv[1:]:
        if opt in ('-h', '--help'):
            usage()
            sys.exit()
        elif opt in ('-d', '--dev'):
            config.ENABLE_INSPECTOR = True
        else:
            print "hotot: unrecognized option '%s'" % opt
            usage()
            sys.exit(1)

    try:
        import i18n
    except:
        from gettext import gettext as _

    try:
        import prctl
        prctl.set_name('hotot')
    except:
        pass

    GObject.threads_init()
    config.loads();

    agent.init_notify()
    app = Hotot()
    agent.app = app

    Gdk.threads_enter()
    Gtk.main()
    Gdk.threads_leave()
    def on_realized(self, widget, data=None):
        if self.blinking and self.tick_id == 0:
            GObject.idle_add(self._blink_idle)

        trackers.con_tracker_get().disconnect(self,
                                              "realize",
                                              self.on_realized)
    def set_blinking(self, blinking):
        self.blinking = blinking

        if blinking and self.tick_id == 0:
            GObject.idle_add(self._blink_idle)
        elif self.tick_id > 0:
            self.stop_blinking = True
    def _button_clicked_cb(self, widget):
        self.set_enabled()

        if self.activity.player.is_playing():
            self.activity.player.pause()
            self.set_button_play()
            GObject.source_remove(self._scale_update_id)
            self._scale_update_id = -1
        else:
            if self.activity.player.error:
                self.set_disabled()
            else:
                if self.activity.player.player.props.current_uri is None:
                    # There is no stream selected to be played
                    # yet. Select the first one
                    available = self.activity.playlist_widget.\
                        _items[0]['available']
                    if available:
                        path = self.activity.playlist_widget._items[0]['path']
                        self.activity.playlist_widget.emit(
                            'play-index', 0, path)
                        self.activity.playlist_widget.set_current_playing(0)
                else:
                    self.activity.player.play()
                    self.activity._switch_canvas(True)
                    self._scale_update_id = GObject.timeout_add(
                        self.SCALE_UPDATE_INTERVAL, self.__update_scale_cb)
Exemple #9
0
 def testAdd(self):
     self.hook = True
     e = E()
     e.connect('signal', self._callback)
     GObject.add_emission_hook(E, "signal", self._emission_hook)
     e.emit('signal')
     self.assertEqual(e.status, 3)
Exemple #10
0
    def __key_release_event_cb(self, window, event):
        if self.__is_alt(event) and self._alt_timeout_sid:
            self._home_box.set_resume_mode(True)
            GObject.source_remove(self._alt_timeout_sid)
            self._alt_timeout_sid = None

        return False
Exemple #11
0
	def on_autorefresh_toggled(self, autorefresh):
		if self.autorefresh_id != 0:
			GObject.source_remove(self.autorefresh_id)
			self.autorefresh_id = 0
			
		if autorefresh.get_active():
			self.autorefresh_id = GObject.timeout_add(AUTOREFRESH_TIMEOUT, self.on_refresh_chart, True)
Exemple #12
0
 def add_log_message(self, client_program_name, q_domain, domain_filter,
                     action):
     """Add log message to the logs window"""
     self._logs_window.add_log_line(client_program_name, q_domain,
                                    domain_filter, action)
     color = ACTION_COLOR_MAP.get(action, ACTION_COLOR_MAP['default'])
     GObject.timeout_add(1000, self.set_blinker, color)
 def find_books(self, search_text):
     if _NEW_TOOLBAR_SUPPORT:
         self.enable_button(False)
     else:
         self._books_toolbar.enable_button(False)
     self.clear_downloaded_bytes()
     textbuffer = self.textview.get_buffer()
     textbuffer.set_text(_('Performing lookup, please wait') + '...')
     self.book_selected = False
     self.ls.clear()
     search_tuple = search_text.lower().split()
     if len(search_tuple) == 0:
         self._alert(_('Error'), _('You must enter at least one search word.'))
         if _NEW_TOOLBAR_SUPPORT:
             self.search_entry.grab_focus()
         else:
             self._books_toolbar.search_entry.grab_focus()
         return
     FL = urllib.quote('fl[]')
     SORT = urllib.quote('sort[]')
     self.search_url = 'http://www.archive.org/advancedsearch.php?q=' +  \
         urllib.quote('(title:(' + search_text.lower() + ') OR creator:(' + search_text.lower() +')) AND format:(DJVU)')
     self.search_url += '&' + FL + '=creator&' + FL + '=description&' + FL + '=format&' + FL + '=identifier&'  \
         + FL + '=language'
     self.search_url += '&' + FL +  '=publisher&' + FL + '=subject&' + FL + '=title&' + FL + '=volume'
     self.search_url += '&' + SORT + '=title&' + SORT + '&' + SORT + '=&rows=500&save=yes&fmt=csv&xmlsearch=Search'
     GObject.idle_add(self.download_csv,  self.search_url)
    def _create_activity(self):
        if self._handle.activity_id is None:
            self._handle.activity_id = create_activity_id()

        self._shell.NotifyLaunch(
            self._service_name, self._handle.activity_id,
            reply_handler=self._no_reply_handler,
            error_handler=self._notify_launch_error_handler)

        environ = get_environment(self._bundle)
        (log_path, log_file) = open_log_file(self._bundle)
        command = get_command(self._bundle, self._handle.activity_id,
                              self._handle.object_id, self._handle.uri,
                              self._handle.invited)

        dev_null = file('/dev/null', 'r')
        child = subprocess.Popen([str(s) for s in command],
                                 env=environ,
                                 cwd=str(self._bundle.get_path()),
                                 close_fds=True,
                                 stdin=dev_null.fileno(),
                                 stdout=log_file.fileno(),
                                 stderr=log_file.fileno())

        GObject.child_watch_add(child.pid,
                                _child_watch_cb,
                                (log_file,
                                 self._handle.activity_id))
Exemple #15
0
    def run(self):

        GObject.timeout_add(100, self._idle, priority=GObject.PRIORITY_HIGH)

        while True:
            Gtk.main_iteration()
            gevent.sleep(.001)
Exemple #16
0
    def _import_gst(self):
        """Import the necessary GObject-related modules and assign `Gst`
        and `GObject` fields on this object.
        """

        try:
            import gi
        except ImportError:
            raise FatalReplayGainError(
                "Failed to load GStreamer: python-gi not found"
            )

        try:
            gi.require_version('Gst', '1.0')
        except ValueError as e:
            raise FatalReplayGainError(
                "Failed to load GStreamer 1.0: {0}".format(e)
            )

        from gi.repository import GObject, Gst, GLib
        # Calling GObject.threads_init() is not needed for
        # PyGObject 3.10.2+
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            GObject.threads_init()
        Gst.init([sys.argv[0]])

        self.GObject = GObject
        self.GLib = GLib
        self.Gst = Gst
Exemple #17
0
 def checkFiles( self ):
     for monitored in self.monitoredFiles:
         if monitored.hasChanged():
             if monitored.args:
                 GObject.idle_add( monitored.callback, monitored.args )
             else:
                 GObject.idle_add( monitored.callback )
Exemple #18
0
    def __init__(self, window):
        Gtk.Dialog.__init__(self, _('Edit archive'), window, Gtk.DialogFlags.MODAL,
            (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL))
        self.kill = False # Dialog is killed.
        self.file_handler = window.file_handler
        self._window = window
        self._save_button = self.add_button(Gtk.STOCK_SAVE_AS, Gtk.ResponseType.OK)
        # There is no stock response for "import", but by using
        # RESPONSE_HELP we automatically get the button placed at the left.
        self._import_button = self.add_button(_('Import'), Gtk.ResponseType.HELP)
        self._import_button.set_image(Gtk.Image.new_from_stock(Gtk.STOCK_ADD,
            Gtk.IconSize.BUTTON))
        self.set_border_width(4)
        self.resize(min(Gdk.Screen.get_default().get_width() - 50, 750),
            min(Gdk.Screen.get_default().get_height() - 50, 600))
        self.connect('response', self._response)
        
        self._image_area = _ImageArea(self)
        self._other_area = _OtherArea(self)

        notebook = Gtk.Notebook()
        notebook.set_border_width(6)
        notebook.append_page(self._image_area, Gtk.Label(label=_('Images')))
        notebook.append_page(self._other_area, Gtk.Label(label=_('Other files')))
        self.vbox.pack_start(notebook, True, True, 0)
        self.show_all()
        GObject.idle_add(self._load_original_files)
 def test_searchentry(self):
     from softwarecenter.ui.gtk3.widgets.searchentry import get_test_searchentry_window
     win = get_test_searchentry_window()
     s = "foo"
     win.entry.insert_text(s, len(s))
     GObject.timeout_add(TIMEOUT, lambda: win.destroy())
     Gtk.main()
Exemple #20
0
 def run(self, argv):
     GObject.threads_init()
     GObject.timeout_add(10, self.on_timer)
     self.connect("startup", self.on_startup)
     self.connect("activate", self.on_activate)
     self.connect("shutdown", self.on_shutdown)
     return super(Gtk3Example, self).run(argv)
Exemple #21
0
def main():
    debug = False

    print("Trackma-gtk v{}".format(utils.VERSION))

    if '-h' in sys.argv:
        print("Usage: trackma-qt [options]")
        print()
        print('Options:')
        print(' -d  Shows debugging information')
        print(' -h  Shows this help')
        return
    if '-d' in sys.argv:
        debug = True

    app = TrackmaWindow(debug)
    try:
        GObject.threads_init()
        Gdk.threads_init()
        Gdk.threads_enter()
        app.main()
        Gtk.main()
    except utils.TrackmaFatal as e:
        md = Gtk.MessageDialog(None,
                               Gtk.DialogFlags.DESTROY_WITH_PARENT,
                               Gtk.MessageType.ERROR,
                               Gtk.ButtonsType.CLOSE, str(e))
        md.run()
        md.destroy()
    finally:
        Gdk.threads_leave()
Exemple #22
0
    def __init__(self):
        GObject.GObject.__init__(self)
        self.connected = False
        
        
        # check is ONECONF_NET_CONNECTED is in the environment variables
        # if so force the network status to be connected or disconnected
        if "ONECONF_NET_CONNECTED" in os.environ:
            if os.environ["ONECONF_NET_CONNECTED"].lower() == 'true':
                GObject.idle_add(self._on_connection_state_changed, self.NM_STATE_CONNECTED_LOCAL)
                LOG.warn('forced netstate into connected mode...')
            else:
                GObject.idle_add(self._on_connection_state_changed, self.NM_STATE_DISCONNECTED)
                LOG.warn('forced netstate into disconnected mode...')
            return
        try:
            bus = dbus.SystemBus()
            nm = bus.get_object('org.freedesktop.NetworkManager',
                                '/org/freedesktop/NetworkManager')
            nm.connect_to_signal("StateChanged", self._on_connection_state_changed)
            network_state = nm.state(dbus_interface='org.freedesktop.NetworkManager')
            self._on_connection_state_changed(network_state)

        except Exception as e:
            LOG.warn("failed to init network state watcher '%s'" % e)
            self._on_connection_state_changed(self.NM_STATE_UNKNOWN)
Exemple #23
0
    def __init__(self, pipeline_string='videotestsrc pattern=18 ! tee name=t ! queue ! autovideosink t. ! queue ! videoconvert ! videorate ! video/x-raw,width=(int)320,height=(int)240,format=(string)RGB16,framerate=(fraction)30/1 ! appsink name=sink'):
        self.data = None# this will contain the data passed between
        self.source_id = None
        self.lock = Lock()

        self.isWhite = True
        self.isStream = True
        self.timestamp = 0

        self.pipeline = Gst.parse_launch(pipeline_string)

        self.appsink = self.pipeline.get_by_name('sink')

        assert self.appsink, 'appsink element named \'sink\' not found'

        self.appsink.connect('new-sample', self.on_new_buffer)
        self.appsink.set_property('emit-signals', True)

        self.pipeline.set_state(Gst.State.PLAYING)

        # OUTPUT pipeline
        self.pipeline_out = Gst.parse_launch('appsrc name=source ! videoconvert ! autovideosink')

        self.appsrc = self.pipeline_out.get_by_name('source')

        assert self.appsrc, 'appsrc element named \'source\' not found'

        self.appsrc.set_property('caps', Gst.Caps.from_string('video/x-raw,format=(string)RGB16,width=(int)320,height=(int)240,framerate=(fraction)30/1'))

        self.appsrc.connect('need-data', self.on_need_data)
        self.appsrc.connect('enough-data', self.on_enough_data)

        self.pipeline_out.set_state(Gst.State.PLAYING)

        GObject.timeout_add_seconds(2, self._switch_data_type)
def run():
    # Protobuf
    #c = ControllerProtobuf()

    # Directly connected to the vision server
    c = VisionManager()
    
    if not c.is_connected():
        print("Vision server is not accessible.")
        return

    server = Server()
    server.start("127.0.0.1", 5030)

    # add observer output for "server"
    c.add_filter_output_observer(server.send)

    from gi.repository import Gtk, GObject
    import CapraVision.client.gtk.main
    GObject.threads_init()

    w = CapraVision.client.gtk.main.WinFilterChain(c)

    w.window.show_all()
    Gtk.main()

    # Close connection
    server.stop()
    c.close_server()
Exemple #25
0
	def __init__(self):
		#self.radio = tea5767()
		self.player = player()
		self.load = False
		self.defaullt = "/data/media/Music"
		self.config = configparser.ConfigParser()
		self.config.read('config.ini')
		interface = gtk.Builder()
		interface.add_from_file('./interface/interface.glade')
		self.volume = interface.get_object("volume")
		self.progression = interface.get_object("progression")
		self.music = interface.get_object("music")
		self.artiste = interface.get_object("artiste")
		self.cover = interface.get_object("pochette")
		self.mode = interface.get_object("mode")
		self.freq = interface.get_object("scale1")
		self.deroul = interface.get_object("liststore1") 
		self.folder = interface.get_object("filechooserbutton1")
		self.tab = interface.get_object('notebook1')
		self.on_notebook1_switch_page(self.tab, None,self.tab.get_current_page())
		self.fullScreen = interface.get_object("main")
		interface.connect_signals(self)
		gobject.idle_add(self.test)
		if True:#(self.config["player"]["last"] != self.defaullt)
			time.sleep(2)
			self.player.new_folder(self.defaullt)
			self.config["player"]["last"] = self.defaullt
			with open("./config.ini", 'w') as configfile:    # save
				self.config.write(configfile)
	def fullscreen(self):
		""" Makes the window fullscreen. """
		
		if not self.is_fullscreen:
			GObject.idle_add(self.main.set_resizable, True)
			GObject.idle_add(self.main.fullscreen)
			self.is_fullscreen = True
	def unfullscreen(self):
		""" Unfullscreens the window """
		
		if self.is_fullscreen:
			GObject.idle_add(self.main.set_resizable, False)
			GObject.idle_add(self.main.unfullscreen)
			self.is_fullscreen = False
    def _move(self, up=False):
        text = self._search_entry.get_text()
        if not text:
            return

        if up and self.__selected_search_result == 1:
            return False

        model = self._treeview.get_model()
        selection = self._treeview.get_selection()
        # disable flush timeout while searching
        if self._entry_flush_timeout:
            GObject.source_remove(self._entry_flush_timeout)
            self._entry_flush_timeout = 0
        # search
        start_count = self.__selected_search_result + (-1 if up else 1)
        start_iter = model.get_iter_first()
        found_iter = self.search_iter(selection, start_iter, text, 0,
                                      start_count)
        if found_iter:
            self.__selected_search_result += (-1 if up else 1)
            return True
        else:
            # Return to old iter
            self.search_iter(selection, start_iter, text, 0,
                             self.__selected_search_result)
            return False
        # renew flush timeout
        self._renew_flush_timeout()
        return
    def go_to_bookmark(self, subfilenumber, identifier):
        if self._sub_file_number != subfilenumber:
            self.__load_file(subfilenumber, timeout=100)

        GObject.timeout_add(100,
                            self.__scroll_to_bookmark_position_in_file,
                            identifier)
Exemple #30
0
    def calculateDiffs(self, menuItem, showNotification=True):
        self.setMenuEnabled(False)
        self.packageTitle.set_label('Calculating file diffs...')
        while Gtk.events_pending():
            Gtk.main_iteration()
        selected = self.getSelectedPackages()

        totalDiff = 0

        for package in selected:
            diff = self.bkup.getFileSizeDiff(package)
            totalDiff += diff
            print(self.bkup.humanPrint(diff))
            humanDiff = self.bkup.humanPrint(diff)
            newLabel = package + ' (' + humanDiff + ' change)'
            print(self.packages[package].set_label(newLabel))

        self.setMenuEnabled(True)
        self.packageTitle.set_label('Packages from bkup.yaml:')
        self.removeDiffLabelTime = time.time() + 60 * 5
        GObject.timeout_add(60 * 1000, self.checkDiffLabelRemovalTime)

        if showNotification:
            msg = Notify.Notification.new('Calculated file diffs', 'Bkup')
            msg.show()

        return totalDiff
Exemple #31
0
#!/usr/bin/env python3

from gi.repository import Gtk, GObject


def update_progressbar():
    fraction = progressbar.get_fraction()

    if fraction < 1.0:
        progressbar.set_fraction(fraction + 0.1)
    else:
        progressbar.set_fraction(0.0)

    return True


window = Gtk.Window()
window.connect("destroy", lambda q: Gtk.main_quit())

progressbar = Gtk.ProgressBar()
progressbar.set_show_text(True)
window.add(progressbar)

window.show_all()

GObject.timeout_add(1000, update_progressbar)

Gtk.main()
Exemple #32
0
 def on_my_value_changed(self, widget):
     if self._value_changed_timer:
         GObject.source_remove(self._value_changed_timer)
     self._value_changed_timer = GObject.timeout_add(300, self.update_settings_value)
Exemple #33
0
    def switchClipWin2(self):
        # self.newVideo.stopPlay()
        self.revealer2.set_reveal_child(False)
        self.revealer3.set_reveal_child(True)
        print("switchClipWin2")

    def on_key_press_event(self, widget, event):
        # print("Key press on widget: ", widget)
        # print("          Modifiers: ", event.state)
        # print("      Key val, name: ", event.keyval, Gdk.keyval_name(event.keyval))

        # check the event modifiers (can also use SHIFTMASK, etc)
        ctrl = event.state & Gdk.ModifierType.CONTROL_MASK

        # see if we recognise a keypress
        if ctrl and event.keyval == Gdk.KEY_q:
            print("Quit App")
            Gtk.main_quit()


GObject.threads_init()
win = MyWindow()
win.connect("destroy", Gtk.main_quit)
# print(dir(win.button.props))
# win.set_size_request(800, 600)
win.set_position(Gtk.WindowPosition.CENTER)
# win.set_resizable(False)

Gtk.main()
Exemple #34
0

# Run the program

# Gst.init(None)
# Gst.debug_set_colored(Gst.DebugColorMode.ON)
# Gst.debug_set_active(True)
# Gst.debug_set_default_threshold(3)
# player = VideoPlayer()
# thread = threading.Thread(target=player.play)
# thread.start()
# GObject.threads_init()
# evt_loop = GObject.MainLoop()
# evt_loop.run()

# GObject.threads_init()
# Gst.init(None)
# Gtk.main()  # bu satır olmalı mı acaba?

if __name__ == "__main__":
    uri = "rtsp://184.72.239.149/vod/mp4:BigBuckBunny_175k.mov"
    Gst.init(None)
    Gst.debug_set_colored(Gst.DebugColorMode.ON)
    Gst.debug_set_active(True)
    Gst.debug_set_default_threshold(2)
    player = VideoPlayer(uri, None)
    thread = threading.Thread(target=player.play)
    thread.start()
    GObject.threads_init()
    evt_loop = GObject.MainLoop()
    evt_loop.run()
 def gobject_main_loop():
     GObject.threads_init()
     self.main_loop = GObject.MainLoop()
     self.main_loop.run()
class ApiInfoPanel(GObject.Object, Gedit.WindowActivatable):
    __gtype_name__ = "ApiInfoPanel"
    window = GObject.property(type=Gedit.Window)

    def __init__(self, plugin):
        GObject.Object.__init__(self)
        self.plugin = plugin
        self.dataDir = plugin.plugin_info.get_data_dir()
        self.geditWindow = plugin.window

        self.builder = Gtk.Builder()
        self.builder.add_from_file(self.dataDir + "/" + "ui" + "/" +
                                   "ApiInfoWindow.glade")
        self.builder.connect_signals(self)

        self.scrolledWindow = self.builder.get_object("scrolledWindow")

        self.textView = self.builder.get_object("textView")
        self.textView.set_editable(False)
        self.textView.modify_fg(Gtk.StateType.NORMAL,
                                Gdk.Color(red=65535, green=65535, blue=65535))
        self.textView.modify_bg(Gtk.StateType.NORMAL,
                                Gdk.Color(red=11776, green=13312, blue=13824))
        self.textView.modify_bg(Gtk.StateType.SELECTED,
                                Gdk.Color(red=51776, green=0, blue=0))
        #self.textView.connect("button-press-event", self.onTextViewClick)

        if configuration.getShowApiInfoPanel():
            self.geditBottomPanel = self.geditWindow.get_bottom_panel()
            self.geditBottomPanel.add_item(
                self.scrolledWindow, "haxe_api_info_panel", "api info",
                Gtk.Image.new_from_file(self.dataDir + "/" + "icons" + "/" +
                                        "haxe_logo_16.png")
            )  # Gtk.Image.new_from_stock(Gtk.STOCK_YES, Gtk.IconSize.MENU))
            self.geditBottomPanel.activate_item(self.scrolledWindow)

    def activate(self):
        if configuration.getShowApiInfoPanel():
            self.geditBottomPanel.activate_item(self.scrolledWindow)

    def remove(self):
        if configuration.getShowApiInfoPanel():
            self.geditBottomPanel.remove_item(self.scrolledWindow)

    def setText(self, txt):
        textBuffer = self.textView.get_buffer()
        textBuffer.set_text(txt)

    def appendText(self, txt):
        textBuffer = self.textView.get_buffer()
        textBuffer.insert(textBuffer.get_end_iter(), txt)
        self.textView.scroll_mark_onscreen(textBuffer.get_insert())
        #self.textView.scroll_to_mark(textBuffer.get_insert(), 0)

    def onTextViewClick(self, textView, event):
        if event.type == Gdk.EventType._2BUTTON_PRESS:
            hyperLink = self.parseHyperLinkLine()
            if hyperLink == None:
                return True

            return True

    def parseHyperLinkLine(self):
        doc = self.textView.get_buffer()
        iter = doc.get_iter_at_mark(doc.get_insert())
        lineStart = iter.copy()
        lineEnd = iter.copy()
        lineStart.set_offset(iter.get_offset() - iter.get_line_offset())

        #get the complete line
        lineEnd.forward_to_line_end()
        currentLine = unicode(
            doc.get_text(lineStart, lineEnd, include_hidden_chars=True))
        if len(currentLine) == 0:
            return None
        #print currentLine;
        return None
Exemple #37
0
    def set_status(self, status, donedate=None, propagation=False, init=False):
        old_status = self.status
        self.can_be_deleted = False
        # No need to update children or whatever if the task is not loaded
        if status and self.is_loaded():
            # we first modify the status of the children
            # If Done, we set the done date
            if status in [self.STA_DONE, self.STA_DISMISSED]:
                for c in self.get_subtasks():
                    if c.get_status() in [self.STA_ACTIVE]:
                        c.set_status(status,
                                     donedate=donedate,
                                     propagation=True)

                # If the task is recurring, it must be duplicate with
                # another task id and the next occurence of the task
                # while preserving child/parent relations.
                # For a task to be duplicated, it must satisfy 3 rules.
                #   1- It is recurring.
                #   2- It has no parent or no recurring parent.
                #   3- It was directly marked as done (not by propagation from its parent).
                rules = [self.recurring, not propagation]
                if all(rules) and not self.is_parent_recurring():
                    # duplicate all the children
                    nexttask_tid = self.duplicate_recursively()
                    if self.has_parent():
                        for p_tid in self.get_parents():
                            par = self.req.get_task(p_tid)
                            if (par.is_loaded()
                                    and par.get_status() in (self.STA_ACTIVE)):
                                par.add_child(nexttask_tid)

                                par.sync()

            # If we mark a task as Active and that some parent are not
            # Active, we break the parent/child relation
            # It has no sense to have an active subtask of a done parent.
            # (old_status check is necessary to avoid false positive a start)
            elif status in [self.STA_ACTIVE] and\
                    old_status in [self.STA_DONE, self.STA_DISMISSED]:
                if self.has_parent():
                    for p_tid in self.get_parents():
                        par = self.req.get_task(p_tid)
                        if par.is_loaded() and par.get_status() in\
                                [self.STA_DONE, self.STA_DISMISSED]:
                            # we can either break the parent/child relationship
                            # self.remove_parent(p_tid)
                            # or restore the parent too
                            par.set_status(self.STA_ACTIVE)
                # We dont mark the children as Active because
                # They might be already completed after all

        # then the task itself
        if status:
            if not init:
                GObject.idle_add(self.req.emit, "status-changed", self.tid,
                                 status)
            self.status = status

        # Set closing date
        if status and status in [self.STA_DONE, self.STA_DISMISSED]:
            # to the specified date (if any)
            if donedate:
                self.closed_date = donedate
            # or to today
            else:
                self.closed_date = Date.today()
        self.sync()
class WindowActivatable(GObject.Object, Gedit.WindowActivatable):
    __gtype_name__ = "ExternalToolsWindowActivatable"

    window = GObject.property(type=Gedit.Window)

    def __init__(self):
        GObject.Object.__init__(self)
        self._manager = None
        self._manager_default_size = None
        self.menu = None

    def do_activate(self):
        # Ugly hack... we need to get access to the activatable to update the menuitems
        self.window._external_tools_window_activatable = self
        self._library = ToolLibrary()

        ui_manager = self.window.get_ui_manager()

        self._action_group = Gtk.ActionGroup(name='ExternalToolsPluginActions')
        self._action_group.set_translation_domain('gedit')
        self._action_group.add_actions([
            ('ExternalToolManager', None, _('Manage _External Tools...'), None,
             _("Opens the External Tools Manager"),
             lambda action: self.open_dialog()),
            ('ExternalTools', None, _('External _Tools'), None,
             _("External tools"), None)
        ])
        ui_manager.insert_action_group(self._action_group, -1)

        ui_string = """
            <ui>
              <menubar name="MenuBar">
                <menu name="ToolsMenu" action="Tools">
                  <placeholder name="ToolsOps_4">
                    <separator/>
                    <menu name="ExternalToolsMenu" action="ExternalTools">
                        <placeholder name="ExternalToolPlaceholder"/>
                    </menu>
                    <separator/>
                  </placeholder>
                  <placeholder name="ToolsOps_5">
                    <menuitem name="ExternalToolManager" action="ExternalToolManager"/>
                  </placeholder>
                </menu>
              </menubar>
            </ui>"""

        self._merge_id = ui_manager.add_ui_from_string(ui_string)

        # Create output console
        self._output_buffer = OutputPanel(self.plugin_info.get_data_dir(),
                                          self.window)

        self.menu = ToolMenu(
            self._library, self.window, self._output_buffer,
            "/MenuBar/ToolsMenu/ToolsOps_4/ExternalToolsMenu/ExternalToolPlaceholder"
        )
        ui_manager.ensure_update()

        bottom = self.window.get_bottom_panel()
        image = Gtk.Image(stock=Gtk.STOCK_EXECUTE, icon_size=Gtk.IconSize.MENU)
        bottom.add_item(self._output_buffer.panel,
                        "GeditExternalToolsShellOutput", _("Tool Output"),
                        image)

    def do_update_state(self):
        if self.menu is not None:
            self.menu.filter(self.window.get_active_document())
            self.window.get_ui_manager().ensure_update()

    def do_deactivate(self):
        self.window._external_tools_window_activatable = None
        ui_manager = self.window.get_ui_manager()
        self.menu.deactivate()
        ui_manager.remove_ui(self._merge_id)
        ui_manager.remove_action_group(self._action_group)
        ui_manager.ensure_update()

        bottom = self.window.get_bottom_panel()
        bottom.remove_item(self._output_buffer.panel)

    def open_dialog(self):
        if not self._manager:
            self._manager = Manager(self.plugin_info.get_data_dir())

            if self._manager_default_size:
                self._manager.dialog.set_default_size(
                    *self._manager_default_size)

            self._manager.dialog.connect('destroy', self.on_manager_destroy)
            self._manager.connect('tools-updated',
                                  self.on_manager_tools_updated)

        window = Gio.Application.get_default().get_active_window()
        self._manager.run(window)

        return self._manager.dialog

    def update_manager(self, tool):
        if self._manager:
            self._manager.tool_changed(tool, True)

    def on_manager_destroy(self, dialog):
        self._manager_default_size = self._manager.get_final_size()
        self._manager = None

    def on_manager_tools_updated(self, manager):
        for window in Gio.Application.get_default().get_windows():
            window._external_tools_window_activatable.menu.update()
 def onPlayStep(self):
     self.onFowardClick(None)
     if self.play:
         GObject.timeout_add(1000, self.onPlayStep)
Exemple #40
0
                energy[ver] -= 1

    # The following will force the re-drawing of the graph, and issue a
    # re-drawing of the GTK window.
    win.graph.regenerate_surface(lazy=False)
    win.graph.queue_draw()

    # if doing an offscreen animation, dump frame to disk
    if offscreen:
        global count
        pixbuf = win.get_pixbuf()
        pixbuf.savev(r'./frames/sirs%06d.png' % count, 'png', [], [])
        if count > max_count:
            sys.exit(0)
        count += 1

    # We need to return True so that the main loop will call this function more
    # than once.
    return True


# Bind the function above as an 'idle' callback.
cid = GObject.idle_add(update_state)

# We will give the user the ability to stop the program by closing the window.
win.connect("delete_event", Gtk.main_quit)

# Actually show the window, and start the main loop.
win.show_all()
Gtk.main()
Exemple #41
0
            return

        self.emit('connection-removed', conn)

    def get_connections(self):
        return self._connections.values()


def get_instance():
    global _instance
    if _instance is None:
        _instance = ConnectionWatcher()
    return _instance


if __name__ == '__main__':
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

    def connection_added_cb(conn_watcher, conn):
        print 'new connection', conn.service_name

    def connection_removed_cb(conn_watcher, conn):
        print 'removed connection', conn.service_name

    watcher = ConnectionWatcher()
    watcher.connect('connection-added', connection_added_cb)
    watcher.connect('connection-removed', connection_removed_cb)

    loop = GObject.MainLoop()
    loop.run()
Exemple #42
0
            if icon_found:
                image.set_from_icon_name(realIconName, Gtk.IconSize.DND)
                image.set_pixel_size(iconSize)
            else:
                image = None

            return image
        except Exception, e:
            print "Exception " + e.__class__.__name__ + ": " + e.message
            return None

    def themeChanged( self, theme ):
        self.emit( "changed" )

GObject.type_register(IconManager)

class easyButton( Gtk.Button ):

    def __init__( self, iconName, iconSize, labels = None, buttonWidth = -1, buttonHeight = -1 ):
        GObject.GObject.__init__( self )
        self.connections = [ ]
        self.iconName = iconName
        self.iconSize = iconSize
        self.showIcon = True

        self.set_relief( Gtk.ReliefStyle.NONE )
        self.set_size_request( buttonWidth, buttonHeight )

        Align1 = Gtk.Alignment.new( 0, 0.5, 1.0, 0 )
        HBox1 = Gtk.Box( orientation=Gtk.Orientation.HORIZONTAL )
Exemple #43
0
 def wrapper(*args, **kwargs):
     GObject.idle_add(func, *args, **kwargs)
 def onPlayClick(self, event):
     self.play = True
     GObject.timeout_add(10, self.onPlayStep)
Exemple #45
0
def _too_small_screen_exit():
    global exit_timeout_id
    exit_timeout_id = GObject.timeout_add(200, _show_too_small_info)
    # Launch gtk+ main loop
    Gtk.main()
Exemple #46
0
 def run(self):
     GObject.threads_init()
     Gtk.main()
Exemple #47
0
def stop_autosave():
    global autosave_timeout_id
    if autosave_timeout_id == -1:
        return
    GObject.source_remove(autosave_timeout_id)
    autosave_timeout_id = -1
Exemple #48
0
class Model(GObject.GObject, downloader.Handler):
    __gsignals__ = {
        'download-pulse': (GObject.SIGNAL_RUN_FIRST, None, ())
    }
    state = GObject.Property(type=str, default='start')
    prev_state = GObject.Property(type=str)
    mode = GObject.Property(type=str, default='audio')
    url = GObject.Property(type=str)
    error = GObject.Property(type=str)
    resolution = GObject.Property(type=GObject.TYPE_UINT, default=1080)
    download_dir = GObject.Property(type=str)
    download_dir_abs = GObject.Property(type=str)
    prefer_mpeg = GObject.Property(type=bool, default=False)
    download_playlist_index = GObject.Property(type=GObject.TYPE_INT64)
    download_playlist_count = GObject.Property(type=GObject.TYPE_INT64)
    download_filename = GObject.Property(type=str)
    download_title = GObject.Property(type=str)
    download_thumbnail = GObject.Property(type=str)
    # 0.0 - 1.0 (inclusive), negative if unknown:
    download_progress = GObject.Property(type=float, default=-1)
    download_bytes = GObject.Property(type=GObject.TYPE_INT64, default=-1)
    download_bytes_total = GObject.Property(type=GObject.TYPE_INT64,
                                            default=-1)
    download_speed = GObject.Property(type=GObject.TYPE_INT64, default=-1)
    download_eta = GObject.Property(type=GObject.TYPE_INT64, default=-1)
    resolutions = [
        (MAX_RESOLUTION, N_('Best')),
        (4320, N_('4320p (8K)')),
        (2160, N_('2160p (4K)')),
        (1440, N_('1440p (HD)')),
        (1080, N_('1080p (HD)')),
        (720, N_('720p (HD)')),
        (480, N_('480p')),
        (360, N_('360p')),
        (240, N_('240p')),
        (144, N_('144p'))]

    def __init__(self, handler=None):
        super().__init__()
        self._handler = handler
        self._downloader = downloader.Downloader(self)
        self._download_finished_filenames = []
        self._filemanager_proxy = Gio.DBusProxy.new_for_bus_sync(
            Gio.BusType.SESSION, Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES |
            Gio.DBusProxyFlags.DO_NOT_CONNECT_SIGNALS |
            Gio.DBusProxyFlags.DO_NOT_AUTO_START_AT_CONSTRUCTION, None,
            'org.freedesktop.FileManager1', '/org/freedesktop/FileManager1',
            'org.freedesktop.FileManager1')
        bind_property(self, 'download-dir', self, 'download-dir-abs',
                      expand_path)
        self.actions = Gio.SimpleActionGroup.new()
        self.actions.add_action_entries([
            ('download', lambda *_: self.set_property('state', 'download')),
            ('cancel', lambda *_: self.set_property('state', 'cancel')),
            ('back', lambda *_: self.set_property('state', 'start')),
            ('open-download-dir', self._open_download_dir)])
        bind_property(self, 'url', self.actions.lookup_action('download'),
                      'enabled', bool)
        bind_property(self, 'state', self,
                      'prev-state', self._state_transition)
        bind_property(self, 'state', self.actions.lookup_action('cancel'),
                      'enabled', lambda s: s == 'download')

    def _state_transition(self, state):
        if state == 'start':
            assert self.prev_state != 'download'
        elif state == 'download':
            assert self.prev_state == 'start'
            self.error = ''
            self.download_playlist_index = 0
            self.download_playlist_count = 0
            self.download_filename = ''
            self.download_title = ''
            self.download_thumbnail = ''
            self.download_progress = -1
            self.download_bytes = -1
            self.download_bytes_total = -1
            self.download_speed = -1
            self.download_eta = -1
            self._download_finished_filenames.clear()
            self._downloader.start()
        elif state == 'cancel':
            assert self.prev_state == 'download'
            self._downloader.cancel()
        elif state in ['success', 'error']:
            assert self.prev_state == 'download'
        else:
            assert False
        return state

    def _open_download_dir(self, action, parameter, user_data):
        if len(self._download_finished_filenames) == 1:
            method = 'ShowItems'
            paths = [os.path.join(self.download_dir_abs, filename) for
                     filename in self._download_finished_filenames]
        else:
            method = 'ShowFolders'
            paths = [self.download_dir_abs]
        parameters = GLib.Variant(
            '(ass)', ([Gio.File.new_for_path(p).get_uri() for p in paths], ''))
        try:
            self._filemanager_proxy.call_sync(
                method, parameters, Gio.DBusCallFlags.NONE, -1)
        except GLib.Error:
            g_log('youtube-dl', GLib.LogLevelFlags.LEVEL_WARNING, '%s',
                  traceback.format_exc())
            subprocess.run(['xdg-open', self.download_dir_abs], check=True)

    def on_pulse(self):
        assert self.state in ['download', 'cancel']
        self.emit('download-pulse')

    def on_finished(self, success):
        assert self.state in ['download', 'cancel']
        if self.state == 'cancel':
            self.state = 'start'
        else:
            self.state = 'success' if success else 'error'

    def get_download_dir(self):
        assert self.state in ['download', 'cancel']
        return self.download_dir_abs

    def get_prefer_mpeg(self):
        assert self.state in ['download', 'cancel']
        return self.prefer_mpeg

    def get_url(self):
        assert self.state in ['download', 'cancel']
        return self.url

    def get_mode(self):
        assert self.state in ['download', 'cancel']
        return self.mode

    def get_resolution(self):
        assert self.state in ['download', 'cancel']
        return self.resolution

    def on_playlist_request(self):
        assert self.state in ['download', 'cancel']
        return self._handler.on_playlist_request()

    def on_login_request(self):
        assert self.state in ['download', 'cancel']
        return self._handler.on_login_request()

    def on_videopassword_request(self):
        assert self.state in ['download', 'cancel']
        return self._handler.on_videopassword_request()

    def on_error(self, msg):
        assert self.state in ['download', 'cancel']
        self.error = msg

    def on_load_progress(self, filename, progress, bytes_, bytes_total, eta,
                         speed):
        assert self.state in ['download', 'cancel']
        self.download_filename = filename
        self.download_progress = progress
        self.download_bytes = bytes_
        self.download_bytes_total = bytes_total
        self.download_eta = eta
        self.download_speed = speed

    def on_progress_start(self, playlist_index, playlist_count, title,
                          thumbnail):
        assert self.state in ['download', 'cancel']
        self.download_playlist_index = playlist_index
        self.download_playlist_count = playlist_count
        self.download_title = title
        self.download_thumbnail = thumbnail

    def on_progress_end(self, filename):
        assert self.state in ['download', 'cancel']
        self._download_finished_filenames.append(filename)
Exemple #49
0
def open_assoc_file():
    GObject.source_remove(assoc_timeout_id)
    projectaction.actually_load_project(assoc_file_path,
                                        block_recent_files=False)
Exemple #50
0
def destroy_splash_screen():
    splash_screen.destroy()
    GObject.source_remove(splash_timeout_id)
            height = in_height - self._top - self._bottom

            new_format = othercaps.get_structure(0).copy()

            # https://lazka.github.io/pgi-docs/index.html#Gst-1.0/classes/Structure.html#Gst.Structure.fixate_field_nearest_int
            new_format.fixate_field_nearest_int("width", width)
            new_format.fixate_field_nearest_int("height", height)
            new_caps = Gst.Caps.new_empty()
            new_caps.append_structure(new_format)

            # https://lazka.github.io/pgi-docs/index.html#Gst-1.0/classes/Caps.html#Gst.Caps.fixate
            return new_caps.fixate()

    def do_set_caps(self, incaps: Gst.Caps, outcaps: Gst.Caps) -> bool:

        in_w, in_h = [incaps.get_structure(0).get_value(v) for v in ['width', 'height']]
        out_w, out_h = [outcaps.get_structure(0).get_value(v) for v in ['width', 'height']]

        # if input_size == output_size set plugin to passthrough mode
        # https://gstreamer.freedesktop.org/documentation/additional/design/element-transform.html?gi-language=c#processing
        if in_h == out_h and in_w == out_w:
            self.set_passthrough(True)

        return True


# Register plugin to use it from command line
GObject.type_register(GstVideoCrop)
__gstelementfactory__ = (GstVideoCrop.GST_PLUGIN_NAME,
                         Gst.Rank.NONE, GstVideoCrop)
Exemple #52
0
def _do_window_resized_update():
    GObject.source_remove(resize_timeout_id)
    updater.window_resized()
Exemple #53
0
 def activate(self):
     gobject.idle_add(self._do_activate)
Exemple #54
0
def main(root_path):
    """
    Called at application start.
    Initializes application with a default project.
    """
    # DEBUG: Direct output to log file if log file set
    if _log_file != None:
        log_print_output_to_file()

    print "Application version: " + editorstate.appversion

    # Print OS, Python version and GTK+ version
    try:
        os_release_file = open("/etc/os-release", "r")
        os_text = os_release_file.read()
        s_index = os_text.find("PRETTY_NAME=")
        e_index = os_text.find("\n", s_index)
        print "OS: " + os_text[s_index + 13:e_index - 1]
    except:
        pass

    print "Python", sys.version

    gtk_version = "%s.%s.%s" % (Gtk.get_major_version(),
                                Gtk.get_minor_version(),
                                Gtk.get_micro_version())
    print "GTK+ version:", gtk_version
    editorstate.gtk_version = gtk_version
    try:
        editorstate.mlt_version = mlt.LIBMLT_VERSION
    except:
        editorstate.mlt_version = "0.0.99"  # magic string for "not found"

    #print "SDL version:", str(editorstate.get_sdl_version())

    # passing -xdg as a flag will change the user_dir location with XDG_CONFIG_HOME
    # For full xdg-app support all the launch processes need to add this too, currently not impl.

    for arg in sys.argv:
        if arg.lower() == "-xdg":
            editorstate.use_xdg = True

    # Create hidden folders if not present
    user_dir = utils.get_hidden_user_dir_path()

    print "User dir:", user_dir
    if not os.path.exists(user_dir):
        os.mkdir(user_dir)
    if not os.path.exists(user_dir + mltprofiles.USER_PROFILES_DIR):
        os.mkdir(user_dir + mltprofiles.USER_PROFILES_DIR)
    if not os.path.exists(user_dir + AUTOSAVE_DIR):
        os.mkdir(user_dir + AUTOSAVE_DIR)
    if not os.path.exists(user_dir + BATCH_DIR):
        os.mkdir(user_dir + BATCH_DIR)
    if not os.path.exists(user_dir + appconsts.AUDIO_LEVELS_DIR):
        os.mkdir(user_dir + appconsts.AUDIO_LEVELS_DIR)
    if not os.path.exists(utils.get_hidden_screenshot_dir_path()):
        os.mkdir(utils.get_hidden_screenshot_dir_path())
    if not os.path.exists(user_dir + appconsts.GMIC_DIR):
        os.mkdir(user_dir + appconsts.GMIC_DIR)
    if not os.path.exists(user_dir + appconsts.MATCH_FRAME_DIR):
        os.mkdir(user_dir + appconsts.MATCH_FRAME_DIR)
    if not os.path.exists(user_dir + appconsts.TRIM_VIEW_DIR):
        os.mkdir(user_dir + appconsts.TRIM_VIEW_DIR)
    if not os.path.exists(user_dir + appconsts.NATRON_DIR):
        os.mkdir(user_dir + appconsts.NATRON_DIR)

    # Set paths.
    respaths.set_paths(root_path)

    # Load editor prefs and list of recent projects
    editorpersistance.load()
    if editorpersistance.prefs.theme != appconsts.LIGHT_THEME:
        respaths.apply_dark_theme()
    if editorpersistance.prefs.display_all_audio_levels == False:
        editorstate.display_all_audio_levels = False
    editorpersistance.create_thumbs_folder_if_needed(user_dir)
    editorpersistance.create_rendered_clips_folder_if_needed(user_dir)

    editorpersistance.save()

    # Init translations module with translations data
    translations.init_languages()
    translations.load_filters_translations()
    mlttransitions.init_module()

    # Apr-2017 - SvdB - Keyboard shortcuts
    shortcuts.load_shortcut_files()
    shortcuts.load_shortcuts()

    # We respaths and translations data available so we need to init in a function.
    workflow.init_data()

    # RHEL7/CentOS compatibility fix
    if gtk_version == "3.8.8":
        GObject.threads_init()

    # Init gtk threads
    Gdk.threads_init()
    Gdk.threads_enter()

    # Themes
    if editorpersistance.prefs.theme != appconsts.LIGHT_THEME:
        Gtk.Settings.get_default().set_property(
            "gtk-application-prefer-dark-theme", True)
        if editorpersistance.prefs.theme == appconsts.FLOWBLADE_THEME:
            gui.apply_gtk_css()

    # Load drag'n'drop images
    dnd.init()

    # Adjust gui parameters for smaller screens
    scr_w = Gdk.Screen.width()
    scr_h = Gdk.Screen.height()
    editorstate.SCREEN_WIDTH = scr_w
    editorstate.SCREEN_HEIGHT = scr_h

    print "Screen size:", scr_w, "x", scr_h
    print "Small height:", editorstate.screen_size_small_height()
    print "Small width:", editorstate.screen_size_small_width()

    _set_draw_params()

    # Refuse to run on too small screen.
    if scr_w < 1151 or scr_h < 767:
        _too_small_screen_exit()
        return

    # Splash screen
    if editorpersistance.prefs.display_splash_screen == True:
        show_splash_screen()

    # Init MLT framework
    repo = mlt.Factory().init()
    processutils.prepare_mlt_repo(repo)

    # Set numeric locale to use "." as radix, MLT initilizes this to OS locale and this causes bugs.
    locale.setlocale(locale.LC_NUMERIC, 'C')

    # Check for codecs and formats on the system.
    mltenv.check_available_features(repo)
    renderconsumer.load_render_profiles()

    # Load filter and compositor descriptions from xml files.
    mltfilters.load_filters_xml(mltenv.services)
    mlttransitions.load_compositors_xml(mltenv.transitions)

    # Replace some services if better replacements available.
    mltfilters.replace_services(mltenv.services)

    # Create list of available mlt profiles.
    mltprofiles.load_profile_list()

    # Save assoc file path if found in arguments.
    global assoc_file_path
    assoc_file_path = get_assoc_file_path()

    # There is always a project open, so at startup we create a default project.
    # Set default project as the project being edited.
    editorstate.project = projectdata.get_default_project()
    check_crash = True

    # Audiomonitoring being available needs to be known before GUI creation.
    audiomonitoring.init(editorstate.project.profile)

    # Set trim view mode to current default value.
    editorstate.show_trim_view = editorpersistance.prefs.trim_view_default

    # Check for tools and init tools integration.
    gmic.test_availablity()
    toolnatron.init()
    toolsintegration.init()
    #toolsintegration.test()

    # Create player object.
    create_player()

    # Create main window and set widget handles in gui.py for more convenient reference.
    create_gui()

    # Inits widgets with project data.
    init_project_gui()

    # Inits widgets with current sequence data.
    init_sequence_gui()

    # Launch player now that data and gui exist
    launch_player()

    # Editor and modules need some more initializing.
    init_editor_state()

    # Tracks need to be recentered if window is resized.
    # Connect listener for this now that the tline panel size allocation is sure to be available.
    global window_resize_id, window_state_id
    window_resize_id = gui.editor_window.window.connect(
        "size-allocate", lambda w, e: updater.window_resized())
    window_state_id = gui.editor_window.window.connect(
        "window-state-event", lambda w, e: updater.window_resized())

    # Get existing autosave files
    autosave_files = get_autosave_files()

    # Show splash
    if ((editorpersistance.prefs.display_splash_screen == True)
            and len(autosave_files) == 0
        ) and not editorstate.runtime_version_greater_then_test_version(
            editorpersistance.prefs.workflow_dialog_last_version_shown,
            editorstate.appversion):
        global splash_timeout_id
        splash_timeout_id = GLib.timeout_add(2600, destroy_splash_screen)
        splash_screen.show_all()

    appconsts.SAVEFILE_VERSION = projectdata.SAVEFILE_VERSION  # THIS IS A QUESTIONABLE IDEA TO SIMPLIFY IMPORTS, NOT DRY. WHEN DOING TOOLS THAT RUN IN ANOTHER PROCESSES AND SAVE PROJECTS, THIS LINE NEEDS TO BE THERE ALSO.

    # Every running instance has unique autosave file which is deleted at exit
    set_instance_autosave_id()

    # Existance of autosave file hints that program was exited abnormally.
    if check_crash == True and len(autosave_files) > 0:
        if len(autosave_files) == 1:
            GObject.timeout_add(10, autosave_recovery_dialog)
        else:
            GObject.timeout_add(10, autosaves_many_recovery_dialog)
    else:
        start_autosave()

    # We prefer to monkeypatch some callbacks into some modules, usually to
    # maintain a simpler and/or non-circular import structure.
    monkeypatch_callbacks()

    # File in assoc_file_path is opened after very short delay.
    if not (check_crash == True and len(autosave_files) > 0):
        if assoc_file_path != None:
            print "Launch assoc file:", assoc_file_path
            global assoc_timeout_id
            assoc_timeout_id = GObject.timeout_add(10, open_assoc_file)

    # SDL 2 consumer needs to created after Gtk.main() has run enough for window to be visble
    #if editorstate.get_sdl_version() == editorstate.SDL_2: # needs more state considerion still
    #    print "SDL2 timeout launch"
    #    global sdl2_timeout_id
    #    sdl2_timeout_id = GObject.timeout_add(1500, create_sdl_2_consumer)

    # In PositionNumericalEntries we are using Gtk.Entry objects in a way that works for us nicely, but is somehow "error" for Gtk, so we just kill this.
    Gtk.Settings.get_default().set_property("gtk-error-bell", False)

    # Show first run worflow info dialog if not shown for this version of application.
    if editorstate.runtime_version_greater_then_test_version(
            editorpersistance.prefs.workflow_dialog_last_version_shown,
            editorstate.appversion):
        GObject.timeout_add(500, show_worflow_info_dialog)

    # Launch gtk+ main loop
    Gtk.main()

    Gdk.threads_leave()
Exemple #55
0
def createSignal(signalName, emittingClass):
	GObject.signal_new(signalName, emittingClass, GObject.SIGNAL_RUN_LAST, GObject.TYPE_PYOBJECT, [])
Exemple #56
0
class ActionGutter(Gtk.DrawingArea):

    __gtype_name__ = 'ActionGutter'

    action_mode = GObject.Property(
        type=int,
        nick='Action mode for chunk change actions',
        default=ActionMode.Replace,
    )

    @GObject.Property(
        type=object,
        nick='List of diff chunks for display',
    )
    def chunks(self):
        return self._chunks

    @chunks.setter
    def chunks_set(self, chunks):
        self._chunks = chunks
        self.chunk_starts = [c.start_a for c in chunks]

    @GObject.Property(
        type=Gtk.IconLookupFlags,
        nick='Which direction should directional changes appear to go',
        flags=(
            GObject.ParamFlags.READABLE |
            GObject.ParamFlags.WRITABLE |
            GObject.ParamFlags.CONSTRUCT_ONLY
        ),
        default=Gtk.IconLookupFlags.DIR_LTR,
    )
    def icon_direction(self):
        return self._icon_direction

    @icon_direction.setter
    def icon_direction_set(self, direction: Gtk.IconLookupFlags):
        if direction not in (
                Gtk.IconLookupFlags.DIR_LTR, Gtk.IconLookupFlags.DIR_RTL):
            raise ValueError('Invalid icon direction {}'.format(direction))

        replace_icons = {
            Gtk.IconLookupFlags.DIR_LTR: 'apply-right',
            Gtk.IconLookupFlags.DIR_RTL: 'apply-left',
        }
        self.action_map = {
            ActionMode.Replace: ActionIcons.load(replace_icons[direction]),
            ActionMode.Delete: ActionIcons.load('delete'),
            ActionMode.Insert: ActionIcons.load('copy'),
        }
        self._icon_direction = direction

    _source_view: Gtk.TextView
    _source_editable_connect_id: int = 0

    @GObject.Property(
        type=Gtk.TextView,
        nick='Text view for which action are displayed',
        default=None,
    )
    def source_view(self):
        return self._source_view

    @source_view.setter
    def source_view_setter(self, view: Gtk.TextView):
        if self._source_editable_connect_id:
            self._source_view.disconnect(self._source_editable_connect_id)

        self._source_editable_connect_id = view.connect(
            'notify::editable', lambda *args: self.queue_draw())
        self._source_view = view
        self.queue_draw()

    _target_view: Gtk.TextView
    _target_editable_connect_id: int = 0

    @GObject.Property(
        type=Gtk.TextView,
        nick='Text view to which actions are directed',
        default=None,
    )
    def target_view(self):
        return self._target_view

    @target_view.setter
    def target_view_setter(self, view: Gtk.TextView):
        if self._target_editable_connect_id:
            self._target_view.disconnect(self._target_editable_connect_id)

        self._target_editable_connect_id = view.connect(
            'notify::editable', lambda *args: self.queue_draw())
        self._target_view = view
        self.queue_draw()

    @GObject.Signal
    def chunk_action_activated(
            self,
            action: str,  # String-ified ChunkAction
            from_view: Gtk.TextView,
            to_view: Gtk.TextView,
            chunk: object,
            ) -> None:
        ...

    def __init__(self):
        super().__init__()

        # Object-type defaults
        self.chunks = []
        self.action_map = {}

        # State for "button" implementation
        self.buttons = []
        self.pointer_chunk = None
        self.pressed_chunk = None

    def on_setting_changed(self, settings, key):
        if key == 'style-scheme':
            self.fill_colors, self.line_colors = get_common_theme()
            alpha = self.fill_colors['current-chunk-highlight'].alpha
            self.chunk_highlights = {
                state: Gdk.RGBA(*[alpha + c * (1.0 - alpha) for c in colour])
                for state, colour in self.fill_colors.items()
            }

    def do_realize(self):
        self.set_events(
            Gdk.EventMask.LEAVE_NOTIFY_MASK |
            Gdk.EventMask.POINTER_MOTION_MASK |
            Gdk.EventMask.BUTTON_PRESS_MASK |
            Gdk.EventMask.BUTTON_RELEASE_MASK
        )
        self.connect('notify::action-mode', lambda *args: self.queue_draw())

        meld_settings = get_meld_settings()
        meld_settings.connect('changed', self.on_setting_changed)
        self.on_setting_changed(meld_settings, 'style-scheme')

        return Gtk.DrawingArea.do_realize(self)

    def do_motion_notify_event(self, event):
        # This is the simplest button/intersection implementation in
        # the world, but it basically works for our purposes.
        for button in self.buttons:
            x1, y1, x2, y2, chunk = button

            # Check y first; it's more likely to be out of range
            if y1 <= event.y <= y2 and x1 <= event.x <= x2:
                new_pointer_chunk = chunk
                break
        else:
            new_pointer_chunk = None

        if new_pointer_chunk != self.pointer_chunk:
            self.pointer_chunk = new_pointer_chunk
            self.queue_draw()

    def do_leave_notify_event(self, event):
        if self.pointer_chunk:
            self.pointer_chunk = None
            self.queue_draw()

    def do_button_press_event(self, event):
        if self.pointer_chunk:
            self.pressed_chunk = self.pointer_chunk

        return Gtk.DrawingArea.do_button_press_event(self, event)

    def do_button_release_event(self, event):
        if self.pointer_chunk and self.pointer_chunk == self.pressed_chunk:
            self.activate(self.pressed_chunk)
        self.pressed_chunk = None

        return Gtk.DrawingArea.do_button_press_event(self, event)

    def _action_on_chunk(self, action: ChunkAction, chunk):
        self.chunk_action_activated.emit(
            action.value, self.source_view, self.target_view, chunk)

    def activate(self, chunk):

        action = self._classify_change_actions(chunk)

        # FIXME: When fully transitioned to GAction, we should see
        # whether we can do this by getting the container's action
        # group and activating the actions directly instead.

        if action == ActionMode.Replace:
            self._action_on_chunk(ChunkAction.replace, chunk)
        elif action == ActionMode.Delete:
            self._action_on_chunk(ChunkAction.delete, chunk)
        elif action == ActionMode.Insert:
            copy_menu = self._make_copy_menu(chunk)
            copy_menu.popup_at_pointer(None)

    def _make_copy_menu(self, chunk):
        copy_menu = Gtk.Menu()
        copy_up = Gtk.MenuItem.new_with_mnemonic(_('Copy _up'))
        copy_down = Gtk.MenuItem.new_with_mnemonic(_('Copy _down'))
        copy_menu.append(copy_up)
        copy_menu.append(copy_down)
        copy_menu.show_all()

        def copy_chunk(widget, action):
            self._action_on_chunk(action, chunk)

        copy_up.connect('activate', copy_chunk, ChunkAction.copy_up)
        copy_down.connect('activate', copy_chunk, ChunkAction.copy_down)
        return copy_menu

    def get_chunk_range(self, start_y, end_y):
        start_line = self.source_view.get_line_num_for_y(start_y)
        end_line = self.source_view.get_line_num_for_y(end_y)

        start_idx = bisect.bisect(self.chunk_starts, start_line)
        end_idx = bisect.bisect(self.chunk_starts, end_line)

        if start_idx > 0 and start_line <= self.chunks[start_idx - 1].end_a:
            start_idx -= 1

        return self.chunks[start_idx:end_idx]

    def do_draw(self, context):
        view = self.source_view
        if not view or not view.get_realized():
            return

        self.buttons = []

        width = self.get_allocated_width()
        height = self.get_allocated_height()

        style_context = self.get_style_context()
        Gtk.render_background(style_context, context, 0, 0, width, height)

        buf = view.get_buffer()

        context.save()
        context.set_line_width(1.0)

        # Get our linked view's visible offset, get our vertical offset
        # against our view (e.g., for info bars at the top of the view)
        # and translate our context to match.
        view_y_start = view.get_visible_rect().y
        view_y_offset = view.translate_coordinates(self, 0, 0)[1]
        gutter_y_translate = view_y_offset - view_y_start
        context.translate(0, gutter_y_translate)

        button_x = 1
        button_width = width - 2

        for chunk in self.get_chunk_range(view_y_start, view_y_start + height):

            change_type, start_line, end_line, *_unused = chunk

            rect_y = view.get_y_for_line_num(start_line)
            rect_height = max(
                0, view.get_y_for_line_num(end_line) - rect_y - 1)

            # Draw our rectangle outside x bounds, so we don't get
            # vertical lines. Fill first, over-fill with a highlight
            # if in the focused chunk, and then stroke the border.
            context.rectangle(-0.5, rect_y + 0.5, width + 1, rect_height)
            if start_line != end_line:
                context.set_source_rgba(*self.fill_colors[change_type])
                context.fill_preserve()
                if view.current_chunk_check(chunk):
                    highlight = self.fill_colors['current-chunk-highlight']
                    context.set_source_rgba(*highlight)
                    context.fill_preserve()
            context.set_source_rgba(*self.line_colors[change_type])
            context.stroke()

            # Button rendering and tracking
            action = self._classify_change_actions(chunk)
            if action is None:
                continue

            it = buf.get_iter_at_line(start_line)
            button_y, button_height = view.get_line_yrange(it)
            button_y += 1
            button_height -= 2

            button_style_context = get_style(None, 'button.flat.image-button')
            if chunk == self.pointer_chunk:
                button_style_context.set_state(Gtk.StateFlags.PRELIGHT)

            Gtk.render_background(
                button_style_context, context, button_x, button_y,
                button_width, button_height)
            Gtk.render_frame(
                button_style_context, context, button_x, button_y,
                button_width, button_height)

            # TODO: Ideally we'd do this in a pre-render step of some
            # kind, but I'm having trouble figuring out what that would
            # look like.
            self.buttons.append(
                (
                    button_x,
                    button_y + gutter_y_translate,
                    button_x + button_width,
                    button_y + gutter_y_translate + button_height,
                    chunk,
                )
            )

            pixbuf = self.action_map.get(action)
            icon_x = button_x + (button_width - pixbuf.props.width) // 2
            icon_y = button_y + (button_height - pixbuf.props.height) // 2
            Gtk.render_icon(
                button_style_context, context, pixbuf, icon_x, icon_y)

        context.restore()

    def _classify_change_actions(self, change) -> Optional[ActionMode]:
        """Classify possible actions for the given change

        Returns the action that can be performed given the content and
        context of the change.
        """
        source_editable = self.source_view.get_editable()
        target_editable = self.target_view.get_editable()

        if not source_editable and not target_editable:
            return None

        # Reclassify conflict changes, since we treat them the same as a
        # normal two-way change as far as actions are concerned
        change_type = change[0]
        if change_type == 'conflict':
            if change[1] == change[2]:
                change_type = 'insert'
            elif change[3] == change[4]:
                change_type = 'delete'
            else:
                change_type = 'replace'

        if change_type == 'insert':
            return None

        action = self.action_mode
        if action == ActionMode.Delete and not source_editable:
            action = None
        elif action == ActionMode.Insert and change_type == 'delete':
            action = ActionMode.Replace
        if not target_editable:
            action = ActionMode.Delete
        return action
 def set_Password(self, password):
     self.password = password
     if ((self.state == self.STATE_READY_FOR_SETUP) and self.SSID
             and self.password):
         GObject.timeout_add(1, self.connect)
class RadioToolButton(Gtk.RadioToolButton):
    """An implementation of a "push" button."""

    __gtype_name__ = 'SugarRadioToolButton'

    def __init__(self, icon_name=None, **kwargs):
        self._accelerator = None
        self._tooltip = None
        self._xo_color = None
        self._hide_tooltip_on_click = True

        self._palette_invoker = ToolInvoker()

        GObject.GObject.__init__(self, **kwargs)

        self._palette_invoker.attach_tool(self)

        if icon_name:
            self.set_icon_name(icon_name)

        self.connect('destroy', self.__destroy_cb)

    def __destroy_cb(self, icon):
        if self._palette_invoker is not None:
            self._palette_invoker.detach()

    def set_tooltip(self, tooltip):
        if self.palette is None or self._tooltip is None:
            self.palette = Palette(tooltip)
        elif self.palette is not None:
            self.palette.set_primary_text(tooltip)

        self._tooltip = tooltip

        # Set label, shows up when toolbar overflows
        Gtk.RadioToolButton.set_label(self, tooltip)

    def get_tooltip(self):
        return self._tooltip

    tooltip = GObject.property(type=str,
                               setter=set_tooltip,
                               getter=get_tooltip)

    def set_accelerator(self, accelerator):
        self._accelerator = accelerator
        toolbutton.setup_accelerator(self)

    def get_accelerator(self):
        return self._accelerator

    accelerator = GObject.property(type=str,
                                   setter=set_accelerator,
                                   getter=get_accelerator)

    def set_icon_name(self, icon_name):
        icon = Icon(icon_name=icon_name, xo_color=self._xo_color)
        self.set_icon_widget(icon)
        icon.show()

    def get_icon_name(self):
        if self.props.icon_widget is not None:
            return self.props.icon_widget.props.icon_name
        else:
            return None

    icon_name = GObject.property(type=str,
                                 setter=set_icon_name,
                                 getter=get_icon_name)

    def set_xo_color(self, xo_color):
        if self._xo_color != xo_color:
            self._xo_color = xo_color
            if self.props.icon_widget is not None:
                self.props.icon_widget.props.xo_color = xo_color

    def get_xo_color(self):
        return self._xo_color

    xo_color = GObject.property(type=object,
                                setter=set_xo_color,
                                getter=get_xo_color)

    def create_palette(self):
        return None

    def get_palette(self):
        return self._palette_invoker.palette

    def set_palette(self, palette):
        self._palette_invoker.palette = palette

    palette = GObject.property(type=object,
                               setter=set_palette,
                               getter=get_palette)

    def get_palette_invoker(self):
        return self._palette_invoker

    def set_palette_invoker(self, palette_invoker):
        self._palette_invoker.detach()
        self._palette_invoker = palette_invoker

    palette_invoker = GObject.property(type=object,
                                       setter=set_palette_invoker,
                                       getter=get_palette_invoker)

    def do_draw(self, cr):
        if self.palette and self.palette.is_up():
            allocation = self.get_allocation()
            # draw a black background, has been done by the engine before
            cr.set_source_rgb(0, 0, 0)
            cr.rectangle(0, 0, allocation.width, allocation.height)
            cr.paint()

        Gtk.RadioToolButton.do_draw(self, cr)

        if self.palette and self.palette.is_up():
            invoker = self.palette.props.invoker
            invoker.draw_rectangle(cr, self.palette)

        return False

    def get_hide_tooltip_on_click(self):
        return self._hide_tooltip_on_click

    def set_hide_tooltip_on_click(self, hide_tooltip_on_click):
        if self._hide_tooltip_on_click != hide_tooltip_on_click:
            self._hide_tooltip_on_click = hide_tooltip_on_click

    hide_tooltip_on_click = GObject.property(type=bool,
                                             default=True,
                                             getter=get_hide_tooltip_on_click,
                                             setter=set_hide_tooltip_on_click)

    def do_clicked(self):
        if self._hide_tooltip_on_click and self.palette:
            self.palette.popdown(True)
 def set_SSID(self, SSID):
     self.SSID = SSID
     if ((self.state == self.STATE_READY_FOR_SETUP) and self.SSID
             and self.password):
         GObject.timeout_add(1, self.connect)
class ControlYourTabsPlugin(GObject.Object, Gedit.WindowActivatable,
                            PeasGtk.Configurable):
    __gtype_name__ = 'ControlYourTabsPlugin'

    window = GObject.property(type=Gedit.Window)

    SELECTED_TAB_COLUMN = 3

    META_KEYS = [
        'Shift_L', 'Shift_R', 'Control_L', 'Control_R', 'Meta_L', 'Meta_R',
        'Super_L', 'Super_R', 'Hyper_L', 'Hyper_R', 'Alt_L', 'Alt_R'
    ]
    # Compose, Apple?

    MAX_TAB_WINDOW_ROWS = 9

    MAX_TAB_WINDOW_HEIGHT_PERCENTAGE = 0.5

    # based on MAX_DOC_NAME_LENGTH in gedit-documents-panel.c
    MAX_DOC_NAME_LENGTH = 60

    # based on formats in tab_get_name() in gedit-documents-panel.c < 3.12
    TAB_NAME_GEDITPANEL_FORMATS = {
        'modified': "<i>%s</i>",
        'readonly': " [<i>%s</i>]"
    }

    # based on formats in document_row_sync_tab_name_and_icon() in gedit-documents-panel.c >= 3.12
    TAB_NAME_LISTBOX_FORMATS = {'modified': "<b>%s</b>", 'readonly': " [%s]"}

    # based on switch statement in _gedit_tab_get_icon() in gedit-tab.c < 3.12
    TAB_STATE_TO_STOCK_ICON = {
        Gedit.TabState.STATE_LOADING:
        Gtk.STOCK_OPEN,
        Gedit.TabState.STATE_REVERTING:
        Gtk.STOCK_REVERT_TO_SAVED,
        Gedit.TabState.STATE_SAVING:
        Gtk.STOCK_SAVE,
        Gedit.TabState.STATE_PRINTING:
        Gtk.STOCK_PRINT,
        Gedit.TabState.STATE_PRINT_PREVIEWING:
        Gtk.STOCK_PRINT_PREVIEW,
        Gedit.TabState.STATE_SHOWING_PRINT_PREVIEW:
        Gtk.STOCK_PRINT_PREVIEW,
        Gedit.TabState.STATE_LOADING_ERROR:
        Gtk.STOCK_DIALOG_ERROR,
        Gedit.TabState.STATE_REVERTING_ERROR:
        Gtk.STOCK_DIALOG_ERROR,
        Gedit.TabState.STATE_SAVING_ERROR:
        Gtk.STOCK_DIALOG_ERROR,
        Gedit.TabState.STATE_GENERIC_ERROR:
        Gtk.STOCK_DIALOG_ERROR,
        Gedit.TabState.STATE_EXTERNALLY_MODIFIED_NOTIFICATION:
        Gtk.STOCK_DIALOG_WARNING
    }

    # based on switch statement in _gedit_tab_get_icon() in gedit-tab.c >= 3.12
    TAB_STATE_TO_NAMED_ICON = {
        Gedit.TabState.STATE_PRINTING:
        'printer-printing-symbolic',
        Gedit.TabState.STATE_PRINT_PREVIEWING:
        'printer-symbolic',
        Gedit.TabState.STATE_SHOWING_PRINT_PREVIEW:
        'printer-symbolic',
        Gedit.TabState.STATE_LOADING_ERROR:
        'dialog-error-symbolic',
        Gedit.TabState.STATE_REVERTING_ERROR:
        'dialog-error-symbolic',
        Gedit.TabState.STATE_SAVING_ERROR:
        'dialog-error-symbolic',
        Gedit.TabState.STATE_GENERIC_ERROR:
        'dialog-error-symbolic',
        Gedit.TabState.STATE_EXTERNALLY_MODIFIED_NOTIFICATION:
        'dialog-warning-symbolic'
    }

    SETTINGS_SCHEMA_ID = 'com.thingsthemselves.gedit.plugins.controlyourtabs'

    USE_TABBAR_ORDER = 'use-tabbar-order'

    # gedit plugin api

    def __init__(self):
        GObject.Object.__init__(self)

    def do_activate(self):
        window = self.window
        notebooks = {}

        tabwin = Gtk.Window(type=Gtk.WindowType.POPUP)
        tabwin.set_transient_for(window)
        tabwin.set_destroy_with_parent(True)
        tabwin.set_accept_focus(False)
        tabwin.set_decorated(False)
        tabwin.set_resizable(False)
        tabwin.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
        tabwin.set_type_hint(Gdk.WindowTypeHint.UTILITY)
        tabwin.set_skip_taskbar_hint(False)
        tabwin.set_skip_pager_hint(False)

        sw = Gtk.ScrolledWindow()
        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        sw.show()

        tabwin.add(sw)

        view = Gtk.TreeView()
        view.set_enable_search(False)
        view.set_headers_visible(False)
        view.show()

        sw.add(view)

        col = Gtk.TreeViewColumn(_("Documents"))
        col.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)

        icon_cell = Gtk.CellRendererPixbuf()
        name_cell = Gtk.CellRendererText()
        space_cell = Gtk.CellRendererPixbuf()

        col.pack_start(icon_cell, False)
        col.pack_start(name_cell, True)
        col.pack_start(space_cell, False)

        col.add_attribute(icon_cell, 'pixbuf', 0)
        col.add_attribute(name_cell, 'markup', 1)

        view.append_column(col)

        sel = view.get_selection()
        sel.set_mode(Gtk.SelectionMode.SINGLE)

        # hack to ensure tabwin is correctly positioned/sized on first show
        view.realize()

        try:
            GtkStack = Gtk.Stack
        except AttributeError:
            is_side_panel_stack = False
        else:
            is_side_panel_stack = isinstance(window.get_side_panel(),
                                             GtkStack)  # since 3.12

        self._tabbing = False
        self._paging = False
        self._switching = False
        self._ctrl_l = False
        self._ctrl_r = False
        self._multi = None
        self._notebooks = notebooks
        self._tabwin = tabwin
        self._view = view
        self._sw = sw
        self._icon_cell = icon_cell
        self._space_cell = space_cell
        self._tabwin_resize_id = None
        self._settings = self._get_settings()
        self._is_side_panel_stack = is_side_panel_stack

        tab = window.get_active_tab()
        if tab:
            self._setup(window, tab, notebooks, view)
            if self._multi:
                self.on_window_active_tab_changed(window, tab, notebooks, view)
        else:
            connect_handlers(self, window, ['tab-added'], 'window')

    def do_deactivate(self):
        window = self.window

        disconnect_handlers(self, window)

        if self._multi:
            disconnect_handlers(self, self._multi)

        notebooks = self._notebooks
        for notebook in notebooks:
            disconnect_handlers(self, notebooks[notebook][1])

        for doc in window.get_documents():
            disconnect_handlers(self, Gedit.Tab.get_from_document(doc))

        self._cancel_tabwin_resize()
        self._end_switching()

        self._tabwin.destroy()

        self._tabbing = None
        self._paging = None
        self._switching = None
        self._ctrl_l = None
        self._ctrl_r = None
        self._multi = None
        self._notebooks = None
        self._tabwin = None
        self._view = None
        self._sw = None
        self._icon_cell = None
        self._space_cell = None
        self._tabwin_resize_id = None
        self._settings = None
        self._is_side_panel_stack = None

    def do_update_state(self):
        pass

    # settings ui

    def do_create_configure_widget(self):
        settings = self._get_settings()
        if settings:
            widget = Gtk.CheckButton(
                _("Use tabbar order for Ctrl+Tab / Ctrl+Shift+Tab"))
            widget.set_active(settings.get_boolean(self.USE_TABBAR_ORDER))
            connect_handlers(self, widget, ['toggled'],
                             'configure_check_button', settings)
            connect_handlers(self, settings,
                             ['changed::' + self.USE_TABBAR_ORDER],
                             'configure_settings', widget)
        else:
            widget = Gtk.Box()
            widget.add(
                Gtk.Label(
                    _("Sorry, no preferences are available for this version of gedit."
                      )))
        widget.set_border_width(5)
        return widget

    def on_configure_check_button_toggled(self, widget, settings):
        settings.set_boolean(self.USE_TABBAR_ORDER, widget.get_active())

    def on_configure_settings_changed_use_tabbar_order(self, settings, prop,
                                                       widget):
        widget.set_active(settings.get_boolean(self.USE_TABBAR_ORDER))

    # plugin setup

    def on_window_tab_added(self, window, tab):
        disconnect_handlers(self, window)
        self._setup(window, tab, self._notebooks, self._view)

    def _setup(self, window, tab, notebooks, view):
        if self._is_side_panel_stack:
            is_valid_size, icon_size_width, icon_size_height = Gtk.icon_size_lookup(
                Gtk.IconSize.MENU)
        else:
            is_valid_size, icon_size_width, icon_size_height = Gtk.icon_size_lookup_for_settings(
                tab.get_settings(), Gtk.IconSize.MENU)

        self._icon_cell.set_fixed_size(icon_size_height, icon_size_height)
        self._space_cell.set_fixed_size(icon_size_height, icon_size_height)

        multi = self._get_multi_notebook(tab)

        if multi:
            self._multi = multi

            for doc in window.get_documents():
                self.on_multi_notebook_notebook_added(
                    multi,
                    Gedit.Tab.get_from_document(doc).get_parent(), notebooks,
                    view)

            connect_handlers(self, multi, [
                'notebook-added', 'notebook-removed', 'tab-added',
                'tab-removed'
            ], 'multi_notebook', notebooks, view)
            connect_handlers(self, window, [
                'tabs-reordered', 'active-tab-changed', 'key-press-event',
                'key-release-event', 'focus-out-event', 'configure-event'
            ], 'window', notebooks, view)

        else:
            try:
                Gedit.debug_plugin_message(
                    "cannot find multi notebook from %s", tab)
            except AttributeError:
                pass

    # signal handlers / main logic

    def on_multi_notebook_notebook_added(self, multi, notebook, notebooks,
                                         view):
        if notebook not in notebooks:
            model = Gtk.ListStore(GdkPixbuf.Pixbuf, str, Gedit.Tab, 'gboolean')
            connect_handlers(self, model,
                             ['row-inserted', 'row-deleted', 'row-changed'],
                             'model', view, view.get_selection())
            notebooks[notebook] = ([], model)

            for tab in notebook.get_children():
                self.on_multi_notebook_tab_added(multi, notebook, tab,
                                                 notebooks, view)

    def on_multi_notebook_notebook_removed(self, multi, notebook, notebooks,
                                           view):
        if notebook in notebooks:
            for tab in notebook.get_children():
                self.on_multi_notebook_tab_removed(multi, notebook, tab,
                                                   notebooks, view)

            stack, model = notebooks[notebook]
            if view.get_model() is model:
                view.set_model(None)
            disconnect_handlers(self, model)
            del notebooks[notebook]

    def on_multi_notebook_tab_added(self, multi, notebook, tab, notebooks,
                                    view):
        stack, model = notebooks[notebook]
        if tab not in stack:
            stack.append(tab)
            model.append(
                (self._get_tab_icon(tab), self._get_tab_name(tab), tab, False))
            connect_handlers(self, tab, ['notify::name', 'notify::state'],
                             self.on_sync_icon_and_name, notebooks)

    def on_multi_notebook_tab_removed(self, multi, notebook, tab, notebooks,
                                      view):
        stack, model = notebooks[notebook]
        if tab in stack:
            disconnect_handlers(self, tab)
            model.remove(model.get_iter(stack.index(tab)))
            stack.remove(tab)

    def on_window_tabs_reordered(self, window, notebooks, view):
        multi = self._multi
        tab = window.get_active_tab()
        new_notebook = tab.get_parent()
        if tab not in notebooks[new_notebook][0]:
            old_notebook = None
            for notebook in notebooks:
                if tab in notebooks[notebook][0]:
                    old_notebook = notebook
                    break
            if old_notebook:
                self.on_multi_notebook_tab_removed(multi, old_notebook, tab,
                                                   notebooks, view)
            self.on_multi_notebook_tab_added(multi, new_notebook, tab,
                                             notebooks, view)

    def on_window_active_tab_changed(self, window, tab, notebooks, view):
        if not self._switching:
            stack, model = notebooks[tab.get_parent()]

            if view.get_model() is not model:
                view.set_model(model)
                self._schedule_tabwin_resize()

            for row in model:
                row[self.SELECTED_TAB_COLUMN] = False

            if not self._tabbing and not self._paging:
                if tab in stack:
                    model.move_after(model.get_iter(stack.index(tab)), None)
                    stack.remove(tab)
                else:
                    model.insert(0, (self._get_tab_icon(tab),
                                     self._get_tab_name(tab), tab, False))

                stack.insert(0, tab)
                model[0][self.SELECTED_TAB_COLUMN] = True

            else:
                model[stack.index(tab)][self.SELECTED_TAB_COLUMN] = True

    def on_window_key_press_event(self, window, event, notebooks, view):
        key = Gdk.keyval_name(event.keyval)
        state = event.state & Gtk.accelerator_get_default_mod_mask()

        if key == 'Control_L':
            self._ctrl_l = True

        if key == 'Control_R':
            self._ctrl_r = True

        if key in self.META_KEYS or not state & Gdk.ModifierType.CONTROL_MASK:
            return False

        is_ctrl = state == Gdk.ModifierType.CONTROL_MASK
        is_ctrl_shift = state == Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK
        is_tab_key = key in ['ISO_Left_Tab', 'Tab']
        is_page_key = key in ['Page_Up', 'Page_Down']
        is_up_dir = key in ['ISO_Left_Tab', 'Page_Up']

        if not (((is_ctrl or is_ctrl_shift) and is_tab_key) or
                (is_ctrl and is_page_key)):
            self._end_switching()
            return False

        cur = window.get_active_tab()
        if cur:
            settings = self._settings
            notebook = cur.get_parent()
            stack, model = notebooks[notebook]
            is_tabbing = is_tab_key and not (settings and settings.get_boolean(
                self.USE_TABBAR_ORDER))
            tabs = stack if is_tabbing else notebook.get_children()
            tlen = len(tabs)

            if tlen > 1 and cur in tabs:
                i = -1 if is_up_dir else 1
                next = tabs[(tabs.index(cur) + i) % tlen]

                model[stack.index(cur)][self.SELECTED_TAB_COLUMN] = False
                model[stack.index(next)][self.SELECTED_TAB_COLUMN] = True

                if is_tabbing:
                    tabwin = self._tabwin

                    if not self._tabbing:
                        view.scroll_to_cell(Gtk.TreePath.new_first(), None,
                                            True, 0, 0)
                        tabwin.show_all()
                    else:
                        tabwin.present_with_time(event.time)

                    self._tabbing = True
                else:
                    self._paging = True

                self._switching = True
                window.set_active_tab(next)
                self._switching = False

        return True

    def on_window_key_release_event(self, window, event, notebooks, view):
        key = Gdk.keyval_name(event.keyval)

        if key == 'Control_L':
            self._ctrl_l = False

        if key == 'Control_R':
            self._ctrl_r = False

        if not self._ctrl_l and not self._ctrl_r:
            self._end_switching()

    def on_window_focus_out_event(self, window, event, notebooks, view):
        self._end_switching()

    def on_window_configure_event(self, window, event, notebooks, view):
        self._schedule_tabwin_resize()

    def _end_switching(self):
        if self._tabbing or self._paging:
            self._tabbing = False
            self._paging = False
            self._switching = False
            self._ctrl_l = False
            self._ctrl_r = False
            self._tabwin.hide()

            window = self.window
            tab = window.get_active_tab()
            if tab:
                self.on_window_active_tab_changed(window, tab, self._notebooks,
                                                  self._view)

    def on_model_row_inserted(self, model, path, iter, view, sel):
        if view.get_model() is model:
            self._schedule_tabwin_resize()

    def on_model_row_deleted(self, model, path, view, sel):
        if view.get_model() is model:
            self._schedule_tabwin_resize()

    def on_model_row_changed(self, model, path, iter, view, sel):
        if view.get_model() is model:
            if model[path][self.SELECTED_TAB_COLUMN]:
                sel.select_path(path)
                view.scroll_to_cell(path, None, True, 0.5, 0)
            else:
                sel.unselect_path(path)
            self._schedule_tabwin_resize()

    def on_sync_icon_and_name(self, tab, pspec, notebooks):
        stack, model = notebooks[tab.get_parent()]
        if tab in stack:
            path = stack.index(tab)
            model[path][0] = self._get_tab_icon(tab)
            model[path][1] = self._get_tab_name(tab)

    # tab name / icon

    # based on
    # <  3.12: tab_get_name() in gedit-documents-panel.c
    # >= 3.12: doc_get_name() and document_row_sync_tab_name_and_icon() in gedit-documents-panel.c
    def _get_tab_name(self, tab):
        doc = tab.get_document()
        name = doc.get_short_name_for_display()
        docname = Gedit.utils_str_middle_truncate(name,
                                                  self.MAX_DOC_NAME_LENGTH)
        tab_name_formats = self.TAB_NAME_LISTBOX_FORMATS if self._is_side_panel_stack else self.TAB_NAME_GEDITPANEL_FORMATS

        if not doc.get_modified():
            tab_name = escape(docname)
        else:
            tab_name = tab_name_formats['modified'] % escape(docname)

        try:
            file = doc.get_file()
            is_readonly = GtkSource.File.is_readonly(file)
        except AttributeError:
            is_readonly = doc.get_readonly()  # deprecated since 3.18

        if is_readonly:
            tab_name += tab_name_formats['readonly'] % escape(_("Read-Only"))

        return tab_name

    def _get_tab_icon(self, tab):
        if self._is_side_panel_stack:
            icon = self._get_named_tab_icon(tab)
        else:
            icon = self._get_stock_tab_icon(tab)
        return icon

    # based on _gedit_tab_get_icon() in gedit-tab.c >= 3.12
    def _get_named_tab_icon(self, tab):
        icon_name = None
        pixbuf = None
        state = tab.get_state()

        if state in self.TAB_STATE_TO_NAMED_ICON:
            icon_name = self.TAB_STATE_TO_NAMED_ICON[state]

        if icon_name:
            theme = Gtk.IconTheme.get_for_screen(tab.get_screen())
            is_valid_size, icon_size_width, icon_size_height = Gtk.icon_size_lookup(
                Gtk.IconSize.MENU)
            pixbuf = Gtk.IconTheme.load_icon(theme, icon_name,
                                             icon_size_height, 0)

        return pixbuf

    # based on _gedit_tab_get_icon() in gedit-tab.c < 3.12
    def _get_stock_tab_icon(self, tab):
        theme = Gtk.IconTheme.get_for_screen(tab.get_screen())
        is_valid_size, icon_size_width, icon_size_height = Gtk.icon_size_lookup_for_settings(
            tab.get_settings(), Gtk.IconSize.MENU)
        state = tab.get_state()

        if state in self.TAB_STATE_TO_STOCK_ICON:
            try:
                pixbuf = self._get_stock_icon(
                    theme, self.TAB_STATE_TO_STOCK_ICON[state],
                    icon_size_height)
            except GObject.GError:
                pixbuf = None
        else:
            pixbuf = None

        if not pixbuf:
            pixbuf = self._get_icon(theme,
                                    tab.get_document().get_location(),
                                    icon_size_height)

        return pixbuf

    # based on get_stock_icon() in gedit-tab.c in < 3.12
    def _get_stock_icon(self, theme, stock, size):
        pixbuf = theme.load_icon(stock, size, 0)
        return self._resize_icon(pixbuf, size)

    # based on get_icon() in gedit-tab.c in < 3.12
    def _get_icon(self, theme, location, size):
        if not location:
            return self._get_stock_icon(theme, Gtk.STOCK_FILE, size)

        # FIXME: Doing a sync stat is bad, this should be fixed
        try:
            info = location.query_info(Gio.FILE_ATTRIBUTE_STANDARD_ICON,
                                       Gio.FileQueryInfoFlags.NONE, None)
        except GObject.GError:
            info = None

        if not info:
            return self._get_stock_icon(theme, Gtk.STOCK_FILE, size)

        icon = info.get_icon()

        if not icon:
            return self._get_stock_icon(theme, Gtk.STOCK_FILE, size)

        icon_info = theme.lookup_by_gicon(icon, size, 0)

        if not icon_info:
            return self._get_stock_icon(theme, Gtk.STOCK_FILE, size)

        pixbuf = icon_info.load_icon()

        if not pixbuf:
            return self._get_stock_icon(theme, Gtk.STOCK_FILE, size)

        return self._resize_icon(pixbuf, size)

    # based on resize_icon() in gedit-tab.c in < 3.12
    def _resize_icon(self, pixbuf, size):
        width = pixbuf.get_width()
        height = pixbuf.get_height()

        # if the icon is larger than the nominal size, scale down
        if max(width, height) > size:
            if width > height:
                height = height * size / width
                width = size
            else:
                width = width * size / height
                height = size

            pixbuf = pixbuf.scale_simple(width, height,
                                         GdkPixbuf.InterpType.BILINEAR)

        return pixbuf

    # tab window resizing

    def _schedule_tabwin_resize(self):
        if not self._tabwin_resize_id:
            # need to wait a little before asking the treeview for its preferred size
            # maybe because treeview rendering is async?
            # this feels like a giant hack
            try:
                resize_id = GLib.idle_add(self._do_tabwin_resize)
            except TypeError:
                # gedit 3.0
                resize_id = GObject.idle_add(self._do_tabwin_resize)

            self._tabwin_resize_id = resize_id

    def _cancel_tabwin_resize(self):
        if self._tabwin_resize_id:
            GLib.source_remove(self._tabwin_resize_id)
            self._tabwin_resize_id = None

    def _do_tabwin_resize(self):
        view = self._view
        sw = self._sw

        view_min_size, view_nat_size = view.get_preferred_size()
        view_height = max(view_min_size.height, view_nat_size.height)

        num_rows = max(len(view.get_model()), 2)
        row_height = math.ceil(view_height / num_rows)
        max_rows_height = self.MAX_TAB_WINDOW_ROWS * row_height

        win_width, win_height = self.window.get_size()
        max_win_height = round(self.MAX_TAB_WINDOW_HEIGHT_PERCENTAGE *
                               win_height)

        max_height = min(max_rows_height, max_win_height)

        # we can't reliably tell if overlay scrolling is being used
        # since gtk_scrolled_window_get_overlay_scrolling() can still return True if GTK_OVERLAY_SCROLLING=0 is set
        # and even if we can tell if overlay scrolling is disabled,
        # we cannot tell if the scrolled window has reserved enough space for the scrollbar
        #   fedora < 25: reserved
        #   fedora >= 25: not reserved
        #   ubuntu 17.04: reserved
        # so let's ignore overlay scrolling for now :-(

        vscrollbar_policy = Gtk.PolicyType.AUTOMATIC if view_height > max_height else Gtk.PolicyType.NEVER
        sw.set_policy(Gtk.PolicyType.NEVER, vscrollbar_policy)

        sw_min_size, sw_nat_size = sw.get_preferred_size()

        tabwin_width = max(sw_min_size.width, sw_nat_size.width)
        tabwin_height = min(view_height, max_height)

        self._tabwin.set_size_request(tabwin_width, tabwin_height)

        self._tabwin_resize_id = None
        return False

    # misc

    # this is a /hack/
    def _get_multi_notebook(self, tab):
        multi = tab.get_parent()
        while multi:
            if multi.__gtype__.name == 'GeditMultiNotebook':
                break
            multi = multi.get_parent()
        return multi

    def _get_settings(self):
        schemas_path = os.path.join(BASE_PATH, 'schemas')
        try:
            # available in gedit >= 3.4
            schema_source = Gio.SettingsSchemaSource.new_from_directory(
                schemas_path, Gio.SettingsSchemaSource.get_default(), False)
            schema = Gio.SettingsSchemaSource.lookup(schema_source,
                                                     self.SETTINGS_SCHEMA_ID,
                                                     False)
            settings = Gio.Settings.new_full(schema, None,
                                             None) if schema else None
        except AttributeError:
            settings = None
        except:
            try:
                Gedit.debug_plugin_message(
                    "could not load settings schema from %s", schemas_path)
            except AttributeError:
                pass
            settings = None
        return settings