summaryrefslogtreecommitdiffstats
path: root/krusader/Panel/krcalcspacedialog.cpp
blob: fc82574ea15db71210fa3ae4e9dcc903b6a36fe5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/***************************************************************************
                          krcalcspacedialog.cpp  -  description
                             -------------------
    begin                : Fri Jan 2 2004
    copyright            : (C) 2004 by Shie Erlich & Rafi Yanai
 e-mail               : krusader@users.sourceforge.net
 web site             : http://krusader.sourceforge.net
---------------------------------------------------------------------------
Description
***************************************************************************

A

  db   dD d8888b. db    db .d8888.  .d8b.  d8888b. d88888b d8888b.
  88 ,8P' 88  `8D 88    88 88'  YP d8' `8b 88  `8D 88'     88  `8D
  88,8P   88oobY' 88    88 `8bo.   88ooo88 88   88 88ooooo 88oobY'
  88`8b   88`8b   88    88   `Y8b. 88~~~88 88   88 88~~~~~ 88`8b
  88 `88. 88 `88. 88b  d88 db   8D 88   88 88  .8D 88.     88 `88.
  YP   YD 88   YD ~Y8888P' `8888Y' YP   YP Y8888D' Y88888P 88   YD

                                                  S o u r c e    F i l e

***************************************************************************
*                                                                         *
*   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.                                   *
*                                                                         *
***************************************************************************/

// TQt Includes
#include <tqtimer.h>
#include <tqlayout.h>
#include <tqlabel.h>
// KDE Includes
#include <klocale.h>
#include <kcursor.h>
// Krusader Includes
#include "krcalcspacedialog.h"
#include "listpanel.h"
#include "panelfunc.h"
#include "../krusader.h"
#include "../VFS/krpermhandler.h"

/* --=={ Patch by Heiner <h.eichmann@gmx.de> }==-- */
KrCalcSpaceDialog::CalcThread::CalcThread(KrCalcSpaceDialog * tqparent, ListPanel * panel, const TQStringList & items)
	: m_totalSize(0), m_currentSize(0), m_totalFiles(0), m_totalDirs(0), m_items(items), m_files(panel->func->files()),
	  m_view(panel->view), m_parent(tqparent), m_threadInUse(true), m_stop(false) {}

void KrCalcSpaceDialog::CalcThread::cleanUp(){
	if (m_threadInUse || !finished())
		m_synchronizeUsageAccess.unlock();
	else{
		m_synchronizeUsageAccess.unlock(); // prevents a resource leak
		// otherwise: no one needs this instance any more: delete it
		delete this;
	}
}

void KrCalcSpaceDialog::CalcThread::deleteInstance(){
	// synchronize to avoid race condition.
	m_synchronizeUsageAccess.lock();
	m_threadInUse = false;
	cleanUp();
}

void KrCalcSpaceDialog::CalcThread::run(){
	if ( !m_items.isEmpty() ) // if something to do: do the calculation
	for ( TQStringList::ConstIterator it = m_items.begin(); it != m_items.end(); ++it )
        {
                m_currentSize = 0;
                m_files->vfs_calcSpace( *it, &m_currentSize, &m_totalFiles, &m_totalDirs , & m_stop);
                if (m_stop)
                    break;
                KrDetailedViewItem * viewItem = dynamic_cast<KrDetailedViewItem *>(m_view->findItemByName ( *it ) );
                if (viewItem){
                     KrCalcSpaceDialog::setDirSize(viewItem, m_currentSize);
                     //viewItem->tqrepaintItem(); // crash in KrDetailedViewItem::tqrepaintItem(): setPixmap(_view->column(KrDetailedView::Name),KrView::getIcon(_vf))
                }
                m_totalSize += m_currentSize;
                m_currentSize = 0;
        }
	// synchronize to avoid race condition.
	m_synchronizeUsageAccess.lock();
	cleanUp(); // this does not need the instance any more
}

void KrCalcSpaceDialog::CalcThread::stop(){
	// cancel was pressed
	m_stop = true;
}

KrCalcSpaceDialog::KrCalcSpaceDialog(TQWidget *tqparent, ListPanel * files, const TQStringList & items, bool autoclose) :
	KDialogBase(tqparent, "KrCalcSpaceDialog", true, i18n("Calculate Occupied Space"), Ok|Cancel),
	m_autoClose(autoclose), m_canceled(false), m_timerCounter(0){
	// the dialog: The Ok button is hidden until it is needed
	showButtonOK(false);
	m_thread = new CalcThread(this, files, items);
	m_pollTimer = new TQTimer(this);
	TQWidget * mainWidget = new TQWidget( this );
	setMainWidget(mainWidget);
	TQVBoxLayout *topLayout = new TQVBoxLayout( mainWidget, 0, spacingHint() );

	m_label = new TQLabel( "", mainWidget, "caption" );
	showResult(); // fill m_label with something usefull
	topLayout->addWidget( m_label );
	topLayout->addStretch(10);
}

void KrCalcSpaceDialog::calculationFinished(){
	// close dialog if auto close is true
	if (m_autoClose){
		done(0);
		return;
	}
	// otherwise hide cancel and show ok button
	showButtonCancel(false);
	showButtonOK(true);
	showResult(); // and show final result
}

/* This timer has two jobs: it polls the thread if it is finished. Polling is
  better here as it might finish while the dialog builds up. Secondly it refreshes
  the displayed result.
 */
void KrCalcSpaceDialog::timer(){
	// thread finished?
	if (m_thread->finished()){
		// close dialog or switch buttons
		calculationFinished();
		m_pollTimer->stop(); // stop the polling. No longer needed
		return;
	}

	// Every 10 pollings (1 second) refresh the displayed result
	if (++m_timerCounter > 10){
		m_timerCounter = 0;
		showResult();
	}
}

void KrCalcSpaceDialog::showResult(){
  if (!m_thread) return;
  TQString msg;
  TQString fileName = ( ( m_thread->getItems().count() == 1 ) ? ( i18n( "Name: " ) + m_thread->getItems().first() + "\n" ) : TQString( "" ) );
  msg = fileName + i18n( "Total occupied space: %1").tqarg( KIO::convertSize( m_thread->getTotalSize() ) );
  if (m_thread->getTotalSize() >= 1024)
     msg += " (" + KRpermHandler::parseSize( m_thread->getTotalSize() ) + "bytes)";
  msg += "\n";
  msg += i18n("in %n directory", "in %n directories", m_thread->getTotalDirs() );
  msg += " ";
  msg += i18n("and %n file", "and %n files", m_thread->getTotalFiles() );
  m_label->setText(msg);
}

void KrCalcSpaceDialog::slotCancel(){
	m_thread->stop(); // notify teh thread to stop
	m_canceled = true; // set the cancel flag
	KDialogBase::slotCancel(); // close the dialog
}

KrCalcSpaceDialog::~KrCalcSpaceDialog(){
	CalcThread * tmp = m_thread;
	m_thread = 0; // do not access the thread anymore or core dump if smoe piece of code wrongly does
	tmp->deleteInstance(); // Notify the thread, that the dialog does not need anymore.
}

void KrCalcSpaceDialog::exec(){
	m_thread->start(); // start the thread
	if (m_autoClose){ // autoclose
		// set the cursor to busy mode and wait 3 seconds or until the thread finishes
		krApp->setCursor( KCursor::waitCursor() );
		bool result = m_thread->wait(3000);
		krApp->setCursor( KCursor::arrowCursor() );  // return the cursor to normal mode
		if (result) return;// thread finished: do not show the dialog
		showResult(); // fill the invisible dialog with usefull data
	}
	// prepare and start the poll timer
	connect(m_pollTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(timer()));
	m_pollTimer->start(100);
	KDialogBase::exec(); // show the dialog
}
/* --=={ End of patch by Heiner <h.eichmann@gmx.de> }==-- */


#include "krcalcspacedialog.moc"