1 /*
2 * File name: k4dirstat.cpp
3 * Summary: The K4DirStat Application
4 * License: GPL - See file COPYING for details.
5 *
6 * Author: Stefan Hundhammer <kdirstat@gmx.de>
7 * Joshua Hodosh <kdirstat@grumpypenguin.org>
8 * Parts auto-generated by KDevelop
9 *
10 * Updated: 2010-03-01
11 */
12
13 #include "k4dirstat.h"
14 #include "settings.h"
15
16 #include <unistd.h>
17 #include <QtGui/QDropEvent>
18 #include <QtGui/QPainter>
19
20 #include <QStatusBar>
21 #include <kconfigdialog.h>
22
23 #include <kactioncollection.h>
24 #include <krecentfilesaction.h>
25 #include <kstandardaction.h>
26
27 #include <KLocalizedString>
28 #include <QFileDialog>
29 #include <QGuiApplication>
30 #include <kmessagebox.h>
31 #include <ktoggleaction.h>
32 #include <ktoolbar.h>
33 #include <ktoolinvocation.h>
34 #include <kurlrequesterdialog.h>
35 #include <kxmlguifactory.h>
36
37 #include "kactivitytracker.h"
38 #include "kcleanupcollection.h"
39 #include "kdirstatsettings.h"
40 #include "kdirtree.h"
41 #include "kdirtreecache.h"
42 #include "kdirtreeview.h"
43 #include "kexcluderules.h"
44 #include "ktreemaptile.h"
45 #include "ktreemapview.h"
46 #include <KIO/ApplicationLauncherJob>
47 #include <KIO/JobUiDelegate>
48 #include <KHelpClient>
49 #include <KIconEngine>
50 #include <KIconLoader>
51 #include <QClipboard>
52 #include <QIcon>
53 #include <QList>
54 #include <QMenu>
55 #include <QSplitter>
56 #include <QStorageInfo>
57 #include <QLabel>
58
59 #include "settings.h"
60
61 #define USER_CLEANUPS 10 // Number of user cleanup actions
62
63 #define ID_STATUS_MSG 1
64 #define ID_PACMAN 42
65 #define PACMAN_WIDTH 350
66 #define PACMAN_INTERVAL 75 // millisec
67
68 using namespace KDirStat;
69
icon(const QString & iconName)70 static QIcon icon(const QString &iconName) {
71 return QIcon(new KIconEngine(iconName, KIconLoader::global()));
72 }
73
74 k4dirstat *k4dirstat::instance_ = NULL;
75
k4dirstat()76 k4dirstat::k4dirstat()
77 : KXmlGuiWindow(),
78 // m_view(new k4dirstatView(this)),
79 m_printer(0) {
80 Q_ASSERT(instance_ == NULL);
81 instance_ = this;
82 // accept dnd
83 setAcceptDrops(true);
84
85 // Simple inits
86
87 _activityTracker = 0; // Might or might not be needed
88
89 // Those will be created delayed, only when needed
90
91 _settingsDialog = 0;
92 _feedbackDialog = 0;
93 _treemapView = 0;
94 _pacMan = 0;
95 _pacManDelimiter = 0;
96 _treemapViewHeight = 0;
97
98 connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this,
99 SLOT(triggerSaveConfig()));
100
101 // Set up internal (mainWin -> mainWin) connections
102
103 connect(this, SIGNAL(readConfig(void)), this, SLOT(readMainWinConfig(void)));
104
105 connect(this, SIGNAL(saveConfig(void)), this, SLOT(saveMainWinConfig(void)));
106
107 // Create main window
108
109 _splitter = new QSplitter(Qt::Vertical, this);
110 setCentralWidget(_splitter);
111
112 _treeView = new KDirTreeView(_splitter);
113
114 connect(_treeView, SIGNAL(progressInfo(const QString &)), this,
115 SLOT(statusMsg(const QString &)));
116
117 connect(_treeView->tree(), SIGNAL(selectionChanged(KDirTree*)), this,
118 SLOT(selectionChanged(KDirTree*)));
119
120 connect(_treeView, SIGNAL(contextMenu(const QPoint &)),
121 this, SLOT(contextMenu(const QPoint &)));
122
123 connect(this, SIGNAL(readConfig()), _treeView, SLOT(readConfig()));
124 connect(this, SIGNAL(saveConfig()), _treeView, SLOT(saveConfig()));
125
126 connect(_treeView, SIGNAL(finished()), this,
127 SLOT(createTreemapViewDelayed()));
128 connect(_treeView, SIGNAL(aborted()), this, SLOT(createTreemapViewDelayed()));
129 connect(_treeView, SIGNAL(startingReading()), this,
130 SLOT(deleteTreemapView()));
131
132 connect(_treeView, SIGNAL(startingReading()), this, SLOT(updateActions()));
133 connect(_treeView, SIGNAL(finished()), this, SLOT(updateActions()));
134 connect(_treeView, SIGNAL(aborted()), this, SLOT(updateActions()));
135
136 // tell the KXmlGuiWindow that this is indeed the main widget
137 // setCentralWidget(m_view);
138
139 // set up the elements of the status bar
140 initStatusBar();
141
142 // then, setup our actions
143 setupActions();
144
145 // setup the cleanup actions
146 initCleanups();
147
148 _freeSpaceLabel = new QLabel();
149 statusBar()->addPermanentWidget(_freeSpaceLabel);
150 // add a status bar
151 statusBar()->show();
152
153 // a call to KXmlGuiWindow::setupGUI() populates the GUI
154 // with actions, using KXMLGUI.
155 // It also applies the saved mainwindow settings, if any, and ask the
156 // mainwindow to automatically save settings if changed: window size,
157 // toolbar position, icon size, etc.
158 setupGUI();
159
160 _treeViewContextMenu =
161 static_cast<QMenu *>(factory()->container("treeViewContextMenu", this));
162 _treemapContextMenu =
163 static_cast<QMenu *>(factory()->container("treemapContextMenu", this));
164
165 readMainWinConfig();
166
167 // Disable certain actions at startup
168
169 _editCopy->setEnabled(false);
170 _reportMailToOwner->setEnabled(false);
171 _fileRefreshAll->setEnabled(false);
172 _fileRefreshSelected->setEnabled(false);
173 updateActions();
174 }
175
~k4dirstat()176 k4dirstat::~k4dirstat() {}
177
setupActions()178 void k4dirstat::setupActions() {
179
180 _fileAskOpenDir =
181 KStandardAction::open(this, SLOT(fileAskOpenDir()), actionCollection());
182
183 _fileAskOpenUrl = actionCollection()->addAction("file_open_url", this,
184 SLOT(fileAskOpenUrl()));
185 _fileAskOpenUrl->setText(i18n("Open &URL..."));
186 _fileAskOpenUrl->setIcon(icon("konqueror"));
187
188 _fileOpenRecent = KStandardAction::openRecent(
189 this, SLOT(fileOpenRecent(const QUrl &)), actionCollection());
190 _fileCloseDir =
191 KStandardAction::close(this, SLOT(fileCloseDir()), actionCollection());
192
193 _fileRefreshAll = actionCollection()->addAction("file_refresh_all", this,
194 SLOT(refreshAll()));
195 _fileRefreshAll->setText(i18n("Refresh &All"));
196 _fileRefreshAll->setIcon(icon("document-revert"));
197
198 _fileRefreshSelected = actionCollection()->addAction(
199 "file_refresh_selected", this, SLOT(refreshSelected()));
200 _fileRefreshSelected->setText(i18n("Refresh &Selected"));
201
202 _fileReadExcludedDir = actionCollection()->addAction(
203 "file_read_excluded_dir", this, SLOT(refreshSelected()));
204 _fileReadExcludedDir->setText(i18n("Read &Excluded Directory"));
205
206 _fileContinueReadingAtMountPoint = actionCollection()->addAction(
207 "file_continue_reading_at_mount_point", this, SLOT(refreshSelected()));
208 _fileContinueReadingAtMountPoint->setText(
209 i18n("Continue Reading at &Mount Point"));
210 _fileContinueReadingAtMountPoint->setIcon(icon("drive-harddisk"));
211
212 _fileStopReading = actionCollection()->addAction("file_stop_reading", this,
213 SLOT(stopReading()));
214 _fileStopReading->setText(i18n("Stop Rea&ding"));
215 _fileStopReading->setIcon(icon("process-stop"));
216
217 _fileAskWriteCache = actionCollection()->addAction(
218 "file_ask_write_cache", this, SLOT(askWriteCache()));
219 _fileAskWriteCache->setText(i18n("&Write to Cache File..."));
220 _fileAskWriteCache->setIcon(icon("document-export"));
221
222 _fileAskReadCache = actionCollection()->addAction("file_ask_read_cache", this,
223 SLOT(askReadCache()));
224 _fileAskReadCache->setText(i18n("&Read Cache File..."));
225 _fileAskReadCache->setIcon(icon("document-import"));
226
227 _fileQuit = KStandardAction::quit(QCoreApplication::instance(), SLOT(quit()),
228 actionCollection());
229 _editCopy = KStandardAction::copy(this, SLOT(editCopy()), actionCollection());
230
231 _cleanupOpenWith = actionCollection()->addAction("cleanup_open_with", this,
232 SLOT(cleanupOpenWith()));
233 _cleanupOpenWith->setText(i18n("Open With"));
234
235 _treemapZoomIn = actionCollection()->addAction("treemap_zoom_in", this,
236 SLOT(treemapZoomIn()));
237 _treemapZoomIn->setText(i18n("Zoom in"));
238 _treemapZoomIn->setIcon(icon("zoom-in"));
239 actionCollection()->setDefaultShortcut(_treemapZoomIn, Qt::Key_Plus);
240
241 _treemapZoomOut = actionCollection()->addAction("treemap_zoom_out", this,
242 SLOT(treemapZoomOut()));
243 _treemapZoomOut->setText(i18n("Zoom out"));
244 _treemapZoomOut->setIcon(icon("zoom-out"));
245 actionCollection()->setDefaultShortcut(_treemapZoomOut, Qt::Key_Minus);
246
247 _treemapSelectParent = actionCollection()->addAction(
248 "treemap_select_parent", this, SLOT(treemapSelectParent()));
249 _treemapSelectParent->setText(i18n("Select Parent"));
250 _treemapSelectParent->setIcon(icon("go-up"));
251 actionCollection()->setDefaultShortcut(_treemapSelectParent,
252 Qt::Key_Asterisk);
253
254 _treemapRebuild = actionCollection()->addAction("treemap_rebuild", this,
255 SLOT(treemapRebuild()));
256 _treemapRebuild->setText(i18n("Rebuild Treemap"));
257
258 _showTreemapView =
259 new KToggleAction(i18n("Show Treemap"), actionCollection());
260 actionCollection()->addAction("options_show_treemap", _showTreemapView);
261 //_showTreemapView->set
262 connect(_showTreemapView, SIGNAL(triggered()), this,
263 SLOT(toggleTreemapView()));
264 actionCollection()->setDefaultShortcut(_showTreemapView, Qt::Key_F9);
265
266 QAction *newAct =
267 actionCollection()->addAction("treemap_help", this, SLOT(treemapHelp()));
268 newAct->setText(i18n("Help about Treemaps"));
269 newAct->setIcon(icon("help-contents"));
270
271 QAction *pref = KStandardAction::preferences(this, SLOT(preferences()),
272 actionCollection());
273
274 _reportMailToOwner = actionCollection()->addAction(
275 "report_mail_to_owner", _treeView, SLOT(sendMailToOwner()));
276 _reportMailToOwner->setText(i18n("Send &Mail to Owner"));
277 _reportMailToOwner->setIcon(icon("mail-message-new"));
278
279 // _helpSendFeedbackMail =
280 // actionCollection()->addAction("help_send_feedback_mail",this,
281 // SLOT(sendFeedbackMail())); _helpSendFeedbackMail->setText(i18n("Send
282 // &Feedback Mail"));
283
284 _fileAskOpenDir->setStatusTip(i18n("Opens a directory"));
285 _fileAskOpenUrl->setStatusTip(i18n("Opens a (possibly remote) directory"));
286 _fileOpenRecent->setStatusTip(i18n("Opens a recently used directory"));
287 _fileCloseDir->setStatusTip(i18n("Closes the current directory"));
288 _fileRefreshAll->setStatusTip(i18n("Re-reads the entire directory tree"));
289 _fileRefreshSelected->setStatusTip(i18n("Re-reads the selected subtree"));
290 _fileReadExcludedDir->setStatusTip(
291 i18n("Scan directory tree that was previously excluded"));
292 _fileContinueReadingAtMountPoint->setStatusTip(
293 i18n("Scan mounted file systems"));
294 _fileStopReading->setStatusTip(i18n("Stops directory reading"));
295 _fileAskWriteCache->setStatusTip(
296 i18n("Writes the current directory tree to a cache file that can be "
297 "loaded much faster"));
298 _fileAskReadCache->setStatusTip(
299 i18n("Reads a directory tree from a cache file"));
300 _fileQuit->setStatusTip(i18n("Quits the application"));
301 _editCopy->setStatusTip(
302 i18n("Copies the URL of the selected item to the clipboard"));
303 _cleanupOpenWith->setStatusTip(
304 i18n("Open file or directory with arbitrary application"));
305 _showTreemapView->setStatusTip(i18n("Enables/disables the treemap view"));
306 _treemapZoomIn->setStatusTip(i18n("Zoom treemap in"));
307 _treemapZoomOut->setStatusTip(i18n("Zoom treemap out"));
308 _treemapSelectParent->setStatusTip(i18n("Select parent"));
309 _treemapRebuild->setStatusTip(
310 i18n("Rebuild treemap to fit into available space"));
311 pref->setStatusTip(i18n("Opens the preferences dialog"));
312 _reportMailToOwner->setStatusTip(
313 i18n("Sends a mail to the owner of the selected subtree"));
314
315 // custom menu and menu item - the slot is in the class k4dirstatView
316 // KAction *custom = new KAction(KIcon("colorize"), i18n("Swi&tch Colors"),
317 // this); actionCollection()->addAction( QLatin1String("switch_action"), custom
318 // ); connect(custom, SIGNAL(triggered(bool)), m_view, SLOT(switchColors()));
319 }
320
initCleanups()321 void k4dirstat::initCleanups() {
322 _cleanupCollection = new KCleanupCollection(*actionCollection());
323 _cleanupCollection->setParent(this);
324 Q_CHECK_PTR(_cleanupCollection);
325 _cleanupCollection->addStdCleanups();
326 _cleanupCollection->addUserCleanups(USER_CLEANUPS);
327 _cleanupCollection->readConfig();
328
329 connect(_treeView->tree(), SIGNAL(selectionChanged(KDirTree*)),
330 _cleanupCollection, SIGNAL(selectionChanged(KDirTree*)));
331
332 connect(this, SIGNAL(readConfig(void)), _cleanupCollection,
333 SLOT(readConfig(void)));
334
335 connect(this, SIGNAL(saveConfig(void)), _cleanupCollection,
336 SLOT(saveConfig(void)));
337 }
338
revertCleanupsToDefaults()339 void k4dirstat::revertCleanupsToDefaults() {
340 _cleanupCollection->revertToDefault(USER_CLEANUPS);
341 }
342
initStatusBar()343 void k4dirstat::initStatusBar() { statusBar()->showMessage(i18n("Ready.")); }
344
openURL(const QUrl & url)345 void k4dirstat::openURL(const QUrl &url) {
346 statusMsg(i18n("Opening directory..."));
347
348 _treeView->openURL(url);
349 _fileOpenRecent->addUrl(url);
350 _fileRefreshAll->setEnabled(true);
351 setCaption(url.fileName(), false);
352
353 statusMsg(i18n("Ready."));
354 }
355
readMainWinConfig()356 void k4dirstat::readMainWinConfig() {
357 KConfigGroup config = KSharedConfig::openConfig()->group("General Options");
358
359 // Status settings of the various bars and views
360
361 _showTreemapView->setChecked(config.readEntry("Show Treemap", true));
362 toggleTreemapView();
363
364 // Position settings of the various bars
365
366 // KToolBar::BarPosition toolBarPos;
367 // toolBarPos = ( KToolBar::BarPosition ) config->readEntry( "ToolBarPos",
368 // KToolBar::Top ); toolBar( "mainToolBar" )->setBarPos( toolBarPos );
369
370 _treemapViewHeight = config.readEntry("TreemapViewHeight", 250);
371
372 // initialize the recent file list
373 _fileOpenRecent->loadEntries(config);
374
375 QSize size = config.readEntry("Geometry", QSize());
376
377 if (!size.isEmpty())
378 resize(size);
379
380 config = KSharedConfig::openConfig()->group("Animation");
381 _treeView->enablePacManAnimation(config.readEntry("DirTreePacMan", false));
382
383 config = KSharedConfig::openConfig()->group("Exclude");
384 QStringList excludeRules = config.readEntry("ExcludeRules", QStringList());
385 KExcludeRules::excludeRules()->clear();
386
387 for (QStringList::Iterator it = excludeRules.begin();
388 it != excludeRules.end(); ++it) {
389 QString ruleText = *it;
390 KExcludeRules::excludeRules()->add(new KExcludeRule(QRegExp(ruleText)));
391 qDebug() << "Adding exclude rule: " << ruleText << Qt::endl;
392 }
393
394 if (excludeRules.size() == 0)
395 qDebug() << "No exclude rules defined" << Qt::endl;
396 }
397
saveMainWinConfig()398 void k4dirstat::saveMainWinConfig() {
399 KConfigGroup config = KSharedConfig::openConfig()->group("General Options");
400 _fileOpenRecent->saveEntries(config);
401 config.writeEntry("Show Treemap", _showTreemapView->isChecked());
402 if (_treemapView)
403 config.writeEntry("TreemapViewHeight", _treemapView->height());
404 }
405
406 //============================================================================
407 // Slots
408 //============================================================================
409
fileAskOpenDir()410 void k4dirstat::fileAskOpenDir() {
411 statusMsg(i18n("Opening directory..."));
412 QUrl url =
413 QFileDialog::getExistingDirectoryUrl(this, i18n("Open Directory..."));
414
415 if (!url.isEmpty())
416 openURL(url);
417
418 statusMsg(i18n("Ready."));
419 }
420
fileAskOpenUrl()421 void k4dirstat::fileAskOpenUrl() {
422 statusMsg(i18n("Opening URL..."));
423
424 QUrl url = KUrlRequesterDialog::getUrl(QUrl(), // startDir
425 this, i18n("Open URL..."));
426
427 if (!url.isEmpty())
428 openURL(fixedUrl(url.url()));
429
430 statusMsg(i18n("Ready."));
431 }
432
fileOpenRecent(const QUrl & url)433 void k4dirstat::fileOpenRecent(const QUrl &url) {
434 statusMsg(i18n("Opening directory..."));
435
436 if (!url.isEmpty())
437 openURL(fixedUrl(url.url()));
438
439 statusMsg(i18n("Ready."));
440 }
441
fileCloseDir()442 void k4dirstat::fileCloseDir() {
443 statusMsg(i18n("Closing directory..."));
444
445 _treeView->clear();
446 _fileRefreshAll->setEnabled(false);
447 close();
448
449 statusMsg(i18n("Ready."));
450 }
451
refreshAll()452 void k4dirstat::refreshAll() {
453 statusMsg(i18n("Refreshing directory tree..."));
454 _treeView->refreshAll();
455 statusMsg(i18n("Ready."));
456 }
457
refreshSelected()458 void k4dirstat::refreshSelected() {
459 statusMsg(i18n("Refreshing selected subtree..."));
460 auto sel = _treeView->tree()->selection();
461 for(auto it = sel.begin(); it != sel.end(); ++it)
462 if(!(*it)->isDotEntry())
463 _treeView->tree()->refresh(*it);
464 statusMsg(i18n("Ready."));
465 }
466
stopReading()467 void k4dirstat::stopReading() { _treeView->abortReading(); }
468
askWriteCache()469 void k4dirstat::askWriteCache() {
470 QString file_name;
471
472 do {
473 file_name = QFileDialog::getSaveFileName(this, i18n("Write to Cache File"),
474 DEFAULT_CACHE_NAME);
475
476 if (file_name.isEmpty()) // user hit "cancel"
477 return;
478
479 if (access(file_name.toLatin1(), F_OK) == 0) // file exists
480 {
481 int button = KMessageBox::questionYesNoCancel(
482 this, i18n("File %1 exists. Overwrite?", file_name),
483 i18n("Overwrite?")); // caption
484
485 if (button == KMessageBox::Cancel)
486 return;
487 if (button == KMessageBox::No)
488 file_name = "";
489 }
490 } while (file_name.isEmpty());
491
492 statusMsg(i18n("Writing cache file..."));
493
494 if (!_treeView || !_treeView->writeCache(file_name)) {
495 QString errMsg = i18n("Error writing cache file %1", file_name);
496 statusMsg(errMsg);
497 KMessageBox::sorry(this, errMsg,
498 i18n("Write Error")); // caption
499 }
500
501 statusMsg(i18n("Wrote cache file %1", file_name));
502 }
503
askReadCache()504 void k4dirstat::askReadCache() {
505 QString file_name = QFileDialog::getOpenFileName(
506 this, i18n("Read Cache File"), DEFAULT_CACHE_NAME);
507
508 if (!file_name.isNull() && _treeView) {
509 statusMsg(i18n("Reading cache file..."));
510 _fileRefreshAll->setEnabled(true);
511 _treeView->readCache(file_name);
512 }
513 }
514
editCopy()515 void k4dirstat::editCopy() {
516 if (_treeView->selection()) {
517 QGuiApplication *app =
518 dynamic_cast<QGuiApplication *>(QCoreApplication::instance());
519 if (app)
520 app->clipboard()->setText(_treeView->selection()->url());
521 }
522
523 #if 0
524 #warning debug
525 if ( _activityTracker )
526 _activityTracker->trackActivity( 800 );
527 #endif
528 }
529
cleanupOpenWith()530 void k4dirstat::cleanupOpenWith() {
531 if (!_treeView->selection())
532 return;
533
534 KFileInfo *sel = _treeView->selection();
535
536 if (sel->isDotEntry())
537 return;
538
539 QList<QUrl> urlList;
540 urlList.append(QUrl::fromUserInput(sel->url(), QDir::currentPath(),
541 QUrl::AssumeLocalFile));
542 auto *job = new KIO::ApplicationLauncherJob();
543 job->setUrls(urlList);
544 job->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
545 job->start();
546 }
547
atLeastOneNotDotEntry(KDirTree * tree)548 bool atLeastOneNotDotEntry(KDirTree * tree) {
549 auto sel = tree->selection();
550 for(auto it = sel.begin(); it != sel.end(); ++it) {
551 if((*it)->isDotEntry())
552 return false;
553 }
554 return true;
555 }
556
selectionChanged(KDirTree * tree)557 void k4dirstat::selectionChanged(KDirTree* tree) {
558 _fileRefreshSelected->setEnabled(atLeastOneNotDotEntry(tree));
559 if (tree->selection().size() == 1) {
560 // TODO: Most action have been written for single selection. We keep
561 // that logic until all actions have been ported to multi-selection.
562 KFileInfo * selection = tree->selection()[0];
563 _editCopy->setEnabled(true);
564 _reportMailToOwner->setEnabled(true);
565 _cleanupOpenWith->setEnabled(!selection->isDotEntry());
566 _fileReadExcludedDir->setEnabled(selection->isExcluded());
567
568 if (selection->isMountPoint() &&
569 selection->readState() == KDirOnRequestOnly) {
570 _fileContinueReadingAtMountPoint->setEnabled(true);
571 } else
572 _fileContinueReadingAtMountPoint->setEnabled(false);
573
574 statusMsg(selection->url());
575 QStorageInfo i(selection->url());
576 if(i.isValid())
577 _freeSpaceLabel->setText(formatSize(i.bytesFree()) + " free");
578 } else {
579 _editCopy->setEnabled(false);
580 _reportMailToOwner->setEnabled(false);
581 _fileContinueReadingAtMountPoint->setEnabled(false);
582 _cleanupOpenWith->setEnabled(false);
583 statusMsg("");
584 }
585
586 updateActions();
587 }
588
updateActions()589 void k4dirstat::updateActions() {
590 _treemapZoomIn->setEnabled(_treemapView && _treemapView->canZoomIn());
591 _treemapZoomOut->setEnabled(_treemapView && _treemapView->canZoomOut());
592 _treemapRebuild->setEnabled(_treemapView && _treemapView->rootTile());
593 _treemapSelectParent->setEnabled(_treemapView &&
594 _treemapView->canSelectParent());
595
596 if (_treeView->tree() && _treeView->tree()->isBusy())
597 _fileStopReading->setEnabled(true);
598 else
599 _fileStopReading->setEnabled(false);
600 }
601
treemapZoomIn()602 void k4dirstat::treemapZoomIn() {
603 if (_treemapView) {
604 _treemapView->zoomIn();
605 updateActions();
606 }
607 }
608
treemapZoomOut()609 void k4dirstat::treemapZoomOut() {
610 if (_treemapView) {
611 _treemapView->zoomOut();
612 updateActions();
613 }
614 }
615
treemapSelectParent()616 void k4dirstat::treemapSelectParent() {
617 if (_treemapView) {
618 _treemapView->selectParent();
619 updateActions();
620 }
621 }
622
treemapRebuild()623 void k4dirstat::treemapRebuild() {
624 if (_treemapView) {
625 _treemapView->rebuildTreemap();
626 updateActions();
627 }
628 }
629
treemapHelp()630 void k4dirstat::treemapHelp() { KHelpClient::invokeHelp("treemap_intro"); }
631
toggleTreemapView()632 void k4dirstat::toggleTreemapView() {
633 if (_showTreemapView->isChecked()) {
634 if (!_treemapView)
635 createTreemapView();
636 } else {
637 if (_treemapView)
638 deleteTreemapView();
639 }
640 }
641
preferences()642 void k4dirstat::preferences() {
643 if (_settingsDialog && _settingsDialog->isVisible())
644 return;
645 // TODO no longer store the instance as it's always recreated.
646 // need to detect closing
647 _settingsDialog = new KDirStat::KSettingsDialog(this);
648 _settingsDialog->show();
649 }
650
statusMsg(const QString & text)651 void k4dirstat::statusMsg(const QString &text) {
652 // Change status message permanently
653 statusBar()->showMessage(text);
654 }
655
contextMenu(const QPoint & pos)656 void k4dirstat::contextMenu(const QPoint &pos) {
657 if (_treeViewContextMenu)
658 _treeViewContextMenu->popup(pos);
659 }
660
contextMenu(KTreemapTile * tile,const QPoint & pos)661 void k4dirstat::contextMenu(KTreemapTile *tile, const QPoint &pos) {
662 NOT_USED(tile);
663
664 if (_treemapContextMenu)
665 _treemapContextMenu->popup(pos);
666 }
667
createTreemapViewDelayed()668 void k4dirstat::createTreemapViewDelayed() {
669 QTimer::singleShot(0, this, SLOT(createTreemapView()));
670 }
671
createTreemapView()672 void k4dirstat::createTreemapView() {
673 if (!_showTreemapView->isChecked() || !_treeView->tree())
674 return;
675
676 if (_treemapView)
677 delete _treemapView;
678
679 // qDebug() << "Creating KTreemapView" << endl;
680 _treemapView =
681 new KTreemapView(_treeView->tree(), _splitter,
682 QSize(_splitter->width(), _treemapViewHeight));
683 Q_CHECK_PTR(_treemapView);
684
685 connect(_treemapView, SIGNAL(contextMenu(KTreemapTile *, const QPoint &)),
686 this, SLOT(contextMenu(KTreemapTile *, const QPoint &)));
687
688 connect(_treemapView, SIGNAL(treemapChanged()), this, SLOT(updateActions()));
689
690 if (_activityTracker) {
691 connect(_treemapView, SIGNAL(userActivity(int)), _activityTracker,
692 SLOT(trackActivity(int)));
693 }
694
695 _treemapView->show(); // QSplitter needs explicit show() for new children
696 updateActions();
697 }
698
deleteTreemapView()699 void k4dirstat::deleteTreemapView() {
700 if (_treemapView) {
701 // qDebug() << "Deleting KTreemapView" << endl;
702 _treemapViewHeight = _treemapView->height();
703
704 delete _treemapView;
705 _treemapView = 0;
706 }
707
708 updateActions();
709 }
710
triggerSaveConfig()711 void k4dirstat::triggerSaveConfig() { emit saveConfig(); }
712
713 /*void k4dirstat::fileNew()
714 {
715 // this slot is called whenever the File->New menu is selected,
716 // the New shortcut is pressed (usually CTRL+N) or the New toolbar
717 // button is clicked
718
719 // create a new window
720 (new k4dirstat)->show();
721 }
722
723 void k4dirstat::optionsPreferences()
724 {
725 // The preference dialog is derived from prefs_base.ui
726 //
727 // compare the names of the widgets in the .ui file
728 // to the names of the variables in the .kcfg file
729 //avoid to have 2 dialogs shown
730 if ( KConfigDialog::showDialog( "settings" ) ) {
731 return;
732 }
733 KConfigDialog *dialog = new KConfigDialog(this, "settings",
734 Settings::self()); QWidget *generalSettingsDlg = new QWidget;
735 ui_prefs_base.setupUi(generalSettingsDlg);
736 dialog->addPage(generalSettingsDlg, i18n("General"), "package_setting");
737 connect(dialog, SIGNAL(settingsChanged(QString)), m_view,
738 SLOT(settingsChanged())); dialog->setAttribute( Qt::WA_DeleteOnClose );
739 dialog->show();
740 }*/
741