mirror of
https://gitlab.gnome.org/jpu/cambalache.git
synced 2025-08-10 00:03:17 -04:00
Compare commits
2 Commits
19851963fb
...
fa89006ff2
Author | SHA1 | Date | |
---|---|---|---|
|
fa89006ff2 | ||
|
15b8ecf3d8 |
@ -1,6 +1,6 @@
|
|||||||
# Cambalache
|
# Cambalache
|
||||||
#
|
#
|
||||||
# Copyright (C) 2021 Juan Pablo Ugarte
|
# Copyright (C) 2021-2023 Juan Pablo Ugarte
|
||||||
#
|
#
|
||||||
# This library is free software; you can redistribute it and/or
|
# This library is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU Lesser General Public
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
@ -28,10 +28,10 @@ import builtins
|
|||||||
|
|
||||||
from . import config
|
from . import config
|
||||||
|
|
||||||
gi.require_version("Gdk", "3.0")
|
gi.require_version("Gdk", "4.0")
|
||||||
gi.require_version("Gtk", "3.0")
|
gi.require_version("Gtk", "4.0")
|
||||||
gi.require_version("GtkSource", "4")
|
gi.require_version("GtkSource", "5")
|
||||||
gi.require_version("WebKit2", "4.1")
|
gi.require_version("WebKit", "6.0")
|
||||||
|
|
||||||
# Ensure _() builtin
|
# Ensure _() builtin
|
||||||
if "_" not in builtins.__dict__:
|
if "_" not in builtins.__dict__:
|
||||||
@ -54,8 +54,9 @@ resource._register()
|
|||||||
|
|
||||||
provider = Gtk.CssProvider()
|
provider = Gtk.CssProvider()
|
||||||
provider.load_from_resource("/ar/xjuan/Cambalache/cambalache.css")
|
provider.load_from_resource("/ar/xjuan/Cambalache/cambalache.css")
|
||||||
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
|
display = Gdk.Display.get_default()
|
||||||
Gtk.IconTheme.get_default().add_resource_path("/ar/xjuan/Cambalache/icons")
|
Gtk.StyleContext.add_provider_for_display(display, provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
|
||||||
|
Gtk.IconTheme.get_for_display(display).add_resource_path("/ar/xjuan/Cambalache/icons")
|
||||||
|
|
||||||
|
|
||||||
def getLogger(name):
|
def getLogger(name):
|
||||||
|
@ -21,27 +21,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@binding-set WindowBindings {
|
|
||||||
bind "<Control>s" { "cmb-action" ("save") };
|
|
||||||
bind "<Control>w" { "cmb-action" ("close") };
|
|
||||||
bind "<Control>z" { "cmb-action" ("undo") };
|
|
||||||
bind "<Control><shift>z" { "cmb-action" ("redo") };
|
|
||||||
bind "Delete" { "cmb-action" ("delete") };
|
|
||||||
bind "<Control>n" { "cmb-action" ("create_new") };
|
|
||||||
bind "<Control>o" { "cmb-action" ("open") };
|
|
||||||
bind "<Control>Insert" { "cmb-action-bool" ("add_placeholder", 0) };
|
|
||||||
bind "<Control>Delete" { "cmb-action-bool" ("remove_placeholder", 0) };
|
|
||||||
bind "<Control><shift>Insert" { "cmb-action-bool" ("add_placeholder", 1) };
|
|
||||||
bind "<Control><shift>Delete" { "cmb-action-bool" ("remove_placeholder", 1) };
|
|
||||||
}
|
|
||||||
|
|
||||||
CmbWindow .logo {
|
CmbWindow .logo {
|
||||||
background: url('resource:///ar/xjuan/Cambalache/app/images/logo-symbolic.svg') no-repeat 50% 35% / 40%
|
background: url('resource:///ar/xjuan/Cambalache/app/images/logo-symbolic.svg') no-repeat 50% 35% / 40%;
|
||||||
}
|
}
|
||||||
|
|
||||||
CmbWindow.dark .logo {
|
CmbWindow.dark .logo {
|
||||||
color: white;
|
color: white;
|
||||||
background: -gtk-recolor(url('resource:///ar/xjuan/Cambalache/app/images/logo-symbolic.svg'), success #ffcb85, error #1a1a1a) no-repeat 50% 35% / 40%
|
background: -gtk-recolor(url('resource:///ar/xjuan/Cambalache/app/images/logo-symbolic.svg'), success #ffcb85, error #1a1a1a) no-repeat 50% 35% / 40%;
|
||||||
}
|
}
|
||||||
|
|
||||||
CmbWindow label.message {
|
CmbWindow label.message {
|
||||||
@ -56,7 +43,7 @@ CmbWindow.dark label.message {
|
|||||||
background-color: rgba(255, 255, 255, .6);
|
background-color: rgba(255, 255, 255, .6);
|
||||||
}
|
}
|
||||||
|
|
||||||
popover.cmb-tutor {
|
popover.cmb-tutor > * {
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,13 +52,23 @@ popover.cmb-tutor label {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
popover.cmb-tutor image {
|
||||||
|
padding-right: 1em;
|
||||||
|
-gtk-icon-size: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
button.cmb-tutor-highlight,
|
button.cmb-tutor-highlight,
|
||||||
modelbutton.cmb-tutor-highlight,
|
modelbutton.cmb-tutor-highlight,
|
||||||
buttonbox.cmb-tutor-highlight > button,
|
buttonbox.cmb-tutor-highlight > button,
|
||||||
stackswitcher.cmb-tutor-highlight > button,
|
stackswitcher.cmb-tutor-highlight > button,
|
||||||
entry.cmb-tutor-highlight,
|
entry.cmb-tutor-highlight,
|
||||||
treeview.cmb-tutor-highlight,
|
treeview.cmb-tutor-highlight,
|
||||||
box.cmb-tutor-highlight {
|
box.cmb-tutor-highlight,
|
||||||
|
CmbView.cmb-tutor-highlight {
|
||||||
box-shadow: inset 0px 0px 6px @theme_selected_bg_color;
|
box-shadow: inset 0px 0px 6px @theme_selected_bg_color;
|
||||||
transition: box-shadow .75s ease;
|
transition: box-shadow .75s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CmbView.cmb-tutor-highlight {
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Cambalache Application
|
# Cambalache Application
|
||||||
#
|
#
|
||||||
# Copyright (C) 2021 Juan Pablo Ugarte
|
# Copyright (C) 2021-2024 Juan Pablo Ugarte
|
||||||
#
|
#
|
||||||
# This library is free software; you can redistribute it and/or
|
# This library is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU Lesser General Public
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
@ -43,7 +43,8 @@ class CmbApplication(Gtk.Application):
|
|||||||
def __add_window(self):
|
def __add_window(self):
|
||||||
window = CmbWindow(application=self)
|
window = CmbWindow(application=self)
|
||||||
window.connect("open-project", self.__on_open_project)
|
window.connect("open-project", self.__on_open_project)
|
||||||
window.connect("delete-event", self.__on_window_delete_event)
|
|
||||||
|
window.connect("close-request", self.__on_window_close_request)
|
||||||
self.add_window(window)
|
self.add_window(window)
|
||||||
return window
|
return window
|
||||||
|
|
||||||
@ -91,7 +92,7 @@ class CmbApplication(Gtk.Application):
|
|||||||
|
|
||||||
provider = Gtk.CssProvider()
|
provider = Gtk.CssProvider()
|
||||||
provider.load_from_resource("/ar/xjuan/Cambalache/app/cambalache.css")
|
provider.load_from_resource("/ar/xjuan/Cambalache/app/cambalache.css")
|
||||||
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
|
Gtk.StyleContext.add_provider_for_display(Gdk.Display.get_default(), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
|
||||||
|
|
||||||
def do_activate(self):
|
def do_activate(self):
|
||||||
if self.props.active_window is None:
|
if self.props.active_window is None:
|
||||||
@ -103,9 +104,17 @@ class CmbApplication(Gtk.Application):
|
|||||||
else:
|
else:
|
||||||
self.open_project(filename, target_tk, uiname)
|
self.open_project(filename, target_tk, uiname)
|
||||||
|
|
||||||
def __check_can_quit(self, windows):
|
def __check_can_quit(self, window=None):
|
||||||
|
windows = self.__get_windows() if window is None else [window]
|
||||||
unsaved_windows = []
|
unsaved_windows = []
|
||||||
projects2save = []
|
windows2save = []
|
||||||
|
|
||||||
|
def do_quit():
|
||||||
|
if window is None:
|
||||||
|
self.quit()
|
||||||
|
else:
|
||||||
|
self.remove_window(window)
|
||||||
|
window.destroy()
|
||||||
|
|
||||||
# Gather projects that needs saving
|
# Gather projects that needs saving
|
||||||
for win in windows:
|
for win in windows:
|
||||||
@ -117,16 +126,17 @@ class CmbApplication(Gtk.Application):
|
|||||||
|
|
||||||
unsaved_windows_len = len(unsaved_windows)
|
unsaved_windows_len = len(unsaved_windows)
|
||||||
if unsaved_windows_len == 0:
|
if unsaved_windows_len == 0:
|
||||||
return True
|
do_quit()
|
||||||
|
return
|
||||||
|
|
||||||
# Create Dialog
|
# Create Dialog
|
||||||
text = _("Save changes before closing?")
|
text = _("Save changes before closing?")
|
||||||
dialog = Gtk.MessageDialog(
|
dialog = Gtk.MessageDialog(
|
||||||
transient_for=windows[0],
|
transient_for=windows[0],
|
||||||
flags=0,
|
|
||||||
message_type=Gtk.MessageType.QUESTION,
|
message_type=Gtk.MessageType.QUESTION,
|
||||||
text=f"<b><big>{text}</big></b>",
|
text=f"<b><big>{text}</big></b>",
|
||||||
use_markup=True,
|
use_markup=True,
|
||||||
|
modal=True
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add buttons
|
# Add buttons
|
||||||
@ -141,36 +151,58 @@ class CmbApplication(Gtk.Application):
|
|||||||
|
|
||||||
dialog.set_default_response(Gtk.ResponseType.ACCEPT)
|
dialog.set_default_response(Gtk.ResponseType.ACCEPT)
|
||||||
|
|
||||||
if unsaved_windows_len > 1:
|
if unsaved_windows_len > 1 or unsaved_windows[0].project.filename is None:
|
||||||
# Add checkbox for each unsaved project
|
# Add checkbox for each unsaved project
|
||||||
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=4)
|
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=4)
|
||||||
box.add(Gtk.Label(label=_("Select which files:"), halign=Gtk.Align.START))
|
box.append(Gtk.Label(label=_("Select which files:"), halign=Gtk.Align.START))
|
||||||
|
|
||||||
|
home = GLib.get_home_dir()
|
||||||
|
untitled = 0
|
||||||
|
|
||||||
for win in unsaved_windows:
|
for win in unsaved_windows:
|
||||||
path = win.project.filename.replace(GLib.get_home_dir(), "~")
|
if win.project.filename is None:
|
||||||
check = Gtk.CheckButton(label=path, active=True, margin_start=8, can_focus=False)
|
untitled += 1
|
||||||
projects2save.append((win.project, check))
|
|
||||||
box.add(check)
|
|
||||||
|
|
||||||
box.show_all()
|
# Find Unique name
|
||||||
dialog.props.message_area.add(box)
|
while os.path.exists(f"Untitled {untitled}.cmb"):
|
||||||
|
untitled += 1
|
||||||
|
|
||||||
# Run Dialog
|
check = Gtk.CheckButton(active=True, margin_start=8, can_focus=False)
|
||||||
response = dialog.run()
|
entry = Gtk.Entry(text=f"Untitled {untitled}")
|
||||||
dialog.destroy()
|
|
||||||
|
|
||||||
# Handle response
|
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=4)
|
||||||
if response == Gtk.ResponseType.ACCEPT:
|
hbox.append(check)
|
||||||
if unsaved_windows_len > 1:
|
hbox.append(entry)
|
||||||
for project, check in projects2save:
|
|
||||||
|
box.append(hbox)
|
||||||
|
else:
|
||||||
|
path = win.project.filename.replace(home, "~")
|
||||||
|
check = Gtk.CheckButton(label=path, active=True, margin_start=8, can_focus=False)
|
||||||
|
box.append(check)
|
||||||
|
|
||||||
|
windows2save.append((win, check, entry))
|
||||||
|
|
||||||
|
box.show()
|
||||||
|
dialog.props.message_area.append(box)
|
||||||
|
else:
|
||||||
|
windows2save.append((unsaved_windows[0], None, None))
|
||||||
|
|
||||||
|
def callback(dialog, response, window):
|
||||||
|
dialog.destroy()
|
||||||
|
|
||||||
|
if response == Gtk.ResponseType.ACCEPT:
|
||||||
|
for win, check, entry in windows2save:
|
||||||
|
if entry is not None:
|
||||||
|
win.project.filename = entry.props.text
|
||||||
if check is None or check.props.active:
|
if check is None or check.props.active:
|
||||||
project.save()
|
win.save_project()
|
||||||
elif unsaved_windows_len:
|
elif response == Gtk.ResponseType.CANCEL:
|
||||||
unsaved_windows[0].project.save()
|
return
|
||||||
elif response == Gtk.ResponseType.CANCEL:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
do_quit()
|
||||||
|
|
||||||
|
dialog.connect("response", callback, window)
|
||||||
|
dialog.present()
|
||||||
|
|
||||||
def __get_windows(self):
|
def __get_windows(self):
|
||||||
retval = []
|
retval = []
|
||||||
@ -181,8 +213,9 @@ class CmbApplication(Gtk.Application):
|
|||||||
|
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
def __on_window_delete_event(self, window, event):
|
def __on_window_close_request(self, window):
|
||||||
return not self.__check_can_quit([window])
|
self.__check_can_quit(window)
|
||||||
|
return True
|
||||||
|
|
||||||
def do_window_removed(self, window):
|
def do_window_removed(self, window):
|
||||||
windows = self.__get_windows()
|
windows = self.__get_windows()
|
||||||
@ -191,8 +224,7 @@ class CmbApplication(Gtk.Application):
|
|||||||
self.activate_action("quit")
|
self.activate_action("quit")
|
||||||
|
|
||||||
def _on_quit_activate(self, action, data):
|
def _on_quit_activate(self, action, data):
|
||||||
if self.__check_can_quit(self.__get_windows()):
|
self.__check_can_quit()
|
||||||
self.quit()
|
|
||||||
|
|
||||||
def do_handle_local_options(self, options):
|
def do_handle_local_options(self, options):
|
||||||
if options.contains("version"):
|
if options.contains("version"):
|
||||||
|
@ -1,86 +1,74 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Created with Cambalache 0.9.0 -->
|
|
||||||
<interface>
|
<interface>
|
||||||
<!-- interface-name cmb_shortcuts.ui -->
|
<requires lib="gtk" version="4.0"/>
|
||||||
<requires lib="gtk+" version="3.0"/>
|
|
||||||
<object class="GtkShortcutsWindow" id="shortcuts">
|
<object class="GtkShortcutsWindow" id="shortcuts">
|
||||||
<property name="section-name">shortcuts</property>
|
<property name="section-name">shortcuts</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkShortcutsSection">
|
<object class="GtkShortcutsSection">
|
||||||
<property name="section-name">shortcuts</property>
|
<property name="section-name">shortcuts</property>
|
||||||
<property name="visible">True</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkShortcutsGroup">
|
<object class="GtkShortcutsGroup">
|
||||||
<property name="title" translatable="yes">Project</property>
|
<property name="title" translatable="1">Project</property>
|
||||||
<property name="view">shortcuts</property>
|
<property name="view">shortcuts</property>
|
||||||
<property name="visible">True</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkShortcutsShortcut">
|
<object class="GtkShortcutsShortcut">
|
||||||
<property name="accelerator"><Control>n</property>
|
<property name="accelerator"><Control>n</property>
|
||||||
<property name="title" translatable="yes">Create new project</property>
|
<property name="title" translatable="1">Create new project</property>
|
||||||
<property name="visible">True</property>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkShortcutsShortcut">
|
<object class="GtkShortcutsShortcut">
|
||||||
<property name="accelerator"><Control>o</property>
|
<property name="accelerator"><Control>o</property>
|
||||||
<property name="title" translatable="yes">Open a project</property>
|
<property name="title" translatable="1">Open a project</property>
|
||||||
<property name="visible">True</property>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkShortcutsShortcut">
|
<object class="GtkShortcutsShortcut">
|
||||||
<property name="accelerator"><Control>w</property>
|
<property name="accelerator"><Control>w</property>
|
||||||
<property name="title" translatable="yes">Close the project</property>
|
<property name="title" translatable="1">Close the project</property>
|
||||||
<property name="visible">True</property>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkShortcutsShortcut">
|
<object class="GtkShortcutsShortcut">
|
||||||
<property name="accelerator"><Control>s</property>
|
<property name="accelerator"><Control>s</property>
|
||||||
<property name="title" translatable="yes">Save the project</property>
|
<property name="title" translatable="1">Save the project</property>
|
||||||
<property name="visible">True</property>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkShortcutsShortcut">
|
<object class="GtkShortcutsShortcut">
|
||||||
|
<property name="visible">0</property>
|
||||||
<property name="accelerator"><Control>e</property>
|
<property name="accelerator"><Control>e</property>
|
||||||
<property name="title" translatable="yes">Save and Export</property>
|
<property name="title" translatable="1">Save and Export</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkShortcutsGroup">
|
<object class="GtkShortcutsGroup">
|
||||||
<property name="title" translatable="yes">Workspace</property>
|
<property name="title" translatable="1">Workspace</property>
|
||||||
<property name="view">shortcuts</property>
|
<property name="view">shortcuts</property>
|
||||||
<property name="visible">True</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkShortcutsShortcut">
|
<object class="GtkShortcutsShortcut">
|
||||||
<property name="accelerator"><Control>Insert</property>
|
<property name="accelerator"><Control>Insert</property>
|
||||||
<property name="title" translatable="yes">Add slot/column</property>
|
<property name="title" translatable="1">Add slot/column</property>
|
||||||
<property name="visible">True</property>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkShortcutsShortcut">
|
<object class="GtkShortcutsShortcut">
|
||||||
<property name="accelerator"><Control>Delete</property>
|
<property name="accelerator"><Control>Delete</property>
|
||||||
<property name="title" translatable="yes">Remove slot/column</property>
|
<property name="title" translatable="1">Remove slot/column</property>
|
||||||
<property name="visible">True</property>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkShortcutsShortcut">
|
<object class="GtkShortcutsShortcut">
|
||||||
<property name="accelerator"><Control><shift>Insert</property>
|
<property name="accelerator"><Control><shift>Insert</property>
|
||||||
<property name="title" translatable="yes">Add row</property>
|
<property name="title" translatable="1">Add row</property>
|
||||||
<property name="visible">True</property>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkShortcutsShortcut">
|
<object class="GtkShortcutsShortcut">
|
||||||
<property name="accelerator"><Control><shift>Delete</property>
|
<property name="accelerator"><Control><shift>Delete</property>
|
||||||
<property name="title" translatable="yes">Remove row</property>
|
<property name="title" translatable="1">Remove row</property>
|
||||||
<property name="visible">True</property>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
from gi.repository import GObject, GLib, Gdk, Gtk
|
from gi.repository import GObject, GLib, Gdk, Gtk
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
from cambalache import utils
|
||||||
|
|
||||||
|
|
||||||
class CmbTutorState(Enum):
|
class CmbTutorState(Enum):
|
||||||
@ -85,32 +86,30 @@ class CmbTutor(GObject.GObject):
|
|||||||
def __add(self, text, widget_name, delay, name=None, position=CmbTutorPosition.BOTTOM):
|
def __add(self, text, widget_name, delay, name=None, position=CmbTutorPosition.BOTTOM):
|
||||||
retval = {}
|
retval = {}
|
||||||
|
|
||||||
def find_widget(w, data):
|
def find_by_css_name_or_buildable_id(widget, name):
|
||||||
if data.get("widget", None):
|
retval = None
|
||||||
return
|
css_name = widget.get_name()
|
||||||
|
|
||||||
name = None
|
# Get css name first
|
||||||
n = w.get_name()
|
if css_name and css_name != GObject.type_name(widget) and css_name == name:
|
||||||
|
return widget
|
||||||
|
|
||||||
# Get css name first then GtkBuildable name
|
# then GtkBuildable name
|
||||||
if n and n != GObject.type_name(w):
|
if isinstance(widget, Gtk.Buildable) and Gtk.Buildable.get_buildable_id(widget) == name:
|
||||||
name = n
|
return widget
|
||||||
elif isinstance(w, Gtk.Buildable):
|
|
||||||
n = Gtk.Buildable.get_name(w)
|
|
||||||
if n and not n.startswith("___object"):
|
|
||||||
name = n
|
|
||||||
|
|
||||||
# Return widget
|
# or ModelButton name
|
||||||
if name == widget_name:
|
if GObject.type_name(widget) == "GtkModelButton" and widget.props.text == name:
|
||||||
data["widget"] = w
|
return widget
|
||||||
return
|
|
||||||
|
|
||||||
if isinstance(w, Gtk.Container):
|
for child in utils.widget_get_children(widget):
|
||||||
w.forall(find_widget, data)
|
retval = find_by_css_name_or_buildable_id(child, name)
|
||||||
|
if retval:
|
||||||
|
return retval
|
||||||
|
|
||||||
self.window.forall(find_widget, retval)
|
return retval
|
||||||
|
|
||||||
widget = retval.get("widget", None)
|
widget = find_by_css_name_or_buildable_id(self.window, widget_name)
|
||||||
|
|
||||||
if widget:
|
if widget:
|
||||||
self.script.append(ScriptNode(widget, text, delay, name, position))
|
self.script.append(ScriptNode(widget, text, delay, name, position))
|
||||||
@ -140,14 +139,19 @@ class CmbTutor(GObject.GObject):
|
|||||||
self.notify("state")
|
self.notify("state")
|
||||||
|
|
||||||
def __popover_new(self, text):
|
def __popover_new(self, text):
|
||||||
popover = Gtk.Popover(modal=False)
|
popover = Gtk.Popover(autohide=False)
|
||||||
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
|
popover.add_css_class("cmb-tutor")
|
||||||
|
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, hexpand=True)
|
||||||
|
|
||||||
box.add(Gtk.Image(icon_name="dialog-information-symbolic", icon_size=Gtk.IconSize.DIALOG))
|
box.append(Gtk.Image(icon_name="dialog-information-symbolic"))
|
||||||
box.add(Gtk.Label(label=text, wrap=True, max_width_chars=28))
|
box.append(Gtk.Label(
|
||||||
popover.add(box)
|
label=text,
|
||||||
popover.get_style_context().add_class("cmb-tutor")
|
vexpand=False,
|
||||||
box.show_all()
|
hexpand=True,
|
||||||
|
wrap=True,
|
||||||
|
max_width_chars=24
|
||||||
|
))
|
||||||
|
popover.set_child(box)
|
||||||
|
|
||||||
return popover
|
return popover
|
||||||
|
|
||||||
@ -203,11 +207,11 @@ class CmbTutor(GObject.GObject):
|
|||||||
if parent:
|
if parent:
|
||||||
parent.popup()
|
parent.popup()
|
||||||
|
|
||||||
node.widget.get_style_context().add_class("cmb-tutor-highlight")
|
node.widget.add_css_class("cmb-tutor-highlight")
|
||||||
|
|
||||||
# Create popover
|
# Create popover
|
||||||
self.popover = self.__popover_new(node.text)
|
self.popover = self.__popover_new(node.text)
|
||||||
self.popover.set_relative_to(node.widget)
|
self.popover.set_parent(node.widget)
|
||||||
|
|
||||||
if node.position == CmbTutorPosition.BOTTOM:
|
if node.position == CmbTutorPosition.BOTTOM:
|
||||||
self.popover.set_position(Gtk.PositionType.BOTTOM)
|
self.popover.set_position(Gtk.PositionType.BOTTOM)
|
||||||
|
@ -36,9 +36,9 @@ intro = [
|
|||||||
(_("Common actions like Undo"), "undo_button", 4),
|
(_("Common actions like Undo"), "undo_button", 4),
|
||||||
(_("Redo"), "redo_button", 2),
|
(_("Redo"), "redo_button", 2),
|
||||||
(_("Add new UI file"), "add_button", 3),
|
(_("Add new UI file"), "add_button", 3),
|
||||||
(_("and Save are directly accessible in the headerbar"), "save_button", 6),
|
(_("and Save are directly accessible in the headerbar"), "cmb_save_button", 6),
|
||||||
(_("just like Save As"), "save_as_button", 2),
|
(_("just like Save As"), "save_as_button", 2),
|
||||||
(_("and the main menu"), "menu_button", 3),
|
(_("and the main menu"), "menu_button", 3, "menu_button"),
|
||||||
(_("Create a project to continue"), "intro_button", 2, "add-project"),
|
(_("Create a project to continue"), "intro_button", 2, "add-project"),
|
||||||
(_("Great!"), "intro_button", 2),
|
(_("Great!"), "intro_button", 2),
|
||||||
(
|
(
|
||||||
@ -66,14 +66,21 @@ intro = [
|
|||||||
(_("Quite easy! Isn't it?"), "intro_button", 3),
|
(_("Quite easy! Isn't it?"), "intro_button", 3),
|
||||||
(
|
(
|
||||||
_("Once you finish, you can export all UI files to xml here"),
|
_("Once you finish, you can export all UI files to xml here"),
|
||||||
"export_all",
|
_("Export all"),
|
||||||
5,
|
5,
|
||||||
"main-menu",
|
"main-menu",
|
||||||
CmbTutorPosition.LEFT,
|
CmbTutorPosition.LEFT,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
_("If you have any question, contact us on Matrix!"),
|
||||||
|
_("Contact"),
|
||||||
|
7,
|
||||||
|
None,
|
||||||
|
CmbTutorPosition.LEFT,
|
||||||
|
),
|
||||||
(
|
(
|
||||||
_("That is all for now.\nIf you find Cambalache useful please consider donating"),
|
_("That is all for now.\nIf you find Cambalache useful please consider donating"),
|
||||||
"donate",
|
_("Donate"),
|
||||||
7,
|
7,
|
||||||
"donate",
|
"donate",
|
||||||
CmbTutorPosition.LEFT,
|
CmbTutorPosition.LEFT,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# CmbWindow
|
# CmbWindow
|
||||||
#
|
#
|
||||||
# Copyright (C) 2021-2023 Juan Pablo Ugarte
|
# Copyright (C) 2021-2024 Juan Pablo Ugarte
|
||||||
#
|
#
|
||||||
# This library is free software; you can redistribute it and/or
|
# This library is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU Lesser General Public
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
@ -30,7 +30,7 @@ from gi.repository import GLib, GObject, Gio, Gdk, Gtk, Pango
|
|||||||
from .cmb_tutor import CmbTutor, CmbTutorState
|
from .cmb_tutor import CmbTutor, CmbTutorState
|
||||||
from . import cmb_tutorial
|
from . import cmb_tutorial
|
||||||
|
|
||||||
from cambalache import CmbProject, CmbUI, CmbCSS, CmbObject, CmbTypeChooserPopover, getLogger, config, _
|
from cambalache import CmbProject, CmbUI, CmbCSS, CmbObject, CmbTypeChooserPopover, getLogger, config, utils, _
|
||||||
|
|
||||||
logger = getLogger(__name__)
|
logger = getLogger(__name__)
|
||||||
|
|
||||||
@ -39,15 +39,17 @@ logger = getLogger(__name__)
|
|||||||
class CmbWindow(Gtk.ApplicationWindow):
|
class CmbWindow(Gtk.ApplicationWindow):
|
||||||
__gtype_name__ = "CmbWindow"
|
__gtype_name__ = "CmbWindow"
|
||||||
|
|
||||||
__gsignals__ = {"open-project": (GObject.SignalFlags.RUN_FIRST, None, (str, str, str))}
|
__gsignals__ = {
|
||||||
|
"open-project": (GObject.SignalFlags.RUN_FIRST, None, (str, str, str)),
|
||||||
|
"project-saved": (GObject.SignalFlags.RUN_FIRST, None, (CmbProject, ))
|
||||||
|
}
|
||||||
|
|
||||||
open_filter = Gtk.Template.Child()
|
open_filter = Gtk.Template.Child()
|
||||||
import_filter = Gtk.Template.Child()
|
import_filter = Gtk.Template.Child()
|
||||||
|
|
||||||
open_button_box = Gtk.Template.Child()
|
|
||||||
import_button_box = Gtk.Template.Child()
|
|
||||||
|
|
||||||
headerbar = Gtk.Template.Child()
|
headerbar = Gtk.Template.Child()
|
||||||
|
subtitle = Gtk.Template.Child()
|
||||||
|
recent_menu = Gtk.Template.Child()
|
||||||
undo_button = Gtk.Template.Child()
|
undo_button = Gtk.Template.Child()
|
||||||
redo_button = Gtk.Template.Child()
|
redo_button = Gtk.Template.Child()
|
||||||
stack = Gtk.Template.Child()
|
stack = Gtk.Template.Child()
|
||||||
@ -85,62 +87,83 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
|
|
||||||
# Tutor widgets
|
# Tutor widgets
|
||||||
intro_button = Gtk.Template.Child()
|
intro_button = Gtk.Template.Child()
|
||||||
main_menu = Gtk.Template.Child()
|
menu_button = Gtk.Template.Child()
|
||||||
export_all = Gtk.Template.Child()
|
|
||||||
|
|
||||||
# Settings
|
# Settings
|
||||||
completed_intro = GObject.Property(type=bool, default=False, flags=GObject.ParamFlags.READWRITE)
|
completed_intro = GObject.Property(type=bool, default=False, flags=GObject.ParamFlags.READWRITE)
|
||||||
|
|
||||||
|
MAXIMIZED = 1 << 2
|
||||||
|
FULLSCREEN = 1 << 4
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
self.__project = None
|
self.__project = None
|
||||||
self.__last_saved_index = None
|
self.__last_saved_index = None
|
||||||
|
self.__np_location = None
|
||||||
|
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
self.editor_stack.set_size_request(420, -1)
|
self.editor_stack.set_size_request(420, -1)
|
||||||
|
|
||||||
self.actions = {}
|
self.actions = {}
|
||||||
self.open_button_box.props.homogeneous = False
|
|
||||||
self.import_button_box.props.homogeneous = False
|
|
||||||
|
|
||||||
for action in [
|
for action in [
|
||||||
"open",
|
"about",
|
||||||
"create_new",
|
|
||||||
"new",
|
|
||||||
"undo",
|
|
||||||
"redo",
|
|
||||||
"intro",
|
|
||||||
"save",
|
|
||||||
"save_as",
|
|
||||||
"add_ui",
|
|
||||||
"add_css",
|
"add_css",
|
||||||
"copy",
|
|
||||||
"paste",
|
|
||||||
"cut",
|
|
||||||
"delete",
|
|
||||||
"add_object",
|
"add_object",
|
||||||
"add_object_toplevel",
|
"add_object_toplevel",
|
||||||
"clear",
|
|
||||||
"add_placeholder",
|
"add_placeholder",
|
||||||
"remove_placeholder",
|
|
||||||
"add_placeholder_row",
|
"add_placeholder_row",
|
||||||
"remove_placeholder_row",
|
"add_ui",
|
||||||
"import",
|
"clear",
|
||||||
"export",
|
|
||||||
"close",
|
"close",
|
||||||
"debug",
|
|
||||||
"show_workspace",
|
|
||||||
"donate",
|
|
||||||
"liberapay",
|
|
||||||
"patreon",
|
|
||||||
"contact",
|
"contact",
|
||||||
"about",
|
"copy",
|
||||||
|
"create_new",
|
||||||
|
"cut",
|
||||||
|
"debug",
|
||||||
|
"delete",
|
||||||
|
"donate",
|
||||||
|
"export",
|
||||||
|
"import",
|
||||||
|
"intro",
|
||||||
|
"liberapay",
|
||||||
|
"new",
|
||||||
|
"open",
|
||||||
|
"paste",
|
||||||
|
"patreon",
|
||||||
|
"redo",
|
||||||
|
"remove_placeholder",
|
||||||
|
"remove_placeholder_row",
|
||||||
|
"save",
|
||||||
|
"save_as",
|
||||||
|
"select_project_location",
|
||||||
|
"show_workspace",
|
||||||
|
"undo",
|
||||||
|
"workspace_restart",
|
||||||
|
"inspect"
|
||||||
]:
|
]:
|
||||||
gaction = Gio.SimpleAction.new(action, None)
|
gaction = Gio.SimpleAction.new(action, None)
|
||||||
gaction.connect("activate", getattr(self, f"_on_{action}_activate"))
|
gaction.connect("activate", getattr(self, f"_on_{action}_activate"))
|
||||||
self.actions[action] = gaction
|
self.actions[action] = gaction
|
||||||
self.add_action(gaction)
|
self.add_action(gaction)
|
||||||
|
|
||||||
|
# Stateful actions
|
||||||
|
for action, parameter_type, state in [
|
||||||
|
("open_recent", "s", None),
|
||||||
|
("workspace_theme", "s", "")
|
||||||
|
]:
|
||||||
|
if state is None:
|
||||||
|
gaction = Gio.SimpleAction.new(action, GLib.VariantType.new(parameter_type))
|
||||||
|
else:
|
||||||
|
gaction = Gio.SimpleAction.new_stateful(
|
||||||
|
action,
|
||||||
|
GLib.VariantType.new(parameter_type),
|
||||||
|
GLib.Variant(parameter_type, state)
|
||||||
|
)
|
||||||
|
gaction.connect("activate", getattr(self, f"_on_{action}_activate"))
|
||||||
|
self.actions[action] = gaction
|
||||||
|
self.add_action(gaction)
|
||||||
|
|
||||||
# Add global accelerators
|
# Add global accelerators
|
||||||
action_map = [
|
action_map = [
|
||||||
("win.save", ["<Primary>s"]),
|
("win.save", ["<Primary>s"]),
|
||||||
@ -205,7 +228,7 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.tutor = None
|
self.tutor = None
|
||||||
self.turor_waiting_for_user_action = False
|
self.tutor_waiting_for_user_action = False
|
||||||
|
|
||||||
self.__clipboard_enabled = True
|
self.__clipboard_enabled = True
|
||||||
self.__message_timeout_id = None
|
self.__message_timeout_id = None
|
||||||
@ -237,6 +260,14 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL,
|
GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.view.connect("notify::gtk-theme", self.__on_view_gtk_theme_notify)
|
||||||
|
self.connect("notify::focus-widget", self.__on_focus_widget_notify)
|
||||||
|
self.__update_recent_menu()
|
||||||
|
|
||||||
|
def __on_view_gtk_theme_notify(self, obj, pspec):
|
||||||
|
print("__on_view_gtk_theme_notify", obj.props.gtk_theme)
|
||||||
|
#self.actions["workspace_theme"].set_state(GLib.Variant("s", obj.props.gtk_theme))
|
||||||
|
|
||||||
@GObject.Property(type=CmbProject)
|
@GObject.Property(type=CmbProject)
|
||||||
def project(self):
|
def project(self):
|
||||||
return self.__project
|
return self.__project
|
||||||
@ -246,7 +277,6 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
if self.__project is not None:
|
if self.__project is not None:
|
||||||
self.__project.disconnect_by_func(self.__on_project_filename_notify)
|
self.__project.disconnect_by_func(self.__on_project_filename_notify)
|
||||||
self.__project.disconnect_by_func(self.__on_project_selection_changed)
|
self.__project.disconnect_by_func(self.__on_project_selection_changed)
|
||||||
self.__project.disconnect_by_func(self.__on_project_filename_required)
|
|
||||||
self.__project.disconnect_by_func(self.__on_project_changed)
|
self.__project.disconnect_by_func(self.__on_project_changed)
|
||||||
|
|
||||||
self.__project = project
|
self.__project = project
|
||||||
@ -267,10 +297,9 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
self.__on_project_filename_notify(None, None)
|
self.__on_project_filename_notify(None, None)
|
||||||
self.__project.connect("notify::filename", self.__on_project_filename_notify)
|
self.__project.connect("notify::filename", self.__on_project_filename_notify)
|
||||||
self.__project.connect("selection-changed", self.__on_project_selection_changed)
|
self.__project.connect("selection-changed", self.__on_project_selection_changed)
|
||||||
self.__project.connect("filename-required", self.__on_project_filename_required)
|
|
||||||
self.__project.connect("changed", self.__on_project_changed)
|
self.__project.connect("changed", self.__on_project_changed)
|
||||||
else:
|
else:
|
||||||
self.headerbar.set_subtitle(None)
|
self.subtitle.props.visible = False
|
||||||
|
|
||||||
self.__update_actions()
|
self.__update_actions()
|
||||||
|
|
||||||
@ -279,15 +308,9 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
path = self.project.filename.replace(GLib.get_home_dir(), "~")
|
path = self.project.filename.replace(GLib.get_home_dir(), "~")
|
||||||
else:
|
else:
|
||||||
path = _("Untitled")
|
path = _("Untitled")
|
||||||
self.headerbar.set_subtitle(path)
|
|
||||||
|
|
||||||
@Gtk.Template.Callback("on_about_dialog_delete_event")
|
self.subtitle.props.visible = True
|
||||||
def __on_about_dialog_delete_event(self, widget, event):
|
self.subtitle.props.label = path
|
||||||
return True
|
|
||||||
|
|
||||||
@Gtk.Template.Callback("on_about_dialog_response")
|
|
||||||
def __on_about_dialog_response(self, widget, response_id):
|
|
||||||
widget.hide()
|
|
||||||
|
|
||||||
@Gtk.Template.Callback("on_type_chooser_type_selected")
|
@Gtk.Template.Callback("on_type_chooser_type_selected")
|
||||||
def __on_type_chooser_type_selected(self, popover, info):
|
def __on_type_chooser_type_selected(self, popover, info):
|
||||||
@ -297,10 +320,10 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
if obj and type(obj) not in [CmbObject, CmbUI]:
|
if obj and type(obj) not in [CmbObject, CmbUI]:
|
||||||
return
|
return
|
||||||
|
|
||||||
valid, state = Gtk.get_current_event_state()
|
device = self.get_display().get_default_seat().get_keyboard()
|
||||||
|
|
||||||
# If alt is pressed, force adding object to selection
|
# If alt is pressed, force adding object to selection
|
||||||
if valid and bool(state & Gdk.ModifierType.MOD1_MASK):
|
if device and bool(device.props.modifier_state & Gdk.ModifierType.ALT_MASK):
|
||||||
if obj:
|
if obj:
|
||||||
parent_id = obj.object_id if isinstance(obj, CmbObject) else None
|
parent_id = obj.object_id if isinstance(obj, CmbObject) else None
|
||||||
self.project.add_object(obj.ui_id, info.type_id, None, parent_id)
|
self.project.add_object(obj.ui_id, info.type_id, None, parent_id)
|
||||||
@ -334,12 +357,9 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
|
|
||||||
@Gtk.Template.Callback("on_view_placeholder_activated")
|
@Gtk.Template.Callback("on_view_placeholder_activated")
|
||||||
def __on_view_placeholder_activated(self, view, ui_id, object_id, layout, position, child_type):
|
def __on_view_placeholder_activated(self, view, ui_id, object_id, layout, position, child_type):
|
||||||
r = Gdk.Rectangle()
|
|
||||||
r.x, r.y = self.view.get_pointer()
|
|
||||||
r.width = r.height = 4
|
|
||||||
|
|
||||||
obj = self.project.get_object_by_id(ui_id, object_id)
|
obj = self.project.get_object_by_id(ui_id, object_id)
|
||||||
popover = CmbTypeChooserPopover(relative_to=self.view, pointing_to=r, parent_type_id=obj.type_id)
|
popover = CmbTypeChooserPopover(pointing_to=utils.get_pointing_to(self.view), parent_type_id=obj.type_id)
|
||||||
|
popover.set_parent(self.view)
|
||||||
|
|
||||||
popover.project = self.project
|
popover.project = self.project
|
||||||
|
|
||||||
@ -349,13 +369,6 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
)
|
)
|
||||||
popover.popup()
|
popover.popup()
|
||||||
|
|
||||||
@Gtk.Template.Callback("on_open_recent_action_item_activated")
|
|
||||||
def __on_open_recent_action_item_activated(self, recent):
|
|
||||||
uri = recent.get_current_uri()
|
|
||||||
if uri is not None:
|
|
||||||
filename, host = GLib.filename_from_uri(uri)
|
|
||||||
self.emit("open-project", filename, None, None)
|
|
||||||
|
|
||||||
@Gtk.Template.Callback("on_ui_editor_remove_ui")
|
@Gtk.Template.Callback("on_ui_editor_remove_ui")
|
||||||
def __on_ui_editor_remove_ui(self, editor):
|
def __on_ui_editor_remove_ui(self, editor):
|
||||||
self.__remove_object_with_confirmation(editor.object)
|
self.__remove_object_with_confirmation(editor.object)
|
||||||
@ -366,9 +379,10 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
self.__remove_object_with_confirmation(editor.object)
|
self.__remove_object_with_confirmation(editor.object)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@Gtk.Template.Callback("on_window_set_focus")
|
def __on_focus_widget_notify(self, obj, pspec):
|
||||||
def __on_window_set_focus(self, window, widget):
|
widget = self.props.focus_widget
|
||||||
types = [Gtk.Entry, Gtk.TextView, Gtk.SpinButton]
|
|
||||||
|
types = [Gtk.Text, Gtk.TextView]
|
||||||
focused_widget_needs = True
|
focused_widget_needs = True
|
||||||
|
|
||||||
for type in types:
|
for type in types:
|
||||||
@ -413,16 +427,16 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
r, g, b = (linear(c.red), linear(c.green), linear(c.blue))
|
r, g, b = (linear(c.red), linear(c.green), linear(c.blue))
|
||||||
return 0.2126 * r + 0.7152 * g + 0.0722 * b
|
return 0.2126 * r + 0.7152 * g + 0.0722 * b
|
||||||
|
|
||||||
ctx = self.get_style_context()
|
|
||||||
|
|
||||||
# Get foreground color
|
# Get foreground color
|
||||||
fg = ctx.get_color(Gtk.StateFlags.NORMAL)
|
fg = self.get_color()
|
||||||
|
|
||||||
# If foreground luminance is closer to 1 then the background must be dark
|
# If foreground luminance is closer to 1 then the background must be dark
|
||||||
if luminance(fg) > 0.5:
|
if luminance(fg) > 0.5:
|
||||||
ctx.add_class("dark")
|
self.add_css_class("dark")
|
||||||
|
self.view._set_dark_mode(True)
|
||||||
else:
|
else:
|
||||||
ctx.remove_class("dark")
|
self.remove_css_class("dark")
|
||||||
|
self.view._set_dark_mode(False)
|
||||||
|
|
||||||
def __np_name_to_ui(self, binding, value):
|
def __np_name_to_ui(self, binding, value):
|
||||||
if len(value):
|
if len(value):
|
||||||
@ -549,20 +563,16 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
self.__update_action_undo_redo()
|
self.__update_action_undo_redo()
|
||||||
self.__update_action_add_object()
|
self.__update_action_add_object()
|
||||||
|
|
||||||
def __file_open_dialog_new(
|
def __file_open_dialog_new(self, title, filter_obj=None, accept_label=None):
|
||||||
self, title, action=Gtk.FileChooserAction.OPEN, filter_obj=None, select_multiple=False, accept_label=None
|
dialog = Gtk.FileDialog(
|
||||||
):
|
modal=True,
|
||||||
dialog = Gtk.FileChooserNative(
|
|
||||||
title=title,
|
title=title,
|
||||||
transient_for=self,
|
default_filter=filter_obj,
|
||||||
action=action,
|
|
||||||
filter=filter_obj,
|
|
||||||
select_multiple=select_multiple,
|
|
||||||
accept_label=accept_label,
|
accept_label=accept_label,
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.project and self.project.filename:
|
if self.project and self.project.filename:
|
||||||
dialog.set_current_folder(os.path.dirname(self.project.filename))
|
dialog.set_initial_folder(Gio.File.new_for_path(os.path.dirname(self.project.filename)))
|
||||||
|
|
||||||
return dialog
|
return dialog
|
||||||
|
|
||||||
@ -580,18 +590,21 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
def present_message_to_user(self, message, secondary_text=None, details=None):
|
def present_message_to_user(self, message, secondary_text=None, details=None):
|
||||||
dialog = Gtk.MessageDialog(
|
dialog = Gtk.MessageDialog(
|
||||||
transient_for=self,
|
transient_for=self,
|
||||||
flags=0,
|
|
||||||
message_type=Gtk.MessageType.INFO,
|
message_type=Gtk.MessageType.INFO,
|
||||||
buttons=Gtk.ButtonsType.OK,
|
buttons=Gtk.ButtonsType.OK,
|
||||||
text=message,
|
text=message,
|
||||||
secondary_text=secondary_text,
|
secondary_text=secondary_text,
|
||||||
|
modal=True
|
||||||
)
|
)
|
||||||
|
|
||||||
if details:
|
if details:
|
||||||
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=4)
|
box = Gtk.Box(
|
||||||
|
orientation=Gtk.Orientation.VERTICAL,
|
||||||
|
spacing=4
|
||||||
|
)
|
||||||
|
|
||||||
for detail in details:
|
for detail in details:
|
||||||
box.add(
|
box.append(
|
||||||
Gtk.Label(
|
Gtk.Label(
|
||||||
label=detail,
|
label=detail,
|
||||||
halign=Gtk.Align.START,
|
halign=Gtk.Align.START,
|
||||||
@ -602,12 +615,10 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
ellipsize=Pango.EllipsizeMode.END,
|
ellipsize=Pango.EllipsizeMode.END,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
dialog.props.message_area.append(box)
|
||||||
|
|
||||||
box.show_all()
|
dialog.connect("response", lambda d, r: dialog.destroy())
|
||||||
dialog.props.message_area.add(box)
|
dialog.present()
|
||||||
|
|
||||||
dialog.run()
|
|
||||||
dialog.destroy()
|
|
||||||
|
|
||||||
def import_file(self, filename):
|
def import_file(self, filename):
|
||||||
if self.project is None:
|
if self.project is None:
|
||||||
@ -688,25 +699,41 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def _on_open_activate(self, action, data):
|
def _on_open_activate(self, action, data):
|
||||||
dialog = self.__file_open_dialog_new(_("Choose project to open"), filter_obj=self.open_filter)
|
def dialog_callback(dialog, res):
|
||||||
if dialog.run() == Gtk.ResponseType.ACCEPT:
|
try:
|
||||||
self.emit("open-project", dialog.get_filename(), None, None)
|
file = dialog.open_finish(res)
|
||||||
|
self.emit("open-project", file.get_path(), None, None)
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
|
||||||
dialog.destroy()
|
dialog = self.__file_open_dialog_new(_("Choose project to open"), filter_obj=self.open_filter)
|
||||||
|
dialog.open(self, None, dialog_callback)
|
||||||
|
|
||||||
|
def _on_select_project_location_activate(self, action, data):
|
||||||
|
def dialog_callback(dialog, res):
|
||||||
|
try:
|
||||||
|
self.__np_location = dialog.select_folder_finish(res).get_path()
|
||||||
|
self.np_location_chooser.props.label = os.path.basename(self.__np_location)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
|
||||||
|
dialog = self.__file_open_dialog_new(_("Select project location"))
|
||||||
|
dialog.select_folder(self, None, dialog_callback)
|
||||||
|
|
||||||
def _on_create_new_activate(self, action, data):
|
def _on_create_new_activate(self, action, data):
|
||||||
self.__set_page("new_project")
|
self.__set_page("new_project")
|
||||||
self.set_focus(self.np_name_entry)
|
self.set_focus(self.np_name_entry)
|
||||||
|
|
||||||
home = GLib.get_home_dir()
|
if self.__np_location is None:
|
||||||
projects = os.path.join(home, "Projects")
|
home = GLib.get_home_dir()
|
||||||
directory = projects if os.path.isdir(projects) else home
|
projects = os.path.join(home, "Projects")
|
||||||
|
self.__np_location = projects if os.path.isdir(projects) else home
|
||||||
|
|
||||||
self.np_location_chooser.set_current_folder(directory)
|
self.np_location_chooser.props.label = os.path.basename(self.__np_location)
|
||||||
|
|
||||||
def _on_new_activate(self, action, data):
|
def _on_new_activate(self, action, data):
|
||||||
name = self.np_name_entry.props.text
|
name = self.np_name_entry.props.text
|
||||||
location = self.np_location_chooser.get_filename() or "."
|
|
||||||
uiname = self.np_ui_entry.props.text
|
uiname = self.np_ui_entry.props.text
|
||||||
filename = None
|
filename = None
|
||||||
uipath = None
|
uipath = None
|
||||||
@ -718,7 +745,7 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
|
|
||||||
if len(name):
|
if len(name):
|
||||||
name, ext = os.path.splitext(name)
|
name, ext = os.path.splitext(name)
|
||||||
filename = os.path.join(location, name + ".cmb")
|
filename = os.path.join(self.__np_location, name + ".cmb")
|
||||||
|
|
||||||
if len(uiname) == 0:
|
if len(uiname) == 0:
|
||||||
uiname = self.np_ui_entry.props.placeholder_text
|
uiname = self.np_ui_entry.props.placeholder_text
|
||||||
@ -728,7 +755,7 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
self.set_focus(self.np_name_entry)
|
self.set_focus(self.np_name_entry)
|
||||||
return
|
return
|
||||||
|
|
||||||
uipath = os.path.join(location, uiname)
|
uipath = os.path.join(self.__np_location, uiname)
|
||||||
|
|
||||||
self.emit("open-project", filename, target_tk, uipath)
|
self.emit("open-project", filename, target_tk, uipath)
|
||||||
self.__set_page("workspace" if self.project is not None else "cambalache")
|
self.__set_page("workspace" if self.project is not None else "cambalache")
|
||||||
@ -743,30 +770,23 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
self.project.redo()
|
self.project.redo()
|
||||||
self.__update_action_undo_redo()
|
self.__update_action_undo_redo()
|
||||||
|
|
||||||
def __on_project_filename_required(self, project):
|
|
||||||
filename = None
|
|
||||||
|
|
||||||
if project.filename is None:
|
|
||||||
dialog = self.__file_open_dialog_new(_("Choose a file to save the project"), Gtk.FileChooserAction.SAVE)
|
|
||||||
if dialog.run() == Gtk.ResponseType.ACCEPT:
|
|
||||||
filename = dialog.get_filename()
|
|
||||||
dialog.destroy()
|
|
||||||
|
|
||||||
return filename
|
|
||||||
|
|
||||||
def _on_save_activate(self, action, data):
|
def _on_save_activate(self, action, data):
|
||||||
self.__save_project()
|
self.save_project()
|
||||||
|
|
||||||
|
def __save_dialog_callback(self, dialog, res):
|
||||||
|
try:
|
||||||
|
file = dialog.save_finish(res)
|
||||||
|
self.project.filename = file.get_path()
|
||||||
|
self.__save()
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
|
||||||
def _on_save_as_activate(self, action, data):
|
def _on_save_as_activate(self, action, data):
|
||||||
if self.project is None:
|
if self.project is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
dialog = self.__file_open_dialog_new(_("Choose a new file to save the project"), Gtk.FileChooserAction.SAVE)
|
dialog = self.__file_open_dialog_new(_("Choose a new file to save the project"))
|
||||||
if dialog.run() == Gtk.ResponseType.ACCEPT:
|
dialog.save(self, None, self.__save_dialog_callback)
|
||||||
self.project.filename = dialog.get_filename()
|
|
||||||
self.__save_project()
|
|
||||||
|
|
||||||
dialog.destroy()
|
|
||||||
|
|
||||||
def _on_add_ui_activate(self, action, data):
|
def _on_add_ui_activate(self, action, data):
|
||||||
if self.project is None:
|
if self.project is None:
|
||||||
@ -785,19 +805,23 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
def __remove_object_with_confirmation(self, obj):
|
def __remove_object_with_confirmation(self, obj):
|
||||||
dialog = Gtk.MessageDialog(
|
dialog = Gtk.MessageDialog(
|
||||||
transient_for=self,
|
transient_for=self,
|
||||||
flags=0,
|
modal=True,
|
||||||
message_type=Gtk.MessageType.QUESTION,
|
message_type=Gtk.MessageType.QUESTION,
|
||||||
buttons=Gtk.ButtonsType.YES_NO,
|
buttons=Gtk.ButtonsType.YES_NO,
|
||||||
text=_("Do you really want to remove {name}?").format(name=obj.get_display_name()),
|
text=_("Do you really want to remove {name}?").format(name=obj.get_display_name()),
|
||||||
)
|
)
|
||||||
|
|
||||||
if dialog.run() == Gtk.ResponseType.YES:
|
def on_dialog_response(dialog, response):
|
||||||
if type(obj) == CmbUI:
|
if response == Gtk.ResponseType.YES:
|
||||||
self.project.remove_ui(obj)
|
if type(obj) == CmbUI:
|
||||||
elif type(obj) == CmbCSS:
|
self.project.remove_ui(obj)
|
||||||
self.project.remove_css(obj)
|
elif type(obj) == CmbCSS:
|
||||||
|
self.project.remove_css(obj)
|
||||||
|
|
||||||
dialog.destroy()
|
dialog.destroy()
|
||||||
|
|
||||||
|
dialog.connect("response", on_dialog_response)
|
||||||
|
dialog.present()
|
||||||
|
|
||||||
def _on_copy_activate(self, action, data):
|
def _on_copy_activate(self, action, data):
|
||||||
if self.project:
|
if self.project:
|
||||||
@ -891,30 +915,43 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
if self.project is None:
|
if self.project is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def dialog_callback(dialog, res):
|
||||||
|
try:
|
||||||
|
for file in dialog.open_multiple_finish(res):
|
||||||
|
self.import_file(file.get_path())
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
|
||||||
dialog = self.__file_open_dialog_new(
|
dialog = self.__file_open_dialog_new(
|
||||||
_("Choose file to import"), filter_obj=self.import_filter, select_multiple=True, accept_label=_("Import")
|
_("Choose file to import"), filter_obj=self.import_filter, accept_label=_("Import")
|
||||||
)
|
)
|
||||||
|
dialog.open_multiple(self, None, dialog_callback)
|
||||||
|
|
||||||
if dialog.run() == Gtk.ResponseType.ACCEPT:
|
def __save(self):
|
||||||
filenames = dialog.get_filenames()
|
if self.project.save():
|
||||||
dialog.destroy()
|
self.__last_saved_index = self.project.history_index
|
||||||
|
self.__update_action_save()
|
||||||
|
self.emit("project-saved", self.project)
|
||||||
|
|
||||||
for filename in filenames:
|
def save_project(self):
|
||||||
self.import_file(filename)
|
if self.project is None:
|
||||||
else:
|
return False
|
||||||
dialog.destroy()
|
|
||||||
|
|
||||||
def __save_project(self):
|
if self.project.filename is None:
|
||||||
if self.project is not None:
|
dialog = self.__file_open_dialog_new(_("Choose a file to save the project"))
|
||||||
if self.project.save():
|
dialog.save(self, None, self.__save_dialog_callback)
|
||||||
self.__last_saved_index = self.project.history_index
|
return True
|
||||||
self.__update_action_save()
|
|
||||||
|
# Save project and update last saved index
|
||||||
|
self.__save()
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def _on_export_activate(self, action, data):
|
def _on_export_activate(self, action, data):
|
||||||
if self.project is None:
|
if self.project is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.__save_project()
|
self.save_project()
|
||||||
|
|
||||||
n = self.project.export()
|
n = self.project.export()
|
||||||
|
|
||||||
@ -931,7 +968,7 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
fd, filename = tempfile.mkstemp(".db", "cmb")
|
fd, filename = tempfile.mkstemp(".db", "cmb")
|
||||||
|
|
||||||
self.project.db_move_to_fs(filename)
|
self.project.db_move_to_fs(filename)
|
||||||
Gtk.show_uri_on_window(self, f"file://{filename}", Gdk.CURRENT_TIME)
|
Gtk.show_uri(self, f"file://{filename}", Gdk.CURRENT_TIME)
|
||||||
|
|
||||||
def _on_about_activate(self, action, data):
|
def _on_about_activate(self, action, data):
|
||||||
self.about_dialog.present()
|
self.about_dialog.present()
|
||||||
@ -940,13 +977,13 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
self.__set_page("donate")
|
self.__set_page("donate")
|
||||||
|
|
||||||
def _on_liberapay_activate(self, action, data):
|
def _on_liberapay_activate(self, action, data):
|
||||||
Gtk.show_uri_on_window(self, "https://liberapay.com/xjuan/donate", Gdk.CURRENT_TIME)
|
Gtk.show_uri(self, "https://liberapay.com/xjuan/donate", Gdk.CURRENT_TIME)
|
||||||
|
|
||||||
def _on_patreon_activate(self, action, data):
|
def _on_patreon_activate(self, action, data):
|
||||||
Gtk.show_uri_on_window(self, "https://www.patreon.com/cambalache", Gdk.CURRENT_TIME)
|
Gtk.show_uri(self, "https://www.patreon.com/cambalache", Gdk.CURRENT_TIME)
|
||||||
|
|
||||||
def _on_contact_activate(self, action, data):
|
def _on_contact_activate(self, action, data):
|
||||||
Gtk.show_uri_on_window(self, "https://matrix.to/#/#cambalache:gnome.org", Gdk.CURRENT_TIME)
|
Gtk.show_uri(self, "https://matrix.to/#/#cambalache:gnome.org", Gdk.CURRENT_TIME)
|
||||||
|
|
||||||
def _on_add_placeholder_activate(self, action, data):
|
def _on_add_placeholder_activate(self, action, data):
|
||||||
self.view.add_placeholder()
|
self.view.add_placeholder()
|
||||||
@ -974,18 +1011,18 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
|
|
||||||
def __on_project_notify(self, obj, pspec):
|
def __on_project_notify(self, obj, pspec):
|
||||||
if self.project:
|
if self.project:
|
||||||
self.turor_waiting_for_user_action = False
|
self.tutor_waiting_for_user_action = False
|
||||||
self.tutor.play()
|
self.tutor.play()
|
||||||
self.disconnect_by_func(self.__on_project_notify)
|
self.disconnect_by_func(self.__on_project_notify)
|
||||||
|
|
||||||
def __on_object_added(self, project, obj, data):
|
def __on_object_added(self, project, obj, data):
|
||||||
if obj.info.is_a(data):
|
if obj.info.is_a(data):
|
||||||
project.disconnect_by_func(self.__on_object_added)
|
project.disconnect_by_func(self.__on_object_added)
|
||||||
self.turor_waiting_for_user_action = False
|
self.tutor_waiting_for_user_action = False
|
||||||
self.tutor.play()
|
self.tutor.play()
|
||||||
|
|
||||||
def __on_ui_added(self, project, ui):
|
def __on_ui_added(self, project, ui):
|
||||||
self.turor_waiting_for_user_action = False
|
self.tutor_waiting_for_user_action = False
|
||||||
project.disconnect_by_func(self.__on_ui_added)
|
project.disconnect_by_func(self.__on_ui_added)
|
||||||
self.tutor.play()
|
self.tutor.play()
|
||||||
|
|
||||||
@ -1001,14 +1038,12 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
self.project.connect("object-added", self.__on_object_added, "GtkGrid")
|
self.project.connect("object-added", self.__on_object_added, "GtkGrid")
|
||||||
elif node == "add-button":
|
elif node == "add-button":
|
||||||
self.project.connect("object-added", self.__on_object_added, "GtkButton")
|
self.project.connect("object-added", self.__on_object_added, "GtkButton")
|
||||||
elif node == "main-menu":
|
elif node in ["menu_button", "main-menu"]:
|
||||||
self.main_menu.props.modal = False
|
self.menu_button.popup()
|
||||||
elif node == "show-type-popover":
|
elif node == "show-type-popover":
|
||||||
widget.props.popover.modal = False
|
|
||||||
widget.props.popover.popup()
|
widget.props.popover.popup()
|
||||||
elif node == "show-type-popover-gtk":
|
elif node == "show-type-popover-gtk":
|
||||||
child = widget.get_children()[0]
|
child = utils.widget_get_children(widget)[0]
|
||||||
child.props.popover.props.modal = False
|
|
||||||
child.props.popover.popup()
|
child.props.popover.popup()
|
||||||
|
|
||||||
def __on_tutor_hide_node(self, tutor, node, widget):
|
def __on_tutor_hide_node(self, tutor, node, widget):
|
||||||
@ -1017,28 +1052,23 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
self.__clear_tutor()
|
self.__clear_tutor()
|
||||||
elif node == "add-project":
|
elif node == "add-project":
|
||||||
if self.__project is None:
|
if self.__project is None:
|
||||||
self.turor_waiting_for_user_action = True
|
self.tutor_waiting_for_user_action = True
|
||||||
self.tutor.pause()
|
self.tutor.pause()
|
||||||
elif node in ["add-ui", "add-window", "add-grid", "add-button"]:
|
elif node in ["add-ui", "add-window", "add-grid", "add-button"]:
|
||||||
self.turor_waiting_for_user_action = True
|
self.tutor_waiting_for_user_action = True
|
||||||
self.tutor.pause()
|
self.tutor.pause()
|
||||||
elif node == "main-menu":
|
elif node in ["menu_button", "donate"]:
|
||||||
self.export_all.get_style_context().remove_class("cmb-tutor-highlight")
|
self.menu_button.popdown()
|
||||||
elif node == "donate":
|
|
||||||
self.main_menu.props.modal = True
|
|
||||||
self.main_menu.popdown()
|
|
||||||
elif node == "show-type-popover":
|
elif node == "show-type-popover":
|
||||||
widget.props.popover.modal = True
|
|
||||||
widget.props.popover.popdown()
|
widget.props.popover.popdown()
|
||||||
elif node == "show-type-popover-gtk":
|
elif node == "show-type-popover-gtk":
|
||||||
child = widget.get_children()[0]
|
child = utils.widget_get_children(widget)[0]
|
||||||
child.props.popover.props.modal = True
|
|
||||||
child.props.popover.popdown()
|
child.props.popover.popdown()
|
||||||
|
|
||||||
self.__update_actions()
|
self.__update_actions()
|
||||||
|
|
||||||
def _on_intro_activate(self, action, data):
|
def _on_intro_activate(self, action, data):
|
||||||
if self.turor_waiting_for_user_action:
|
if self.tutor_waiting_for_user_action:
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.tutor:
|
if self.tutor:
|
||||||
@ -1058,28 +1088,69 @@ class CmbWindow(Gtk.ApplicationWindow):
|
|||||||
self.tutor.connect("hide-node", self.__on_tutor_hide_node)
|
self.tutor.connect("hide-node", self.__on_tutor_hide_node)
|
||||||
self.tutor.play()
|
self.tutor.play()
|
||||||
|
|
||||||
|
def _on_workspace_restart_activate(self, action, data):
|
||||||
|
self.view.restart_workspace()
|
||||||
|
|
||||||
|
def _on_workspace_theme_activate(self, action, data):
|
||||||
|
self.view.props.gtk_theme = data.get_string()
|
||||||
|
action.set_state(data)
|
||||||
|
|
||||||
|
def _on_inspect_activate(self, action, data):
|
||||||
|
self.view.inspect()
|
||||||
|
|
||||||
|
def _on_open_recent_activate(self, action, data):
|
||||||
|
self.emit("open-project", data.get_string(), None, None)
|
||||||
|
|
||||||
|
def __update_recent_menu(self):
|
||||||
|
manager = Gtk.RecentManager.get_default()
|
||||||
|
|
||||||
|
mime_types = [
|
||||||
|
"application/x-cambalache-project"
|
||||||
|
]
|
||||||
|
|
||||||
|
for recent in manager.get_items():
|
||||||
|
if recent.get_mime_type() not in mime_types:
|
||||||
|
continue
|
||||||
|
|
||||||
|
filename, host = GLib.filename_from_uri(recent.get_uri())
|
||||||
|
if not os.path.exists(filename):
|
||||||
|
continue
|
||||||
|
|
||||||
|
item = Gio.MenuItem()
|
||||||
|
item.set_label(recent.get_display_name())
|
||||||
|
item.set_action_and_target_value("win.open_recent", GLib.Variant("s", filename))
|
||||||
|
self.recent_menu.append_item(item)
|
||||||
|
|
||||||
def __load_window_state(self):
|
def __load_window_state(self):
|
||||||
state = self.window_settings.get_uint("state")
|
state = self.window_settings.get_uint("state")
|
||||||
|
|
||||||
if state & Gdk.WindowState.MAXIMIZED:
|
if state & self.MAXIMIZED:
|
||||||
self.maximize()
|
self.maximize()
|
||||||
|
elif state & self.FULLSCREEN:
|
||||||
|
self.fullscreen()
|
||||||
else:
|
else:
|
||||||
size = self.window_settings.get_value("size").unpack()
|
size = self.window_settings.get_value("size").unpack()
|
||||||
self.set_default_size(*size)
|
self.set_default_size(*size)
|
||||||
|
|
||||||
def __save_window_state(self):
|
def __save_window_state(self):
|
||||||
state = self.props.window.get_state()
|
fullscreen = self.props.fullscreened
|
||||||
|
maximized = self.props.maximized
|
||||||
|
state = 0
|
||||||
|
|
||||||
fullscreen = state & Gdk.WindowState.FULLSCREEN
|
if fullscreen:
|
||||||
maximized = state & Gdk.WindowState.MAXIMIZED
|
state = state | self.FULLSCREEN
|
||||||
|
|
||||||
|
if maximized:
|
||||||
|
state = state | self.MAXIMIZED
|
||||||
|
|
||||||
|
# Maintain compatibility with Gtk 3 state
|
||||||
self.window_settings.set_uint("state", state)
|
self.window_settings.set_uint("state", state)
|
||||||
|
|
||||||
size = (0, 0) if fullscreen or maximized else self.get_size()
|
size = (0, 0) if fullscreen or maximized else (self.props.default_width, self.props.default_height)
|
||||||
|
|
||||||
self.window_settings.set_value("size", GLib.Variant("(ii)", size))
|
self.window_settings.set_value("size", GLib.Variant("(ii)", size))
|
||||||
|
|
||||||
def do_delete_event(self, event):
|
def do_close_request(self):
|
||||||
self.__save_window_state()
|
self.__save_window_state()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# CmbContextMenu - Cambalache UI Editor
|
# CmbContextMenu - Cambalache UI Editor
|
||||||
#
|
#
|
||||||
# Copyright (C) 2021 Juan Pablo Ugarte
|
# Copyright (C) 2021-2024 Juan Pablo Ugarte
|
||||||
#
|
#
|
||||||
# This library is free software; you can redistribute it and/or
|
# This library is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU Lesser General Public
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from gi.repository import GObject, GLib, Gdk, Gtk
|
from gi.repository import GObject, GLib, Gio, Gdk, Gtk
|
||||||
from cambalache import _
|
from cambalache import _
|
||||||
|
|
||||||
|
|
||||||
@ -31,23 +31,17 @@ from cambalache import _
|
|||||||
class CmbContextMenu(Gtk.PopoverMenu):
|
class CmbContextMenu(Gtk.PopoverMenu):
|
||||||
__gtype_name__ = "CmbContextMenu"
|
__gtype_name__ = "CmbContextMenu"
|
||||||
|
|
||||||
gtk_theme = GObject.Property(type=str, flags=GObject.ParamFlags.READWRITE)
|
|
||||||
target_tk = GObject.Property(type=str, flags=GObject.ParamFlags.READWRITE)
|
target_tk = GObject.Property(type=str, flags=GObject.ParamFlags.READWRITE)
|
||||||
|
|
||||||
main_box = Gtk.Template.Child()
|
main_section = Gtk.Template.Child()
|
||||||
separator = Gtk.Template.Child()
|
|
||||||
css_theme = Gtk.Template.Child()
|
|
||||||
css_theme_box = Gtk.Template.Child()
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
|
self.theme_submenu = None
|
||||||
|
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
self.connect("notify::target-tk", lambda o, p: self.__populate_css_theme_box())
|
self.connect("notify::target-tk", lambda o, p: self.__populate_css_theme_box())
|
||||||
|
|
||||||
def __on_css_theme_button_toggled(self, button, data):
|
|
||||||
if button.props.active:
|
|
||||||
self.gtk_theme = data
|
|
||||||
|
|
||||||
def __populate_css_theme_box(self):
|
def __populate_css_theme_box(self):
|
||||||
gtk_path = "gtk-3.0"
|
gtk_path = "gtk-3.0"
|
||||||
|
|
||||||
@ -56,9 +50,17 @@ class CmbContextMenu(Gtk.PopoverMenu):
|
|||||||
|
|
||||||
if self.target_tk == "gtk-4.0":
|
if self.target_tk == "gtk-4.0":
|
||||||
gtk_path = "gtk-4.0"
|
gtk_path = "gtk-4.0"
|
||||||
|
# FIXME: whats the real default theme for gtk4?
|
||||||
|
themes = ["Default"]
|
||||||
|
else:
|
||||||
|
themes = ["Adwaita", "HighContrast", "HighContrastInverse"]
|
||||||
|
|
||||||
for child in self.css_theme_box.get_children():
|
if self.theme_submenu is None:
|
||||||
self.css_theme_box.remove(child)
|
self.theme_submenu = Gio.Menu()
|
||||||
|
self.main_section.prepend_submenu(_("CSS theme"), self.theme_submenu)
|
||||||
|
|
||||||
|
# Remove all items from theme submenu
|
||||||
|
self.theme_submenu.remove_all()
|
||||||
|
|
||||||
dirs = []
|
dirs = []
|
||||||
|
|
||||||
@ -71,9 +73,6 @@ class CmbContextMenu(Gtk.PopoverMenu):
|
|||||||
# Append ~/.themes
|
# Append ~/.themes
|
||||||
dirs.append(os.path.join(GLib.get_home_dir(), ".themes"))
|
dirs.append(os.path.join(GLib.get_home_dir(), ".themes"))
|
||||||
|
|
||||||
# Default themes
|
|
||||||
themes = ["Adwaita", "HighContrast", "HighContrastInverse"]
|
|
||||||
|
|
||||||
for path in dirs:
|
for path in dirs:
|
||||||
if not os.path.isdir(path):
|
if not os.path.isdir(path):
|
||||||
continue
|
continue
|
||||||
@ -86,23 +85,16 @@ class CmbContextMenu(Gtk.PopoverMenu):
|
|||||||
# Dedup and sort
|
# Dedup and sort
|
||||||
themes = list(dict.fromkeys(themes))
|
themes = list(dict.fromkeys(themes))
|
||||||
|
|
||||||
# Add back item
|
|
||||||
button = Gtk.ModelButton(text=_("CSS themes"), menu_name="main", inverted=True, centered=True, visible=True)
|
|
||||||
self.css_theme_box.add(button)
|
|
||||||
|
|
||||||
group = None
|
group = None
|
||||||
for theme in sorted(themes):
|
for theme in sorted(themes):
|
||||||
button = Gtk.RadioButton(label=theme, group=group, active=self.gtk_theme == theme, visible=True)
|
item = Gio.MenuItem()
|
||||||
if group is None:
|
item.set_label(theme)
|
||||||
group = button
|
item.set_action_and_target_value("win.workspace_theme", GLib.Variant("s", theme))
|
||||||
|
self.theme_submenu.append_item(item)
|
||||||
button.connect("toggled", self.__on_css_theme_button_toggled, theme)
|
|
||||||
self.css_theme_box.add(button)
|
|
||||||
|
|
||||||
self.separator.props.visible = self.css_theme.props.visible = len(themes) > 0
|
|
||||||
|
|
||||||
def popup_at(self, x, y):
|
def popup_at(self, x, y):
|
||||||
r = Gdk.Rectangle()
|
r = Gdk.Rectangle()
|
||||||
r.x, r.y, r.width, r.height = (x, y, 10, 10)
|
r.x, r.y = (x, y)
|
||||||
|
r.width = r.height = 0
|
||||||
self.set_pointing_to(r)
|
self.set_pointing_to(r)
|
||||||
self.popup()
|
self.popup()
|
||||||
|
@ -1,182 +1,46 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Generated with glade 3.38.2 -->
|
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.24"/>
|
<requires lib="gtk" version="4.0"/>
|
||||||
|
<menu id="menu_model">
|
||||||
|
<section>
|
||||||
|
<item>
|
||||||
|
<attribute name="action">win.cut</attribute>
|
||||||
|
<attribute name="label" translatable="1">Cut</attribute>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<attribute name="action">win.copy</attribute>
|
||||||
|
<attribute name="label" translatable="1">Copy</attribute>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<attribute name="action">win.paste</attribute>
|
||||||
|
<attribute name="label" translatable="1">Paste</attribute>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<attribute name="action">win.delete</attribute>
|
||||||
|
<attribute name="label" translatable="1">Delete</attribute>
|
||||||
|
</item>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<item>
|
||||||
|
<attribute name="action">win.add_object</attribute>
|
||||||
|
<attribute name="label" translatable="1">Add object here</attribute>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<attribute name="action">win.add_object_toplevel</attribute>
|
||||||
|
<attribute name="label" translatable="1">Add object as toplevel</attribute>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<attribute name="action">win.clear</attribute>
|
||||||
|
<attribute name="label" translatable="1">Clear Properties</attribute>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<attribute name="action">win.documentation</attribute>
|
||||||
|
<attribute name="label" translatable="1">Read Documentation</attribute>
|
||||||
|
</item>
|
||||||
|
</section>
|
||||||
|
<section id="main_section"/>
|
||||||
|
</menu>
|
||||||
<template class="CmbContextMenu" parent="GtkPopoverMenu">
|
<template class="CmbContextMenu" parent="GtkPopoverMenu">
|
||||||
<property name="can-focus">False</property>
|
<property name="menu-model">menu_model</property>
|
||||||
<child>
|
|
||||||
<object class="GtkBox" id="main_box">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="border-width">4</property>
|
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<property name="spacing">2</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkModelButton">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="receives-default">True</property>
|
|
||||||
<property name="action-name">win.cut</property>
|
|
||||||
<property name="text" translatable="yes">Cut</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkModelButton">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="receives-default">True</property>
|
|
||||||
<property name="action-name">win.copy</property>
|
|
||||||
<property name="text" translatable="yes">Copy</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkModelButton">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="receives-default">True</property>
|
|
||||||
<property name="action-name">win.paste</property>
|
|
||||||
<property name="text" translatable="yes">Paste</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkModelButton">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="receives-default">True</property>
|
|
||||||
<property name="action-name">win.delete</property>
|
|
||||||
<property name="text" translatable="yes">Delete</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">3</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkSeparator">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">4</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkModelButton">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="receives-default">True</property>
|
|
||||||
<property name="action-name">win.add_object</property>
|
|
||||||
<property name="text" translatable="yes">Add object here</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">5</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkModelButton">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="receives-default">True</property>
|
|
||||||
<property name="action-name">win.add_object_toplevel</property>
|
|
||||||
<property name="text" translatable="yes">Add object as toplevel</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">6</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkModelButton">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="receives-default">True</property>
|
|
||||||
<property name="action-name">win.clear</property>
|
|
||||||
<property name="text" translatable="yes">Clear Properties</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">7</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkModelButton">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="receives-default">True</property>
|
|
||||||
<property name="action-name">win.documentation</property>
|
|
||||||
<property name="text" translatable="yes">Read Documentation</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">8</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkSeparator" id="separator">
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">9</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkModelButton" id="css_theme">
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="receives-default">True</property>
|
|
||||||
<property name="text" translatable="yes">CSS theme</property>
|
|
||||||
<property name="menu-name">css-theme</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">10</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="submenu">main</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkBox" id="css_theme_box">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="border-width">4</property>
|
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<property name="spacing">2</property>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="submenu">css-theme</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</template>
|
</template>
|
||||||
</interface>
|
</interface>
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
from gi.repository import GObject, Gtk
|
from gi.repository import GObject, Gtk
|
||||||
from .cmb_css import CmbCSS
|
from .cmb_css import CmbCSS
|
||||||
|
from . import utils
|
||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/ar/xjuan/Cambalache/cmb_css_editor.ui")
|
@Gtk.Template(resource_path="/ar/xjuan/Cambalache/cmb_css_editor.ui")
|
||||||
@ -121,8 +122,7 @@ class CmbCSSEditor(Gtk.Grid):
|
|||||||
|
|
||||||
def __update_provider_for(self):
|
def __update_provider_for(self):
|
||||||
# Remove all css_ui check buttons
|
# Remove all css_ui check buttons
|
||||||
ui_box_children = self.ui_box.get_children()
|
for child in utils.widget_get_children(self.ui_box):
|
||||||
for child in ui_box_children:
|
|
||||||
self.ui_box.remove(child)
|
self.ui_box.remove(child)
|
||||||
|
|
||||||
if self._object is None:
|
if self._object is None:
|
||||||
@ -137,7 +137,7 @@ class CmbCSSEditor(Gtk.Grid):
|
|||||||
label=ui.get_display_name(), active=ui.ui_id in provider_for, halign=Gtk.Align.START, visible=True
|
label=ui.get_display_name(), active=ui.ui_id in provider_for, halign=Gtk.Align.START, visible=True
|
||||||
)
|
)
|
||||||
check.connect("toggled", self.__on_check_button_toggled, ui)
|
check.connect("toggled", self.__on_check_button_toggled, ui)
|
||||||
self.ui_box.add(check)
|
self.ui_box.append(check)
|
||||||
|
|
||||||
def __on_file_changed(self, obj):
|
def __on_file_changed(self, obj):
|
||||||
self.infobar.set_revealed(True)
|
self.infobar.set_revealed(True)
|
||||||
|
@ -1,89 +1,74 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Generated with glade 3.38.2 -->
|
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.24"/>
|
<requires lib="gtk" version="4.0"/>
|
||||||
<requires lib="gladecambalache" version="0.0"/>
|
|
||||||
<!-- n-columns=2 n-rows=6 -->
|
|
||||||
<template class="CmbCSSEditor" parent="GtkGrid">
|
<template class="CmbCSSEditor" parent="GtkGrid">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="row-spacing">4</property>
|
<property name="row-spacing">4</property>
|
||||||
<property name="column-spacing">3</property>
|
<property name="column-spacing">3</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="label" translatable="yes">Filename:</property>
|
<property name="label" translatable="1">Filename:</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">0</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="label" translatable="yes">Priority:</property>
|
<property name="label" translatable="1">Priority:</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">1</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
<property name="tooltip-text" translatable="1">This provider will be used in all UI.</property>
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="tooltip-text" translatable="yes">This provider will be used in all UI.</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="label" translatable="yes">Global:</property>
|
<property name="label" translatable="1">Global:</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">2</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="CmbEntry" id="filename">
|
<object class="CmbEntry" id="filename">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="can-focus">True</property>
|
||||||
<property name="hexpand">True</property>
|
<property name="hexpand">True</property>
|
||||||
<property name="placeholder-text" translatable="yes"><file name relative to project></property>
|
<property name="placeholder-text" translatable="1"><file name relative to project></property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">0</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkSpinButton" id="priority">
|
<object class="GtkSpinButton" id="priority">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">1</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkSwitch" id="is_global">
|
<object class="GtkSwitch" id="is_global">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">2</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="ui_box">
|
<object class="GtkBox" id="ui_box">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
<child>
|
<child>
|
||||||
<placeholder/>
|
<placeholder/>
|
||||||
@ -94,189 +79,116 @@
|
|||||||
<child>
|
<child>
|
||||||
<placeholder/>
|
<placeholder/>
|
||||||
</child>
|
</child>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">3</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">3</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
<property name="tooltip-text" translatable="1">List of UI where this provider will be used</property>
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="tooltip-text" translatable="yes">List of UI where this provider will be used</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="valign">start</property>
|
<property name="valign">start</property>
|
||||||
<property name="label" translatable="yes">Provider for:</property>
|
<property name="label" translatable="1">Provider for:</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">3</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">3</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="spacing">4</property>
|
<property name="spacing">4</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="remove_button">
|
<object class="GtkButton" id="remove_button">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
<!-- <property name="receives-default">1</property> -->
|
||||||
<property name="receives-default">True</property>
|
<!-- <property name="tooltip-text" translatable="1">Remove CSS file from project</property> -->
|
||||||
<property name="tooltip-text" translatable="yes">Remove CSS file from project</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="valign">end</property>
|
<property name="valign">end</property>
|
||||||
<signal name="clicked" handler="on_remove_button_clicked" swapped="no"/>
|
<signal name="clicked" handler="on_remove_button_clicked" swapped="no"/>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="icon-name">app-remove-symbolic</property>
|
<property name="icon-name">app-remove-symbolic</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">center</property>
|
<property name="halign">center</property>
|
||||||
<property name="valign">center</property>
|
<property name="valign">center</property>
|
||||||
<property name="label" translatable="yes"><small>Note: CSS files need to be loaded at runtime</small></property>
|
<property name="label" translatable="1"><small>Note: CSS files need to be loaded at runtime</small></property>
|
||||||
<property name="use-markup">True</property>
|
<property name="use-markup">1</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="save_button">
|
<object class="GtkButton" id="save_button">
|
||||||
<property name="visible">True</property>
|
<property name="sensitive">0</property>
|
||||||
<property name="sensitive">False</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="receives-default">1</property>
|
||||||
<property name="receives-default">True</property>
|
<property name="tooltip-text" translatable="1">Save CSS file</property>
|
||||||
<property name="tooltip-text" translatable="yes">Save CSS file</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="valign">end</property>
|
<property name="valign">end</property>
|
||||||
<signal name="clicked" handler="on_save_button_clicked" swapped="no"/>
|
<signal name="clicked" handler="on_save_button_clicked" swapped="no"/>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="icon-name">document-save-symbolic</property>
|
<property name="icon-name">document-save-symbolic</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="pack-type">end</property>
|
|
||||||
<property name="position">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">5</property>
|
||||||
|
<property name="column-span">2</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">5</property>
|
|
||||||
<property name="width">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkFrame">
|
<object class="GtkFrame">
|
||||||
<property name="visible">True</property>
|
<property name="child">
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="label-xalign">0</property>
|
|
||||||
<property name="shadow-type">in</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkInfoBar" id="infobar">
|
<object class="GtkInfoBar" id="infobar">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="message-type">warning</property>
|
<property name="message-type">warning</property>
|
||||||
<property name="show-close-button">True</property>
|
<property name="show-close-button">1</property>
|
||||||
<property name="revealed">False</property>
|
<property name="revealed">0</property>
|
||||||
<signal name="response" handler="on_infobar_response" swapped="no"/>
|
<signal name="response" handler="on_infobar_response" swapped="no"/>
|
||||||
<child internal-child="action_area">
|
<child type="action">
|
||||||
<object class="GtkButtonBox">
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="spacing">6</property>
|
|
||||||
<property name="layout-style">end</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkButton" id="reload_button">
|
<object class="GtkButton" id="reload_button">
|
||||||
<property name="label" translatable="yes">Reload</property>
|
<property name="label" translatable="1">Reload</property>
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="receives-default">1</property>
|
||||||
<property name="receives-default">True</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="valign">end</property>
|
<property name="valign">end</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="pack-type">end</property>
|
|
||||||
<property name="position">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">False</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child internal-child="content_area">
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="can-focus">False</property>
|
<property name="visible">0</property>
|
||||||
<property name="hexpand">True</property>
|
<property name="hexpand">1</property>
|
||||||
<property name="spacing">16</property>
|
<property name="spacing">16</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="hexpand">True</property>
|
<property name="hexpand">1</property>
|
||||||
<property name="label" translatable="yes">The file changed on disk.</property>
|
<property name="label" translatable="1">The file changed on disk.</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">False</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<action-widgets>
|
<action-widgets>
|
||||||
<action-widget response="-5">reload_button</action-widget>
|
<action-widget response="-5">reload_button</action-widget>
|
||||||
</action-widgets>
|
</action-widgets>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow">
|
<object class="GtkScrolledWindow">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="vexpand">1</property>
|
||||||
<property name="vexpand">True</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="CmbSourceView" id="view">
|
<object class="CmbSourceView" id="view">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@ -285,23 +197,18 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
<child type="label_item">
|
<child type="label_item">
|
||||||
<placeholder/>
|
<placeholder/>
|
||||||
</child>
|
</child>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">4</property>
|
||||||
|
<property name="column-span">2</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">4</property>
|
|
||||||
<property name="width">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
</template>
|
</template>
|
||||||
</interface>
|
</interface>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# CmbDB - Cambalache DataBase
|
# CmbDB - Cambalache DataBase
|
||||||
#
|
#
|
||||||
# Copyright (C) 2021-2023 Juan Pablo Ugarte
|
# Copyright (C) 2021-2024 Juan Pablo Ugarte
|
||||||
#
|
#
|
||||||
# This library is free software; you can redistribute it and/or
|
# This library is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU Lesser General Public
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
@ -28,7 +28,7 @@ import ast
|
|||||||
|
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
from lxml.builder import E
|
from lxml.builder import E
|
||||||
from gi.repository import Gio, GObject, Gtk
|
from gi.repository import GLib, Gio, GObject
|
||||||
from cambalache import config, getLogger, _
|
from cambalache import config, getLogger, _
|
||||||
from . import cmb_db_migration, utils
|
from . import cmb_db_migration, utils
|
||||||
from .constants import EXTERNAL_TYPE, GMENU_TYPE, GMENU_SECTION_TYPE, GMENU_SUBMENU_TYPE, GMENU_ITEM_TYPE
|
from .constants import EXTERNAL_TYPE, GMENU_TYPE, GMENU_SECTION_TYPE, GMENU_SUBMENU_TYPE, GMENU_ITEM_TYPE
|
||||||
@ -618,8 +618,8 @@ class CmbDB(GObject.GObject):
|
|||||||
|
|
||||||
return f"\t({r})"
|
return f"\t({r})"
|
||||||
|
|
||||||
def _dump_table(c, table):
|
def _dump_query(c, query):
|
||||||
c.execute(f"SELECT * FROM {table};")
|
c.execute(query)
|
||||||
row = c.fetchone()
|
row = c.fetchone()
|
||||||
|
|
||||||
if row is None:
|
if row is None:
|
||||||
@ -635,20 +635,27 @@ class CmbDB(GObject.GObject):
|
|||||||
|
|
||||||
return f"\n{retval}\n "
|
return f"\n{retval}\n "
|
||||||
|
|
||||||
|
def append_data(project, name, data):
|
||||||
|
if data is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
element = etree.Element(name)
|
||||||
|
element.text = data
|
||||||
|
project.append(element)
|
||||||
|
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
c = self.conn.cursor()
|
c = self.conn.cursor()
|
||||||
|
|
||||||
project = E("cambalache-project", version=config.FILE_FORMAT_VERSION, target_tk=self.target_tk)
|
project = E("cambalache-project", version=config.FILE_FORMAT_VERSION, target_tk=self.target_tk)
|
||||||
|
|
||||||
for table in self.__tables:
|
for table in self.__tables:
|
||||||
data = _dump_table(c, table)
|
data = _dump_query(c, f"SELECT * FROM {table};")
|
||||||
|
append_data(project, table, data)
|
||||||
|
|
||||||
if data is None:
|
# DUMP custom properties and signals
|
||||||
continue
|
for table in ["property", "signal"]:
|
||||||
|
data = _dump_query(c, f"SELECT {table}.* FROM {table},type WHERE {table}.owner_id == type.type_id AND type.library_id IS NULL;")
|
||||||
element = etree.Element(table)
|
append_data(project, table, data)
|
||||||
element.text = data
|
|
||||||
project.append(element)
|
|
||||||
|
|
||||||
# Dump xml to file
|
# Dump xml to file
|
||||||
with open(filename, "wb") as fd:
|
with open(filename, "wb") as fd:
|
||||||
@ -1523,12 +1530,11 @@ class CmbDB(GObject.GObject):
|
|||||||
if column is not None:
|
if column is not None:
|
||||||
c.execute(f"UPDATE ui SET {column}=? WHERE ui_id=?", (value, ui_id))
|
c.execute(f"UPDATE ui SET {column}=? WHERE ui_id=?", (value, ui_id))
|
||||||
else:
|
else:
|
||||||
print(child)
|
|
||||||
custom_fragments.append(child)
|
custom_fragments.append(child)
|
||||||
# self.__unknown_tag(child, None, child.tag)
|
|
||||||
|
|
||||||
while Gtk.events_pending():
|
main_loop = GLib.MainContext.default()
|
||||||
Gtk.main_iteration_do(False)
|
while main_loop.pending():
|
||||||
|
main_loop.iteration(False)
|
||||||
|
|
||||||
# Fix object references!
|
# Fix object references!
|
||||||
self.__fix_object_references(ui_id)
|
self.__fix_object_references(ui_id)
|
||||||
|
@ -1,31 +1,19 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Generated with glade 3.38.2 -->
|
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.24"/>
|
<requires lib="gtk" version="4.0"/>
|
||||||
<requires lib="gladecambalache" version="0.0"/>
|
|
||||||
<template class="CmbFragmentEditor" parent="GtkBox">
|
<template class="CmbFragmentEditor" parent="GtkBox">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
<property name="spacing">4</property>
|
<property name="spacing">4</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="label" translatable="yes">Extra fragments:</property>
|
<property name="label" translatable="1">Extra fragments:</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow">
|
<object class="GtkScrolledWindow">
|
||||||
<property name="visible">True</property>
|
<property name="vexpand">1</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="shadow-type">in</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="CmbSourceView" id="view">
|
<object class="CmbSourceView" id="view">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@ -34,11 +22,6 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">True</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
</template>
|
</template>
|
||||||
</interface>
|
</interface>
|
||||||
|
@ -71,7 +71,8 @@ class CmbObjectDataEditor(Gtk.Box):
|
|||||||
else:
|
else:
|
||||||
self.__data.parent.remove_data(self.__data)
|
self.__data.parent.remove_data(self.__data)
|
||||||
|
|
||||||
@Gtk.Template.Callback("on_remove_size_allocate")
|
# FIXME: GTK4
|
||||||
|
#@Gtk.Template.Callback("on_remove_size_allocate")
|
||||||
def __on_remove_size_allocate(self, button, alloc):
|
def __on_remove_size_allocate(self, button, alloc):
|
||||||
info = self.data.info if self.data else self.info
|
info = self.data.info if self.data else self.info
|
||||||
|
|
||||||
@ -182,9 +183,9 @@ class CmbObjectDataEditor(Gtk.Box):
|
|||||||
child_info = info.children[child]
|
child_info = info.children[child]
|
||||||
button = Gtk.ModelButton(label=_("Add {key}").format(key=child_info.key), visible=True)
|
button = Gtk.ModelButton(label=_("Add {key}").format(key=child_info.key), visible=True)
|
||||||
button.connect("clicked", self.__on_child_button_clicked, child_info)
|
button.connect("clicked", self.__on_child_button_clicked, child_info)
|
||||||
box.add(button)
|
box.append(button)
|
||||||
|
|
||||||
popover.add(box)
|
popover.set_child(box)
|
||||||
|
|
||||||
return popover
|
return popover
|
||||||
|
|
||||||
@ -236,7 +237,7 @@ class CmbObjectDataEditor(Gtk.Box):
|
|||||||
|
|
||||||
nchildren = len(info.children)
|
nchildren = len(info.children)
|
||||||
|
|
||||||
self.remove_button.set_tooltip_text(_("Remove {key}").format(key=info.key))
|
self.remove_button.props.tooltip_text = _("Remove {key}").format(key=info.key)
|
||||||
|
|
||||||
# Add a menu if there is more than one child type
|
# Add a menu if there is more than one child type
|
||||||
if nchildren > 1:
|
if nchildren > 1:
|
||||||
@ -244,7 +245,7 @@ class CmbObjectDataEditor(Gtk.Box):
|
|||||||
self.add_child.set_visible(True)
|
self.add_child.set_visible(True)
|
||||||
elif nchildren:
|
elif nchildren:
|
||||||
key = list(info.children.keys())[0]
|
key = list(info.children.keys())[0]
|
||||||
self.add_only_child.set_tooltip_text(_("Add {key}").format(key=key))
|
self.add_only_child.props.tooltip_text = _("Add {key}").format(key=key)
|
||||||
self.add_only_child.set_visible(True)
|
self.add_only_child.set_visible(True)
|
||||||
|
|
||||||
# Item name
|
# Item name
|
||||||
@ -267,7 +268,7 @@ class CmbObjectDataEditor(Gtk.Box):
|
|||||||
GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL,
|
GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.top_box.add(editor)
|
self.top_box.append(editor)
|
||||||
|
|
||||||
nargs = len(info.args)
|
nargs = len(info.args)
|
||||||
|
|
||||||
@ -287,7 +288,7 @@ class CmbObjectDataEditor(Gtk.Box):
|
|||||||
# Special case items with one argument and no value (like styles)
|
# Special case items with one argument and no value (like styles)
|
||||||
if nargs == 1 and not info.type_id:
|
if nargs == 1 and not info.type_id:
|
||||||
self.label.props.label = f"{info.key} {arg_info.key}"
|
self.label.props.label = f"{info.key} {arg_info.key}"
|
||||||
self.top_box.add(editor)
|
self.top_box.append(editor)
|
||||||
else:
|
else:
|
||||||
label = Gtk.Label(visible=True, label=arg_info.key, xalign=1)
|
label = Gtk.Label(visible=True, label=arg_info.key, xalign=1)
|
||||||
self.__add(editor, label)
|
self.__add(editor, label)
|
||||||
|
@ -1,74 +1,43 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Generated with glade 3.38.2 -->
|
|
||||||
<!-- Created with Cambalache 0.11.2 -->
|
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.24"/>
|
<requires lib="gtk" version="4.0"/>
|
||||||
<template class="CmbObjectDataEditor" parent="GtkBox">
|
<template class="CmbObjectDataEditor" parent="GtkBox">
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
<property name="spacing">4</property>
|
<property name="spacing">4</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="top_box">
|
<object class="GtkBox" id="top_box">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="no-show-all">True</property>
|
|
||||||
<property name="spacing">4</property>
|
<property name="spacing">4</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuButton" id="add_child">
|
<object class="GtkMenuButton" id="add_child">
|
||||||
<property name="can-focus">False</property>
|
<property name="visible">0</property>
|
||||||
<property name="receives-default">False</property>
|
|
||||||
<property name="halign">end</property>
|
<property name="halign">end</property>
|
||||||
<property name="relief">none</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="icon-name">list-add-symbolic</property>
|
<property name="icon-name">list-add-symbolic</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="pack-type">end</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="add_only_child">
|
<object class="GtkButton" id="add_only_child">
|
||||||
<property name="can-focus">True</property>
|
<property name="visible">0</property>
|
||||||
<property name="receives-default">False</property>
|
<property name="focusable">1</property>
|
||||||
<property name="halign">end</property>
|
<property name="halign">end</property>
|
||||||
<property name="relief">none</property>
|
|
||||||
<signal name="clicked" handler="on_add_only_child_clicked" swapped="no"/>
|
<signal name="clicked" handler="on_add_only_child_clicked" swapped="no"/>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="icon-name">list-add-symbolic</property>
|
<property name="icon-name">list-add-symbolic</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="pack-type">end</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="remove_button">
|
<object class="GtkButton" id="remove_button">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="receives-default">False</property>
|
|
||||||
<property name="halign">end</property>
|
<property name="halign">end</property>
|
||||||
<property name="relief">none</property>
|
|
||||||
<signal name="clicked" handler="on_remove_clicked" swapped="no"/>
|
<signal name="clicked" handler="on_remove_clicked" swapped="no"/>
|
||||||
<signal name="size-allocate" handler="on_remove_size_allocate" swapped="no"/>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="icon-name">user-trash-symbolic</property>
|
<property name="icon-name">user-trash-symbolic</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
@ -76,36 +45,15 @@
|
|||||||
<class name="hidden"/>
|
<class name="hidden"/>
|
||||||
</style>
|
</style>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="pack-type">end</property>
|
|
||||||
<property name="position">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="label">
|
<object class="GtkLabel" id="label"/>
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">3</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<!-- n-columns=2 n-rows=1 -->
|
|
||||||
<object class="GtkGrid" id="grid">
|
<object class="GtkGrid" id="grid">
|
||||||
<property name="visible">True</property>
|
<property name="vexpand">1</property>
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="row-spacing">4</property>
|
<property name="row-spacing">4</property>
|
||||||
<property name="column-spacing">4</property>
|
<property name="column-spacing">4</property>
|
||||||
<child>
|
<child>
|
||||||
@ -115,11 +63,6 @@
|
|||||||
<placeholder/>
|
<placeholder/>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">True</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
</template>
|
</template>
|
||||||
</interface>
|
</interface>
|
||||||
|
@ -29,9 +29,10 @@ from .control import CmbEntry, CmbChildTypeComboBox, cmb_create_editor
|
|||||||
from .cmb_property_label import CmbPropertyLabel
|
from .cmb_property_label import CmbPropertyLabel
|
||||||
from cambalache import _
|
from cambalache import _
|
||||||
from .constants import EXTERNAL_TYPE
|
from .constants import EXTERNAL_TYPE
|
||||||
|
from . import utils
|
||||||
|
|
||||||
|
|
||||||
class CmbObjectEditor(Gtk.ScrolledWindow):
|
class CmbObjectEditor(Gtk.Box):
|
||||||
__gtype_name__ = "CmbObjectEditor"
|
__gtype_name__ = "CmbObjectEditor"
|
||||||
|
|
||||||
layout = GObject.Property(type=bool, flags=GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, default=False)
|
layout = GObject.Property(type=bool, flags=GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, default=False)
|
||||||
@ -43,10 +44,7 @@ class CmbObjectEditor(Gtk.ScrolledWindow):
|
|||||||
|
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
self.box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, visible=True)
|
self.props.orientation = Gtk.Orientation.VERTICAL
|
||||||
viewport = Gtk.Viewport(visible=True, shadow_type=Gtk.ShadowType.NONE)
|
|
||||||
viewport.add(self.box)
|
|
||||||
self.add(viewport)
|
|
||||||
|
|
||||||
def __create_id_editor(self):
|
def __create_id_editor(self):
|
||||||
grid = Gtk.Grid(hexpand=True, row_spacing=4, column_spacing=4)
|
grid = Gtk.Grid(hexpand=True, row_spacing=4, column_spacing=4)
|
||||||
@ -97,12 +95,12 @@ class CmbObjectEditor(Gtk.ScrolledWindow):
|
|||||||
box = Gtk.FlowBox(visible=True, hexpand=True, selection_mode=Gtk.SelectionMode.NONE)
|
box = Gtk.FlowBox(visible=True, hexpand=True, selection_mode=Gtk.SelectionMode.NONE)
|
||||||
|
|
||||||
label = Gtk.Label(label=_("Add"), xalign=0, visible=True)
|
label = Gtk.Label(label=_("Add"), xalign=0, visible=True)
|
||||||
box.add(label)
|
box.append(label)
|
||||||
|
|
||||||
for type_id in info.child_type_shortcuts:
|
for type_id in info.child_type_shortcuts:
|
||||||
button = Gtk.Button(label=type_id, visible=True)
|
button = Gtk.Button(label=type_id, visible=True)
|
||||||
button.connect("clicked", self.__on_shortcut_button_clicked, type_id)
|
button.connect("clicked", self.__on_shortcut_button_clicked, type_id)
|
||||||
box.add(button)
|
box.append(button)
|
||||||
|
|
||||||
return box
|
return box
|
||||||
|
|
||||||
@ -127,7 +125,7 @@ class CmbObjectEditor(Gtk.ScrolledWindow):
|
|||||||
def __create_child_type_editor(self):
|
def __create_child_type_editor(self):
|
||||||
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
|
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
|
||||||
|
|
||||||
box.add(Gtk.Label(label=_("Child Type"), width_chars=8))
|
box.append(Gtk.Label(label=_("Child Type"), width_chars=8))
|
||||||
|
|
||||||
combo = CmbChildTypeComboBox(object=self.__object)
|
combo = CmbChildTypeComboBox(object=self.__object)
|
||||||
|
|
||||||
@ -138,12 +136,12 @@ class CmbObjectEditor(Gtk.ScrolledWindow):
|
|||||||
"cmb-value",
|
"cmb-value",
|
||||||
GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL,
|
GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL,
|
||||||
)
|
)
|
||||||
box.pack_start(combo, True, True, 0)
|
box.append(combo)
|
||||||
return box
|
return box
|
||||||
|
|
||||||
def __update_view(self):
|
def __update_view(self):
|
||||||
for child in self.box.get_children():
|
for child in utils.widget_get_children(self):
|
||||||
self.box.remove(child)
|
self.remove(child)
|
||||||
|
|
||||||
if self.__object is None:
|
if self.__object is None:
|
||||||
return
|
return
|
||||||
@ -158,10 +156,10 @@ class CmbObjectEditor(Gtk.ScrolledWindow):
|
|||||||
|
|
||||||
# Child Type input
|
# Child Type input
|
||||||
if parent.info.has_child_types():
|
if parent.info.has_child_types():
|
||||||
self.box.add(self.__create_child_type_editor())
|
self.append(self.__create_child_type_editor())
|
||||||
else:
|
else:
|
||||||
# ID
|
# ID
|
||||||
self.box.add(self.__create_id_editor())
|
self.append(self.__create_id_editor())
|
||||||
|
|
||||||
if obj.type_id == EXTERNAL_TYPE:
|
if obj.type_id == EXTERNAL_TYPE:
|
||||||
label = Gtk.Label(
|
label = Gtk.Label(
|
||||||
@ -174,8 +172,8 @@ It has to be exposed by your application with GtkBuilder expose_object method."
|
|||||||
xalign=0,
|
xalign=0,
|
||||||
wrap=True,
|
wrap=True,
|
||||||
)
|
)
|
||||||
self.box.add(label)
|
self.append(label)
|
||||||
self.show_all()
|
self.show()
|
||||||
return
|
return
|
||||||
|
|
||||||
info = parent.info if self.layout and parent else obj.info
|
info = parent.info if self.layout and parent else obj.info
|
||||||
@ -261,11 +259,11 @@ It has to be exposed by your application with GtkBuilder expose_object method."
|
|||||||
expander = Gtk.Expander(label=f"<b>{owner_id}</b>", use_markup=True, expanded=True)
|
expander = Gtk.Expander(label=f"<b>{owner_id}</b>", use_markup=True, expanded=True)
|
||||||
revealer = Gtk.Revealer(reveal_child=True)
|
revealer = Gtk.Revealer(reveal_child=True)
|
||||||
expander.connect("notify::expanded", self.__on_expander_expanded, revealer)
|
expander.connect("notify::expanded", self.__on_expander_expanded, revealer)
|
||||||
revealer.add(grid)
|
revealer.set_child(grid)
|
||||||
self.box.add(expander)
|
self.append(expander)
|
||||||
self.box.add(revealer)
|
self.append(revealer)
|
||||||
|
|
||||||
self.show_all()
|
self.show()
|
||||||
|
|
||||||
def __on_object_ui_notify(self, obj, pspec):
|
def __on_object_ui_notify(self, obj, pspec):
|
||||||
if pspec.name == "template-id" and self.__template_switch:
|
if pspec.name == "template-id" and self.__template_switch:
|
||||||
|
@ -78,7 +78,6 @@ class CmbProject(Gtk.TreeStore):
|
|||||||
"type-info-added": (GObject.SignalFlags.RUN_FIRST, None, (CmbTypeInfo,)),
|
"type-info-added": (GObject.SignalFlags.RUN_FIRST, None, (CmbTypeInfo,)),
|
||||||
"type-info-removed": (GObject.SignalFlags.RUN_FIRST, None, (CmbTypeInfo,)),
|
"type-info-removed": (GObject.SignalFlags.RUN_FIRST, None, (CmbTypeInfo,)),
|
||||||
"type-info-changed": (GObject.SignalFlags.RUN_FIRST, None, (CmbTypeInfo,)),
|
"type-info-changed": (GObject.SignalFlags.RUN_FIRST, None, (CmbTypeInfo,)),
|
||||||
"filename-required": (GObject.SignalFlags.RUN_FIRST, str, ()),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
target_tk = GObject.Property(type=str, flags=GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT)
|
target_tk = GObject.Property(type=str, flags=GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT)
|
||||||
@ -282,9 +281,6 @@ class CmbProject(Gtk.TreeStore):
|
|||||||
self.__filename = value
|
self.__filename = value
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
if self.filename is None:
|
|
||||||
self.filename = self.emit("filename-required")
|
|
||||||
|
|
||||||
if self.filename:
|
if self.filename:
|
||||||
self.db.save(self.filename)
|
self.db.save(self.filename)
|
||||||
return True
|
return True
|
||||||
@ -378,6 +374,9 @@ class CmbProject(Gtk.TreeStore):
|
|||||||
return (ui, msgs, detail_msg)
|
return (ui, msgs, detail_msg)
|
||||||
|
|
||||||
def __export(self, ui_id, filename, dirname=None):
|
def __export(self, ui_id, filename, dirname=None):
|
||||||
|
if filename is None:
|
||||||
|
return
|
||||||
|
|
||||||
if not os.path.isabs(filename):
|
if not os.path.isabs(filename):
|
||||||
if dirname is None:
|
if dirname is None:
|
||||||
dirname = os.path.dirname(self.filename)
|
dirname = os.path.dirname(self.filename)
|
||||||
@ -1178,14 +1177,15 @@ class CmbProject(Gtk.TreeStore):
|
|||||||
self.__object_update_row(ui.ui_id, template_id)
|
self.__object_update_row(ui.ui_id, template_id)
|
||||||
|
|
||||||
def _ui_changed(self, ui, field):
|
def _ui_changed(self, ui, field):
|
||||||
iter = self.get_iter_from_object(ui)
|
|
||||||
|
|
||||||
if field == "template-id":
|
if field == "template-id":
|
||||||
self.__update_template_type_info(ui)
|
self.__update_template_type_info(ui)
|
||||||
|
|
||||||
|
iter = self.get_iter_from_object(ui)
|
||||||
|
if iter is None:
|
||||||
|
return
|
||||||
|
|
||||||
path = self.get_path(iter)
|
path = self.get_path(iter)
|
||||||
self.row_changed(path, iter)
|
self.row_changed(path, iter)
|
||||||
|
|
||||||
self.emit("ui-changed", ui, field)
|
self.emit("ui-changed", ui, field)
|
||||||
|
|
||||||
def _ui_library_changed(self, ui, lib):
|
def _ui_library_changed(self, ui, lib):
|
||||||
|
@ -43,8 +43,6 @@ class CmbPropertyLabel(Gtk.Button):
|
|||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
self.props.relief = Gtk.ReliefStyle.NONE
|
|
||||||
|
|
||||||
if not self.prop and not self.layout_prop:
|
if not self.prop and not self.layout_prop:
|
||||||
raise Exception("CmbPropertyLabel requires prop or layout_prop to be set")
|
raise Exception("CmbPropertyLabel requires prop or layout_prop to be set")
|
||||||
return
|
return
|
||||||
@ -54,8 +52,8 @@ class CmbPropertyLabel(Gtk.Button):
|
|||||||
|
|
||||||
# Update label status
|
# Update label status
|
||||||
if self.prop:
|
if self.prop:
|
||||||
self.bind_icon = Gtk.Image(icon_size=Gtk.IconSize.MENU, visible=True)
|
self.bind_icon = Gtk.Image(icon_size=Gtk.IconSize.NORMAL, visible=True)
|
||||||
box.add(self.bind_icon)
|
box.append(self.bind_icon)
|
||||||
|
|
||||||
self.label.props.label = self.prop.property_id
|
self.label.props.label = self.prop.property_id
|
||||||
|
|
||||||
@ -71,24 +69,22 @@ class CmbPropertyLabel(Gtk.Button):
|
|||||||
self.__update_layout_property_label()
|
self.__update_layout_property_label()
|
||||||
self.layout_prop.connect("notify::value", lambda o, p: self.__update_layout_property_label())
|
self.layout_prop.connect("notify::value", lambda o, p: self.__update_layout_property_label())
|
||||||
|
|
||||||
box.add(self.label)
|
box.append(self.label)
|
||||||
self.add(box)
|
self.set_child(box)
|
||||||
|
|
||||||
def __update_label(self, prop):
|
def __update_label(self, prop):
|
||||||
style = self.get_style_context()
|
|
||||||
|
|
||||||
if prop.value != prop.info.default_value:
|
if prop.value != prop.info.default_value:
|
||||||
style.add_class("modified")
|
self.add_css_class("modified")
|
||||||
else:
|
else:
|
||||||
style.remove_class("modified")
|
self.remove_css_class("modified")
|
||||||
|
|
||||||
msg = prop.version_warning
|
msg = prop.version_warning
|
||||||
self.set_tooltip_text(msg)
|
self.set_tooltip_text(msg)
|
||||||
|
|
||||||
if msg:
|
if msg:
|
||||||
style.add_class("warning")
|
self.add_css_class("warning")
|
||||||
else:
|
else:
|
||||||
style.remove_class("warning")
|
self.remove_css_class("warning")
|
||||||
|
|
||||||
def __update_layout_property_label(self):
|
def __update_layout_property_label(self):
|
||||||
self.__update_label(self.layout_prop)
|
self.__update_label(self.layout_prop)
|
||||||
@ -101,10 +97,10 @@ class CmbPropertyLabel(Gtk.Button):
|
|||||||
|
|
||||||
if self.prop.bind_property_id:
|
if self.prop.bind_property_id:
|
||||||
self.bind_icon.props.icon_name = "binded-symbolic"
|
self.bind_icon.props.icon_name = "binded-symbolic"
|
||||||
self.get_style_context().remove_class("hidden")
|
self.remove_css_class("hidden")
|
||||||
else:
|
else:
|
||||||
self.bind_icon.props.icon_name = "bind-symbolic"
|
self.bind_icon.props.icon_name = "bind-symbolic"
|
||||||
self.get_style_context().add_class("hidden")
|
self.add_css_class("hidden")
|
||||||
|
|
||||||
def __on_object_editor_notify(self, object_editor, pspec, property_editor):
|
def __on_object_editor_notify(self, object_editor, pspec, property_editor):
|
||||||
object_id = object_editor.cmb_value
|
object_id = object_editor.cmb_value
|
||||||
@ -129,9 +125,10 @@ class CmbPropertyLabel(Gtk.Button):
|
|||||||
popover.popdown()
|
popover.popdown()
|
||||||
|
|
||||||
def __on_bind_button_clicked(self, button):
|
def __on_bind_button_clicked(self, button):
|
||||||
popover = Gtk.Popover(relative_to=button, position=Gtk.PositionType.LEFT)
|
popover = Gtk.Popover(position=Gtk.PositionType.LEFT)
|
||||||
|
popover.set_parent(self)
|
||||||
|
|
||||||
grid = Gtk.Grid(hexpand=True, row_spacing=4, column_spacing=4, border_width=4, visible=True)
|
grid = Gtk.Grid(hexpand=True, row_spacing=4, column_spacing=4, visible=True)
|
||||||
|
|
||||||
grid.attach(Gtk.Label(label="<b>Property Binding</b>", use_markup=True, visible=True, xalign=0), 0, 0, 2, 1)
|
grid.attach(Gtk.Label(label="<b>Property Binding</b>", use_markup=True, visible=True, xalign=0), 0, 0, 2, 1)
|
||||||
|
|
||||||
@ -177,7 +174,7 @@ class CmbPropertyLabel(Gtk.Button):
|
|||||||
grid.attach(clear, 0, i, 2, 1)
|
grid.attach(clear, 0, i, 2, 1)
|
||||||
object_editor.grab_focus()
|
object_editor.grab_focus()
|
||||||
|
|
||||||
popover.add(grid)
|
popover.set_child(grid)
|
||||||
popover.popup()
|
popover.popup()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Generated with glade 3.40.0 -->
|
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.24"/>
|
<requires lib="gtk" version="4.0"/>
|
||||||
<object class="GtkEntryCompletion" id="handler_entrycompletion">
|
<object class="GtkEntryCompletion" id="handler_entrycompletion">
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCellRendererText"/>
|
<object class="GtkCellRendererText"/>
|
||||||
@ -12,42 +11,28 @@
|
|||||||
</object>
|
</object>
|
||||||
<object class="GtkTreeStore" id="treestore">
|
<object class="GtkTreeStore" id="treestore">
|
||||||
<columns>
|
<columns>
|
||||||
<!-- column-name signal -->
|
|
||||||
<column type="GObject"/>
|
<column type="GObject"/>
|
||||||
<!-- column-name owner_id -->
|
|
||||||
<column type="gchararray"/>
|
<column type="gchararray"/>
|
||||||
<!-- column-name signal_id -->
|
|
||||||
<column type="gchararray"/>
|
<column type="gchararray"/>
|
||||||
<!-- column-name detail -->
|
|
||||||
<column type="gchararray"/>
|
<column type="gchararray"/>
|
||||||
<!-- column-name handler -->
|
|
||||||
<column type="gchararray"/>
|
<column type="gchararray"/>
|
||||||
<!-- column-name user_data -->
|
|
||||||
<column type="gchararray"/>
|
<column type="gchararray"/>
|
||||||
<!-- column-name swap -->
|
|
||||||
<column type="gboolean"/>
|
<column type="gboolean"/>
|
||||||
<!-- column-name after -->
|
|
||||||
<column type="gboolean"/>
|
<column type="gboolean"/>
|
||||||
<!-- column-name info -->
|
|
||||||
<column type="GObject"/>
|
<column type="GObject"/>
|
||||||
<!-- column-name version_warning -->
|
|
||||||
<column type="gchararray"/>
|
<column type="gchararray"/>
|
||||||
</columns>
|
</columns>
|
||||||
</object>
|
</object>
|
||||||
<template class="CmbSignalEditor" parent="GtkBox">
|
<template class="CmbSignalEditor" parent="GtkBox">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
<property name="spacing">4</property>
|
<property name="spacing">4</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow">
|
<object class="GtkScrolledWindow">
|
||||||
<property name="visible">True</property>
|
<property name="vexpand">1</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="shadow-type">in</property>
|
<property name="child">
|
||||||
<child>
|
|
||||||
<object class="GtkTreeView" id="treeview">
|
<object class="GtkTreeView" id="treeview">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="model">treestore</property>
|
<property name="model">treestore</property>
|
||||||
<property name="tooltip-column">9</property>
|
<property name="tooltip-column">9</property>
|
||||||
<child internal-child="selection">
|
<child internal-child="selection">
|
||||||
@ -55,9 +40,9 @@
|
|||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkTreeViewColumn" id="signal_id_column">
|
<object class="GtkTreeViewColumn" id="signal_id_column">
|
||||||
<property name="resizable">True</property>
|
<property name="resizable">1</property>
|
||||||
<property name="min-width">64</property>
|
<property name="min-width">64</property>
|
||||||
<property name="title" translatable="yes">Signal</property>
|
<property name="title" translatable="1">Signal</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCellRendererText" id="signal_id">
|
<object class="GtkCellRendererText" id="signal_id">
|
||||||
<signal name="edited" handler="on_detail_edited" swapped="no"/>
|
<signal name="edited" handler="on_detail_edited" swapped="no"/>
|
||||||
@ -70,13 +55,13 @@
|
|||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkTreeViewColumn" id="handler_column">
|
<object class="GtkTreeViewColumn" id="handler_column">
|
||||||
<property name="resizable">True</property>
|
<property name="resizable">1</property>
|
||||||
<property name="min-width">64</property>
|
<property name="min-width">64</property>
|
||||||
<property name="title" translatable="yes">Handler</property>
|
<property name="title" translatable="1">Handler</property>
|
||||||
<property name="expand">True</property>
|
<property name="expand">1</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCellRendererText" id="handler">
|
<object class="GtkCellRendererText" id="handler">
|
||||||
<property name="editable">True</property>
|
<property name="editable">1</property>
|
||||||
<property name="placeholder-text"><Enter callback></property>
|
<property name="placeholder-text"><Enter callback></property>
|
||||||
<signal name="edited" handler="on_handler_edited" swapped="no"/>
|
<signal name="edited" handler="on_handler_edited" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
@ -88,10 +73,10 @@
|
|||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkTreeViewColumn" id="user_data_column">
|
<object class="GtkTreeViewColumn" id="user_data_column">
|
||||||
<property name="title" translatable="yes">Data</property>
|
<property name="title" translatable="1">Data</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCellRendererText" id="user_data">
|
<object class="GtkCellRendererText" id="user_data">
|
||||||
<property name="editable">True</property>
|
<property name="editable">1</property>
|
||||||
<property name="placeholder-text"><object></property>
|
<property name="placeholder-text"><object></property>
|
||||||
<signal name="edited" handler="on_user_data_edited" swapped="no"/>
|
<signal name="edited" handler="on_user_data_edited" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
@ -103,7 +88,7 @@
|
|||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkTreeViewColumn" id="swap_column">
|
<object class="GtkTreeViewColumn" id="swap_column">
|
||||||
<property name="title" translatable="yes">Swap</property>
|
<property name="title" translatable="1">Swap</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCellRendererToggle" id="swap">
|
<object class="GtkCellRendererToggle" id="swap">
|
||||||
<signal name="toggled" handler="on_swap_toggled" swapped="no"/>
|
<signal name="toggled" handler="on_swap_toggled" swapped="no"/>
|
||||||
@ -116,7 +101,7 @@
|
|||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkTreeViewColumn" id="after_column">
|
<object class="GtkTreeViewColumn" id="after_column">
|
||||||
<property name="title" translatable="yes">After</property>
|
<property name="title" translatable="1">After</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCellRendererToggle" id="after">
|
<object class="GtkCellRendererToggle" id="after">
|
||||||
<signal name="toggled" handler="on_after_toggled" swapped="no"/>
|
<signal name="toggled" handler="on_after_toggled" swapped="no"/>
|
||||||
@ -128,13 +113,8 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">True</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">3</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
</template>
|
</template>
|
||||||
</interface>
|
</interface>
|
||||||
|
@ -40,7 +40,6 @@ class CmbTreeView(Gtk.TreeView):
|
|||||||
self.__in_selection_change = False
|
self.__in_selection_change = False
|
||||||
self._selection.connect("changed", self.__on_selection_changed)
|
self._selection.connect("changed", self.__on_selection_changed)
|
||||||
self.set_headers_visible(False)
|
self.set_headers_visible(False)
|
||||||
self.__right_click = False
|
|
||||||
|
|
||||||
renderer = Gtk.CellRendererText()
|
renderer = Gtk.CellRendererText()
|
||||||
column = Gtk.TreeViewColumn("Object(Type)", renderer)
|
column = Gtk.TreeViewColumn("Object(Type)", renderer)
|
||||||
@ -50,31 +49,14 @@ class CmbTreeView(Gtk.TreeView):
|
|||||||
self.connect("notify::model", self.__on_model_notify)
|
self.connect("notify::model", self.__on_model_notify)
|
||||||
self.connect("row-activated", self.__on_row_activated)
|
self.connect("row-activated", self.__on_row_activated)
|
||||||
|
|
||||||
self.menu = CmbContextMenu(relative_to=self)
|
gesture = Gtk.GestureClick(button=3)
|
||||||
|
gesture.connect("pressed", self.__on_button_press)
|
||||||
self.add_events(Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK)
|
self.add_controller(gesture)
|
||||||
self.connect("button-press-event", self.__on_button_press_event)
|
|
||||||
self.connect("button-release-event", self.__on_button_release_event)
|
|
||||||
|
|
||||||
self.set_reorderable(True)
|
self.set_reorderable(True)
|
||||||
|
|
||||||
def __on_button_press_event(self, widget, event):
|
def __on_button_press(self, widget, npress, x, y):
|
||||||
if event.window != self.get_bin_window() or event.button != 3:
|
retval = self.get_path_at_pos(x, y)
|
||||||
return False
|
|
||||||
|
|
||||||
self.__right_click = True
|
|
||||||
return True
|
|
||||||
|
|
||||||
def __on_button_release_event(self, widget, event):
|
|
||||||
if event.window != self.get_bin_window() or event.button != 3:
|
|
||||||
return False
|
|
||||||
|
|
||||||
if not self.__right_click:
|
|
||||||
return False
|
|
||||||
|
|
||||||
self.__right_click = False
|
|
||||||
|
|
||||||
retval = self.get_path_at_pos(event.x, event.y)
|
|
||||||
|
|
||||||
if retval is None:
|
if retval is None:
|
||||||
return False
|
return False
|
||||||
@ -82,7 +64,12 @@ class CmbTreeView(Gtk.TreeView):
|
|||||||
path, col, xx, yy = retval
|
path, col, xx, yy = retval
|
||||||
self.get_selection().select_path(path)
|
self.get_selection().select_path(path)
|
||||||
|
|
||||||
self.menu.popup_at(event.x, event.y)
|
menu = CmbContextMenu()
|
||||||
|
|
||||||
|
# Use parent instead of self to avoid warning and focus not working properly
|
||||||
|
# (run-dev.py:188589): Gtk-CRITICAL **: 16:45:12.790: gtk_css_node_insert_after: assertion 'previous_sibling == NULL || previous_sibling->parent == parent' failed
|
||||||
|
menu.set_parent(self.props.parent)
|
||||||
|
menu.popup_at(x, y)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -156,7 +143,7 @@ class CmbTreeView(Gtk.TreeView):
|
|||||||
project.set_selection([obj])
|
project.set_selection([obj])
|
||||||
|
|
||||||
def do_query_tooltip(self, x, y, keyboard_mode, tooltip):
|
def do_query_tooltip(self, x, y, keyboard_mode, tooltip):
|
||||||
retval, xx, yy, model, path, iter_ = self.get_tooltip_context(x, y, keyboard_mode)
|
retval, model, path, iter_ = self.get_tooltip_context(x, y, keyboard_mode)
|
||||||
|
|
||||||
if not retval:
|
if not retval:
|
||||||
return False
|
return False
|
||||||
|
@ -1,216 +1,134 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Generated with glade 3.38.2 -->
|
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.24"/>
|
<requires lib="gtk" version="4.0"/>
|
||||||
<requires lib="gladecambalache" version="0.0"/>
|
|
||||||
<object class="CmbTypeChooserPopover" id="all">
|
<object class="CmbTypeChooserPopover" id="all">
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="show-categories">True</property>
|
<property name="show-categories">True</property>
|
||||||
</object>
|
</object>
|
||||||
<object class="CmbTypeChooserPopover" id="control">
|
<object class="CmbTypeChooserPopover" id="control">
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="category">control</property>
|
<property name="category">control</property>
|
||||||
</object>
|
</object>
|
||||||
<object class="CmbTypeChooserPopover" id="display">
|
<object class="CmbTypeChooserPopover" id="display">
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="category">display</property>
|
<property name="category">display</property>
|
||||||
</object>
|
</object>
|
||||||
<object class="CmbTypeChooserPopover" id="extra">
|
<object class="CmbTypeChooserPopover" id="extra">
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="uncategorized-only">True</property>
|
<property name="uncategorized-only">True</property>
|
||||||
</object>
|
</object>
|
||||||
<object class="CmbTypeChooserPopover" id="layout">
|
<object class="CmbTypeChooserPopover" id="layout">
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="category">layout</property>
|
<property name="category">layout</property>
|
||||||
</object>
|
</object>
|
||||||
<object class="CmbTypeChooserPopover" id="model">
|
<object class="CmbTypeChooserPopover" id="model">
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="category">model</property>
|
<property name="category">model</property>
|
||||||
</object>
|
</object>
|
||||||
<object class="CmbTypeChooserPopover" id="toplevel">
|
<object class="CmbTypeChooserPopover" id="toplevel">
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="category">toplevel</property>
|
<property name="category">toplevel</property>
|
||||||
</object>
|
</object>
|
||||||
<template class="CmbTypeChooser" parent="GtkBox">
|
<template class="CmbTypeChooser" parent="GtkBox">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="spacing">4</property>
|
<property name="spacing">4</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuButton" id="type_chooser_all">
|
<object class="GtkMenuButton" id="type_chooser_all">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="focus-on-click">0</property>
|
||||||
<property name="focus-on-click">False</property>
|
<property name="receives-default">1</property>
|
||||||
<property name="receives-default">True</property>
|
|
||||||
<property name="popover">all</property>
|
<property name="popover">all</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="icon-name">edit-find-symbolic</property>
|
<property name="icon-name">edit-find-symbolic</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButtonBox" id="type_chooser_gtk">
|
<object class="GtkBox" id="type_chooser_gtk">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="layout-style">expand</property>
|
|
||||||
<property name="homogeneous">False</property>
|
<property name="homogeneous">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuButton">
|
<object class="GtkMenuButton">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="focus-on-click">0</property>
|
||||||
<property name="focus-on-click">False</property>
|
<property name="receives-default">1</property>
|
||||||
<property name="receives-default">True</property>
|
|
||||||
<property name="popover">toplevel</property>
|
<property name="popover">toplevel</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
<property name="label" translatable="1" comments="Widget group for toplevels/windows">Toplevel</property>
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="label" translatable="yes" comments="Widget group for toplevels/windows">Toplevel</property>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">True</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuButton">
|
<object class="GtkMenuButton">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="focus-on-click">0</property>
|
||||||
<property name="focus-on-click">False</property>
|
<property name="receives-default">1</property>
|
||||||
<property name="receives-default">True</property>
|
|
||||||
<property name="popover">layout</property>
|
<property name="popover">layout</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
<property name="label" translatable="1" comments="Widget group for container widgets liek GtkBox grid">Layout</property>
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="label" translatable="yes" comments="Widget group for container widgets liek GtkBox grid">Layout</property>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">True</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuButton">
|
<object class="GtkMenuButton">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="focus-on-click">0</property>
|
||||||
<property name="focus-on-click">False</property>
|
<property name="receives-default">1</property>
|
||||||
<property name="receives-default">True</property>
|
|
||||||
<property name="popover">control</property>
|
<property name="popover">control</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
<property name="label" translatable="1" comments="Widget group for control wildget like buttons, entries">Control</property>
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="label" translatable="yes" comments="Widget group for control wildget like buttons, entries">Control</property>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">True</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuButton">
|
<object class="GtkMenuButton">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="focus-on-click">0</property>
|
||||||
<property name="focus-on-click">False</property>
|
<property name="receives-default">1</property>
|
||||||
<property name="receives-default">True</property>
|
|
||||||
<property name="popover">display</property>
|
<property name="popover">display</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
<property name="label" translatable="1" comments="Widget group for display widgets (label, image)">Display</property>
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="label" translatable="yes" comments="Widget group for display widgets (label, image)">Display</property>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">True</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">3</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuButton">
|
<object class="GtkMenuButton">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="focus-on-click">0</property>
|
||||||
<property name="focus-on-click">False</property>
|
<property name="receives-default">1</property>
|
||||||
<property name="receives-default">True</property>
|
|
||||||
<property name="popover">model</property>
|
<property name="popover">model</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
<property name="label" translatable="1" comments="Widget group for model objects (ListStore, TextBuffer)">Model</property>
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="label" translatable="yes" comments="Widget group for model objects (ListStore, TextBuffer)">Model</property>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">True</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">4</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuButton">
|
<object class="GtkMenuButton">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="receives-default">1</property>
|
||||||
<property name="receives-default">True</property>
|
|
||||||
<property name="popover">extra</property>
|
<property name="popover">extra</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="icon-name">pan-down-symbolic</property>
|
<property name="icon-name">pan-down-symbolic</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">True</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">5</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="pack-type">end</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="type_label">
|
<object class="GtkLabel" id="type_label">
|
||||||
<property name="visible">True</property>
|
<property name="hexpand">1</property>
|
||||||
<property name="sensitive">False</property>
|
<property name="sensitive">0</property>
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<attributes>
|
<attributes>
|
||||||
<attribute name="style" value="italic"/>
|
<attribute name="style" value="italic"></attribute>
|
||||||
</attributes>
|
</attributes>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">True</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="pack-type">end</property>
|
|
||||||
<property name="position">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
</template>
|
</template>
|
||||||
</interface>
|
</interface>
|
||||||
|
@ -47,8 +47,9 @@ class CmbTypeChooserPopover(Gtk.Popover):
|
|||||||
|
|
||||||
self._chooser = CmbTypeChooserWidget()
|
self._chooser = CmbTypeChooserWidget()
|
||||||
self._chooser.connect("type-selected", self.__on_type_selected)
|
self._chooser.connect("type-selected", self.__on_type_selected)
|
||||||
self._chooser.show_all()
|
|
||||||
self.add(self._chooser)
|
self.set_child(self._chooser)
|
||||||
|
self.set_default_widget(self._chooser)
|
||||||
|
|
||||||
for prop in [
|
for prop in [
|
||||||
"project",
|
"project",
|
||||||
|
@ -46,7 +46,6 @@ class CmbTypeChooserWidget(Gtk.Box):
|
|||||||
parent_type_id = GObject.Property(type=str, flags=GObject.ParamFlags.READWRITE)
|
parent_type_id = GObject.Property(type=str, flags=GObject.ParamFlags.READWRITE)
|
||||||
derived_type_id = GObject.Property(type=str, flags=GObject.ParamFlags.READWRITE)
|
derived_type_id = GObject.Property(type=str, flags=GObject.ParamFlags.READWRITE)
|
||||||
|
|
||||||
entrycompletion = Gtk.Template.Child()
|
|
||||||
scrolledwindow = Gtk.Template.Child()
|
scrolledwindow = Gtk.Template.Child()
|
||||||
treeview = Gtk.Template.Child()
|
treeview = Gtk.Template.Child()
|
||||||
|
|
||||||
@ -58,7 +57,7 @@ class CmbTypeChooserWidget(Gtk.Box):
|
|||||||
|
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
self.connect("map", self.__on_map)
|
#self.connect("map", self.__on_map)
|
||||||
|
|
||||||
def __type_info_should_append(self, info):
|
def __type_info_should_append(self, info):
|
||||||
retval = False
|
retval = False
|
||||||
@ -152,7 +151,6 @@ class CmbTypeChooserWidget(Gtk.Box):
|
|||||||
if self._filter:
|
if self._filter:
|
||||||
self._filter.set_visible_func(self.__visible_func)
|
self._filter.set_visible_func(self.__visible_func)
|
||||||
|
|
||||||
self.entrycompletion.props.model = self.__model
|
|
||||||
self.treeview.props.model = self._filter
|
self.treeview.props.model = self._filter
|
||||||
|
|
||||||
if project is not None:
|
if project is not None:
|
||||||
@ -191,10 +189,10 @@ class CmbTypeChooserWidget(Gtk.Box):
|
|||||||
return type_id_lower.find(self._search_text) >= 0
|
return type_id_lower.find(self._search_text) >= 0
|
||||||
|
|
||||||
def __on_map(self, widget):
|
def __on_map(self, widget):
|
||||||
toplevel = widget.get_toplevel()
|
root = widget.get_root()
|
||||||
|
|
||||||
if toplevel:
|
if root:
|
||||||
height = toplevel.get_allocated_height() - 100
|
height = root.get_allocated_height() - 100
|
||||||
if height > 460:
|
if height > 460:
|
||||||
height = height * 0.7
|
height = height * 0.7
|
||||||
|
|
||||||
|
@ -1,54 +1,27 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Generated with glade 3.38.2 -->
|
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.24"/>
|
<requires lib="gtk" version="4.0"/>
|
||||||
<object class="GtkEntryCompletion" id="entrycompletion">
|
|
||||||
<property name="text-column">0</property>
|
|
||||||
<property name="inline-completion">True</property>
|
|
||||||
<property name="popup-completion">False</property>
|
|
||||||
<property name="popup-single-match">False</property>
|
|
||||||
</object>
|
|
||||||
<template class="CmbTypeChooserWidget" parent="GtkBox">
|
<template class="CmbTypeChooserWidget" parent="GtkBox">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="border-width">6</property>
|
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
<property name="spacing">6</property>
|
<property name="spacing">6</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkSearchEntry" id="searchentry">
|
<object class="GtkSearchEntry" id="searchentry">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="primary-icon-name">edit-find-symbolic</property>
|
|
||||||
<property name="primary-icon-activatable">False</property>
|
|
||||||
<property name="primary-icon-sensitive">False</property>
|
|
||||||
<property name="completion">entrycompletion</property>
|
|
||||||
<property name="input-hints">GTK_INPUT_HINT_WORD_COMPLETION | GTK_INPUT_HINT_NONE</property>
|
|
||||||
<signal name="activate" handler="on_searchentry_activate" swapped="no"/>
|
<signal name="activate" handler="on_searchentry_activate" swapped="no"/>
|
||||||
<signal name="search-changed" handler="on_searchentry_search_changed" swapped="no"/>
|
<signal name="search-changed" handler="on_searchentry_search_changed" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow" id="scrolledwindow">
|
<object class="GtkScrolledWindow" id="scrolledwindow">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="hscrollbar-policy">never</property>
|
<property name="hscrollbar-policy">never</property>
|
||||||
<property name="window-placement">bottom-left</property>
|
<property name="window-placement">bottom-left</property>
|
||||||
<property name="shadow-type">in</property>
|
|
||||||
<property name="max-content-height">512</property>
|
<property name="max-content-height">512</property>
|
||||||
<property name="propagate-natural-width">True</property>
|
<property name="propagate-natural-width">1</property>
|
||||||
<property name="propagate-natural-height">True</property>
|
<property name="propagate-natural-height">1</property>
|
||||||
<child>
|
<property name="child">
|
||||||
<object class="GtkTreeView" id="treeview">
|
<object class="GtkTreeView" id="treeview">
|
||||||
<property name="visible">True</property>
|
<property name="headers-visible">0</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="enable-search">0</property>
|
||||||
<property name="headers-visible">False</property>
|
<property name="activate-on-single-click">1</property>
|
||||||
<property name="enable-search">False</property>
|
|
||||||
<property name="activate-on-single-click">True</property>
|
|
||||||
<signal name="row-activated" handler="on_treeview_row_activated" swapped="no"/>
|
<signal name="row-activated" handler="on_treeview_row_activated" swapped="no"/>
|
||||||
<child internal-child="selection">
|
<child internal-child="selection">
|
||||||
<object class="GtkTreeSelection" id="treeview-selection"/>
|
<object class="GtkTreeSelection" id="treeview-selection"/>
|
||||||
@ -65,13 +38,8 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
</template>
|
</template>
|
||||||
</interface>
|
</interface>
|
||||||
|
@ -1,142 +1,120 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Generated with glade 3.40.0 -->
|
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.24"/>
|
<requires lib="gtk" version="4.0"/>
|
||||||
<requires lib="gladecambalache" version="0.0"/>
|
|
||||||
<object class="CmbTextBuffer" id="authors"/>
|
<object class="CmbTextBuffer" id="authors"/>
|
||||||
<object class="CmbTextBuffer" id="comment"/>
|
<object class="CmbTextBuffer" id="comment"/>
|
||||||
<object class="CmbTextBuffer" id="copyright"/>
|
<object class="CmbTextBuffer" id="copyright"/>
|
||||||
<object class="CmbTextBuffer" id="description"/>
|
<object class="CmbTextBuffer" id="description"/>
|
||||||
<!-- n-columns=2 n-rows=8 -->
|
|
||||||
<template class="CmbUIEditor" parent="GtkGrid">
|
<template class="CmbUIEditor" parent="GtkGrid">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="row-spacing">4</property>
|
<property name="row-spacing">4</property>
|
||||||
<property name="column-spacing">3</property>
|
<property name="column-spacing">3</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="label" translatable="yes">Filename:</property>
|
<property name="label" translatable="1">Filename:</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">0</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="label" translatable="yes">Description:</property>
|
<property name="label" translatable="1">Description:</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">2</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="label" translatable="yes">Copyright:</property>
|
<property name="label" translatable="1">Copyright:</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">3</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">3</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="label" translatable="yes">Authors:</property>
|
<property name="label" translatable="1">Authors:</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">4</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">4</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="label" translatable="yes">Domain:</property>
|
<property name="label" translatable="1">Domain:</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">5</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">5</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="CmbEntry" id="filename">
|
<object class="CmbEntry" id="filename">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="can-focus">True</property>
|
||||||
<property name="hexpand">True</property>
|
<property name="hexpand">True</property>
|
||||||
<property name="placeholder-text" translatable="yes"><file name relative to project></property>
|
<property name="placeholder-text" translatable="1"><file name relative to project></property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">0</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="CmbEntry" id="translation_domain">
|
<object class="CmbEntry" id="translation_domain">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="can-focus">True</property>
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="width-chars">16</property>
|
<property name="placeholder-text" translatable="1"><translation domain></property>
|
||||||
<property name="placeholder-text" translatable="yes"><translation domain></property>
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">5</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">5</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow">
|
<object class="GtkScrolledWindow">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="shadow-type">in</property>
|
|
||||||
<property name="min-content-height">96</property>
|
<property name="min-content-height">96</property>
|
||||||
<property name="max-content-height">256</property>
|
<property name="max-content-height">256</property>
|
||||||
<child>
|
<property name="child">
|
||||||
<object class="GtkTextView">
|
<object class="GtkTextView">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="buffer">description</property>
|
<property name="buffer">description</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">2</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow">
|
<object class="GtkScrolledWindow">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="shadow-type">in</property>
|
|
||||||
<property name="min-content-height">96</property>
|
<property name="min-content-height">96</property>
|
||||||
<property name="max-content-height">256</property>
|
<property name="max-content-height">256</property>
|
||||||
<child>
|
<property name="child">
|
||||||
<object class="GtkTextView">
|
<object class="GtkTextView">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="buffer">authors</property>
|
<property name="buffer">authors</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">4</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">4</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="CmbToplevelChooser" id="template_id">
|
<object class="CmbToplevelChooser" id="template_id">
|
||||||
@ -144,129 +122,102 @@
|
|||||||
<property name="can-focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="derivable-only">True</property>
|
<property name="derivable-only">True</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">1</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="label" translatable="yes">Template:</property>
|
<property name="label" translatable="1">Template:</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">1</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="valign">end</property>
|
<property name="valign">end</property>
|
||||||
<property name="vexpand">True</property>
|
<property name="vexpand">1</property>
|
||||||
<property name="spacing">4</property>
|
<property name="spacing">4</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="remove_button">
|
<object class="GtkButton" id="remove_button">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="receives-default">1</property>
|
||||||
<property name="receives-default">True</property>
|
|
||||||
<signal name="clicked" handler="on_remove_button_clicked" swapped="no"/>
|
<signal name="clicked" handler="on_remove_button_clicked" swapped="no"/>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="icon-name">app-remove-symbolic</property>
|
<property name="icon-name">app-remove-symbolic</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="export_button">
|
<object class="GtkButton" id="export_button">
|
||||||
<property name="label" translatable="yes">Export</property>
|
<property name="label" translatable="1">Export</property>
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="receives-default">1</property>
|
||||||
<property name="receives-default">True</property>
|
<property name="tooltip-text" translatable="1">Export</property>
|
||||||
<property name="tooltip-text" translatable="yes">Export</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<signal name="clicked" handler="on_export_button_clicked" swapped="no"/>
|
<signal name="clicked" handler="on_export_button_clicked" swapped="no"/>
|
||||||
<style>
|
<style>
|
||||||
<class name="suggested-action"/>
|
<class name="suggested-action"/>
|
||||||
</style>
|
</style>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="pack-type">end</property>
|
|
||||||
<property name="position">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">7</property>
|
||||||
|
<property name="column-span">2</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">7</property>
|
|
||||||
<property name="width">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow">
|
<object class="GtkScrolledWindow">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="shadow-type">in</property>
|
|
||||||
<property name="min-content-height">96</property>
|
<property name="min-content-height">96</property>
|
||||||
<property name="max-content-height">256</property>
|
<property name="max-content-height">256</property>
|
||||||
<child>
|
<property name="child">
|
||||||
<object class="GtkTextView">
|
<object class="GtkTextView">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="buffer">copyright</property>
|
<property name="buffer">copyright</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">3</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">3</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="label" translatable="yes">Comment:</property>
|
<property name="label" translatable="1">Comment:</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">6</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">6</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow">
|
<object class="GtkScrolledWindow">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="shadow-type">in</property>
|
|
||||||
<property name="min-content-height">96</property>
|
<property name="min-content-height">96</property>
|
||||||
<property name="max-content-height">256</property>
|
<property name="max-content-height">256</property>
|
||||||
<child>
|
<property name="child">
|
||||||
<object class="GtkTextView">
|
<object class="GtkTextView">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="buffer">comment</property>
|
<property name="buffer">comment</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">6</property>
|
||||||
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">6</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
</template>
|
</template>
|
||||||
</interface>
|
</interface>
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
from gi.repository import GObject, Gtk
|
from gi.repository import GObject, Gtk
|
||||||
|
|
||||||
from .cmb_ui import CmbUI
|
from .cmb_ui import CmbUI
|
||||||
|
from . import utils
|
||||||
|
|
||||||
|
|
||||||
class CmbUIRequiresEditor(Gtk.Grid):
|
class CmbUIRequiresEditor(Gtk.Grid):
|
||||||
@ -71,7 +72,7 @@ class CmbUIRequiresEditor(Gtk.Grid):
|
|||||||
def __update(self):
|
def __update(self):
|
||||||
self.__combos = {}
|
self.__combos = {}
|
||||||
|
|
||||||
for child in self.get_children():
|
for child in utils.widget_get_children(self):
|
||||||
self.remove(child)
|
self.remove(child)
|
||||||
|
|
||||||
if self.__object is None:
|
if self.__object is None:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# CmbView - Cambalache View
|
# CmbView - Cambalache View
|
||||||
#
|
#
|
||||||
# Copyright (C) 2021 Juan Pablo Ugarte
|
# Copyright (C) 2021-2024 Juan Pablo Ugarte
|
||||||
#
|
#
|
||||||
# This library is free software; you can redistribute it and/or
|
# This library is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU Lesser General Public
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
@ -27,20 +27,21 @@ import socket
|
|||||||
import time
|
import time
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from gi.repository import GObject, GLib, Gtk, WebKit2
|
from gi.repository import GObject, GLib, Gtk, WebKit
|
||||||
|
|
||||||
from . import config
|
from . import config
|
||||||
from .cmb_ui import CmbUI
|
from .cmb_ui import CmbUI
|
||||||
from .cmb_object import CmbObject
|
from .cmb_object import CmbObject
|
||||||
from .cmb_context_menu import CmbContextMenu
|
from .cmb_context_menu import CmbContextMenu
|
||||||
|
from . import utils
|
||||||
from cambalache import getLogger, _
|
from cambalache import getLogger, _
|
||||||
|
|
||||||
logger = getLogger(__name__)
|
logger = getLogger(__name__)
|
||||||
|
|
||||||
basedir = os.path.dirname(__file__) or "."
|
basedir = os.path.dirname(__file__) or "."
|
||||||
|
|
||||||
GObject.type_ensure(WebKit2.Settings.__gtype__)
|
GObject.type_ensure(WebKit.Settings.__gtype__)
|
||||||
GObject.type_ensure(WebKit2.WebView.__gtype__)
|
GObject.type_ensure(WebKit.WebView.__gtype__)
|
||||||
|
|
||||||
|
|
||||||
class CmbProcess(GObject.Object):
|
class CmbProcess(GObject.Object):
|
||||||
@ -111,7 +112,7 @@ class CmbProcess(GObject.Object):
|
|||||||
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path="/ar/xjuan/Cambalache/cmb_view.ui")
|
@Gtk.Template(resource_path="/ar/xjuan/Cambalache/cmb_view.ui")
|
||||||
class CmbView(Gtk.Stack):
|
class CmbView(Gtk.Box):
|
||||||
__gtype_name__ = "CmbView"
|
__gtype_name__ = "CmbView"
|
||||||
|
|
||||||
__gsignals__ = {
|
__gsignals__ = {
|
||||||
@ -121,6 +122,7 @@ class CmbView(Gtk.Stack):
|
|||||||
|
|
||||||
preview = GObject.Property(type=bool, default=False, flags=GObject.ParamFlags.READWRITE)
|
preview = GObject.Property(type=bool, default=False, flags=GObject.ParamFlags.READWRITE)
|
||||||
|
|
||||||
|
stack = Gtk.Template.Child()
|
||||||
webview = Gtk.Template.Child()
|
webview = Gtk.Template.Child()
|
||||||
text_view = Gtk.Template.Child()
|
text_view = Gtk.Template.Child()
|
||||||
|
|
||||||
@ -129,6 +131,7 @@ class CmbView(Gtk.Stack):
|
|||||||
self.__restart_project = None
|
self.__restart_project = None
|
||||||
self.__ui_id = 0
|
self.__ui_id = 0
|
||||||
self.__theme = None
|
self.__theme = None
|
||||||
|
self.__dark = False
|
||||||
|
|
||||||
self.menu = self.__create_context_menu()
|
self.menu = self.__create_context_menu()
|
||||||
|
|
||||||
@ -145,23 +148,12 @@ class CmbView(Gtk.Stack):
|
|||||||
self.__port = None
|
self.__port = None
|
||||||
self.__merengue_last_exit = None
|
self.__merengue_last_exit = None
|
||||||
|
|
||||||
context = self.get_style_context()
|
|
||||||
context.connect("changed", lambda ctx: self.__update_webview_bg())
|
|
||||||
|
|
||||||
if self.__broadwayd_bin is None:
|
if self.__broadwayd_bin is None:
|
||||||
logger.warning("broadwayd not found, Gtk 3 workspace wont work.")
|
logger.warning("broadwayd not found, Gtk 3 workspace wont work.")
|
||||||
|
|
||||||
if self.__gtk4_broadwayd_bin is None:
|
if self.__gtk4_broadwayd_bin is None:
|
||||||
logger.warning("gtk4-broadwayd not found, Gtk 4 workspace wont work.")
|
logger.warning("gtk4-broadwayd not found, Gtk 4 workspace wont work.")
|
||||||
|
|
||||||
GObject.Object.bind_property(
|
|
||||||
self,
|
|
||||||
"gtk-theme",
|
|
||||||
self.menu,
|
|
||||||
"gtk-theme",
|
|
||||||
GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.connect("notify::preview", self.__on_preview_notify)
|
self.connect("notify::preview", self.__on_preview_notify)
|
||||||
|
|
||||||
def do_destroy(self):
|
def do_destroy(self):
|
||||||
@ -174,23 +166,18 @@ class CmbView(Gtk.Stack):
|
|||||||
def __evaluate_js(self, script):
|
def __evaluate_js(self, script):
|
||||||
self.webview.evaluate_javascript(script, -1, None, None, None, None, None, None)
|
self.webview.evaluate_javascript(script, -1, None, None, None, None, None, None)
|
||||||
|
|
||||||
def __update_webview_bg(self):
|
def _set_dark_mode(self, dark):
|
||||||
context = self.get_style_context()
|
self.__dark = dark
|
||||||
|
self.__evaluate_js(f"document.body.style.background = '{'#222' if dark else 'inherit'}';")
|
||||||
with warnings.catch_warnings():
|
|
||||||
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
|
||||||
bg = context.get_background_color(Gtk.StateFlags.NORMAL)
|
|
||||||
|
|
||||||
self.__evaluate_js(f"document.body.style.background = '{bg.to_string()}';")
|
|
||||||
|
|
||||||
def __on_load_changed(self, webview, event):
|
def __on_load_changed(self, webview, event):
|
||||||
if event != WebKit2.LoadEvent.FINISHED:
|
if event != WebKit.LoadEvent.FINISHED:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.__update_webview_bg()
|
self._set_dark_mode(self.__dark)
|
||||||
|
|
||||||
# Disable alert() function used when broadwayd get disconnected
|
# Disable alert() function used when broadwayd get disconnected
|
||||||
# Monkey patch setupDocument() to avoid disabling document.oncontextmenu
|
# Monkey pat ch setupDocument() to avoid disabling document.oncontextmenu
|
||||||
self.__evaluate_js(
|
self.__evaluate_js(
|
||||||
"""
|
"""
|
||||||
window.alert = function (message) {
|
window.alert = function (message) {
|
||||||
@ -232,7 +219,7 @@ window.setupDocument = function (document) {
|
|||||||
|
|
||||||
def __update_view(self):
|
def __update_view(self):
|
||||||
if self.__project is not None and self.__ui_id > 0:
|
if self.__project is not None and self.__ui_id > 0:
|
||||||
if self.props.visible_child_name == "ui_xml":
|
if self.stack.props.visible_child_name == "ui_xml":
|
||||||
ui = self.__get_ui_xml(self.__ui_id)
|
ui = self.__get_ui_xml(self.__ui_id)
|
||||||
self.text_view.buffer.set_text(ui)
|
self.text_view.buffer.set_text(ui)
|
||||||
return
|
return
|
||||||
@ -468,8 +455,8 @@ window.setupDocument = function (document) {
|
|||||||
self.__merengue_command("gtk_settings_set", args={"property": "gtk-theme-name", "value": theme})
|
self.__merengue_command("gtk_settings_set", args={"property": "gtk-theme-name", "value": theme})
|
||||||
|
|
||||||
@Gtk.Template.Callback("on_context_menu")
|
@Gtk.Template.Callback("on_context_menu")
|
||||||
def __on_context_menu(self, webview, menu, e, hit_test_result):
|
def __on_context_menu(self, webview, menu, hit_test_result):
|
||||||
self.menu.popup_at(e.x, e.y)
|
self.menu.popup_at(*utils.get_pointer(self))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def __webview_set_msg(self, msg):
|
def __webview_set_msg(self, msg):
|
||||||
@ -494,25 +481,20 @@ window.setupDocument = function (document) {
|
|||||||
if bin is not None:
|
if bin is not None:
|
||||||
self.__webview_set_msg(_("Workspace not available\n{bin} executable not found").format(bin=bin))
|
self.__webview_set_msg(_("Workspace not available\n{bin} executable not found").format(bin=bin))
|
||||||
|
|
||||||
def __on_inspect_button_clicked(self, button):
|
def inspect(self):
|
||||||
self.props.visible_child_name = "ui_xml"
|
self.stack.props.visible_child_name = "ui_xml"
|
||||||
self.__update_view()
|
self.__update_view()
|
||||||
|
|
||||||
def __on_restart_button_clicked(self, button):
|
def restart_workspace(self):
|
||||||
self.__restart_project = self.__project
|
self.__restart_project = self.__project
|
||||||
self.project = None
|
self.project = None
|
||||||
|
|
||||||
def __create_context_menu(self):
|
def __create_context_menu(self):
|
||||||
retval = CmbContextMenu(relative_to=self)
|
retval = CmbContextMenu()
|
||||||
|
retval.set_parent(self)
|
||||||
|
|
||||||
restart = Gtk.ModelButton(text=_("Restart workspace"), visible=True)
|
retval.main_section.append(_("Restart workspace"), "win.workspace_restart")
|
||||||
restart.connect("clicked", self.__on_restart_button_clicked)
|
retval.main_section.append(_("Inspect UI definition"), "win.inspect")
|
||||||
|
|
||||||
inspect = Gtk.ModelButton(text=_("Inspect UI definition"), visible=True)
|
|
||||||
inspect.connect("clicked", self.__on_inspect_button_clicked)
|
|
||||||
|
|
||||||
retval.main_box.add(restart)
|
|
||||||
retval.main_box.add(inspect)
|
|
||||||
|
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
|
@ -1,87 +1,73 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Generated with glade 3.38.2 -->
|
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.24"/>
|
<requires lib="gtk" version="4.0"/>
|
||||||
<requires lib="webkit2gtk" version="2.28"/>
|
<object class="WebKitSettings" id="settings">
|
||||||
<object class="WebKitSettings" type-func="webkit_settings_get_type" id="settings">
|
|
||||||
<property name="enable-html5-local-storage">False</property>
|
<property name="enable-html5-local-storage">False</property>
|
||||||
<property name="enable-html5-database">False</property>
|
<property name="enable-html5-database">False</property>
|
||||||
<property name="enable-java">False</property>
|
|
||||||
<property name="enable-fullscreen">False</property>
|
<property name="enable-fullscreen">False</property>
|
||||||
<property name="enable-webaudio">False</property>
|
<property name="enable-webaudio">False</property>
|
||||||
<property name="media-playback-allows-inline">False</property>
|
<property name="media-playback-allows-inline">False</property>
|
||||||
<property name="user-agent">Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15</property>
|
<property name="user-agent">Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15</property>
|
||||||
<property name="enable-accelerated-2d-canvas">True</property>
|
|
||||||
<property name="enable-media">False</property>
|
<property name="enable-media">False</property>
|
||||||
</object>
|
</object>
|
||||||
<template class="CmbView" parent="GtkStack">
|
<template class="CmbView" parent="GtkBox">
|
||||||
<property name="visible">True</property>
|
<child>
|
||||||
<property name="can-focus">False</property>
|
<object class="GtkStack" id="stack">
|
||||||
<property name="events">GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
|
<property name="hexpand">true</property>
|
||||||
<property name="transition-duration">300</property>
|
<property name="transition-duration">300</property>
|
||||||
<property name="transition-type">crossfade</property>
|
<property name="transition-type">crossfade</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="WebKitWebView" type-func="webkit_web_view_get_type" id="webview">
|
<object class="GtkStackPage">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="settings">settings</property>
|
|
||||||
<signal name="context-menu" handler="on_context_menu" swapped="no"/>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="name">ui_view</property>
|
<property name="name">ui_view</property>
|
||||||
<property name="title" translatable="yes">Project View</property>
|
<property name="title" translatable="1">Project View</property>
|
||||||
</packing>
|
<property name="child">
|
||||||
</child>
|
<object class="WebKitWebView" id="webview">
|
||||||
<child>
|
|
||||||
<object class="GtkBox">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkScrolledWindow">
|
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="can-focus">True</property>
|
||||||
<property name="shadow-type">in</property>
|
<property name="settings">settings</property>
|
||||||
|
<signal name="context-menu" handler="on_context_menu" swapped="no"/>
|
||||||
<child>
|
<child>
|
||||||
<object class="CmbSourceView" id="text_view">
|
<placeholder/>
|
||||||
<property name="visible">True</property>
|
</child>
|
||||||
<property name="can-focus">True</property>
|
</object>
|
||||||
<property name="editable">False</property>
|
</property>
|
||||||
<property name="cursor-visible">False</property>
|
</object>
|
||||||
<property name="lang">xml</property>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkStackPage">
|
||||||
|
<property name="name">ui_xml</property>
|
||||||
|
<property name="title" translatable="1">UI Definition</property>
|
||||||
|
<property name="child">
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow">
|
||||||
|
<property name="vexpand">1</property>
|
||||||
|
<property name="focusable">1</property>
|
||||||
|
<child>
|
||||||
|
<object class="CmbSourceView" id="text_view">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="editable">False</property>
|
||||||
|
<property name="cursor-visible">False</property>
|
||||||
|
<property name="lang">xml</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkStackSwitcher">
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="margin-top">4</property>
|
||||||
|
<property name="margin-bottom">4</property>
|
||||||
|
<property name="stack">CmbView</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
</property>
|
||||||
<property name="expand">True</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkStackSwitcher">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">center</property>
|
|
||||||
<property name="margin-top">4</property>
|
|
||||||
<property name="margin-bottom">4</property>
|
|
||||||
<property name="stack">CmbView</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="name">ui_xml</property>
|
|
||||||
<property name="title" translatable="yes">UI Definition</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
</template>
|
</template>
|
||||||
</interface>
|
</interface>
|
||||||
|
@ -35,23 +35,30 @@ class CmbColorEntry(Gtk.Box):
|
|||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
self.entry = Gtk.Entry(visible=True, width_chars=14, editable=False)
|
self.entry = Gtk.Entry(visible=True, width_chars=14, editable=False)
|
||||||
self.button = Gtk.ColorButton(visible=True, use_alpha=True)
|
self.button = Gtk.ColorDialogButton(
|
||||||
|
visible=True,
|
||||||
|
dialog=Gtk.ColorDialog()
|
||||||
|
)
|
||||||
|
|
||||||
self.__default_color = self.button.props.color
|
#self.__default_color = self.button.props.color
|
||||||
self.__default_rgba = self.button.props.rgba
|
self.__default_rgba = self.button.props.rgba
|
||||||
|
|
||||||
self.pack_start(self.entry, False, True, 0)
|
self.append(self.entry)
|
||||||
self.pack_start(self.button, False, True, 4)
|
self.append(self.button)
|
||||||
|
|
||||||
self.button.connect("color-set", self.__on_color_set)
|
# FIXME: GTK4
|
||||||
|
self.button.connect("notify::rgba", self.__on_color_set)
|
||||||
self.entry.connect("icon-press", self.__on_entry_icon_pressed)
|
self.entry.connect("icon-press", self.__on_entry_icon_pressed)
|
||||||
|
|
||||||
def __on_entry_icon_pressed(self, widget, icon_pos, event):
|
def __on_entry_icon_pressed(self, widget, icon_pos, event):
|
||||||
self.cmb_value = None
|
self.cmb_value = None
|
||||||
|
|
||||||
def __on_color_set(self, obj):
|
def __on_color_set(self, obj, pspec):
|
||||||
|
print(self.use_color, self.button.props.rgba.to_string())
|
||||||
if self.use_color:
|
if self.use_color:
|
||||||
self.cmb_value = self.button.props.color.to_string() if self.button.props.color else None
|
pass
|
||||||
|
# FIXME: GTK4
|
||||||
|
#self.cmb_value = self.button.props.color.to_string() if self.button.props.color else None
|
||||||
else:
|
else:
|
||||||
self.cmb_value = self.button.props.rgba.to_string() if self.button.props.rgba else None
|
self.cmb_value = self.button.props.rgba.to_string() if self.button.props.rgba else None
|
||||||
|
|
||||||
@ -75,7 +82,8 @@ class CmbColorEntry(Gtk.Box):
|
|||||||
if value:
|
if value:
|
||||||
valid, color = Gdk.Color.parse(value)
|
valid, color = Gdk.Color.parse(value)
|
||||||
|
|
||||||
self.button.set_color(color if valid else self.__default_color)
|
# FIXME: GTK4
|
||||||
|
#self.button.set_color(color if valid else self.__default_color)
|
||||||
else:
|
else:
|
||||||
rgba = Gdk.RGBA()
|
rgba = Gdk.RGBA()
|
||||||
|
|
||||||
|
@ -37,8 +37,9 @@ class CmbEntry(Gtk.Entry):
|
|||||||
self.props.secondary_icon_name = "document-edit-symbolic"
|
self.props.secondary_icon_name = "document-edit-symbolic"
|
||||||
self.connect("icon-press", self.__on_icon_pressed)
|
self.connect("icon-press", self.__on_icon_pressed)
|
||||||
|
|
||||||
def __on_icon_pressed(self, widget, icon_pos, event):
|
def __on_icon_pressed(self, widget, icon_pos):
|
||||||
popover = CmbTranslatablePopover(relative_to=self)
|
popover = CmbTranslatablePopover()
|
||||||
|
popover.set_parent(self)
|
||||||
popover.bind_properties(self._target)
|
popover.bind_properties(self._target)
|
||||||
popover.popup()
|
popover.popup()
|
||||||
|
|
||||||
|
@ -47,14 +47,16 @@ class CmbFlagsEntry(Gtk.Entry):
|
|||||||
self.__init_popover()
|
self.__init_popover()
|
||||||
|
|
||||||
def __init_popover(self):
|
def __init_popover(self):
|
||||||
self._popover = Gtk.Popover(relative_to=self)
|
self._popover = Gtk.Popover()
|
||||||
|
self._popover.set_parent(self)
|
||||||
|
|
||||||
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||||
box.pack_start(Gtk.Label(label=f"<b>{self.info.type_id}</b>", use_markup=True), False, True, 4)
|
box.prepend(Gtk.Label(label=f"<b>{self.info.type_id}</b>", use_markup=True))
|
||||||
box.pack_start(Gtk.Separator(), False, False, 0)
|
box.prepend(Gtk.Separator())
|
||||||
sw = Gtk.ScrolledWindow(hscrollbar_policy=Gtk.PolicyType.NEVER, propagate_natural_height=True, max_content_height=360)
|
sw = Gtk.ScrolledWindow(hscrollbar_policy=Gtk.PolicyType.NEVER, propagate_natural_height=True, max_content_height=360)
|
||||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||||
sw.add(vbox)
|
sw.set_child(vbox)
|
||||||
box.pack_start(sw, True, True, 0)
|
box.prepend(sw)
|
||||||
|
|
||||||
for row in self.info.flags:
|
for row in self.info.flags:
|
||||||
flag = row[self.text_column]
|
flag = row[self.text_column]
|
||||||
@ -62,18 +64,17 @@ class CmbFlagsEntry(Gtk.Entry):
|
|||||||
|
|
||||||
check = Gtk.CheckButton(label=flag)
|
check = Gtk.CheckButton(label=flag)
|
||||||
check.connect("toggled", self.__on_check_toggled, flag_id)
|
check.connect("toggled", self.__on_check_toggled, flag_id)
|
||||||
vbox.pack_start(check, False, True, 4)
|
vbox.prepend(check)
|
||||||
self._checks[flag_id] = check
|
self._checks[flag_id] = check
|
||||||
|
|
||||||
box.show_all()
|
self._popover.set_child(box)
|
||||||
self._popover.add(box)
|
|
||||||
|
|
||||||
def __on_check_toggled(self, check, flag_id):
|
def __on_check_toggled(self, check, flag_id):
|
||||||
self.flags[flag_id] = check.props.active
|
self.flags[flag_id] = check.props.active
|
||||||
self.props.text = self.__to_string()
|
self.props.text = self.__to_string()
|
||||||
self.notify("cmb-value")
|
self.notify("cmb-value")
|
||||||
|
|
||||||
def __on_icon_release(self, obj, pos, event):
|
def __on_icon_release(self, obj, pos):
|
||||||
self._popover.popup()
|
self._popover.popup()
|
||||||
|
|
||||||
def __to_string(self):
|
def __to_string(self):
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from cambalache import _
|
from cambalache import _
|
||||||
from gi.repository import GdkPixbuf, GObject, Gtk, Pango
|
from gi.repository import GLib, Gio, GdkPixbuf, GObject, Gdk, Gtk, Pango
|
||||||
from .cmb_entry import CmbEntry
|
from .cmb_entry import CmbEntry
|
||||||
from .icon_naming_spec import standard_icon_context, standard_icon_names
|
from .icon_naming_spec import standard_icon_context, standard_icon_names
|
||||||
|
|
||||||
@ -48,6 +48,8 @@ class CmbIconNameEntry(CmbEntry):
|
|||||||
# Model, store it in a Python class variable to share between all instances
|
# Model, store it in a Python class variable to share between all instances
|
||||||
icon_model = None
|
icon_model = None
|
||||||
|
|
||||||
|
iconlist = []
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
self._filters = {}
|
self._filters = {}
|
||||||
|
|
||||||
@ -91,32 +93,56 @@ class CmbIconNameEntry(CmbEntry):
|
|||||||
|
|
||||||
iconlist = []
|
iconlist = []
|
||||||
|
|
||||||
theme = Gtk.IconTheme.get_default()
|
theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default())
|
||||||
|
|
||||||
for context in theme.list_contexts():
|
# FIXME: get the context/category of each icon
|
||||||
for icon in theme.list_icons(context):
|
for icon in theme.get_icon_names():
|
||||||
iconlist.append((icon, context, icon in standard_icon_names))
|
iconlist.append((icon, "cmb_all", icon in standard_icon_names))
|
||||||
|
|
||||||
for icon, context, standard in sorted(iconlist, key=lambda i: i[0].lower()):
|
for icon, context, standard in sorted(iconlist, key=lambda i: i[0].lower()):
|
||||||
if icon.endswith(".symbolic"):
|
if icon.endswith(".symbolic"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
info = theme.lookup_icon(icon, 32, Gtk.IconLookupFlags.FORCE_SIZE)
|
icon_paintable = theme.lookup_icon(icon, None, 32, 1, Gtk.TextDirection.NONE, Gtk.IconLookupFlags.PRELOAD)
|
||||||
symbolic = info.is_symbolic()
|
symbolic = icon_paintable.is_symbolic()
|
||||||
|
|
||||||
if not os.path.exists(info.get_filename()):
|
icon_file = icon_paintable.get_file()
|
||||||
|
if icon_file is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
icon_path = icon_file.get_path()
|
||||||
|
if icon_path is None or not os.path.exists(icon_path):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
standard_symbolic = symbolic and icon.removesuffix("-symbolic") in standard_icon_names
|
standard_symbolic = symbolic and icon.removesuffix("-symbolic") in standard_icon_names
|
||||||
|
|
||||||
iter = cls.icon_model.append(
|
try:
|
||||||
[icon, icon if standard else f"<i>{icon}</i>", context, standard, symbolic, standard_symbolic, None]
|
iter = cls.icon_model.append(
|
||||||
)
|
[icon, icon if standard else f"<i>{icon}</i>", context, standard, symbolic, standard_symbolic, None]
|
||||||
info.load_icon_async(None, cls.__load_icon_finish, iter)
|
)
|
||||||
|
cls.iconlist.append((icon_file, iter))
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
# Kickoff async loading
|
||||||
|
file, iter = cls.iconlist.pop()
|
||||||
|
file.read_async(GLib.PRIORITY_DEFAULT, None, cls.__load_file_finish, iter)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __load_icon_finish(cls, info, res, data):
|
def __load_file_finish(cls, obj, res, iter):
|
||||||
cls.icon_model[data][6] = info.load_icon_finish(res)
|
stream = obj.read_finish(res)
|
||||||
|
GdkPixbuf.Pixbuf.new_from_stream_at_scale_async(stream, 32, 32, True, None, cls.__load_icon_finish, iter)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def __load_icon_finish(cls, obj, res, iter):
|
||||||
|
try:
|
||||||
|
cls.icon_model[iter][cls.COL_PIXBUF] = GdkPixbuf.Pixbuf.new_from_stream_finish(res)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
if len(cls.iconlist):
|
||||||
|
file, iter = cls.iconlist.pop()
|
||||||
|
file.read_async(GLib.PRIORITY_DEFAULT, None, cls.__load_file_finish, iter)
|
||||||
|
|
||||||
def __model_filter_func(self, model, iter, data):
|
def __model_filter_func(self, model, iter, data):
|
||||||
if self.standard_only and self.symbolic_only:
|
if self.standard_only and self.symbolic_only:
|
||||||
@ -146,20 +172,23 @@ class CmbIconNameEntry(CmbEntry):
|
|||||||
else:
|
else:
|
||||||
self.cmb_value = None
|
self.cmb_value = None
|
||||||
|
|
||||||
def __on_icon_pressed(self, widget, icon_pos, event):
|
def __on_icon_pressed(self, widget, icon_pos):
|
||||||
# Create popover with icon chooser
|
# Create popover with icon chooser
|
||||||
popover = Gtk.Popover(relative_to=self)
|
popover = Gtk.Popover()
|
||||||
|
popover.set_parent(self)
|
||||||
|
|
||||||
hbox = Gtk.Box(visible=True)
|
hbox = Gtk.Box(visible=True)
|
||||||
vbox = Gtk.Box(visible=True, orientation=Gtk.Orientation.VERTICAL, vexpand=True)
|
vbox = Gtk.Box(visible=True, orientation=Gtk.Orientation.VERTICAL, vexpand=True)
|
||||||
stack = Gtk.Stack(visible=True, transition_type=Gtk.StackTransitionType.CROSSFADE)
|
stack = Gtk.Stack(visible=True, transition_type=Gtk.StackTransitionType.CROSSFADE)
|
||||||
sidebar = Gtk.StackSidebar(visible=True, stack=stack, vexpand=True)
|
sidebar = Gtk.StackSidebar(visible=True, stack=stack, vexpand=True)
|
||||||
vbox.pack_start(sidebar, True, True, 4)
|
vbox.append(sidebar)
|
||||||
hbox.pack_start(vbox, False, True, 4)
|
hbox.append(vbox)
|
||||||
hbox.pack_start(stack, True, True, 4)
|
hbox.append(stack)
|
||||||
|
|
||||||
theme = Gtk.IconTheme.get_default()
|
theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default())
|
||||||
|
|
||||||
sorted_contexts = sorted(theme.list_contexts())
|
# sorted_contexts = sorted(theme.list_contexts())
|
||||||
|
sorted_contexts = []
|
||||||
sorted_contexts.insert(0, "cmb_all")
|
sorted_contexts.insert(0, "cmb_all")
|
||||||
|
|
||||||
# Add one icon view per context
|
# Add one icon view per context
|
||||||
@ -175,7 +204,7 @@ class CmbIconNameEntry(CmbEntry):
|
|||||||
sw = Gtk.ScrolledWindow(visible=True, min_content_width=600, min_content_height=480)
|
sw = Gtk.ScrolledWindow(visible=True, min_content_width=600, min_content_height=480)
|
||||||
view = Gtk.IconView(visible=True, model=filter, pixbuf_column=self.COL_PIXBUF, text_column=self.COL_ICON_NAME)
|
view = Gtk.IconView(visible=True, model=filter, pixbuf_column=self.COL_PIXBUF, text_column=self.COL_ICON_NAME)
|
||||||
view.connect("selection-changed", self.__on_view_selection_changed)
|
view.connect("selection-changed", self.__on_view_selection_changed)
|
||||||
sw.add(view)
|
sw.set_child(view)
|
||||||
stack.add_titled(sw, context, standard_icon_context.get(context, context))
|
stack.add_titled(sw, context, standard_icon_context.get(context, context))
|
||||||
|
|
||||||
# Add filters
|
# Add filters
|
||||||
@ -185,8 +214,8 @@ class CmbIconNameEntry(CmbEntry):
|
|||||||
self, prop, check, "active", GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL
|
self, prop, check, "active", GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL
|
||||||
)
|
)
|
||||||
check.connect_after("notify::active", self.__on_check_active_notify)
|
check.connect_after("notify::active", self.__on_check_active_notify)
|
||||||
vbox.pack_start(check, False, True, 4)
|
vbox.append(check)
|
||||||
|
|
||||||
popover.get_style_context().add_class("cmb-icon-chooser")
|
popover.add_css_class("cmb-icon-chooser")
|
||||||
popover.add(hbox)
|
popover.set_child(hbox)
|
||||||
popover.popup()
|
popover.popup()
|
||||||
|
@ -106,7 +106,7 @@ class CmbObjectChooser(Gtk.Entry):
|
|||||||
parent.project.add_object(parent.ui_id, info.type_id, parent_id=parent.object_id, inline_property=self.prop.property_id)
|
parent.project.add_object(parent.ui_id, info.type_id, parent_id=parent.object_id, inline_property=self.prop.property_id)
|
||||||
self.__update_icons()
|
self.__update_icons()
|
||||||
|
|
||||||
def __on_icon_pressed(self, widget, icon_pos, event):
|
def __on_icon_pressed(self, widget, icon_pos):
|
||||||
parent = self.parent
|
parent = self.parent
|
||||||
project = parent.project
|
project = parent.project
|
||||||
prop = self.prop
|
prop = self.prop
|
||||||
@ -116,7 +116,8 @@ class CmbObjectChooser(Gtk.Entry):
|
|||||||
project.remove_object(obj)
|
project.remove_object(obj)
|
||||||
self.__update_icons()
|
self.__update_icons()
|
||||||
else:
|
else:
|
||||||
chooser = CmbTypeChooserPopover(relative_to=self, parent_type_id=parent.type_id, derived_type_id=prop.info.type_id)
|
chooser = CmbTypeChooserPopover(parent_type_id=parent.type_id, derived_type_id=prop.info.type_id)
|
||||||
|
chooser.set_parent(self)
|
||||||
chooser.project = project
|
chooser.project = project
|
||||||
chooser.connect("type-selected", self.__on_type_selected)
|
chooser.connect("type-selected", self.__on_type_selected)
|
||||||
chooser.popup()
|
chooser.popup()
|
||||||
|
@ -33,7 +33,6 @@ class CmbTextView(Gtk.ScrolledWindow):
|
|||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
self.props.shadow_type = Gtk.ShadowType.IN
|
|
||||||
self.props.height_request = 64
|
self.props.height_request = 64
|
||||||
self.buffer = CmbTextBuffer()
|
self.buffer = CmbTextBuffer()
|
||||||
self.view = Gtk.TextView(visible=True, buffer=self.buffer)
|
self.view = Gtk.TextView(visible=True, buffer=self.buffer)
|
||||||
@ -46,4 +45,4 @@ class CmbTextView(Gtk.ScrolledWindow):
|
|||||||
GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL,
|
GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.add(self.view)
|
self.set_child(self.view)
|
||||||
|
@ -35,14 +35,13 @@ class CmbTranslatablePopover(Gtk.Popover):
|
|||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||||
box.pack_start(Gtk.Label(label=_("<b>Translation</b>"), use_markup=True), False, True, 4)
|
box.append(Gtk.Label(label=_("<b>Translation</b>"), use_markup=True))
|
||||||
box.pack_start(Gtk.Separator(), False, False, 0)
|
box.append(Gtk.Separator())
|
||||||
|
|
||||||
self._translation = CmbTranslatableWidget()
|
self._translation = CmbTranslatableWidget()
|
||||||
box.pack_start(self._translation, False, False, 0)
|
box.append(self._translation)
|
||||||
|
|
||||||
box.show_all()
|
self.set_child(box)
|
||||||
self.add(box)
|
|
||||||
|
|
||||||
def bind_properties(self, target):
|
def bind_properties(self, target):
|
||||||
self._translation.bind_properties(target)
|
self._translation.bind_properties(target)
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Generated with glade 3.38.2 -->
|
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.24"/>
|
<requires lib="gtk" version="4.0"/>
|
||||||
<object class="GtkTextBuffer" id="buffer_comments"/>
|
<object class="GtkTextBuffer" id="buffer_comments"/>
|
||||||
<object class="GtkTextBuffer" id="buffer_context"/>
|
<object class="GtkTextBuffer" id="buffer_context"/>
|
||||||
<object class="GtkTextBuffer" id="buffer_text"/>
|
<object class="GtkTextBuffer" id="buffer_text"/>
|
||||||
<template class="CmbTranslatableWidget" parent="GtkBox">
|
<template class="CmbTranslatableWidget" parent="GtkBox">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="margin-start">4</property>
|
<property name="margin-start">4</property>
|
||||||
<property name="margin-end">4</property>
|
<property name="margin-end">4</property>
|
||||||
<property name="margin-top">4</property>
|
<property name="margin-top">4</property>
|
||||||
@ -16,126 +13,70 @@
|
|||||||
<property name="spacing">4</property>
|
<property name="spacing">4</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="label" translatable="yes">Text:</property>
|
<property name="label" translatable="1">Text:</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow">
|
<object class="GtkScrolledWindow">
|
||||||
<property name="width-request">300</property>
|
<property name="width-request">300</property>
|
||||||
<property name="height-request">60</property>
|
<property name="height-request">60</property>
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="child">
|
||||||
<property name="shadow-type">in</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkTextView" id="text_view_value">
|
<object class="GtkTextView" id="text_view_value">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="border-width">2</property>
|
|
||||||
<property name="buffer">buffer_text</property>
|
<property name="buffer">buffer_text</property>
|
||||||
<property name="accepts-tab">False</property>
|
<property name="accepts-tab">0</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckButton" id="check_button_translatable">
|
<object class="GtkCheckButton" id="check_button_translatable">
|
||||||
<property name="label" translatable="yes">translatable</property>
|
<property name="label" translatable="1">translatable</property>
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="receives-default">False</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="draw-indicator">True</property>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="margin-top">8</property>
|
<property name="margin-top">8</property>
|
||||||
<property name="label" translatable="yes">Translation context:</property>
|
<property name="label" translatable="1">Translation context:</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">3</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow">
|
<object class="GtkScrolledWindow">
|
||||||
<property name="height-request">60</property>
|
<property name="height-request">60</property>
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="child">
|
||||||
<property name="shadow-type">in</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkTextView" id="text_view_context">
|
<object class="GtkTextView" id="text_view_context">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="border-width">2</property>
|
|
||||||
<property name="buffer">buffer_context</property>
|
<property name="buffer">buffer_context</property>
|
||||||
<property name="accepts-tab">False</property>
|
<property name="accepts-tab">0</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">4</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="margin-top">8</property>
|
<property name="margin-top">8</property>
|
||||||
<property name="label" translatable="yes">Comments for translators:</property>
|
<property name="label" translatable="1">Comments for translators:</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">5</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow">
|
<object class="GtkScrolledWindow">
|
||||||
<property name="height-request">60</property>
|
<property name="height-request">60</property>
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="child">
|
||||||
<property name="shadow-type">in</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkTextView" id="text_view_comments">
|
<object class="GtkTextView" id="text_view_comments">
|
||||||
<property name="visible">True</property>
|
<property name="focusable">1</property>
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="border-width">2</property>
|
|
||||||
<property name="buffer">buffer_comments</property>
|
<property name="buffer">buffer_comments</property>
|
||||||
<property name="accepts-tab">False</property>
|
<property name="accepts-tab">0</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">7</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
</template>
|
</template>
|
||||||
</interface>
|
</interface>
|
||||||
|
@ -136,8 +136,8 @@ class MrgApplication(Gtk.Application):
|
|||||||
# FIXME: object_id could be reused for a different object type
|
# FIXME: object_id could be reused for a different object type
|
||||||
# if you undo the creation of a widget and create a different type
|
# if you undo the creation of a widget and create a different type
|
||||||
# As a workaround if the types do not match we create a new controller
|
# As a workaround if the types do not match we create a new controller
|
||||||
# This could be fixed if we alway auto increment object_id but then
|
# This could be fixed if we always auto increment object_id but then
|
||||||
# we would have to clean up unussed controllers
|
# we would have to clean up unused controllers
|
||||||
if pspec is None or pspec.value_type != obj.__gtype__:
|
if pspec is None or pspec.value_type != obj.__gtype__:
|
||||||
controller = self.registry.new_controller_for_type(obj.__gtype__, self)
|
controller = self.registry.new_controller_for_type(obj.__gtype__, self)
|
||||||
|
|
||||||
|
@ -100,15 +100,20 @@ class MrgGtkWidget(MrgController):
|
|||||||
if self.object is None:
|
if self.object is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.selected:
|
|
||||||
self.object.get_style_context().add_class("merengue_selected")
|
|
||||||
else:
|
|
||||||
self.object.get_style_context().remove_class("merengue_selected")
|
|
||||||
|
|
||||||
# Update toplevel backdrop state
|
# Update toplevel backdrop state
|
||||||
if Gtk.MAJOR_VERSION == 4:
|
if Gtk.MAJOR_VERSION == 4:
|
||||||
|
if self.selected:
|
||||||
|
self.object.add_css_class("merengue_selected")
|
||||||
|
else:
|
||||||
|
self.object.remove_css_class("merengue_selected")
|
||||||
|
|
||||||
toplevel = self.object.get_root()
|
toplevel = self.object.get_root()
|
||||||
else:
|
else:
|
||||||
|
if self.selected:
|
||||||
|
self.object.get_style_context().add_class("merengue_selected")
|
||||||
|
else:
|
||||||
|
self.object.get_style_context().remove_class("merengue_selected")
|
||||||
|
|
||||||
toplevel = self.object.get_toplevel()
|
toplevel = self.object.get_toplevel()
|
||||||
|
|
||||||
if toplevel:
|
if toplevel:
|
||||||
|
@ -80,8 +80,10 @@ class MrgGtkWindow(MrgGtkBin):
|
|||||||
self.object.show_all()
|
self.object.show_all()
|
||||||
|
|
||||||
# Add gtk version CSS class
|
# Add gtk version CSS class
|
||||||
gtkversion = "gtk4" if Gtk.MAJOR_VERSION == 4 else "gtk3"
|
if Gtk.MAJOR_VERSION == 4:
|
||||||
self.object.get_style_context().add_class(gtkversion)
|
self.object.add_css_class("gtk4")
|
||||||
|
else:
|
||||||
|
self.object.get_style_context().add_class("gtk3")
|
||||||
|
|
||||||
self._restore_state()
|
self._restore_state()
|
||||||
|
|
||||||
|
@ -48,15 +48,17 @@ def version_cmp_str(a, b):
|
|||||||
|
|
||||||
|
|
||||||
def unset_scroll_event(widget):
|
def unset_scroll_event(widget):
|
||||||
def ignore_scroll_event(widget, event):
|
pass
|
||||||
Gtk.propagate_event(widget.get_parent(), event)
|
# FIXME: GTK4
|
||||||
return True
|
# def ignore_scroll_event(widget, event):
|
||||||
|
# Gtk.propagate_event(widget.get_parent(), event)
|
||||||
|
# return True
|
||||||
|
|
||||||
events = widget.get_events()
|
# events = widget.get_events()
|
||||||
widget.set_events(events & ~(Gdk.EventMask.SCROLL_MASK | Gdk.EventMask.SMOOTH_SCROLL_MASK))
|
# widget.set_events(events & ~(Gdk.EventMask.SCROLL_MASK | Gdk.EventMask.SMOOTH_SCROLL_MASK))
|
||||||
|
|
||||||
if isinstance(widget, Gtk.ComboBox):
|
# if isinstance(widget, Gtk.ComboBox):
|
||||||
widget.connect("scroll-event", ignore_scroll_event)
|
# widget.connect("scroll-event", ignore_scroll_event)
|
||||||
|
|
||||||
|
|
||||||
def get_version_warning(target, version, deprecated_version, this):
|
def get_version_warning(target, version, deprecated_version, this):
|
||||||
@ -69,3 +71,32 @@ def get_version_warning(target, version, deprecated_version, this):
|
|||||||
return f"UI targets {target} but {this} was deprecated in {deprecated_version}"
|
return f"UI targets {target} but {this} was deprecated in {deprecated_version}"
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def widget_get_children(widget):
|
||||||
|
retval = []
|
||||||
|
|
||||||
|
child = widget.get_first_child()
|
||||||
|
while child is not None:
|
||||||
|
retval.append(child)
|
||||||
|
child = child.get_next_sibling()
|
||||||
|
|
||||||
|
return retval
|
||||||
|
|
||||||
|
|
||||||
|
def get_pointer(widget):
|
||||||
|
root = widget.get_root()
|
||||||
|
pointer = widget.get_display().get_default_seat().get_pointer()
|
||||||
|
valid, x, y, mask = root.get_surface().get_device_position(pointer)
|
||||||
|
|
||||||
|
if valid:
|
||||||
|
return root.translate_coordinates(widget, x, y)
|
||||||
|
|
||||||
|
return (None, None)
|
||||||
|
|
||||||
|
|
||||||
|
def get_pointing_to(widget):
|
||||||
|
r = Gdk.Rectangle()
|
||||||
|
r.x, r.y = get_pointer(widget)
|
||||||
|
r.width = r.height = 0
|
||||||
|
return r
|
||||||
|
@ -6,7 +6,7 @@ project(
|
|||||||
|
|
||||||
# File format version follows app version and only changes when there is a
|
# File format version follows app version and only changes when there is a
|
||||||
# change that prevents older versions to load it.
|
# change that prevents older versions to load it.
|
||||||
fileformatversion = '0.13.1'
|
fileformatversion = '0.17.0'
|
||||||
|
|
||||||
python = import('python')
|
python = import('python')
|
||||||
python_bin = python.find_installation('python3')
|
python_bin = python.find_installation('python3')
|
||||||
|
@ -61,7 +61,7 @@ def close_compositor():
|
|||||||
|
|
||||||
|
|
||||||
# Make sure the right gtk version is loaded
|
# Make sure the right gtk version is loaded
|
||||||
gi.require_version("Gtk", "3.0")
|
gi.require_version("Gtk", "4.0")
|
||||||
|
|
||||||
# Make sure we can run Cambalache from sources
|
# Make sure we can run Cambalache from sources
|
||||||
cmb_init_dev()
|
cmb_init_dev()
|
||||||
|
@ -28,28 +28,23 @@ import struct
|
|||||||
from gi.repository import GLib, Gtk
|
from gi.repository import GLib, Gtk
|
||||||
|
|
||||||
|
|
||||||
# Based on Gtk sources gtk-reftest.c
|
# Based on Gtk sources gtktestutils.c gtk_test_widget_wait_for_draw()
|
||||||
def wait_for_drawing(window):
|
def wait_for_drawing(window):
|
||||||
def on_window_draw(widget, cr, loop):
|
done = { "done": False }
|
||||||
loop.quit()
|
main_loop = GLib.MainContext.default()
|
||||||
return False
|
|
||||||
|
|
||||||
def quit_when_idle(loop):
|
def quit_main_loop_callback(widget, frame_clock, done):
|
||||||
loop.quit()
|
done["done"] = True
|
||||||
|
print("BBBBBBBBB")
|
||||||
|
main_loop.wakeup()
|
||||||
|
print("CCCCCCCCCCCCCC")
|
||||||
return GLib.SOURCE_REMOVE
|
return GLib.SOURCE_REMOVE
|
||||||
|
|
||||||
loop = GLib.MainLoop()
|
window.add_tick_callback(quit_main_loop_callback, done)
|
||||||
|
|
||||||
# We wait until the widget is drawn for the first time.
|
print("AAAAAAAAAAAA")
|
||||||
# We are running in a dedicated compositor so the window should not be obstructed by other windows
|
while not done["done"]:
|
||||||
window.connect("draw", on_window_draw, loop)
|
main_loop.iteration(True)
|
||||||
loop.run()
|
|
||||||
window.disconnect_by_func(on_window_draw)
|
|
||||||
|
|
||||||
# give the WM/server some time to sync. They need it.
|
|
||||||
window.get_display().sync()
|
|
||||||
GLib.timeout_add(500, quit_when_idle, loop)
|
|
||||||
loop.run()
|
|
||||||
|
|
||||||
|
|
||||||
def surface_write_ppm(surface, path):
|
def surface_write_ppm(surface, path):
|
||||||
@ -71,13 +66,20 @@ def window_screenshot(window):
|
|||||||
# Wait for window to finish drawing
|
# Wait for window to finish drawing
|
||||||
wait_for_drawing(window)
|
wait_for_drawing(window)
|
||||||
|
|
||||||
w = window.get_allocated_width()
|
paintable = Gtk.WidgetPaintable.new(window)
|
||||||
h = window.get_allocated_height()
|
snapshot = Gtk.Snapshot()
|
||||||
|
|
||||||
|
w = paintable.get_intrinsic_width()
|
||||||
|
h = paintable.get_intrinsic_height()
|
||||||
|
|
||||||
# Draw widget to cairo surface
|
# Draw widget to cairo surface
|
||||||
surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)
|
surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)
|
||||||
|
|
||||||
|
paintable.snapshot(snapshot, w, h)
|
||||||
|
node = snapshot.to_node()
|
||||||
|
|
||||||
cr = cairo.Context(surface)
|
cr = cairo.Context(surface)
|
||||||
window.draw(cr)
|
node.draw(cr)
|
||||||
|
|
||||||
surface.flush()
|
surface.flush()
|
||||||
|
|
||||||
@ -124,26 +126,36 @@ def mean_squared_error(original, screenshot, ignore_color=None):
|
|||||||
|
|
||||||
|
|
||||||
def process_all_pending_gtk_events():
|
def process_all_pending_gtk_events():
|
||||||
while Gtk.events_pending():
|
main_loop = GLib.MainContext.default()
|
||||||
Gtk.main_iteration_do(False)
|
while main_loop.pending():
|
||||||
|
main_loop.iteration(False)
|
||||||
|
|
||||||
|
|
||||||
|
def __get_children(obj):
|
||||||
|
if obj is None:
|
||||||
|
return []
|
||||||
|
|
||||||
|
retval = []
|
||||||
|
|
||||||
|
child = obj.get_first_child()
|
||||||
|
while child is not None:
|
||||||
|
retval.append(child)
|
||||||
|
child = child.get_next_sibling()
|
||||||
|
return retval
|
||||||
|
|
||||||
|
|
||||||
def find_by_buildable_id(widget, name):
|
def find_by_buildable_id(widget, name):
|
||||||
retval = None
|
retval = None
|
||||||
|
|
||||||
if isinstance(widget, Gtk.Buildable) and Gtk.Buildable.get_name(widget) == name:
|
if isinstance(widget, Gtk.Buildable) and Gtk.Buildable.get_buildable_id(widget) == name:
|
||||||
return widget
|
return widget
|
||||||
|
|
||||||
if not isinstance(widget, Gtk.Container):
|
for child in __get_children(widget):
|
||||||
return None
|
retval = find_by_buildable_id(child, name)
|
||||||
|
if retval:
|
||||||
|
return retval
|
||||||
|
|
||||||
for child in widget.get_children():
|
if isinstance(child, Gtk.Buildable) and Gtk.Buildable.get_buildable_id(child) == name:
|
||||||
if isinstance(child, Gtk.Container):
|
|
||||||
retval = find_by_buildable_id(child, name)
|
|
||||||
if retval:
|
|
||||||
return retval
|
|
||||||
|
|
||||||
if isinstance(child, Gtk.Buildable) and Gtk.Buildable.get_name(child) == name:
|
|
||||||
return child
|
return child
|
||||||
|
|
||||||
return retval
|
return retval
|
||||||
@ -159,8 +171,9 @@ def cmb_create_app():
|
|||||||
window = None
|
window = None
|
||||||
|
|
||||||
# Spin until we get the main window
|
# Spin until we get the main window
|
||||||
while Gtk.events_pending() and not window:
|
main_loop = GLib.MainContext.default()
|
||||||
Gtk.main_iteration_do(False)
|
while main_loop.pending() and not window:
|
||||||
|
main_loop.iteration(False)
|
||||||
|
|
||||||
# Get window if any
|
# Get window if any
|
||||||
windows = app.get_windows()
|
windows = app.get_windows()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user