source: lliurex-apt/trunk/fuentes/src/gui.cpp @ 923

Last change on this file since 923 was 923, checked in by mabarracus, 4 years ago

Imported trusty code

File size: 9.4 KB
Line 
1
2#include "Sources.hpp"
3#include "Commands.hpp"
4#include "Cache.hpp"
5#include "Graphics.hpp"
6
7#include <iostream>
8#include <utility>
9#include <vector>
10#include <map>
11#include <functional>
12
13#include <gtkmm.h>
14#include <glibmm.h>
15#include <giomm.h>
16
17#include <locale.h>
18#include <libintl.h>
19#define T(String) gettext(String)
20
21
22using namespace std;
23using namespace std::placeholders;
24using namespace net::lliurex::apt;
25using namespace net::lliurex::apt::graphics;
26
27
28class Application
29{
30        private:
31       
32        Glib::RefPtr<Gtk::Builder> glade;
33
34        //Main window
35        Gtk::Window * winMain;
36
37        Gtk::Viewport * vpPreview;
38        Gtk::Box * boxA;
39        Gtk::Box * boxB;
40        Gtk::Box * boxC;
41        Gtk::Button * btnOk;
42        Gtk::Button * btnCancel;
43        Gtk::Button * btnUpdateCancel;
44       
45        Gtk::CheckButton * chkWipeSources;
46       
47        Gtk::Box * boxPreview;
48        Gtk::Box * boxChooser;
49
50       
51        //Update window
52        Gtk::Window * winUpdate;
53        Gtk::ProgressBar * pbarUpdate;
54        Gtk::TextView * txtUpdate;
55       
56       
57       
58        Gtk::Box * boxStep1;
59        Gtk::Paned * panedStep2;
60       
61        Gtk::RadioButton * rbCustom;
62       
63       
64        vector<Sources> conf;
65        Sources sources_list;
66        Sources sources_current;
67        Cache cache;
68       
69        vector<pair<Gtk::Image *,SourceLineBubble *> > bubbles;
70        vector<pair<Gtk::ToggleButton *,Sources *> > toggleButtons;
71       
72        string locale;
73
74        public:
75       
76        Application()
77        {
78       
79                locale = getenv("LANG");
80               
81                string glade_path;
82               
83               
84                glade=Gtk::Builder::create_from_resource("/net/lliurex/apt/interface.ui");
85               
86                glade->get_widget("winMain",winMain);
87               
88                glade->get_widget("vpPreview",vpPreview);
89               
90                glade->get_widget("boxA",boxA);
91                glade->get_widget("boxB",boxB);
92                glade->get_widget("boxC",boxC);
93               
94                glade->get_widget("btnOk",btnOk);
95                glade->get_widget("btnCancel",btnCancel);
96                glade->get_widget("btnUpdateCancel",btnUpdateCancel);
97                glade->get_widget("chkWipeSources",chkWipeSources);
98               
99                glade->get_widget("winUpdate",winUpdate);
100                glade->get_widget("pbarUpdate",pbarUpdate);
101                glade->get_widget("txtUpdate",txtUpdate);
102
103               
104               
105               
106               
107
108               
109                //connecting to events
110                winMain->signal_delete_event().connect(sigc::mem_fun(*this,&Application::OnWinMainClose));     
111                chkWipeSources->signal_toggled().connect(sigc::mem_fun(*this,&Application::OnToggle));
112                //btnUpdate->signal_clicked().connect(sigc::mem_fun(*this,&Application::OnUpdateClick));
113               
114                btnOk->signal_clicked().connect(sigc::mem_fun(*this,&Application::OnOkClick));
115                btnCancel->signal_clicked().connect(sigc::mem_fun(*this,&Application::OnCancelClick));
116                btnUpdateCancel->signal_clicked().connect(sigc::mem_fun(*this,&Application::OnUpdateCancelClick));
117               
118                if (Gio::File::create_for_path(Sources::SourcesList)->query_exists()){
119                        sources_list = Sources(Sources::SourcesList);
120                }
121
122               
123                conf = command::LoadConf();
124                               
125               
126               
127                vector<command::Match> status = command::Check(sources_list,conf);
128                map<string,FindLineStatus> source_status;
129               
130                Sources * mandatory = nullptr;
131                int analysis=0; //0-unknown, 1-detected, 2-inconsistent
132                               
133               
134                for(command::Match match : status)
135                {
136               
137                        if(match.status==FindLineStatus::NotFound)continue;
138                       
139                        if(!match.sources->optional && match.status==FindLineStatus::Found)
140                        {
141                                if(mandatory==nullptr)
142                                {
143                                        mandatory=match.sources;
144                                        analysis=1;
145                                }
146                                else
147                                {
148                                        analysis=2;
149                                }
150                        }
151                       
152                        string name=GetName(match.sources->name);
153                       
154                        if(source_status.find(name)==source_status.end())
155                        {
156                                source_status[name]=match.status;
157                        }
158                        else
159                        {
160                                FindLineStatus s = source_status[name];
161                               
162                                //Partial status cannot overwrite Found status
163                                if(s==FindLineStatus::Partial && match.status==FindLineStatus::Found)
164                                {
165                                        source_status[name]=FindLineStatus::Found;
166                                }
167                        }
168                }
169               
170                for(pair<string,FindLineStatus> p : source_status)
171                {
172                        string text;
173                       
174                        if(p.second!=FindLineStatus::Found)
175                                continue;
176                       
177                       
178                        text=T("Found: ");
179                       
180                        text=text+"["+p.first+"]";
181                       
182                        Pango::FontDescription font("Ubuntu 11.0");
183
184                        Gtk::Box * box = new Gtk::Box(Gtk::Orientation::ORIENTATION_HORIZONTAL);                       
185                        Gtk::Arrow * arrow = new Gtk::Arrow(Gtk::ArrowType::ARROW_RIGHT,Gtk::ShadowType::SHADOW_OUT);
186                        box->pack_start(*arrow,false,false);
187
188
189                        Gtk::Label *label = new Gtk::Label(text);
190                        label->override_font(font);
191                        label->set_justify(Gtk::Justification::JUSTIFY_LEFT);
192                        label->set_alignment(0.0,0.5);
193                        label->set_margin_top(5);
194                        label->set_margin_bottom(5);
195
196                        box->pack_start(*label,false,false);
197                       
198                       
199                        boxC->pack_start(*box,false,false);
200                }
201               
202               
203               
204               
205                //source view
206                boxPreview = new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL);
207                vpPreview->add(*boxPreview);
208               
209               
210                //chooser view
211                               
212                boxChooser = boxA;
213               
214                Gtk::RadioButtonGroup group;
215               
216                rbCustom = new Gtk::RadioButton(T("Custom"));
217                rbCustom->set_group(group);
218                boxChooser->pack_start(*rbCustom,false,false);
219                //toggleButtons.push_back(make_pair(rbc,&sources_list));
220               
221                Gtk::RadioButton * rbn = new Gtk::RadioButton(T("None"));
222                rbn->set_group(group);
223                boxChooser->pack_start(*rbn,false,false);
224
225                rbn->signal_toggled().connect(sigc::mem_fun(*this,&Application::OnToggle));
226               
227                       
228                for(int n=0;n<conf.size();n++)
229                {
230                        if(!conf[n].optional)
231                        {
232                                Gtk::RadioButton * rb = new Gtk::RadioButton(GetName(conf[n].name));
233                                rb->set_group(group);
234                                boxChooser->pack_start(*rb,false,false);
235                               
236                                rb->signal_toggled().connect(sigc::mem_fun(*this,&Application::OnToggle));
237                                toggleButtons.push_back(make_pair(rb,&conf[n]));
238                        }
239                }
240               
241                for(int n=0;n<conf.size();n++)
242                {
243                        if(conf[n].optional)
244                        {
245                                Gtk::CheckButton * cb = new Gtk::CheckButton(GetName(conf[n].name));
246                                boxB->pack_start(*cb,false,false);
247
248                                cb->signal_toggled().connect(sigc::mem_fun(*this,&Application::OnToggle));
249                                toggleButtons.push_back(make_pair(cb,&conf[n]));
250                        }
251                       
252                }
253               
254               
255                //connecto to cache hooks
256                function<void(int,string)> p1 = std::bind(&Application::UpdateProgress,this,_1,_2);
257                function<void(void)> p2 = std::bind(&Application::UpdateReady,this);
258               
259                cache=Cache(p1,p2);
260               
261                //force an initial update
262                OnToggle();
263               
264                winMain->show_all();
265               
266        }
267       
268        ~Application()
269        {
270       
271        }
272       
273        /*!
274                Window close event
275        */
276        bool OnWinMainClose(GdkEventAny* event)
277        {
278                Gtk::Main::quit();
279               
280                return true;
281        }
282       
283        /*!
284                Toggle/Check button pressed
285        */
286        void OnToggle()
287        {
288       
289                if(rbCustom->get_active())
290                {
291                        sources_current = sources_list;
292                       
293                        for(int n=0;n<toggleButtons.size();n++)
294                        {
295                                Gtk::ToggleButton * tb;
296                       
297                                tb=toggleButtons[n].first;
298                       
299                                if(tb->get_active())
300                                {
301                                        sources_current = sources_current + *(toggleButtons[n].second);
302                                }
303                        }
304                }
305                else
306                {
307                        vector<string> targets;
308               
309                        for(int n=0;n<toggleButtons.size();n++)
310                        {
311                                Gtk::ToggleButton * tb;
312                       
313                                tb=toggleButtons[n].first;
314                       
315                                if(tb->get_active())
316                                {
317                                        targets.push_back(toggleButtons[n].second->name["C"]);
318                                }
319                        }
320               
321               
322                        sources_current = command::Set(sources_list,conf,targets,chkWipeSources->get_active());
323                }
324               
325                cout<<endl;
326                sources_current.Print();
327                cout<<endl;
328               
329                BuildPreview();
330               
331        }
332       
333       
334        /*!
335                Ok Button clicked
336        */
337        void OnOkClick()
338        {
339                cout<<"Writing..."<<endl;
340                try
341                {
342                        //Warning: this is a blocking function
343                        sources_current.Write(Sources::SourcesList);
344                }
345                catch(runtime_error e)
346                {
347                        //in case authetification fail, just do nothing :)
348                        cout<<"Operation canceled"<<endl;
349                        return;
350                }
351               
352                cout<<"Updating..."<<endl;
353               
354                winUpdate->show_all();
355               
356               
357                cache.Update();
358               
359        }
360       
361        void OnUpdateCancelClick()
362        {
363                cout<<"Update canceled by user"<<endl;
364                cache.Cancel();
365                winUpdate->hide();
366        }
367       
368        /*!
369                Cancel pressed, just quit
370        */
371        void OnCancelClick()
372        {
373                Gtk::Main::quit();
374        }
375       
376       
377        /*!
378                Does a best effort looking
379                for a translated string
380        */
381        string GetName(map<string,string> & name)
382        {
383                string ret="";
384                map<string,string>::iterator it;
385               
386                it=name.find(locale);
387               
388                if(it!=name.end())
389                {
390                        ret=it->second;
391                }
392                else
393                {
394                        it=name.find("C");
395                       
396                        if(it!=name.end())
397                        {
398                                ret=it->second;
399                        }
400                }
401               
402               
403                return ret;
404        }
405
406       
407        /*!
408                Build bubble source preview
409        */
410        void BuildPreview()
411        {
412               
413                //clear current bubbles, if any
414               
415                for(int n=0;n<bubbles.size();n++)
416                {
417                        boxPreview->remove(*bubbles[n].first);
418                        delete bubbles[n].first;
419                        delete bubbles[n].second;
420                }
421               
422                bubbles.clear();
423               
424               
425                //rebuild images
426               
427                for(int n=0;n<sources_current.lines.size();n++)
428                {
429                        SourceLineBubble * line= new SourceLineBubble(sources_current.lines[n],1024,32);
430                       
431                        Gtk::Image * img = new Gtk::Image();
432                        img->set(line->surface);
433                        img->set_alignment(0.0,0.5);
434                        boxPreview->pack_start(*img,false,false);
435                       
436                        bubbles.push_back(make_pair(img,line));
437                }
438               
439                winMain->show_all();
440       
441        }
442       
443        /*!
444                Update progress callback
445        */
446        void UpdateProgress(int progress,string details)
447        {
448                //cout<<"["<<progress<<"%] "<<details<<endl;
449               
450                double fraction = progress/100.0;
451               
452                pbarUpdate->set_fraction(fraction);
453               
454                string line = details + "\n";
455                Gtk::TextIter it = txtUpdate->get_buffer()->end();
456                it=txtUpdate->get_buffer()->insert(it,line);
457                txtUpdate->scroll_to(it);
458        }
459       
460       
461        /*!
462                Update completed... and quit
463        */
464        void UpdateReady()
465        {
466                cout<<"Update complete"<<endl;
467                pbarUpdate->set_fraction(1.0);
468                //btnUpdate->set_sensitive(true);
469               
470               
471                Gtk::MessageDialog* dialog = new Gtk::MessageDialog(T("Update is succesful"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_CLOSE,true);
472                dialog->set_secondary_text(T("Software sources has been updated"));
473                dialog->run();
474                delete dialog;
475               
476                Gtk::Main::quit();
477               
478               
479               
480        }
481       
482       
483};
484
485
486int main(int argc,char * argv[])
487{
488
489        textdomain("lliurex-apt");
490       
491       
492        Gtk::Main kit(argc, argv);
493       
494        Application app;
495       
496        Gtk::Main::run();
497
498        return 0;
499}
Note: See TracBrowser for help on using the repository browser.