Code

This is the first c++ification commit from me. It handles sp-line, sp-polyline, sp...
[inkscape.git] / src / ui / dialog / memory.cpp
1 /** @file
2  * @brief Memory statistics dialog
3  */
4 /* Authors:
5  *   MenTaLguY <mental@rydia.net>
6  *
7  * Copyright (C) 2005 
8  *
9  * Released under GNU GPL.  Read the file 'COPYING' for more information.
10  */
12 #ifdef HAVE_CONFIG_H
13 # include <config.h>
14 #endif
16 #include <glibmm/i18n.h>
17 #include <gtkmm/liststore.h>
18 #include <gtkmm/treeview.h>
20 #include "gc-core.h"
21 #include "ui/dialog/memory.h"
22 #include "debug/heap.h"
23 #include "verbs.h"
25 namespace Inkscape {
26 namespace UI {
27 namespace Dialog {
29 namespace {
31 Glib::ustring format_size(std::size_t value) {
32     if (!value) {
33         return Glib::ustring("0");
34     }
36     typedef std::vector<char> Digits;
37     typedef std::vector<Digits *> Groups;
39     Groups groups;
41     Digits *digits;
43     while (value) {
44         unsigned places=3;
45         digits = new Digits();
46         digits->reserve(places);
48         while ( value && places ) {
49             digits->push_back('0' + (char)( value % 10 ));
50             value /= 10;
51             --places;
52         }
54         groups.push_back(digits);
55     }
57     Glib::ustring temp;
59     while (true) {
60         digits = groups.back();
61         while (!digits->empty()) {
62             temp.append(1, digits->back());
63             digits->pop_back();
64         }
65         delete digits;
67         groups.pop_back();
68         if (groups.empty()) {
69             break;
70         }
72         temp.append(",");
73     }
75     return temp;
76 }
78 }
80 struct Memory::Private {
81     class ModelColumns : public Gtk::TreeModel::ColumnRecord {
82     public:
83         Gtk::TreeModelColumn<Glib::ustring> name;
84         Gtk::TreeModelColumn<Glib::ustring> used;
85         Gtk::TreeModelColumn<Glib::ustring> slack;
86         Gtk::TreeModelColumn<Glib::ustring> total;
88         ModelColumns() { add(name); add(used); add(slack); add(total); }
89     };
91     Private() {
92         model = Gtk::ListStore::create(columns);
93         view.set_model(model);
94         view.append_column(_("Heap"), columns.name);
95         view.append_column(_("In Use"), columns.used);
96         // TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused.
97         //  More typical usage is to call this memory "free" rather than "slack".
98         view.append_column(_("Slack"), columns.slack);
99         view.append_column(_("Total"), columns.total);
100     }
102     void update();
104     void start_update_task();
105     void stop_update_task();
107     ModelColumns columns;
108     Glib::RefPtr<Gtk::ListStore> model;
109     Gtk::TreeView view;
111     sigc::connection update_task;
112 };
114 void Memory::Private::update() {
115     Debug::Heap::Stats total = { 0, 0 };
117     int aggregate_features = Debug::Heap::SIZE_AVAILABLE | Debug::Heap::USED_AVAILABLE;
118     Gtk::ListStore::iterator row;
120     row = model->children().begin();
122     for ( unsigned i = 0 ; i < Debug::heap_count() ; i++ ) {
123         Debug::Heap *heap=Debug::get_heap(i);
124         if (heap) {
125             Debug::Heap::Stats stats=heap->stats();
126             int features=heap->features();
128             aggregate_features &= features;
130             if ( row == model->children().end() ) {
131                 row = model->append();
132             }
134             row->set_value(columns.name, Glib::ustring(heap->name()));
135             if ( features & Debug::Heap::SIZE_AVAILABLE ) {
136                 row->set_value(columns.total, format_size(stats.size));
137                 total.size += stats.size;
138             } else {
139                 row->set_value(columns.total, Glib::ustring(_("Unknown")));
140             }
141             if ( features & Debug::Heap::USED_AVAILABLE ) {
142                 row->set_value(columns.used, format_size(stats.bytes_used));
143                 total.bytes_used += stats.bytes_used;
144             } else {
145                 row->set_value(columns.used, Glib::ustring(_("Unknown")));
146             }
147             if ( features & Debug::Heap::SIZE_AVAILABLE &&
148                  features & Debug::Heap::USED_AVAILABLE )
149             {
150                 row->set_value(columns.slack, format_size(stats.size - stats.bytes_used));
151             } else {
152                 row->set_value(columns.slack, Glib::ustring(_("Unknown")));
153             }
155             ++row;
156         }
157     }
159     if ( row == model->children().end() ) {
160         row = model->append();
161     }
163     Glib::ustring value;
165     row->set_value(columns.name, Glib::ustring(_("Combined")));
167     if ( aggregate_features & Debug::Heap::SIZE_AVAILABLE ) {
168         row->set_value(columns.total, format_size(total.size));
169     } else {
170         row->set_value(columns.total, Glib::ustring("> ") + format_size(total.size));
171     }
173     if ( aggregate_features & Debug::Heap::USED_AVAILABLE ) {
174         row->set_value(columns.used, format_size(total.bytes_used));
175     } else {
176         row->set_value(columns.used, Glib::ustring("> ") + format_size(total.bytes_used));
177     }
179     if ( aggregate_features & Debug::Heap::SIZE_AVAILABLE &&
180          aggregate_features & Debug::Heap::USED_AVAILABLE )
181     {
182         row->set_value(columns.slack, format_size(total.size - total.bytes_used));
183     } else {
184         row->set_value(columns.slack, Glib::ustring(_("Unknown")));
185     }
187     ++row;
189     while ( row != model->children().end() ) {
190         row = model->erase(row);
191     }
194 void Memory::Private::start_update_task() {
195     update_task.disconnect();
196     update_task = Glib::signal_timeout().connect(
197         sigc::bind_return(sigc::mem_fun(*this, &Private::update), true),
198         500
199     );
202 void Memory::Private::stop_update_task() {
203     update_task.disconnect();
206 Memory::Memory() 
207     : UI::Widget::Panel ("", "/dialogs/memory", SP_VERB_HELP_MEMORY, _("Recalculate")),
208       _private(*(new Memory::Private())) 
210     _getContents()->add(_private.view);
212     _private.update();
214     show_all_children();
216     signal_show().connect(sigc::mem_fun(_private, &Private::start_update_task));
217     signal_hide().connect(sigc::mem_fun(_private, &Private::stop_update_task));
219     _private.start_update_task();
222 Memory::~Memory() {
223     delete &_private;
226 void Memory::_apply() {
227     GC::Core::gcollect();
228     _private.update();
231 } // namespace Dialog
232 } // namespace UI
233 } // namespace Inkscape
235 /*
236   Local Variables:
237   mode:c++
238   c-file-style:"stroustrup"
239   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
240   indent-tabs-mode:nil
241   fill-column:99
242   End:
243 */
244 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :