Re: Problem with sorting ColumnView

Jackson Campolattaro via gtkmm-list <[email protected]> Wed, 24 Aug 2022 00:55:01 +0200
Newsgroups gmane.comp.gnome.gtkmm
Message-ID <CAK-p+x-SsiOoYxFCe_mP27NhzRA7dJXcxMeX0_BVRZ=qkxPXYQ@mail.gmail.com>
--===============1917354673927301840==
Content-Type: multipart/alternative; boundary="00000000000001bf8705e6f07594"

--00000000000001bf8705e6f07594
Content-Type: text/plain; charset="UTF-8"

Thanks! Somehow I got the impression that the ColumnView would construct
SortListModels on its own, but looking back at the documentation I'm not
sure where I heard that.

Here is a working solution:

#include <gtkmm.h>
> #include <giomm.h>
>
> class MyWindow : public Gtk::Window {
> private:
>
>     Gtk::ColumnView _columnView;
>
> public:
>
>     MyWindow() {
>
>         auto listModel = Gio::ListStore<Gio::File>::create();
>         auto sortListModel = Gtk::SortListModel::create(listModel,
> _columnView.get_sorter());
>         _columnView.set_model(Gtk::SingleSelection::create(sortListModel));
>
>         auto files = Gio::File::create_for_path(".")->enumerate_children();
>         Glib::RefPtr<Gio::FileInfo> fileInfo;
>         while ((fileInfo = files->next_file())) {
>
> listModel->append(Gio::File::create_for_path(fileInfo->get_name()));
>         }
>
>         auto factory = Gtk::SignalListItemFactory::create();
>         factory->signal_setup().connect([](auto listItem) {
>             listItem->set_child(*Gtk::make_managed<Gtk::Label>("_",
> Gtk::Align::START));
>         });
>         factory->signal_bind().connect([](auto listItem) {
>             auto data =
> std::dynamic_pointer_cast<Gio::File>(listItem->get_item());
>             auto label = dynamic_cast<Gtk::Label *>(listItem->get_child());
>             if (data && label)
>                 label->set_text(data->get_path());
>         });
>
>         auto column = Gtk::ColumnViewColumn::create("File Paths", factory);
>         column->set_sorter(Gtk::StringSorter::create(
>                 Gtk::ClosureExpression<Glib::ustring>::create([](auto
> item) {
>                     auto data = std::dynamic_pointer_cast<Gio::File>(item);
>                     return data->get_basename();
>                 })
>         ));
>         _columnView.append_column(column);
>
>         _columnView.sort_by_column(column, Gtk::SortType::ASCENDING);
>         set_child(_columnView);
>     };
> };
>
> int main(int argc, char *argv[]) {
>     auto app = Gtk::Application::create("org.gtkmm.examples.base");
>     return app->make_window_and_run<MyWindow>(argc, argv);
> }
>

I appreciate your help!

Jackson

On Tue, Aug 23, 2022 at 9:38 PM Andrew Potter <[email protected]> wrote:

> The documentation at
> https://docs.gtk.org/gtk4/method.ColumnView.get_sorter.html suggests you
> need a SortListModel
>
> On Tue, Aug 23, 2022 at 4:32 AM Jackson Campolattaro via gtkmm-list <
> [email protected]> wrote:
>
>> Hello,
>>
>> I'm trying to use the Gtk ColumnView to show a custom ListModel in sorted
>> order. I noticed that when I set a simple sorter for a column and then sort
>> by that column, the order isn't changed. The UI allows me to switch between
>> ascending and descending, but doing so doesn't reverse the list.
>>
>> I've created a simplified example, which is supposed to show the file
>> paths in the current directory in alphabetical order, but doesn't:
>>
>> #include <gtkmm.h>
>>> #include <giomm.h>
>>>
>>> class MyWindow : public Gtk::Window {
>>> private:
>>>
>>>     Glib::RefPtr<Gio::ListStore<Gio::File>> _listModel;
>>>     Glib::RefPtr<Gtk::SingleSelection> _selectionModel;
>>>
>>>     Gtk::ColumnView _columnView;
>>>
>>> public:
>>>     MyWindow() {
>>>
>>>         _listModel = Gio::ListStore<Gio::File>::create();
>>>         _selectionModel = Gtk::SingleSelection::create(_listModel);
>>>         _columnView.set_model(_selectionModel);
>>>
>>>         auto files =
>>> Gio::File::create_for_path(".")->enumerate_children();
>>>         Glib::RefPtr<Gio::FileInfo> fileInfo;
>>>         while ((fileInfo = files->next_file())) {
>>>
>>> _listModel->append(Gio::File::create_for_path(fileInfo->get_name()));
>>>         }
>>>
>>>         auto _factory = Gtk::SignalListItemFactory::create();
>>>         _factory->signal_setup().connect([](auto listItem) {
>>>
>>> listItem->set_child(*Gtk::make_managed<Gtk::Label>("Placeholder!"));
>>>         });
>>>         _factory->signal_bind().connect([](auto listItem) {
>>>             auto data =
>>> std::dynamic_pointer_cast<Gio::File>(listItem->get_item());
>>>             auto label = dynamic_cast<Gtk::Label
>>> *>(listItem->get_child());
>>>             if (data && label) {
>>>                 label->set_text(data->get_path());
>>>                 label->set_xalign(0);
>>>             }
>>>         });
>>>
>>>         auto column = Gtk::ColumnViewColumn::create("File Paths",
>>> _factory);
>>>         _columnView.append_column(column);
>>>
>>>         column->set_sorter(Gtk::StringSorter::create(
>>>                 Gtk::ClosureExpression<Glib::ustring>::create([](auto
>>> item) {
>>>                     auto data =
>>> std::dynamic_pointer_cast<Gio::File>(item);
>>>                     return data->get_path();
>>>                 })
>>>         ));
>>>         _columnView.sort_by_column(column, Gtk::SortType::ASCENDING);
>>>
>>>         set_child(_columnView);
>>>     };
>>> };
>>>
>>> int main(int argc, char *argv[]) {
>>>     auto app = Gtk::Application::create("org.gtkmm.examples.base");
>>>     return app->make_window_and_run<MyWindow>(argc, argv);
>>> }
>>>
>>
>> Perhaps this is a bug, but before I report it I wanted to make sure I'm
>> not doing something wrong.
>>
>> Thanks,
>>
>> Jackson
>> _______________________________________________
>> gtkmm-list mailing list
>> [email protected]
>> https://mail.gnome.org/mailman/listinfo/gtkmm-list
>>
>

-- 
Jackson Campolattaro
Masters Student at TU Delft

--00000000000001bf8705e6f07594
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Thanks! Somehow I got the impression that the ColumnV=
iew would=20
construct SortListModels on its own, but looking back at the=20
documentation I&#39;m not sure where I heard that. <br></div><div><br></div=
><div>Here is a working solution:<br></div><div><br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex"><div><span style=3D"font-family:monospace"=
><span class=3D"gmail-im">#include &lt;gtkmm.h&gt;<br>#include &lt;giomm.h&=
gt;<br><br>class MyWindow : public Gtk::Window {<br>private:<br><br>=C2=A0 =
=C2=A0 Gtk::ColumnView _columnView;<br><br>public:<br><br>=C2=A0 =C2=A0 MyW=
indow() {<br><br></span>=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto listModel =3D Gio:=
:ListStore&lt;Gio::File&gt;::create();<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto =
sortListModel =3D Gtk::SortListModel::create(listModel, _columnView.get_sor=
ter());<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 _columnView.set_model(Gtk::SingleSel=
ection::create(sortListModel));<span class=3D"gmail-im"><br><br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 auto files =3D Gio::File::create_for_path(&quot;.&quot;)-=
&gt;enumerate_children();<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 Glib::RefPtr&lt;Gi=
o::FileInfo&gt; fileInfo;<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 while ((fileInfo =
=3D files-&gt;next_file())) {<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
listModel-&gt;append(Gio::File::create_for_path(fileInfo-&gt;get_name()));<=
br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br><br></span>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
auto factory =3D Gtk::SignalListItemFactory::create();<br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 factory-&gt;signal_setup().connect([](auto listItem) {<br>=C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 listItem-&gt;set_child(*Gtk::make_manag=
ed&lt;Gtk::Label&gt;(&quot;_&quot;, Gtk::Align::START));<br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 });<span class=3D"gmail-im"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 f=
actory-&gt;signal_bind().connect([](auto listItem) {<br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 auto data =3D std::dynamic_pointer_cast&lt;Gio::Fi=
le&gt;(listItem-&gt;get_item());<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 auto label =3D dynamic_cast&lt;Gtk::Label *&gt;(listItem-&gt;get_child(=
));<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (data &amp;&amp; label)=
<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 label-&gt;set_t=
ext(data-&gt;get_path());<br></span>=C2=A0 =C2=A0 =C2=A0 =C2=A0 });<br><br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto column =3D Gtk::ColumnViewColumn::create(&=
quot;File Paths&quot;, factory);<span class=3D"gmail-im"><br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 column-&gt;set_sorter(Gtk::StringSorter::create(<br>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Gtk::ClosureExpression&lt;=
Glib::ustring&gt;::create([](auto item) {<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 auto data =3D std::dynamic_pointe=
r_cast&lt;Gio::File&gt;(item);<br></span>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return data-&gt;get_basename();<br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 })<br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 ));<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 _columnView.append_column(=
column);<span class=3D"gmail-im"><br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 _colum=
nView.sort_by_column(column, Gtk::SortType::ASCENDING);<br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 set_child(_columnView);<br>=C2=A0 =C2=A0 };<br>};<br><br>int =
main(int argc, char *argv[]) {<br>=C2=A0 =C2=A0 auto app =3D Gtk::Applicati=
on::create(&quot;org.gtkmm.examples.base&quot;);<br>=C2=A0 =C2=A0 return ap=
p-&gt;make_window_and_run&lt;MyWindow&gt;(argc, argv);<br>}<br></span></spa=
n></div></blockquote><div><br></div><div>I appreciate your help!</div><div>=
<br></div><div>Jackson </div></div><br><div class=3D"gmail_quote"><div dir=
=3D"ltr" class=3D"gmail_attr">On Tue, Aug 23, 2022 at 9:38 PM Andrew Potter=
 &lt;<a href=3D"mailto:[email protected]">[email protected]</a>&gt; wrote=
:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.=
8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"lt=
r">The documentation at=C2=A0<a href=3D"https://docs.gtk.org/gtk4/method.Co=
lumnView.get_sorter.html" target=3D"_blank">https://docs.gtk.org/gtk4/metho=
d.ColumnView.get_sorter.html</a> suggests you need a SortListModel=C2=A0</d=
iv><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On =
Tue, Aug 23, 2022 at 4:32 AM Jackson Campolattaro via gtkmm-list &lt;<a hre=
f=3D"mailto:[email protected]" target=3D"_blank">[email protected]</a=
>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px=
 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><di=
v dir=3D"ltr"><div>Hello,</div><div><br></div><div>I&#39;m trying to use th=
e Gtk ColumnView to show a custom ListModel in sorted order. I noticed that=
 when I set a simple sorter for a column and then sort by that column, the =
order isn&#39;t changed. The UI allows me to switch between ascending and d=
escending, but doing so doesn&#39;t reverse the list.<br></div><div><br></d=
iv><div>I&#39;ve created a simplified example, which is supposed to show th=
e file paths in the current directory in alphabetical order, but doesn&#39;=
t:</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0p=
x 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><d=
iv><span style=3D"font-family:monospace">#include &lt;gtkmm.h&gt;<br>#inclu=
de &lt;giomm.h&gt;<br><br>class MyWindow : public Gtk::Window {<br>private:=
<br><br>=C2=A0 =C2=A0 Glib::RefPtr&lt;Gio::ListStore&lt;Gio::File&gt;&gt; _=
listModel;<br>=C2=A0 =C2=A0 Glib::RefPtr&lt;Gtk::SingleSelection&gt; _selec=
tionModel;<br><br>=C2=A0 =C2=A0 Gtk::ColumnView _columnView;<br><br>public:=
<br>=C2=A0 =C2=A0 MyWindow() {<br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 _listMode=
l =3D Gio::ListStore&lt;Gio::File&gt;::create();<br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 _selectionModel =3D Gtk::SingleSelection::create(_listModel);<br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 _columnView.set_model(_selectionModel);<br><br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 auto files =3D Gio::File::create_for_path(&quot;.&=
quot;)-&gt;enumerate_children();<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 Glib::RefPt=
r&lt;Gio::FileInfo&gt; fileInfo;<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 while ((fil=
eInfo =3D files-&gt;next_file())) {<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 _listModel-&gt;append(Gio::File::create_for_path(fileInfo-&gt;get_na=
me()));<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0=
 auto _factory =3D Gtk::SignalListItemFactory::create();<br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 _factory-&gt;signal_setup().connect([](auto listItem) {<br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 listItem-&gt;set_child(*Gtk::make=
_managed&lt;Gtk::Label&gt;(&quot;Placeholder!&quot;));<br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 });<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 _factory-&gt;signal_bind().co=
nnect([](auto listItem) {<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 auto=
 data =3D std::dynamic_pointer_cast&lt;Gio::File&gt;(listItem-&gt;get_item(=
));<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 auto label =3D dynamic_cas=
t&lt;Gtk::Label *&gt;(listItem-&gt;get_child());<br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 if (data &amp;&amp; label) {<br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 label-&gt;set_text(data-&gt;get_path());=
<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 label-&gt;set_x=
align(0);<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 });<br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto column =3D Gtk::C=
olumnViewColumn::create(&quot;File Paths&quot;, _factory);<br>=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 _columnView.append_column(column);<br><br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 column-&gt;set_sorter(Gtk::StringSorter::create(<br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Gtk::ClosureExpression&lt;Gli=
b::ustring&gt;::create([](auto item) {<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 auto data =3D std::dynamic_pointer_c=
ast&lt;Gio::File&gt;(item);<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return data-&gt;get_path();<br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 })<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0=
 ));<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 _columnView.sort_by_column(column, Gtk:=
:SortType::ASCENDING);<br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 set_child(_column=
View);<br>=C2=A0 =C2=A0 };<br>};<br><br>int main(int argc, char *argv[]) {<=
br>=C2=A0 =C2=A0 auto app =3D Gtk::Application::create(&quot;org.gtkmm.exam=
ples.base&quot;);<br>=C2=A0 =C2=A0 return app-&gt;make_window_and_run&lt;My=
Window&gt;(argc, argv);<br>}</span></div></blockquote><div><br></div><div>P=
erhaps this is a bug, but before I report it I wanted to make sure I&#39;m =
not doing something wrong.</div><div><br></div><div>Thanks,</div><div><br><=
/div><div>Jackson</div></div>
_______________________________________________<br>
gtkmm-list mailing list<br>
<a href=3D"mailto:[email protected]" target=3D"_blank">gtkmm-list@gnome.=
org</a><br>
<a href=3D"https://mail.gnome.org/mailman/listinfo/gtkmm-list" rel=3D"noref=
errer" target=3D"_blank">https://mail.gnome.org/mailman/listinfo/gtkmm-list=
</a><br>
</blockquote></div>
</blockquote></div><br clear=3D"all"><br>-- <br><div dir=3D"ltr" class=3D"g=
mail_signature"><div dir=3D"ltr"><div><div dir=3D"ltr"><font size=3D"2">Jac=
kson Campolattaro</font></div><div><font size=3D"2"><font size=3D"1">Master=
s Student at TU Delft</font><br></font></div></div></div></div>

--00000000000001bf8705e6f07594--

--===============1917354673927301840==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
gtkmm-list mailing list
[email protected]
https://mail.gnome.org/mailman/listinfo/gtkmm-list

--===============1917354673927301840==--