UI-Lifecycle: tie UI-Bus and UI-Manager directly to GtkLumiera
this is just a tiny change to make things more othogonal. Now the unwinding and calls to any GTK / Widget dtors happen *after* emitting the term signal from UI shutdown. Which means, the other subsystems are shutting down (in their dedicated threads) as well, thus lowering the probability of some action still using the UI and triggering an exception
This commit is contained in:
parent
5e172ff6a0
commit
f089a34934
4 changed files with 35 additions and 30 deletions
|
|
@ -71,7 +71,7 @@ namespace gui {
|
||||||
bool res = this->launchUI (terminationHandle);
|
bool res = this->launchUI (terminationHandle);
|
||||||
|
|
||||||
if (!res || lumiera_error_peek())
|
if (!res || lumiera_error_peek())
|
||||||
throw lumiera::error::Fatal("failed to bring up GUI",lumiera_error());
|
throw lumiera::error::Fatal{"failed to bring up the GUI", lumiera_error()};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -159,7 +159,7 @@ namespace gui {
|
||||||
"Probably this is due to some broken startup logic and should be fixed.");
|
"Probably this is due to some broken startup logic and should be fixed.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
facade.reset (0);
|
facade.reset (nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,9 @@
|
||||||
** of the session model. Notable connections established herein:
|
** of the session model. Notable connections established herein:
|
||||||
** - connection to the [UI-Bus](\ref ui-bus.hpp)
|
** - connection to the [UI-Bus](\ref ui-bus.hpp)
|
||||||
** - the global Actions available though the menu
|
** - the global Actions available though the menu
|
||||||
** - the WindowList
|
|
||||||
** - the InteractionDirector (top-level controller)
|
** - the InteractionDirector (top-level controller)
|
||||||
** - the StyleManager
|
** - the StyleManager
|
||||||
|
** - the WindowList
|
||||||
**
|
**
|
||||||
** @see gtk-lumiera.hpp
|
** @see gtk-lumiera.hpp
|
||||||
** @see ui-bus.hpp
|
** @see ui-bus.hpp
|
||||||
|
|
@ -64,6 +64,7 @@ namespace ctrl {
|
||||||
class Actions;
|
class Actions;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Framework initialisation base */
|
/** Framework initialisation base */
|
||||||
class ApplicationBase
|
class ApplicationBase
|
||||||
: public Gtk::UIManager
|
: public Gtk::UIManager
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,9 @@ namespace gui {
|
||||||
|
|
||||||
namespace { // implementation details
|
namespace { // implementation details
|
||||||
|
|
||||||
|
using ctrl::UiManager;
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************//**
|
/**************************************************************************//**
|
||||||
* Implement the necessary steps for actually making the Lumiera Gui available.
|
* Implement the necessary steps for actually making the Lumiera Gui available.
|
||||||
* Establish the UI backbone services and start up the GTK GUI main event loop.
|
* Establish the UI backbone services and start up the GTK GUI main event loop.
|
||||||
|
|
@ -88,11 +91,15 @@ namespace gui {
|
||||||
class GtkLumiera
|
class GtkLumiera
|
||||||
: boost::noncopyable
|
: boost::noncopyable
|
||||||
{
|
{
|
||||||
|
UiBus uiBus_;
|
||||||
|
UiManager uiManager_;
|
||||||
DisplayService activateDisplayService_; ///////////////////////////TICKET #82 will go away once we have a real OutputSlot offered by the UI
|
DisplayService activateDisplayService_; ///////////////////////////TICKET #82 will go away once we have a real OutputSlot offered by the UI
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GtkLumiera ()
|
GtkLumiera ()
|
||||||
: activateDisplayService_() ///////////////////////////TICKET #82 obsolete (and incurs a race)
|
: uiBus_{}
|
||||||
|
, uiManager_{uiBus_}
|
||||||
|
, activateDisplayService_() ///////////////////////////TICKET #82 obsolete (and incurs a race)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -102,12 +109,9 @@ namespace gui {
|
||||||
string errorMsgBuff;
|
string errorMsgBuff;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
UiBus uiBus;
|
|
||||||
ctrl::UiManager uiManager(uiBus);
|
|
||||||
|
|
||||||
// execute the GTK Event Loop____________
|
// execute the GTK Event Loop____________
|
||||||
uiManager.createApplicationWindow();
|
uiManager_.createApplicationWindow();
|
||||||
uiManager.performMainLoop();
|
uiManager_.performMainLoop();
|
||||||
} // all went well, regular shutdown
|
} // all went well, regular shutdown
|
||||||
|
|
||||||
catch (lumiera::Error& problem)
|
catch (lumiera::Error& problem)
|
||||||
|
|
|
||||||
|
|
@ -211,8 +211,7 @@
|
||||||
aber nur via einfacher "uplink"-Verbindung
|
aber nur via einfacher "uplink"-Verbindung
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html></richcontent>
|
||||||
</richcontent>
|
|
||||||
<icon BUILTIN="button_ok"/>
|
<icon BUILTIN="button_ok"/>
|
||||||
</node>
|
</node>
|
||||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1493753215852" ID="ID_1971120" MODIFIED="1493753233570" TEXT="offen: wie kann man Shutdown implementieren">
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1493753215852" ID="ID_1971120" MODIFIED="1493753233570" TEXT="offen: wie kann man Shutdown implementieren">
|
||||||
|
|
@ -222,7 +221,8 @@
|
||||||
<icon BUILTIN="help"/>
|
<icon BUILTIN="help"/>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1481502320065" FOLDED="true" ID="ID_1298358905" MODIFIED="1488423342540" TEXT="macht bisher der GuiRunner">
|
<node CREATED="1481502320065" FOLDED="true" ID="ID_1298358905" MODIFIED="1495207546647" TEXT="macht bisher der GuiRunner">
|
||||||
|
<icon BUILTIN="info"/>
|
||||||
<node CREATED="1481502327528" ID="ID_75293128" MODIFIED="1487275489277" TEXT="das ist ohnehin schlecht">
|
<node CREATED="1481502327528" ID="ID_75293128" MODIFIED="1487275489277" TEXT="das ist ohnehin schlecht">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head>
|
||||||
|
|
@ -253,13 +253,15 @@
|
||||||
<icon BUILTIN="button_ok"/>
|
<icon BUILTIN="button_ok"/>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1481502305995" FOLDED="true" ID="ID_1943234904" MODIFIED="1493753296498" TEXT="in CoreService verschieben">
|
<node CREATED="1481502305995" FOLDED="true" ID="ID_1943234904" MODIFIED="1495207549076" TEXT="in CoreService verschieben">
|
||||||
|
<icon BUILTIN="button_ok"/>
|
||||||
<node CREATED="1484793022924" ID="ID_1019455888" MODIFIED="1484793099044" TEXT="GuiNotificattion ist jetzt Feld in CoreService">
|
<node CREATED="1484793022924" ID="ID_1019455888" MODIFIED="1484793099044" TEXT="GuiNotificattion ist jetzt Feld in CoreService">
|
||||||
<linktarget COLOR="#4072ad" DESTINATION="ID_1019455888" ENDARROW="Default" ENDINCLINATION="-334;0;" ID="Arrow_ID_693735378" SOURCE="ID_66499328" STARTARROW="None" STARTINCLINATION="-45;-19;"/>
|
<linktarget COLOR="#4072ad" DESTINATION="ID_1019455888" ENDARROW="Default" ENDINCLINATION="-334;0;" ID="Arrow_ID_693735378" SOURCE="ID_66499328" STARTARROW="None" STARTINCLINATION="-45;-19;"/>
|
||||||
<icon BUILTIN="idea"/>
|
<icon BUILTIN="idea"/>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1484793113472" FOLDED="true" ID="ID_221612387" MODIFIED="1488423308106" TEXT="Lebenszyklus nochmal prüfen">
|
<node COLOR="#338800" CREATED="1484793113472" FOLDED="true" ID="ID_221612387" MODIFIED="1495207526746" TEXT="Lebenszyklus nochmal prüfen">
|
||||||
<node CREATED="1484797307376" FOLDED="true" ID="ID_842106541" MODIFIED="1488423308091" TEXT="Abfolge">
|
<icon BUILTIN="button_ok"/>
|
||||||
|
<node CREATED="1484797307376" FOLDED="true" ID="ID_842106541" MODIFIED="1495207516420" TEXT="Abfolge">
|
||||||
<icon BUILTIN="info"/>
|
<icon BUILTIN="info"/>
|
||||||
<node CREATED="1484797311008" ID="ID_424744338" MODIFIED="1484797318947" TEXT="GuiFacade::start"/>
|
<node CREATED="1484797311008" ID="ID_424744338" MODIFIED="1484797318947" TEXT="GuiFacade::start"/>
|
||||||
<node CREATED="1484797337516" ID="ID_750979034" MODIFIED="1484797361213" TEXT="erzeugt unique_ptr<GuiRunner>"/>
|
<node CREATED="1484797337516" ID="ID_750979034" MODIFIED="1484797361213" TEXT="erzeugt unique_ptr<GuiRunner>"/>
|
||||||
|
|
@ -267,7 +269,7 @@
|
||||||
<node CREATED="1484797379239" ID="ID_1948690926" MODIFIED="1484797386210" TEXT="läd Plugin"/>
|
<node CREATED="1484797379239" ID="ID_1948690926" MODIFIED="1484797386210" TEXT="läd Plugin"/>
|
||||||
<node CREATED="1484797399756" ID="ID_1084903350" MODIFIED="1484797408855" TEXT="ruft im ctor launchUi()"/>
|
<node CREATED="1484797399756" ID="ID_1084903350" MODIFIED="1484797408855" TEXT="ruft im ctor launchUi()"/>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1484797429160" FOLDED="true" ID="ID_959278184" MODIFIED="1488423308072" TEXT="guistart.cpp">
|
<node CREATED="1484797429160" ID="ID_959278184" MODIFIED="1495207457728" TEXT="gtk-lumiera.cpp">
|
||||||
<node CREATED="1484797432999" ID="ID_1571358017" MODIFIED="1484797439067" TEXT="implementiert GUI-Plugin"/>
|
<node CREATED="1484797432999" ID="ID_1571358017" MODIFIED="1484797439067" TEXT="implementiert GUI-Plugin"/>
|
||||||
<node CREATED="1484797442686" ID="ID_83446606" MODIFIED="1484797481709" TEXT="launchUI -> erzeugt GUI-Thread"/>
|
<node CREATED="1484797442686" ID="ID_83446606" MODIFIED="1484797481709" TEXT="launchUI -> erzeugt GUI-Thread"/>
|
||||||
</node>
|
</node>
|
||||||
|
|
@ -276,12 +278,12 @@
|
||||||
<node CREATED="1484797512341" ID="ID_57994807" MODIFIED="1484797515712" TEXT="ruft darauf run()"/>
|
<node CREATED="1484797512341" ID="ID_57994807" MODIFIED="1484797515712" TEXT="ruft darauf run()"/>
|
||||||
<node CREATED="1484797517052" ID="ID_840628023" MODIFIED="1484797527271" TEXT="löst das sigTerm aus"/>
|
<node CREATED="1484797517052" ID="ID_840628023" MODIFIED="1484797527271" TEXT="löst das sigTerm aus"/>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1484797531482" FOLDED="true" ID="ID_1734603717" MODIFIED="1488423308072" TEXT="GuiLifecycle::run() -> GtkLumiera::main">
|
<node CREATED="1484797531482" FOLDED="true" ID="ID_1734603717" MODIFIED="1495207502959" TEXT="GtkLumiera::run() -> uiManager.performMainLoop()">
|
||||||
<node CREATED="1484797543593" ID="ID_143907787" MODIFIED="1484797547740" TEXT="erzeugt UiBus"/>
|
<node CREATED="1484797543593" ID="ID_143907787" MODIFIED="1484797547740" TEXT="erzeugt UiBus"/>
|
||||||
<node CREATED="1484797548208" ID="ID_984623574" MODIFIED="1484797555083" TEXT="erzeugt WindowManager"/>
|
<node CREATED="1484797548208" ID="ID_984623574" MODIFIED="1484797555083" TEXT="erzeugt WindowManager"/>
|
||||||
<node CREATED="1484797557383" ID="ID_637078214" MODIFIED="1484797568569" TEXT="Gtk-Kit::run()"/>
|
<node CREATED="1484797557383" ID="ID_637078214" MODIFIED="1484797568569" TEXT="Gtk-Kit::run()"/>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1484797573701" FOLDED="true" ID="ID_162958920" MODIFIED="1488423308072" TEXT="UiBus">
|
<node CREATED="1484797573701" FOLDED="true" ID="ID_162958920" MODIFIED="1495207515202" TEXT="UiBus">
|
||||||
<node CREATED="1484797576972" FOLDED="true" ID="ID_1159570219" MODIFIED="1488423308050" TEXT="erzeugt CoreService">
|
<node CREATED="1484797576972" FOLDED="true" ID="ID_1159570219" MODIFIED="1488423308050" TEXT="erzeugt CoreService">
|
||||||
<node CREATED="1484871312594" ID="ID_1351400025" MODIFIED="1484871320837" TEXT="erbt zwar von BusTerm"/>
|
<node CREATED="1484871312594" ID="ID_1351400025" MODIFIED="1484871320837" TEXT="erbt zwar von BusTerm"/>
|
||||||
<node CREATED="1484871321473" ID="ID_112216780" MODIFIED="1487275489295" TEXT="hat aber keine connection">
|
<node CREATED="1484871321473" ID="ID_112216780" MODIFIED="1487275489295" TEXT="hat aber keine connection">
|
||||||
|
|
@ -321,7 +323,7 @@
|
||||||
</html></richcontent>
|
</html></richcontent>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1484797584483" FOLDED="true" ID="ID_290592673" MODIFIED="1488423308051" TEXT="dieser hat Member ">
|
<node CREATED="1484797584483" FOLDED="true" ID="ID_290592673" MODIFIED="1495207514092" TEXT="dieser hat Member ">
|
||||||
<node CREATED="1484797623574" ID="ID_277189073" MODIFIED="1484797625783" TEXT="Nexus"/>
|
<node CREATED="1484797623574" ID="ID_277189073" MODIFIED="1484797625783" TEXT="Nexus"/>
|
||||||
<node CREATED="1484797620495" ID="ID_1793464076" MODIFIED="1484797620495" TEXT="GuiNotificationService"/>
|
<node CREATED="1484797620495" ID="ID_1793464076" MODIFIED="1484797620495" TEXT="GuiNotificationService"/>
|
||||||
</node>
|
</node>
|
||||||
|
|
@ -1848,8 +1850,7 @@
|
||||||
daß die alte, obsolete Timeline zurückgebaut ist
|
daß die alte, obsolete Timeline zurückgebaut ist
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html></richcontent>
|
||||||
</richcontent>
|
|
||||||
<icon BUILTIN="hourglass"/>
|
<icon BUILTIN="hourglass"/>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1493853590149" ID="ID_1075149702" MODIFIED="1493853655203" TEXT="Race beim triggerShutdown">
|
<node CREATED="1493853590149" ID="ID_1075149702" MODIFIED="1493853655203" TEXT="Race beim triggerShutdown">
|
||||||
|
|
@ -1868,12 +1869,11 @@
|
||||||
bevor die Notification-Facade geöffnet werden konnte
|
bevor die Notification-Facade geöffnet werden konnte
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html></richcontent>
|
||||||
</richcontent>
|
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1485551018975" FOLDED="true" ID="ID_1865473127" MODIFIED="1488423342658" TEXT="obsoletes Project & Controller">
|
<node CREATED="1485551018975" FOLDED="true" ID="ID_1865473127" MODIFIED="1495207303040" TEXT="obsoletes Project & Controller">
|
||||||
<node CREATED="1485551030086" ID="ID_1052165402" MODIFIED="1485551034969" TEXT="in GtkLumiera definiert"/>
|
<node CREATED="1485551030086" ID="ID_1052165402" MODIFIED="1485551034969" TEXT="in GtkLumiera definiert"/>
|
||||||
<node CREATED="1485551035413" ID="ID_1861899005" MODIFIED="1485551056342" TEXT="tatsächlich im Panel (Basisklasse) gespeichert"/>
|
<node CREATED="1485551035413" ID="ID_1861899005" MODIFIED="1485551056342" TEXT="tatsächlich im Panel (Basisklasse) gespeichert"/>
|
||||||
<node CREATED="1485551056834" ID="ID_538186909" MODIFIED="1485551066884" TEXT="tatsächlich nur im alten TimelinePannel gebraucht"/>
|
<node CREATED="1485551056834" ID="ID_538186909" MODIFIED="1485551066884" TEXT="tatsächlich nur im alten TimelinePannel gebraucht"/>
|
||||||
|
|
@ -1961,7 +1961,7 @@
|
||||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1485549049388" ID="ID_530209145" MODIFIED="1485562057742" TEXT="Problem: Aktionen binden">
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1485549049388" ID="ID_530209145" MODIFIED="1485562057742" TEXT="Problem: Aktionen binden">
|
||||||
<linktarget COLOR="#a9b4c1" DESTINATION="ID_530209145" ENDARROW="Default" ENDINCLINATION="-17;-195;" ID="Arrow_ID_626063593" SOURCE="ID_1022779645" STARTARROW="None" STARTINCLINATION="9;270;"/>
|
<linktarget COLOR="#a9b4c1" DESTINATION="ID_530209145" ENDARROW="Default" ENDINCLINATION="-17;-195;" ID="Arrow_ID_626063593" SOURCE="ID_1022779645" STARTARROW="None" STARTINCLINATION="9;270;"/>
|
||||||
<icon BUILTIN="messagebox_warning"/>
|
<icon BUILTIN="messagebox_warning"/>
|
||||||
<node CREATED="1485549075929" FOLDED="true" ID="ID_1887127861" MODIFIED="1488423342658" TEXT="spezifische Aktionen">
|
<node CREATED="1485549075929" FOLDED="true" ID="ID_1887127861" MODIFIED="1495207327780" TEXT="spezifische Aktionen">
|
||||||
<node CREATED="1485549803366" FOLDED="true" ID="ID_1969698948" MODIFIED="1488423342541" TEXT="Fenster-Bindung">
|
<node CREATED="1485549803366" FOLDED="true" ID="ID_1969698948" MODIFIED="1488423342541" TEXT="Fenster-Bindung">
|
||||||
<node CREATED="1485549810780" ID="ID_71301392" MODIFIED="1485549822342" TEXT="Pop-Ups brauchen ein Vater-Fenster"/>
|
<node CREATED="1485549810780" ID="ID_71301392" MODIFIED="1485549822342" TEXT="Pop-Ups brauchen ein Vater-Fenster"/>
|
||||||
<node CREATED="1485549828450" ID="ID_1089795419" MODIFIED="1485917553222">
|
<node CREATED="1485549828450" ID="ID_1089795419" MODIFIED="1485917553222">
|
||||||
|
|
@ -2448,7 +2448,7 @@
|
||||||
<linktarget COLOR="#8e2a4d" DESTINATION="ID_1909730752" ENDARROW="Default" ENDINCLINATION="190;-96;" ID="Arrow_ID_1543429248" SOURCE="ID_1507239589" STARTARROW="None" STARTINCLINATION="-103;109;"/>
|
<linktarget COLOR="#8e2a4d" DESTINATION="ID_1909730752" ENDARROW="Default" ENDINCLINATION="190;-96;" ID="Arrow_ID_1543429248" SOURCE="ID_1507239589" STARTARROW="None" STARTINCLINATION="-103;109;"/>
|
||||||
<icon BUILTIN="flag-yellow"/>
|
<icon BUILTIN="flag-yellow"/>
|
||||||
</node>
|
</node>
|
||||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1485549081728" ID="ID_1122969153" MODIFIED="1488672334405" TEXT="globale Aktionen">
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1485549081728" ID="ID_1122969153" MODIFIED="1495207337712" TEXT="globale Aktionen">
|
||||||
<arrowlink COLOR="#824f68" DESTINATION="ID_826011549" ENDARROW="Default" ENDINCLINATION="-906;-1187;" ID="Arrow_ID_1373278707" STARTARROW="Default" STARTINCLINATION="870;255;"/>
|
<arrowlink COLOR="#824f68" DESTINATION="ID_826011549" ENDARROW="Default" ENDINCLINATION="-906;-1187;" ID="Arrow_ID_1373278707" STARTARROW="Default" STARTINCLINATION="870;255;"/>
|
||||||
<icon BUILTIN="flag-yellow"/>
|
<icon BUILTIN="flag-yellow"/>
|
||||||
<node CREATED="1488419973349" ID="ID_1855791702" MODIFIED="1488419978923" TEXT="brauche ein Konzept">
|
<node CREATED="1488419973349" ID="ID_1855791702" MODIFIED="1488419978923" TEXT="brauche ein Konzept">
|
||||||
|
|
@ -11052,7 +11052,7 @@
|
||||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1485548830035" HGAP="5" ID="ID_1295711115" MODIFIED="1485548844056" TEXT="Nutzen" VSHIFT="17">
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1485548830035" HGAP="5" ID="ID_1295711115" MODIFIED="1485548844056" TEXT="Nutzen" VSHIFT="17">
|
||||||
<icon BUILTIN="bell"/>
|
<icon BUILTIN="bell"/>
|
||||||
<node CREATED="1485548856639" ID="ID_1677281474" MODIFIED="1485548861522" TEXT="spezifische Aktionen">
|
<node CREATED="1485548856639" ID="ID_1677281474" MODIFIED="1485548861522" TEXT="spezifische Aktionen">
|
||||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1485548894522" FOLDED="true" ID="ID_826011549" MODIFIED="1492444340662" TEXT="Problem: globale Aktionen">
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1485548894522" FOLDED="true" ID="ID_826011549" MODIFIED="1495207337712" TEXT="Problem: globale Aktionen">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue