source: projects/synaptic/trunk/gtk/rginstallprogress.cc @ 280

Revision 280, 11.0 KB checked in by yasumichi, 15 years ago (diff)

first import

RevLine 
[280]1/* rginstallprogress.cc
2 *
3 * Copyright (c) 2000, 2001 Conectiva S/A
4 *
5 * Author: Alfredo K. Kojima <kojima@conectiva.com.br>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 */
22
23#include "config.h"
24
25#include "rgmainwindow.h"
26#include "gsynaptic.h"
27
28#include "rginstallprogress.h"
29
30#include <apt-pkg/configuration.h>
31#include <gtk/gtk.h>
32
33#include <unistd.h>
34#include <stdio.h>
35
36#include "i18n.h"
37
38RGInstallProgressMsgs::RGInstallProgressMsgs(RGWindow *win)
39: RGGladeWindow(win, "rginstall_progress_msgs"),
40_currentPackage(0), _hasHeader(false)
41{
42   setTitle(_("Package Manager output"));
43   GtkWidget *textView = glade_xml_get_widget(_gladeXML, "textview");
44   _textBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textView));
45   glade_xml_signal_connect_data(_gladeXML, "on_close_clicked",
46                                 G_CALLBACK(onCloseClicked), this);
47   PangoFontDescription *font;
48   font = pango_font_description_from_string("helvetica 10");
49   gtk_widget_modify_font(textView, font);
50   font = pango_font_description_from_string("helvetica bold 10");
51   gtk_text_buffer_create_tag(_textBuffer, "bold", "font-desc", font, NULL);
52   if(!_config->FindB("Volatile::HideMainwindow", false))
53      skipTaskbar(true);
54   else
55      skipTaskbar(false);
56}
57
58void RGInstallProgressMsgs::onCloseClicked(GtkWidget *self, void *data)
59{
60   //RGInstallProgressMsgs *me = (RGInstallProgressMsgs*)data;
61   gtk_main_quit();
62}
63
64bool RGInstallProgressMsgs::close()
65{
66   gtk_main_quit();
67   return true;
68}
69
70void RGInstallProgressMsgs::addText(const char *text, bool bold)
71{
72   GtkTextIter enditer;
73   gtk_text_buffer_get_end_iter(_textBuffer, &enditer);
74   if (bold == true)
75      gtk_text_buffer_insert_with_tags_by_name(_textBuffer, &enditer,
76                                               text, -1, "bold", NULL);
77   else
78      gtk_text_buffer_insert(_textBuffer, &enditer, text, -1);
79}
80
81void RGInstallProgressMsgs::addLine(const char *text)
82{
83   if (!_hasHeader) {
84      char *header;
85      if (_currentPackage != NULL)
86         header = g_strdup_printf(_("\nWhile installing package %s:\n\n"),
87                                  _currentPackage);
88      else
89         header =
90            g_strdup_printf(_("\nWhile preparing for installation:\n\n"));
91      addText(header, true);
92      _hasHeader = true;
93   }
94   addText(text);
95   addText("\n");
96}
97
98void RGInstallProgressMsgs::newPackage(const char *name)
99{
100   _currentPackage = name;
101   _hasHeader = false;
102}
103
104bool RGInstallProgressMsgs::empty()
105{
106   return gtk_text_buffer_get_char_count(_textBuffer) == 0;
107}
108
109void RGInstallProgressMsgs::run()
110{
111   show();
112   gtk_main();
113   hide();
114}
115
116void RGInstallProgress::startUpdate()
117{
118   show();
119   RGFlushInterface();
120}
121
122void RGInstallProgress::finishUpdate()
123{
124   char buf[1024];
125   bzero(buf, 1024);
126   int len = read(_childin, buf, 1023);
127   if (len > 0) {
128      GtkWidget *dia = gtk_message_dialog_new(GTK_WINDOW(this->window()),
129                                              GTK_DIALOG_DESTROY_WITH_PARENT,
130                                              GTK_MESSAGE_ERROR, 
131                                              GTK_BUTTONS_OK, 
132                                              _("APT system reports:\n%s"), 
133                                              utf8(buf));
134      gtk_dialog_run(GTK_DIALOG(dia));
135      gtk_widget_destroy(dia);
136   }
137
138   if (_startCounting) {
139      gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(_pbar), 1.0);
140      gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(_pbarTotal), 1.0);
141   }
142
143   if (_msgs.empty() == false &&
144       _config->FindB("Synaptic::IgnorePMOutput", false) == false)
145      _msgs.run();
146
147   RGFlushInterface();
148
149   hide();
150}
151
152void RGInstallProgress::prepare(RPackageLister *lister)
153{
154   for (unsigned int row = 0; row < lister->packagesSize(); row++) {
155      RPackage *elem = lister->getPackage(row);
156
157      // Is it going to be seen?
158      if (!(elem->getFlags() & RPackage::FInstall))
159         continue;
160
161      const char *name = elem->name();
162      const char *ver = elem->availableVersion();
163      const char *pos = strchr(ver, ':');
164      if (pos)
165         ver = pos + 1;
166      string namever = string(name) + "-" + string(ver);
167      _summaryMap[namever] = elem->summary();
168   }
169}
170
171void RGInstallProgress::updateInterface()
172{
173   char buf[2];
174   static char line[1024] = "";
175
176   while (1) {
177      // This algorithm should be improved.
178      int len = read(_childin, buf, 1);
179      if (len < 1)
180         break;
181      if (buf[0] == '\n') {
182         float val;
183         if (line[0] != '%') {
184            map<string, string>::const_iterator I = _summaryMap.find(line);
185            if (I == _summaryMap.end()) {
186               if (_startCounting == false) {
187                  gtk_label_set_label(GTK_LABEL(_label), utf8(line));
188                  gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(_pbar), 0);
189               } else {
190                  _msgs.addLine(utf8(line));
191               }
192            } else {
193               // Get from the map, so that _msgs doesn't have
194               // to keep an internal copy.
195               _msgs.newPackage(I->first.c_str());
196               gtk_label_set_label(GTK_LABEL(_label), utf8(line));
197               gtk_label_set_label(GTK_LABEL(_labelSummary),
198                                   utf8(I->second.c_str()));
199               gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(_pbar), 0);
200               _donePackages += 1;
201               val = ((float)_donePackages) / _numPackages;
202               gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(_pbarTotal),
203                                             val);
204               _donePackagesTotal += 1;
205               if (_ss) {
206                  _ss->setTotalSteps(_numPackagesTotal);
207                  _ss->step();
208               }
209            }
210         } else {
211            sscanf(line + 3, "%f", &val);
212            val = val * 0.01;
213            gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(_pbar), val);
214            if (_startCounting == false) {
215               // This will happen when the "Preparing..." progress
216               // is shown and its progress percentage starts.
217               _startCounting = true;
218               // Stop pulsing
219               gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(_pbarTotal), 0);
220            }
221         }
222         line[0] = 0;
223      } else {
224         buf[1] = 0;
225         strcat(line, buf);
226      }
227   }
228
229   if (gtk_events_pending()) {
230      while (gtk_events_pending())
231         gtk_main_iteration();
232   } else {
233      usleep(5000);
234      if (_startCounting == false) {
235         gtk_progress_bar_pulse(GTK_PROGRESS_BAR(_pbar));
236         gtk_progress_bar_pulse(GTK_PROGRESS_BAR(_pbarTotal));
237      }
238   }
239}
240
241class GeometryParser {
242 protected:
243
244   int _width;
245   int _height;
246   int _xpos;
247   int _ypos;
248
249   bool ParseSize(char **size);
250   bool ParsePosition(char **pos);
251
252 public:
253
254   int Width() {
255      return _width;
256   };
257   int Height() {
258      return _height;
259   };
260   int XPos() {
261      return _xpos;
262   };
263   int YPos() {
264      return _ypos;
265   };
266
267   bool HasSize() {
268      return _width != -1 && _height != -1;
269   };
270   bool HasPosition() {
271      return _xpos != -1 && _ypos != -1;
272   };
273
274   bool Parse(string Geo);
275
276   GeometryParser(string Geo = "")
277 :   _width(-1), _height(-1), _xpos(-1), _ypos(-1) {
278      Parse(Geo);
279   };
280};
281
282RGInstallProgress::RGInstallProgress(RGMainWindow *main,
283                                     RPackageLister *lister)
284: RInstallProgress(), RGGladeWindow(main, "rginstall_progress"), _msgs(main)
285{
286   prepare(lister);
287   setTitle(_("Applying Changes"));
288
289   _startCounting = false;
290
291   string GeoStr = _config->Find("Synaptic::Geometry::InstProg", "");
292   GeometryParser Geo(GeoStr);
293   if (Geo.HasSize())
294      gtk_widget_set_usize(GTK_WIDGET(_win), Geo.Width(), Geo.Height());
295   if (Geo.HasPosition())
296      gtk_widget_set_uposition(GTK_WIDGET(_win), Geo.XPos(), Geo.YPos());
297
298   _label = glade_xml_get_widget(_gladeXML, "label_name");
299   _labelSummary = glade_xml_get_widget(_gladeXML, "label_summary");
300   _pbar = glade_xml_get_widget(_gladeXML, "progress_package");
301   _pbarTotal = glade_xml_get_widget(_gladeXML, "progress_total");
302   _image = glade_xml_get_widget(_gladeXML, "image");
303
304   string ssDir = _config->Find("Synaptic::SlideShow", "");
305   if (!ssDir.empty()) {
306      _ss = new RGSlideShow(GTK_IMAGE(_image), ssDir);
307      _ss->refresh();
308      gtk_widget_show(_image);
309   } else {
310      _ss = NULL;
311   }
312
313   PangoFontDescription *bfont;
314   PangoFontDescription *font;
315   bfont = pango_font_description_from_string("helvetica bold 10");
316   font = pango_font_description_from_string("helvetica 10");
317
318   gtk_widget_modify_font(_label, bfont);
319   gtk_widget_modify_font(_labelSummary, font);
320
321   gtk_label_set_text(GTK_LABEL(_label), "");
322   gtk_label_set_text(GTK_LABEL(_labelSummary), "");
323   gtk_progress_bar_pulse(GTK_PROGRESS_BAR(_pbar));
324   gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(_pbar), 0.01);
325   gtk_progress_bar_pulse(GTK_PROGRESS_BAR(_pbarTotal));
326   gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(_pbarTotal), 0.01);
327
328   if(!_config->FindB("Volatile::HideMainwindow", false))
329      skipTaskbar(true);
330   else
331      skipTaskbar(false);
332}
333
334RGInstallProgress::~RGInstallProgress()
335{
336   delete _ss;
337}
338
339bool GeometryParser::ParseSize(char **size)
340{
341   char *buf = *size;
342   char *p = buf;
343   while (*p >= '0' && *p <= '9')
344      p++;
345   if (*p != 'x')
346      return false;
347   *p++ = 0;
348   _width = atoi(buf);
349   buf = p;
350   while (*p >= '0' && *p <= '9')
351      p++;
352   if (*p != '+' && *p != '-' && *p != 0)
353      return false;
354   char tmp = *p;
355   *p = 0;
356   _height = atoi(buf);
357   *p = tmp;
358   *size = p;
359   return true;
360}
361
362bool GeometryParser::ParsePosition(char **pos)
363{
364   char *buf = *pos;
365   char *p = buf + 1;
366   if (*p < '0' || *p > '9')
367      return false;
368   while (*p >= '0' && *p <= '9')
369      p++;
370   if (*p != '+' && *p != '-')
371      return false;
372   char tmp = *p;
373   *p = 0;
374   _xpos = atoi(buf);
375   *p = tmp;
376   buf = p++;
377   if (*p < '0' || *p > '9')
378      return false;
379   while (*p >= '0' && *p <= '9')
380      p++;
381   if (*p != 0)
382      return false;
383   _ypos = atoi(buf);
384   *pos = p;
385   return true;
386}
387
388bool GeometryParser::Parse(string Geo)
389{
390   if (Geo.empty() == true)
391      return false;
392
393   char *buf = strdup(Geo.c_str());
394   char *p = buf;
395   bool ret = false;
396   if (*p == '+' || *p == '-') {
397      ret = ParsePosition(&p);
398   } else {
399      if (*p == '=')
400         p++;
401      ret = ParseSize(&p);
402      if (ret == true && (*p == '+' || *p == '-'))
403         ret = ParsePosition(&p);
404   }
405   free(buf);
406
407   if (ret == false) {
408      _width = -1;
409      _height = -1;
410      _xpos = -1;
411      _ypos = -1;
412   }
413
414   return ret;
415}
416
417// vim:ts=3:sw=3:et
Note: See TracBrowser for help on using the repository browser.