• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeutils API Reference
  • KDE Home
  • Contact Us
 

filelight

  • sources
  • kde-4.12
  • kdeutils
  • filelight
  • src
  • part
  • radialMap
widgetEvents.cpp
Go to the documentation of this file.
1 /***********************************************************************
2 * Copyright 2003-2004 Max Howell <max.howell@methylblue.com>
3 * Copyright 2008-2009 Martin Sandsmark <martin.sandsmark@kde.org>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License or (at your option) version 3 or any later version
9 * accepted by the membership of KDE e.V. (or its successor approved
10 * by the membership of KDE e.V.), which shall act as a proxy
11 * defined in Section 14 of version 3 of the license.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ***********************************************************************/
21 
22 #include "part/fileTree.h"
23 #include "part/Config.h"
24 #include "radialMap.h" //class Segment
25 #include "widget.h"
26 
27 #include <KCursor> //::mouseMoveEvent()
28 #include <KDebug>
29 #include <KIconLoader> //::mousePressEvent()
30 #include <KJob>
31 #include <KIO/Job> //::mousePressEvent()
32 #include <KIO/DeleteJob>
33 #include <KIO/JobUiDelegate>
34 #include <KLocale>
35 #include <KMessageBox> //::mousePressEvent()
36 #include <KMenu> //::mousePressEvent()
37 #include <KRun> //::mousePressEvent()
38 #include <KToolInvocation>
39 #include <KUrl>
40 
41 #include <QtGui/QApplication> //QApplication::setOverrideCursor()
42 #include <QtGui/QClipboard>
43 #include <QtGui/QPainter>
44 #include <QtCore/QTimer> //::resizeEvent()
45 #include <QtGui/QDropEvent>
46 #include <QtGui/QPaintEvent>
47 #include <QtGui/QResizeEvent>
48 #include <QtGui/QMouseEvent>
49 #include <QtGui/QDragEnterEvent>
50 #include <QtGui/QToolTip>
51 
52 #include <cmath> //::segmentAt()
53 
54 void RadialMap::Widget::resizeEvent(QResizeEvent*)
55 {
56  if (m_map.resize(rect()))
57  m_timer.setSingleShot(true);
58  m_timer.start(500); //will cause signature to rebuild for new size
59 
60  //always do these as they need to be initialised on creation
61  m_offset.rx() = (width() - m_map.width()) / 2;
62  m_offset.ry() = (height() - m_map.height()) / 2;
63 }
64 
65 void RadialMap::Widget::paintEvent(QPaintEvent*)
66 {
67  QPainter paint;
68  paint.begin(this);
69 
70  if (!m_map.isNull())
71  paint.drawPixmap(m_offset, m_map.pixmap());
72  else
73  {
74  paint.drawText(rect(), 0, i18nc("We messed up, the user needs to initiate a rescan.", "Internal representation is invalid,\nplease rescan."));
75  return;
76  }
77 
78  //exploded labels
79  if (!m_map.isNull() && !m_timer.isActive())
80  {
81  if (Config::antialias) {
82  paint.setRenderHint(QPainter::Antialiasing);
83  //make lines appear on pixel boundaries
84  paint.translate(0.5, 0.5);
85  }
86  paintExplodedLabels(paint);
87  }
88 }
89 
90 const RadialMap::Segment* RadialMap::Widget::segmentAt(QPoint &e) const
91 {
92  //determine which segment QPoint e is above
93 
94  e -= m_offset;
95 
96  if (!m_map.m_signature)
97  return 0;
98 
99  if (e.x() <= m_map.width() && e.y() <= m_map.height())
100  {
101  //transform to cartesian coords
102  e.rx() -= m_map.width() / 2; //should be an int
103  e.ry() = m_map.height() / 2 - e.y();
104 
105  double length = hypot(e.x(), e.y());
106 
107  if (length >= m_map.m_innerRadius) //not hovering over inner circle
108  {
109  uint depth = ((int)length - m_map.m_innerRadius) / m_map.m_ringBreadth;
110 
111  if (depth <= m_map.m_visibleDepth) //**** do earlier since you can //** check not outside of range
112  {
113  //vector calculation, reduces to simple trigonometry
114  //cos angle = (aibi + ajbj) / albl
115  //ai = x, bi=1, aj=y, bj=0
116  //cos angle = x / (length)
117 
118  uint a = (uint)(acos((double)e.x() / length) * 916.736); //916.7324722 = #radians in circle * 16
119 
120  //acos only understands 0-180 degrees
121  if (e.y() < 0) a = 5760 - a;
122 
123 #define ring (m_map.m_signature + depth)
124  for (ConstIterator<Segment> it = ring->constIterator(); it != ring->end(); ++it)
125  if ((*it)->intersects(a))
126  return *it;
127 #undef ring
128  }
129  }
130  else return m_rootSegment; //hovering over inner circle
131  }
132 
133  return 0;
134 }
135 
136 void RadialMap::Widget::mouseMoveEvent(QMouseEvent *e)
137 {
138  //set m_focus to what we hover over, update UI if it's a new segment
139 
140  Segment const * const oldFocus = m_focus;
141  QPoint p = e->pos();
142 
143  m_focus = segmentAt(p); //NOTE p is passed by non-const reference
144 
145  if (m_focus)
146  {
147  if (m_focus != oldFocus) //if not same as last time
148  {
149  setCursor(Qt::PointingHandCursor);
150 
151  QString string = m_focus->file()->fullPath(m_tree)
152  + QLatin1Char('\n')
153  + m_focus->file()->humanReadableSize()
154  + QLatin1Char('\n');
155 
156  if (m_focus->file()->isFolder()) {
157  int files = static_cast<const Folder*>(m_focus->file())->children();
158  const uint percent = uint((100 * files) / (double)m_tree->children());
159  string += i18np("File: %1", "Files: %1", files);
160 
161  if (percent > 0) string += QString(QLatin1String( " (%1%)" )).arg(KGlobal::locale()->formatNumber(percent, 0));
162  }
163 
164  const KUrl url = Widget::url(m_focus->file());
165  if (m_focus == m_rootSegment && url != url.upUrl()) {
166  string += i18n("\nClick to go up to parent directory");
167  }
168 
169  QToolTip::showText(e->globalPos(), string, this);
170 
171  emit mouseHover(m_focus->file()->fullPath());
172  update();
173  }
174  }
175  else if (oldFocus && oldFocus->file() != m_tree)
176  {
177  unsetCursor();
178  update();
179 
180  emit mouseHover(QString());
181  }
182 }
183 
184 void RadialMap::Widget::enterEvent(QEvent *)
185 {
186  if (!m_focus) return;
187 
188  setCursor(Qt::PointingHandCursor);
189  emit mouseHover(m_focus->file()->fullPath());
190  update();
191 }
192 
193 void RadialMap::Widget::mousePressEvent(QMouseEvent *e)
194 {
195  if (!isEnabled())
196  return;
197 
198  //m_focus is set correctly (I've been strict, I assure you it is correct!)
199 
200  if (m_focus && !m_focus->isFake())
201  {
202  const KUrl url = Widget::url(m_focus->file());
203  const bool isDir = m_focus->file()->isFolder();
204 
205  // Actions in the right click menu
206  QAction* openFileManager = 0;
207  QAction* openTerminal = 0;
208  QAction* centerMap = 0;
209  QAction* openFile = 0;
210  QAction* copyClipboard = 0;
211  QAction* deleteItem = 0;
212 
213  if (e->button() == Qt::RightButton)
214  {
215  KMenu popup;
216  popup.addTitle(m_focus->file()->fullPath(m_tree));
217 
218  if (isDir) {
219  openFileManager = popup.addAction(KIcon(QLatin1String( "system-file-manager" )), i18n("Open &File Manager Here"));
220 
221  if (url.protocol() == QLatin1String("file" ))
222  openTerminal = popup.addAction(KIcon(QLatin1String( "utilities-terminal" )), i18n("Open &Terminal Here"));
223 
224  if (m_focus->file() != m_tree) {
225  popup.addSeparator();
226  centerMap = popup.addAction(KIcon(QLatin1String( "zoom-in" )), i18n("&Center Map Here"));
227  }
228  }
229  else
230  openFile = popup.addAction(KIcon(QLatin1String( "document-open" )), i18nc("Scan/open the path of the selected element", "&Open"));
231 
232  popup.addSeparator();
233  copyClipboard = popup.addAction(KIcon(QLatin1String( "edit-copy" )), i18n("&Copy to clipboard"));
234 
235  popup.addSeparator();
236  deleteItem = popup.addAction(KIcon(QLatin1String( "edit-delete" )), i18n("&Delete"));
237 
238  QAction* clicked = popup.exec(e->globalPos(), 0);
239 
240  if (openFileManager && clicked == openFileManager) {
241  KRun::runUrl(url.url(),QLatin1String( "inode/directory" ), this);
242  } else if (openTerminal && clicked == openTerminal) {
243  KToolInvocation::invokeTerminal(QString(),url.path());
244  } else if (centerMap && clicked == centerMap) {
245  goto section_two;
246  } else if (openFile && clicked == openFile) {
247  goto section_two;
248  } else if (clicked == copyClipboard) {
249  QMimeData* mimedata = new QMimeData();
250  url.populateMimeData(mimedata);
251  QApplication::clipboard()->setMimeData(mimedata , QClipboard::Clipboard);
252  } else if (clicked == deleteItem) {
253  m_toBeDeleted = m_focus;
254  const KUrl url = Widget::url(m_toBeDeleted->file());
255  const QString message = m_toBeDeleted->file()->isFolder()
256  ? i18n("<qt>The folder at <i>'%1'</i> will be <b>recursively</b> and <b>permanently</b> deleted.</qt>", url.prettyUrl())
257  : i18n("<qt><i>'%1'</i> will be <b>permanently</b> deleted.</qt>", url.prettyUrl());
258  const int userIntention = KMessageBox::warningContinueCancel(
259  this, message,
260  QString(), KGuiItem(i18n("&Delete"), QLatin1String( "edit-delete" )));
261 
262  if (userIntention == KMessageBox::Continue) {
263  KIO::Job *job = KIO::del(url);
264  job->ui()->setWindow(this);
265  connect(job, SIGNAL(finished(KJob*)), this, SLOT(deleteJobFinished(KJob*)));
266  QApplication::setOverrideCursor(Qt::BusyCursor);
267  setEnabled(false);
268  }
269  } else {
270  //ensure m_focus is set for new mouse position
271  sendFakeMouseEvent();
272  }
273  }
274  else { // not right mouse button
275 
276 section_two:
277  const QRect rect(e->x() - 20, e->y() - 20, 40, 40);
278 
279  if (!isDir || e->button() == Qt::MidButton) {
280  // KIconEffect::visualActivate(this, rect); // TODO: recreate this
281  new KRun(url, this, true); //FIXME see above
282  }
283  else if (m_focus->file() != m_tree) { // is left click
284  // KIconEffect::visualActivate(this, rect); // TODO: recreate this
285  emit activated(url); //activate first, this will cause UI to prepare itself
286  createFromCache((Folder *)m_focus->file());
287  }
288  else if (url.upUrl() != url)
289  emit giveMeTreeFor(url.upUrl());
290  }
291  }
292 }
293 
294 void RadialMap::Widget::deleteJobFinished(KJob *job)
295 {
296  QApplication::restoreOverrideCursor();
297  setEnabled(true);
298  if (!job->error() && m_toBeDeleted) {
299  m_toBeDeleted->file()->parent()->remove(m_toBeDeleted->file());
300  delete m_toBeDeleted->file();
301  m_toBeDeleted = 0;
302  m_focus = 0;
303  m_map.make(m_tree, true);
304  repaint();
305  } else
306  KMessageBox::error(this, job->errorString(), i18n("Error while deleting"));
307 }
308 
309 void RadialMap::Widget::dropEvent(QDropEvent *e)
310 {
311  KUrl::List uriList = KUrl::List::fromMimeData(e->mimeData());
312  if (!uriList.isEmpty())
313  emit giveMeTreeFor(uriList.first());
314 }
315 
316 void RadialMap::Widget::dragEnterEvent(QDragEnterEvent *e)
317 {
318  KUrl::List uriList = KUrl::List::fromMimeData(e->mimeData());
319  e->setAccepted(!uriList.isEmpty());
320 }
321 
322 void RadialMap::Widget::changeEvent(QEvent *e)
323 {
324  if (e->type() == QEvent::ApplicationPaletteChange ||
325  e->type() == QEvent::PaletteChange)
326  m_map.paint();
327 }
RadialMap::Widget::changeEvent
virtual void changeEvent(QEvent *)
Definition: widgetEvents.cpp:322
RadialMap::Widget::mousePressEvent
virtual void mousePressEvent(QMouseEvent *)
Definition: widgetEvents.cpp:193
RadialMap::Widget::mouseMoveEvent
virtual void mouseMoveEvent(QMouseEvent *)
Definition: widgetEvents.cpp:136
RadialMap::Widget::enterEvent
virtual void enterEvent(QEvent *)
Definition: widgetEvents.cpp:184
Config.h
RadialMap::Widget::dragEnterEvent
virtual void dragEnterEvent(QDragEnterEvent *)
Definition: widgetEvents.cpp:316
RadialMap::Widget::resizeEvent
virtual void resizeEvent(QResizeEvent *)
Definition: widgetEvents.cpp:54
radialMap.h
Folder
Definition: fileTree.h:271
RadialMap::Widget::segmentAt
const Segment * segmentAt(QPoint &) const
Definition: widgetEvents.cpp:90
fileTree.h
RadialMap::Segment::file
const File * file() const
Definition: radialMap.h:51
widget.h
ring
#define ring
RadialMap::Widget::paintEvent
virtual void paintEvent(QPaintEvent *)
Definition: widgetEvents.cpp:65
RadialMap::Widget::url
KUrl url(File const *const =0) const
Definition: widget.cpp:69
RadialMap::Widget::dropEvent
virtual void dropEvent(QDropEvent *)
Definition: widgetEvents.cpp:309
ConstIterator
Definition: fileTree.h:39
RadialMap::Segment
Definition: radialMap.h:31
length
static const int length[]
Definition: progressBox.cpp:99
Filelight::m_map
http QObject const QList< QVariant > m_map(0)
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:08:08 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

filelight

Skip menu "filelight"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdeutils API Reference

Skip menu "kdeutils API Reference"
  • ark
  • filelight
  • kcalc
  • kcharselect
  • kdf
  • kfloppy
  • kgpg
  • kremotecontrol
  • ktimer
  • kwallet
  • superkaramba
  • sweeper

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal