diff options
author | Daniel Burrows <Daniel Burrows Daniel_Burrows@alumni.brown.edu> | 2010-05-25 09:15:56 -0700 |
---|---|---|
committer | Daniel Burrows <Daniel Burrows Daniel_Burrows@alumni.brown.edu> | 2010-05-25 09:15:56 -0700 |
commit | d0a3123239ea004964d3882148a87ca2a6c7db92 (patch) | |
tree | a65efca2c2cc5232792ba7de437fdaecaaf4180e /src | |
parent | f7cfe9bb0487ad521dc40656ae3dd7f94fb29ec3 (diff) | |
download | aptitude-d0a3123239ea004964d3882148a87ca2a6c7db92.tar.gz |
Add a private version of OpTextProgress.
This gives us the freedom to modify its behavior. For instance, this first
cut eliminates the annoying clutter in aptitude's output by deleting the
progress indicator when it's finished, instead of leaving it up. When output
is not a tty (e.g., it's a pipe or a file), the old behavior should be
followed (progress lines are written one after another).
Diffstat (limited to 'src')
-rw-r--r-- | src/generic/apt/Makefile.am | 4 | ||||
-rw-r--r-- | src/generic/apt/SConscript | 2 | ||||
-rw-r--r-- | src/generic/apt/text_progress.cc | 170 | ||||
-rw-r--r-- | src/generic/apt/text_progress.h | 49 |
4 files changed, 224 insertions, 1 deletions
diff --git a/src/generic/apt/Makefile.am b/src/generic/apt/Makefile.am index 0c9329ca..8874390b 100644 --- a/src/generic/apt/Makefile.am +++ b/src/generic/apt/Makefile.am @@ -71,7 +71,9 @@ libgeneric_apt_a_SOURCES = \ tags.cc \ tags.h \ tasks.cc \ - tasks.h + tasks.h \ + text_progress.cc \ + text_progress.h pkg_hier_dump_SOURCES = pkg_hier_dump.cc pkg_hier_dump_LDADD = $(top_builddir)/src/generic/util/libgeneric-util.a libgeneric-apt.a diff --git a/src/generic/apt/SConscript b/src/generic/apt/SConscript index 4c7f5cea..e2323125 100644 --- a/src/generic/apt/SConscript +++ b/src/generic/apt/SConscript @@ -60,6 +60,8 @@ toplevel_srcs = map(File, [ 'tags.h', 'tasks.cc', 'tasks.h', + 'text_progress.cc', + 'text_progress.h', ]) sub_srcs = SConscript(dirs = [ diff --git a/src/generic/apt/text_progress.cc b/src/generic/apt/text_progress.cc new file mode 100644 index 00000000..f32b8fb2 --- /dev/null +++ b/src/generic/apt/text_progress.cc @@ -0,0 +1,170 @@ +/** \file text_progress.cc */ + + +// Copyright (C) 2010 Daniel Burrows +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +#include "text_progress.h" + +#include "apt.h" +#include "config_signal.h" + +#include <aptitude.h> + + +#include <apt-pkg/error.h> + +#include <boost/format.hpp> +#include <boost/make_shared.hpp> + +#include <cwidget/generic/util/transcode.h> + +#include <iostream> + +namespace cw = cwidget; + +using boost::format; +using boost::make_shared; +using boost::shared_ptr; +using cw::util::transcode; + +namespace aptitude +{ + namespace apt + { + namespace + { + class text_progress : public OpProgress + { + // If true, this code will assume it has a TTY as its output + // and use terminal-based trickery. + bool use_tty_decorations; + + // The length of the last line we displayed. + std::size_t last_line_len; + + // The last operation we were displaying; used to output an + // indicator when the operation finishes. + std::string last_op; + + /** \brief Clear the currently displayed progress indicator. */ + void Clear(); + + /** \brief Display the given line without a newline and remember its length + * so it can be cleared with Clear(). + */ + void Display(const std::string &line); + + public: + text_progress(bool _use_tty_decorations) + : use_tty_decorations(_use_tty_decorations), + last_line_len(0) + { + } + + void Done(); + void Update(); + }; + + void text_progress::Clear() + { + std::cout << '\r'; + for(std::size_t i = 0; i < last_line_len; ++i) + std::cout << ' '; + std::cout << '\r' << std::flush; + + last_line_len = 0; + } + + void text_progress::Display(const std::string &line) + { + std::cout << line << std::flush; + + std::wstring line_w = transcode(line); + last_line_len = wcslen(line_w.c_str()); + } + + void text_progress::Done() + { + // If we displayed a progress indicator, finish it off. + if(use_tty_decorations) + { + if(!last_op.empty()) + { + Clear(); + + if(_error->PendingError() == true) + { + std::cout << (format(_("%s... Error!")) % last_op) << std::endl; + last_line_len = 0; + } + } + } + else if(!last_op.empty()) + { + std::cout << std::endl; + last_op.clear(); + } + } + + void text_progress::Update() + { + if(CheckChange(0.7)) + { + if(!use_tty_decorations) + { + if(MajorChange) + { + if(!last_op.empty()) + std::cout << std::endl; + + std::cout << Op << "..."; + last_op = Op; + } + } + else + { + Clear(); + Display((format("%s... %d%%") % Op % Percent).str()); + last_op = Op; + } + } + } + } + + shared_ptr<OpProgress> + make_text_progress(bool require_tty_decorations) + { + bool hide_tty_decorations = false; + bool hidden = false; + + if(!isatty(1)) + hide_tty_decorations = true; + + if(aptcfg->FindI("Quiet", 0)) + hide_tty_decorations = true; + + if(require_tty_decorations && hide_tty_decorations) + hidden = true; + + if(hidden) + return make_shared<OpProgress>(); + else + return make_shared<text_progress>(!hide_tty_decorations); + } + } +} diff --git a/src/generic/apt/text_progress.h b/src/generic/apt/text_progress.h new file mode 100644 index 00000000..f0556d1f --- /dev/null +++ b/src/generic/apt/text_progress.h @@ -0,0 +1,49 @@ +/** \file text_progress.h */ // -*-c++-*- + + +// Copyright (C) 2010 Daniel Burrows +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +#ifndef APTITUDE_UTIL_TEXT_PROGRESS_H +#define APTITUDE_UTIL_TEXT_PROGRESS_H + +#include <apt-pkg/progress.h> + +#include <boost/shared_ptr.hpp> + +namespace aptitude +{ + namespace apt + { + /** \brief Create a customized text spinner that's similar to + * apt's spinner, but "cleans up" after itself if stdout appears + * to be a terminal. + * + * \note Reads the global apt configuration; settings there will + * override the creation parameters. + * + * \param require_tty_decorations If tty decorations can't be + * shown, don't show a progress + * spinner at all. Useful for + * ensuring that the progress + * display is self-disposing. + */ + boost::shared_ptr<OpProgress> make_text_progress(bool require_tty_decorations); + } +} + +#endif // APTITUDE_UTIL_TEXT_PROGRESS |