Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3253e67680 | ||
|
|
e189769f3f | ||
|
|
f6637493db | ||
|
|
063da38597 | ||
|
|
7587b03828 | ||
|
|
8fffb64f79 | ||
|
|
735eae0d0e | ||
|
|
8c98be6ef6 | ||
|
|
115e22e52c | ||
|
|
792a81ad03 | ||
|
|
2ea0ff6870 | ||
|
|
6242087152 | ||
|
|
1da6e31de1 | ||
|
|
cb4979ab7c | ||
|
|
da653c754d | ||
|
|
c4907b81fd | ||
|
|
4c104560d5 | ||
|
|
2253e378ac | ||
|
|
ba66ac40a3 | ||
|
|
40d0d92498 | ||
|
|
4ed6cf8e18 | ||
|
|
3fc1c74f51 | ||
|
|
150e8779c7 | ||
|
|
5462248565 |
@@ -33,7 +33,7 @@ Alpaca is an [Ollama](https://github.com/ollama/ollama) client where you can man
|
||||
|
||||
Normal conversation | Image recognition | Code highlighting | YouTube transcription | Model management
|
||||
:------------------:|:-----------------:|:-----------------:|:---------------------:|:----------------:
|
||||
 |  |  |  | 
|
||||
 |  |  |  | 
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
@@ -82,6 +82,18 @@
|
||||
<url type="contribute">https://github.com/Jeffser/Alpaca/discussions/154</url>
|
||||
<url type="vcs-browser">https://github.com/Jeffser/Alpaca</url>
|
||||
<releases>
|
||||
<release version="2.6.5" date="2024-10-13">
|
||||
<url type="details">https://github.com/Jeffser/Alpaca/releases/tag/2.6.5</url>
|
||||
<description>
|
||||
<p>New</p>
|
||||
<ul>
|
||||
<li>Details page for models</li>
|
||||
<li>Model selector gets replaced with 'manage models' button when there are no models downloaded</li>
|
||||
<li>Added warning when model is too big for the device</li>
|
||||
<li>Added AMD GPU indicator in preferences</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="2.6.0" date="2024-10-11">
|
||||
<url type="details">https://github.com/Jeffser/Alpaca/releases/tag/2.6.0</url>
|
||||
<description>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
project('Alpaca', 'c',
|
||||
version: '2.6.0',
|
||||
version: '2.6.5',
|
||||
meson_version: '>= 0.62.0',
|
||||
default_options: [ 'warning_level=2', 'werror=false', ],
|
||||
)
|
||||
|
||||
1059
po/alpaca.pot
1059
po/alpaca.pot
File diff suppressed because it is too large
Load Diff
1059
po/nb_NO.po
1059
po/nb_NO.po
File diff suppressed because it is too large
Load Diff
1061
po/pt_BR.po
1061
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
1062
po/zh_Hans.po
1062
po/zh_Hans.po
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
name: alpaca
|
||||
name: jeffser-alpaca
|
||||
base: core24
|
||||
adopt-info: alpaca
|
||||
|
||||
@@ -63,14 +63,15 @@ parts:
|
||||
ollama:
|
||||
plugin: dump
|
||||
source:
|
||||
- on amd64: https://github.com/ollama/ollama/releases/download/v0.3.10/ollama-linux-amd64.tgz
|
||||
- on arm64: https://github.com/ollama/ollama/releases/download/v0.3.10/ollama-linux-arm64.tgz
|
||||
- on amd64: https://github.com/ollama/ollama/releases/download/v0.3.12/ollama-linux-amd64.tgz
|
||||
- on arm64: https://github.com/ollama/ollama/releases/download/v0.3.12/ollama-linux-arm64.tgz
|
||||
|
||||
# Alpaca app
|
||||
alpaca:
|
||||
plugin: meson
|
||||
source-type: git
|
||||
source: https://github.com/Jeffser/Alpaca.git
|
||||
source-tag: 2.6.5
|
||||
source-depth: 1
|
||||
meson-parameters:
|
||||
- --prefix=/snap/alpaca/current/usr
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
<file alias="icons/scalable/status/chat-bubble-text-symbolic.svg">icons/chat-bubble-text-symbolic.svg</file>
|
||||
<file alias="icons/scalable/status/execute-from-symbolic.svg">icons/execute-from-symbolic.svg</file>
|
||||
<file alias="icons/scalable/status/cross-large-symbolic.svg">icons/cross-large-symbolic.svg</file>
|
||||
<file alias="icons/scalable/status/info-outline-symbolic.svg">icons/info-outline-symbolic.svg</file>
|
||||
<file preprocess="xml-stripblanks">window.ui</file>
|
||||
<file preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
|
||||
</gresource>
|
||||
|
||||
@@ -16,10 +16,18 @@ def log_output(pipe):
|
||||
with pipe:
|
||||
try:
|
||||
for line in iter(pipe.readline, ''):
|
||||
#print(line, end='')
|
||||
print(line, end='')
|
||||
f.write(line)
|
||||
f.flush()
|
||||
except:
|
||||
if 'msg="model request too large for system"' in line:
|
||||
window.show_toast(_("Model request too large for system"), window.main_overlay)
|
||||
elif 'msg="amdgpu detected, but no compatible rocm library found.' in line:
|
||||
window.ollama_information_label.set_label(_("AMD GPU detected but the extension is missing, Ollama will use CPU"))
|
||||
window.ollama_information_label.set_css_classes(['dim-label', 'error'])
|
||||
elif 'msg="amdgpu is supported"' in line:
|
||||
window.ollama_information_label.set_label(_("Using AMD GPU type '{}'").format(line.split('=')[-1]))
|
||||
window.ollama_information_label.set_css_classes(['dim-label', 'success'])
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
class instance():
|
||||
@@ -116,6 +124,8 @@ class instance():
|
||||
self.instance = instance
|
||||
if not self.idle_timer:
|
||||
self.start_timer()
|
||||
window.ollama_information_label.set_label(_("Integrated Ollama instance is running"))
|
||||
window.ollama_information_label.set_css_classes(['dim-label', 'success'])
|
||||
else:
|
||||
self.remote = True
|
||||
window.remote_connection_switch.set_sensitive(True)
|
||||
@@ -130,6 +140,8 @@ class instance():
|
||||
self.instance.terminate()
|
||||
self.instance.wait()
|
||||
self.instance = None
|
||||
window.ollama_information_label.set_label(_("Integrated Ollama instance is not running"))
|
||||
window.ollama_information_label.set_css_classes(['dim-label'])
|
||||
logger.info("Stopped Alpaca's Ollama instance")
|
||||
|
||||
def reset(self):
|
||||
|
||||
@@ -56,7 +56,7 @@ class model_selector_popup(Gtk.Popover):
|
||||
class model_selector_row(Gtk.ListBoxRow):
|
||||
__gtype_name__ = 'AlpacaModelSelectorRow'
|
||||
|
||||
def __init__(self, model_name:str, image_recognition:bool):
|
||||
def __init__(self, model_name:str, data:dict):
|
||||
super().__init__(
|
||||
child = Gtk.Label(
|
||||
label=window.convert_model_name(model_name, 0),
|
||||
@@ -68,7 +68,8 @@ class model_selector_row(Gtk.ListBoxRow):
|
||||
name=model_name,
|
||||
tooltip_text=window.convert_model_name(model_name, 0)
|
||||
)
|
||||
self.image_recognition = image_recognition
|
||||
self.data = data
|
||||
self.image_recognition = 'projector_info' in self.data
|
||||
|
||||
class model_selector_button(Gtk.MenuButton):
|
||||
__gtype_name__ = 'AlpacaModelSelectorButton'
|
||||
@@ -81,11 +82,10 @@ class model_selector_button(Gtk.MenuButton):
|
||||
orientation=0,
|
||||
spacing=5
|
||||
)
|
||||
self.label = Gtk.Label(label=_('Select a Model'))
|
||||
self.label = Gtk.Label()
|
||||
container.append(self.label)
|
||||
container.append(Gtk.Image.new_from_icon_name("down-symbolic"))
|
||||
super().__init__(
|
||||
tooltip_text=_('Select a Model'),
|
||||
child=container,
|
||||
popover=self.popover,
|
||||
halign=3
|
||||
@@ -104,27 +104,28 @@ class model_selector_button(Gtk.MenuButton):
|
||||
self.label.set_label(window.convert_model_name(model_name, 0))
|
||||
self.set_tooltip_text(window.convert_model_name(model_name, 0))
|
||||
elif len(list(listbox)) == 0:
|
||||
self.label.set_label(_("Select a Model"))
|
||||
self.set_tooltip_text(_("Select a Model"))
|
||||
window.title_stack.set_visible_child_name('no_models')
|
||||
window.model_manager.verify_if_image_can_be_used()
|
||||
|
||||
def add_model(self, model_name:str):
|
||||
vision = False
|
||||
data = None
|
||||
response = window.ollama_instance.request("POST", "api/show", json.dumps({"name": model_name}))
|
||||
if response.status_code != 200:
|
||||
logger.error(f"Status code was {response.status_code}")
|
||||
return
|
||||
try:
|
||||
vision = 'projector_info' in json.loads(response.text)
|
||||
data = json.loads(response.text)
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching vision info: {str(e)}")
|
||||
model_row = model_selector_row(model_name, vision)
|
||||
logger.error(f"Error fetching 'api - show' info: {str(e)}")
|
||||
model_row = model_selector_row(model_name, data)
|
||||
GLib.idle_add(self.get_popover().model_list_box.append, model_row)
|
||||
GLib.idle_add(self.change_model, model_name)
|
||||
GLib.idle_add(window.title_stack.set_visible_child_name, 'model_selector')
|
||||
|
||||
def remove_model(self, model_name:str):
|
||||
self.get_popover().model_list_box.remove(next((model for model in list(self.get_popover().model_list_box) if model.get_name() == model_name), None))
|
||||
self.model_changed(self.get_popover().model_list_box)
|
||||
window.title_stack.set_visible_child_name('model_selector' if len(window.model_manager.get_model_list()) > 0 else 'no_models')
|
||||
|
||||
def clear_list(self):
|
||||
self.get_popover().model_list_box.remove_all()
|
||||
@@ -248,6 +249,37 @@ class pulling_model_list(Gtk.ListBox):
|
||||
visible=False
|
||||
)
|
||||
|
||||
class information_bow(Gtk.Box):
|
||||
__gtype_name__ = 'AlpacaModelInformationBow'
|
||||
|
||||
def __init__(self, title:str, subtitle:str):
|
||||
self.title = title
|
||||
self.subtitle = subtitle
|
||||
title_label = Gtk.Label(
|
||||
label=self.title,
|
||||
css_classes=['subtitle', 'caption', 'dim-label'],
|
||||
hexpand=True,
|
||||
margin_top=10,
|
||||
margin_start=0,
|
||||
margin_end=0
|
||||
)
|
||||
subtitle_label = Gtk.Label(
|
||||
label=self.subtitle if self.subtitle else '(none)',
|
||||
css_classes=['heading'],
|
||||
hexpand=True,
|
||||
margin_bottom=10,
|
||||
margin_start=0,
|
||||
margin_end=0
|
||||
)
|
||||
super().__init__(
|
||||
spacing=5,
|
||||
orientation=1,
|
||||
css_classes=['card']
|
||||
)
|
||||
self.append(title_label)
|
||||
self.append(subtitle_label)
|
||||
|
||||
|
||||
class local_model(Gtk.ListBoxRow):
|
||||
__gtype_name__ = 'AlpacaLocalModel'
|
||||
|
||||
@@ -275,6 +307,16 @@ class local_model(Gtk.ListBoxRow):
|
||||
description_box.append(model_label)
|
||||
description_box.append(tag_label)
|
||||
|
||||
info_button = Gtk.Button(
|
||||
icon_name = "info-outline-symbolic",
|
||||
vexpand = False,
|
||||
valign = 3,
|
||||
css_classes = ["circular"],
|
||||
tooltip_text = _("Details")
|
||||
)
|
||||
|
||||
info_button.connect('clicked', self.show_information)
|
||||
|
||||
delete_button = Gtk.Button(
|
||||
icon_name = "user-trash-symbolic",
|
||||
vexpand = False,
|
||||
@@ -302,6 +344,7 @@ class local_model(Gtk.ListBoxRow):
|
||||
margin_end=10
|
||||
)
|
||||
container_box.append(description_box)
|
||||
container_box.append(info_button)
|
||||
container_box.append(delete_button)
|
||||
|
||||
super().__init__(
|
||||
@@ -309,6 +352,53 @@ class local_model(Gtk.ListBoxRow):
|
||||
name=model_name
|
||||
)
|
||||
|
||||
def show_information(self, button):
|
||||
model = next((element for element in list(window.model_manager.model_selector.get_popover().model_list_box) if element.get_name() == self.get_name()), None)
|
||||
model_name = model.get_child().get_label()
|
||||
|
||||
window.model_detail_page.set_title(' ('.join(model_name.split(' (')[:-1]))
|
||||
window.model_detail_page.set_description(' ('.join(model_name.split(' (')[-1:])[:-1])
|
||||
window.model_detail_create_button.set_name(model_name)
|
||||
window.model_detail_create_button.set_tooltip_text(_("Create Model Based on '{}'").format(model_name))
|
||||
|
||||
details_flow_box = Gtk.FlowBox(
|
||||
valign=1,
|
||||
hexpand=True,
|
||||
vexpand=False,
|
||||
selection_mode=0,
|
||||
max_children_per_line=2,
|
||||
min_children_per_line=1,
|
||||
margin_top=12,
|
||||
margin_bottom=12,
|
||||
margin_start=12,
|
||||
margin_end=12
|
||||
)
|
||||
|
||||
translation_strings={
|
||||
'modified_at': _('Modified At'),
|
||||
'parent_model': _('Parent Model'),
|
||||
'format': _('Format'),
|
||||
'family': _('Family'),
|
||||
'parameter_size': _('Parameter Size'),
|
||||
'quantization_level': _('Quantization Level')
|
||||
}
|
||||
|
||||
if 'modified_at' in model.data and model.data['modified_at']:
|
||||
details_flow_box.append(information_bow(
|
||||
title=translation_strings['modified_at'],
|
||||
subtitle=datetime.datetime.strptime(':'.join(model.data['modified_at'].split(':')[:2]), '%Y-%m-%dT%H:%M').strftime('%Y-%m-%d %H:%M')
|
||||
))
|
||||
|
||||
for name, value in model.data['details'].items():
|
||||
if isinstance(value, str):
|
||||
details_flow_box.append(information_bow(
|
||||
title=translation_strings[name] if name in translation_strings else name.replace('_', ' ').title(),
|
||||
subtitle=value
|
||||
))
|
||||
|
||||
window.model_detail_page.set_child(details_flow_box)
|
||||
window.navigation_view_manage_models.push_by_tag('model_information')
|
||||
|
||||
class local_model_list(Gtk.ListBox):
|
||||
__gtype_name__ = 'AlpacaLocalModelList'
|
||||
|
||||
@@ -521,7 +611,8 @@ class model_manager_container(Gtk.Box):
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
window.connection_error()
|
||||
window.title_stack.set_visible_child_name('model_selector')
|
||||
window.title_stack.set_visible_child_name('model_selector' if len(window.model_manager.get_model_list()) > 0 else 'no_models')
|
||||
#window.title_stack.set_visible_child_name('model_selector')
|
||||
window.chat_list_box.update_welcome_screens(len(self.get_model_list()) > 0)
|
||||
|
||||
#Should only be called when the app starts
|
||||
|
||||
2
src/icons/info-outline-symbolic.svg
Normal file
2
src/icons/info-outline-symbolic.svg
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><path d="m 8 0 c -4.410156 0 -8 3.589844 -8 8 s 3.589844 8 8 8 s 8 -3.589844 8 -8 s -3.589844 -8 -8 -8 z m 0 2 c 3.332031 0 6 2.667969 6 6 s -2.667969 6 -6 6 s -6 -2.667969 -6 -6 s 2.667969 -6 6 -6 z m 0 1.875 c -0.621094 0 -1.125 0.503906 -1.125 1.125 s 0.503906 1.125 1.125 1.125 s 1.125 -0.503906 1.125 -1.125 s -0.503906 -1.125 -1.125 -1.125 z m -1.523438 3.125 c -0.265624 0.011719 -0.476562 0.230469 -0.476562 0.5 c 0 0.277344 0.222656 0.5 0.5 0.5 h 0.5 v 3 h -0.5 c -0.277344 0 -0.5 0.222656 -0.5 0.5 s 0.222656 0.5 0.5 0.5 h 3 c 0.277344 0 0.5 -0.222656 0.5 -0.5 s -0.222656 -0.5 -0.5 -0.5 h -0.5 v -4 h -2.5 c -0.007812 0 -0.015625 0 -0.023438 0 z m 0 0" fill="#222222"/></svg>
|
||||
|
After Width: | Height: | Size: 813 B |
@@ -102,6 +102,9 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
||||
title_stack = Gtk.Template.Child()
|
||||
manage_models_dialog = Gtk.Template.Child()
|
||||
model_scroller = Gtk.Template.Child()
|
||||
model_detail_page = Gtk.Template.Child()
|
||||
model_detail_create_button = Gtk.Template.Child()
|
||||
ollama_information_label = Gtk.Template.Child()
|
||||
|
||||
chat_list_container = Gtk.Template.Child()
|
||||
chat_list_box = None
|
||||
@@ -332,6 +335,10 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
||||
clipboard.read_text_async(None, self.cb_text_received)
|
||||
clipboard.read_texture_async(None, self.cb_image_received)
|
||||
|
||||
@Gtk.Template.Callback()
|
||||
def model_detail_create_button_clicked(self, button):
|
||||
self.create_model(button.get_name(), False)
|
||||
|
||||
def convert_model_name(self, name:str, mode:int) -> str: # mode=0 name:tag -> Name (tag) | mode=1 Name (tag) -> name:tag
|
||||
try:
|
||||
if mode == 0:
|
||||
@@ -351,20 +358,15 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
||||
modelfile_buffer.delete(modelfile_buffer.get_start_iter(), modelfile_buffer.get_end_iter())
|
||||
self.create_model_system.set_text('')
|
||||
if not file:
|
||||
response = self.ollama_instance.request("POST", "api/show", json.dumps({"name": self.convert_model_name(model, 1)}))
|
||||
if response.status_code == 200:
|
||||
data = json.loads(response.text)
|
||||
modelfile = []
|
||||
for line in data['modelfile'].split('\n'):
|
||||
if line.startswith('SYSTEM'):
|
||||
self.create_model_system.set_text(line[len('SYSTEM'):].strip())
|
||||
if not line.startswith('SYSTEM') and not line.startswith('FROM') and not line.startswith('#'):
|
||||
modelfile.append(line)
|
||||
self.create_model_name.set_text(self.convert_model_name(model, 1).split(':')[0] + "-custom")
|
||||
modelfile_buffer.insert(modelfile_buffer.get_start_iter(), '\n'.join(modelfile), len('\n'.join(modelfile).encode('utf-8')))
|
||||
else:
|
||||
##TODO ERROR MESSAGE
|
||||
return
|
||||
data = next((element for element in list(self.model_manager.model_selector.get_popover().model_list_box) if element.get_name() == self.convert_model_name(model, 1)), None).data
|
||||
modelfile = []
|
||||
for line in data['modelfile'].split('\n'):
|
||||
if line.startswith('SYSTEM'):
|
||||
self.create_model_system.set_text(line[len('SYSTEM'):].strip())
|
||||
if not line.startswith('SYSTEM') and not line.startswith('FROM') and not line.startswith('#'):
|
||||
modelfile.append(line)
|
||||
self.create_model_name.set_text(self.convert_model_name(model, 1).split(':')[0] + "-custom")
|
||||
modelfile_buffer.insert(modelfile_buffer.get_start_iter(), '\n'.join(modelfile), len('\n'.join(modelfile).encode('utf-8')))
|
||||
self.create_model_base.set_subtitle(self.convert_model_name(model, 1))
|
||||
else:
|
||||
self.create_model_name.set_text(os.path.splitext(os.path.basename(model))[0])
|
||||
@@ -607,6 +609,7 @@ Generate a title following these rules:
|
||||
self.chat_list_box.prepend_chat(_("New Chat"))
|
||||
|
||||
|
||||
|
||||
def generate_numbered_name(self, chat_name:str, compare_list:list) -> str:
|
||||
if chat_name in compare_list:
|
||||
for i in range(len(compare_list)):
|
||||
@@ -829,7 +832,7 @@ Generate a title following these rules:
|
||||
|
||||
[element.set_sensitive(True) for element in sensitive_elements]
|
||||
self.get_application().lookup_action('manage_models').set_enabled(True)
|
||||
self.title_stack.set_visible_child_name('model_selector')
|
||||
self.title_stack.set_visible_child_name('model_selector' if len(self.model_manager.get_model_list()) > 0 else 'no_models')
|
||||
|
||||
if state:
|
||||
options = {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<signal name="close-request" handler="closing_app"/>
|
||||
<property name="resizable">True</property>
|
||||
<property name="width-request">400</property>
|
||||
<property name="height-request">400</property>
|
||||
<property name="height-request">600</property>
|
||||
<property name="default-width">1300</property>
|
||||
<property name="default-height">800</property>
|
||||
<property name="title">Alpaca</property>
|
||||
@@ -97,6 +97,18 @@
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">no_models</property>
|
||||
<property name="child">
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Manage Models</property>
|
||||
<property name="tooltip-text" translatable="yes">Manage Models</property>
|
||||
<property name="action-name">app.manage_models</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
@@ -212,6 +224,7 @@
|
||||
<signal name="paste-clipboard" handler="on_clipboard_paste"/>
|
||||
<style>
|
||||
<class name="message_text_view"/>
|
||||
<class name="undershoot-bottom"/>
|
||||
</style>
|
||||
<property name="wrap-mode">word</property>
|
||||
<property name="top-margin">10</property>
|
||||
@@ -457,6 +470,19 @@
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<child>
|
||||
<object class="GtkLabel" id="ollama_information_label">
|
||||
<property name="wrap">true</property>
|
||||
<property name="label" translatable="yes">Integrated Ollama instance is not running</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -639,20 +665,48 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwNavigationPage">
|
||||
<property name="title" translatable="yes">Create Model</property>
|
||||
<property name="tag">model_create_page</property>
|
||||
<property name="title" translatable="yes">Model Details</property>
|
||||
<property name="tag">model_information</property>
|
||||
<property name="child">
|
||||
<object class="AdwToolbarView">
|
||||
<child type="top">
|
||||
<object class="AdwHeaderBar">
|
||||
<child type="start">
|
||||
<object class="GtkButton">
|
||||
<signal name="clicked" handler="link_button_handler"/>
|
||||
<property name="icon-name">globe-symbolic</property>
|
||||
<object class="GtkButton" id="model_detail_create_button">
|
||||
<signal name="clicked" handler="model_detail_create_button_clicked"/>
|
||||
<property name="icon-name">edit-copy-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<property name="content">
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="vexpand">true</property>
|
||||
<property name="hexpand">true</property>
|
||||
<child>
|
||||
<object class="AdwStatusPage" id="model_detail_page">
|
||||
<property name="icon-name">brain-augemnted-symbolic</property>
|
||||
<property name="description">text</property>
|
||||
<style>
|
||||
<class name="compact"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwNavigationPage">
|
||||
<property name="title" translatable="yes">Create Model</property>
|
||||
<property name="tag">model_create_page</property>
|
||||
<property name="child">
|
||||
<object class="AdwToolbarView">
|
||||
<child type="top">
|
||||
<object class="AdwHeaderBar"/>
|
||||
</child>
|
||||
<property name="content">
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="vexpand">true</property>
|
||||
@@ -726,6 +780,9 @@
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<style>
|
||||
<class name="undershoot-bottom"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkTextView" id="create_model_modelfile">
|
||||
<style>
|
||||
|
||||
Reference in New Issue
Block a user