14
14
#include < LibCore/File.h>
15
15
#include < LibDesktop/Launcher.h>
16
16
#include < LibGUI/Application.h>
17
+ #include < LibGUI/BoxLayout.h>
17
18
#include < LibGUI/Breadcrumbbar.h>
18
19
#include < LibGUI/Clipboard.h>
19
20
#include < LibGUI/FileIconProvider.h>
20
21
#include < LibGUI/Icon.h>
22
+ #include < LibGUI/Label.h>
21
23
#include < LibGUI/Menu.h>
22
24
#include < LibGUI/Menubar.h>
23
25
#include < LibGUI/MessageBox.h>
27
29
#include < unistd.h>
28
30
29
31
static const char * APP_NAME = " Space Analyzer" ;
32
+ static constexpr size_t FILES_ENCOUNTERED_UPDATE_STEP_SIZE = 25 ;
30
33
31
34
struct TreeNode : public SpaceAnalyzer ::TreeMapNode {
32
35
TreeNode (String name)
@@ -123,6 +126,38 @@ static long long int update_totals(TreeNode& node)
123
126
return result;
124
127
}
125
128
129
+ static NonnullRefPtr<GUI::Window> create_progress_window ()
130
+ {
131
+ auto window = GUI::Window::construct ();
132
+
133
+ window->set_title (APP_NAME);
134
+ window->set_resizable (false );
135
+ window->set_closeable (false );
136
+ window->resize (240 , 50 );
137
+ window->center_on_screen ();
138
+
139
+ auto & main_widget = window->set_main_widget <GUI::Widget>();
140
+ main_widget.set_fill_with_background_color (true );
141
+ main_widget.set_layout <GUI::VerticalBoxLayout>();
142
+
143
+ auto & label = main_widget.add <GUI::Label>(" Analyzing storage space..." );
144
+ label.set_fixed_height (22 );
145
+
146
+ auto & progresslabel = main_widget.add <GUI::Label>();
147
+ progresslabel.set_name (" progresslabel" );
148
+ progresslabel.set_fixed_height (22 );
149
+
150
+ return window;
151
+ }
152
+
153
+ static void update_progress_label (GUI::Label& progresslabel, size_t files_encountered_count)
154
+ {
155
+ auto text = String::formatted (" {} files..." , files_encountered_count);
156
+ progresslabel.set_text (text);
157
+
158
+ Core::EventLoop::current ().pump (Core::EventLoop::WaitMode::PollForEvents);
159
+ }
160
+
126
161
struct QueueEntry {
127
162
QueueEntry (String path, TreeNode* node)
128
163
: path(move(path))
@@ -131,12 +166,13 @@ struct QueueEntry {
131
166
TreeNode* node { nullptr };
132
167
};
133
168
134
- static void populate_filesize_tree (TreeNode& root, Vector<MountInfo>& mounts, HashMap<int , int >& error_accumulator)
169
+ static void populate_filesize_tree (TreeNode& root, Vector<MountInfo>& mounts, HashMap<int , int >& error_accumulator, GUI::Label& progresslabel )
135
170
{
136
171
VERIFY (!root.m_name .ends_with (" /" ));
137
172
138
173
Queue<QueueEntry> queue;
139
174
queue.enqueue (QueueEntry (root.m_name , &root));
175
+ size_t files_encountered_count = 0 ;
140
176
141
177
StringBuilder builder = StringBuilder ();
142
178
builder.append (root.m_name );
@@ -167,6 +203,10 @@ static void populate_filesize_tree(TreeNode& root, Vector<MountInfo>& mounts, Ha
167
203
queue_entry.node ->m_children ->append (TreeNode (dir_iterator.next_path ()));
168
204
}
169
205
for (auto & child : *queue_entry.node ->m_children ) {
206
+ files_encountered_count += 1 ;
207
+ if (!(files_encountered_count % FILES_ENCOUNTERED_UPDATE_STEP_SIZE))
208
+ update_progress_label (progresslabel, files_encountered_count);
209
+
170
210
String& name = child.m_name ;
171
211
int name_len = name.length ();
172
212
builder.append (name);
@@ -192,13 +232,22 @@ static void populate_filesize_tree(TreeNode& root, Vector<MountInfo>& mounts, Ha
192
232
193
233
static void analyze (RefPtr<Tree> tree, SpaceAnalyzer::TreeMapWidget& treemapwidget, GUI::Statusbar& statusbar)
194
234
{
235
+ statusbar.set_text (" " );
236
+ auto progress_window = create_progress_window ();
237
+ progress_window->show ();
238
+
239
+ auto & progresslabel = *progress_window->main_widget ()->find_descendant_of_type_named <GUI::Label>(" progresslabel" );
240
+ update_progress_label (progresslabel, 0 );
241
+
195
242
// Build an in-memory tree mirroring the filesystem and for each node
196
243
// calculate the sum of the file size for all its descendants.
197
244
TreeNode* root = &tree->m_root ;
198
245
Vector<MountInfo> mounts;
199
246
fill_mounts (mounts);
200
247
HashMap<int , int > error_accumulator;
201
- populate_filesize_tree (*root, mounts, error_accumulator);
248
+ populate_filesize_tree (*root, mounts, error_accumulator, progresslabel);
249
+
250
+ progress_window->close ();
202
251
203
252
// Display an error summary in the statusbar.
204
253
if (!error_accumulator.is_empty ()) {
0 commit comments