• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.10.1 API Reference
  • KDE Home
  • Contact Us
 

KDEUI

  • kdeui
  • actions
krecentfilesaction.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE libraries
2  Copyright (C) 1999 Reginald Stadlbauer <reggie@kde.org>
3  (C) 1999 Simon Hausmann <hausmann@kde.org>
4  (C) 2000 Nicolas Hadacek <haadcek@kde.org>
5  (C) 2000 Kurt Granroth <granroth@kde.org>
6  (C) 2000 Michael Koch <koch@kde.org>
7  (C) 2001 Holger Freyther <freyther@kde.org>
8  (C) 2002 Ellis Whitehead <ellis@kde.org>
9  (C) 2002 Joseph Wenninger <jowenn@kde.org>
10  (C) 2003 Andras Mantia <amantia@kde.org>
11  (C) 2005-2006 Hamish Rodda <rodda@kde.org>
12 
13  This library is free software; you can redistribute it and/or
14  modify it under the terms of the GNU Library General Public
15  License version 2 as published by the Free Software Foundation.
16 
17  This library is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20  Library General Public License for more details.
21 
22  You should have received a copy of the GNU Library General Public License
23  along with this library; see the file COPYING.LIB. If not, write to
24  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25  Boston, MA 02110-1301, USA.
26 */
27 
28 #include "krecentfilesaction.h"
29 #include "krecentfilesaction_p.h"
30 
31 #include <QtCore/QFile>
32 #include <QtGui/QDesktopWidget>
33 #ifdef Q_OS_WIN
34 #include <QtCore/QDir>
35 #endif
36 
37 #include <kconfig.h>
38 #include <kconfiggroup.h>
39 #include <kdebug.h>
40 #include <kicon.h>
41 #include <klocale.h>
42 #include <kstandarddirs.h>
43 
44 #include "kmenu.h"
45 
46 
47 KRecentFilesAction::KRecentFilesAction(QObject *parent)
48  : KSelectAction(*new KRecentFilesActionPrivate, parent)
49 {
50  Q_D(KRecentFilesAction);
51  d->init();
52 }
53 
54 KRecentFilesAction::KRecentFilesAction(const QString &text, QObject *parent)
55  : KSelectAction(*new KRecentFilesActionPrivate, parent)
56 {
57  Q_D(KRecentFilesAction);
58  d->init();
59 
60  // Want to keep the ampersands
61  setText(text);
62 }
63 
64 KRecentFilesAction::KRecentFilesAction(const KIcon &icon, const QString &text, QObject *parent)
65  : KSelectAction(*new KRecentFilesActionPrivate, parent)
66 {
67  Q_D(KRecentFilesAction);
68  d->init();
69 
70  setIcon(icon);
71  // Want to keep the ampersands
72  setText(text);
73 }
74 
75 void KRecentFilesActionPrivate::init()
76 {
77  Q_Q(KRecentFilesAction);
78  delete q->menu();
79  q->setMenu(new KMenu());
80  q->setToolBarMode(KSelectAction::MenuMode);
81  m_noEntriesAction = q->menu()->addAction(i18n("No Entries"));
82  m_noEntriesAction->setEnabled(false);
83  clearSeparator = q->menu()->addSeparator();
84  clearSeparator->setVisible(false);
85  clearAction = q->menu()->addAction(i18n("Clear List"), q, SLOT(clear()));
86  clearAction->setVisible(false);
87  q->setEnabled(false);
88  q->connect(q, SIGNAL(triggered(QAction*)), SLOT(_k_urlSelected(QAction*)));
89 }
90 
91 KRecentFilesAction::~KRecentFilesAction()
92 {
93 }
94 
95 void KRecentFilesActionPrivate::_k_urlSelected( QAction* action )
96 {
97  Q_Q(KRecentFilesAction);
98  emit q->urlSelected(m_urls[action]);
99 }
100 
101 int KRecentFilesAction::maxItems() const
102 {
103  Q_D(const KRecentFilesAction);
104  return d->m_maxItems;
105 }
106 
107 void KRecentFilesAction::setMaxItems( int maxItems )
108 {
109  Q_D(KRecentFilesAction);
110  // set new maxItems
111  d->m_maxItems = maxItems;
112 
113  // remove all excess items
114  while( selectableActionGroup()->actions().count() > maxItems )
115  delete removeAction(selectableActionGroup()->actions().last());
116 }
117 
118 static QString titleWithSensibleWidth(const QString& nameValue, const QString& value)
119 {
120  // Calculate 3/4 of screen geometry, we do not want
121  // action titles to be bigger than that
122  // Since we do not know in which screen we are going to show
123  // we choose the min of all the screens
124  const QDesktopWidget desktopWidget;
125  int maxWidthForTitles = INT_MAX;
126  for (int i = 0; i < desktopWidget.screenCount(); ++i) {
127  maxWidthForTitles = qMin(maxWidthForTitles, desktopWidget.availableGeometry(i).width() * 3 / 4);
128  }
129  const QFontMetrics fontMetrics = QFontMetrics(QFont());
130 
131  QString title = nameValue + " [" + value + ']';
132  if (fontMetrics.width(title) > maxWidthForTitles){
133  // If it does not fit, try to cut only the whole path, though if the
134  // name is too long (more than 3/4 of the whole text) we cut it a bit too
135  const int nameValueMaxWidth = maxWidthForTitles * 3 / 4;
136  const int nameWidth = fontMetrics.width(nameValue);
137  QString cutNameValue, cutValue;
138  if (nameWidth > nameValueMaxWidth) {
139  cutNameValue = fontMetrics.elidedText(nameValue, Qt::ElideMiddle, nameValueMaxWidth);
140  cutValue = fontMetrics.elidedText(value, Qt::ElideMiddle, maxWidthForTitles - nameValueMaxWidth);
141  } else {
142  cutNameValue = nameValue;
143  cutValue = fontMetrics.elidedText(value, Qt::ElideMiddle, maxWidthForTitles - nameWidth);
144  }
145  title = cutNameValue + " [" + cutValue + ']';
146  }
147  return title;
148 }
149 
150 void KRecentFilesAction::addUrl( const KUrl& _url, const QString& name )
151 {
152  Q_D(KRecentFilesAction);
158  const KUrl url( _url );
159 
160  if ( url.isLocalFile() && KGlobal::dirs()->relativeLocation("tmp", url.toLocalFile()) != url.toLocalFile() )
161  return;
162  const QString tmpName = name.isEmpty() ? url.fileName() : name;
163 #ifdef Q_OS_WIN
164  const QString file = url.isLocalFile() ? QDir::toNativeSeparators( url.pathOrUrl() ) : url.pathOrUrl();
165 #else
166  const QString file = url.pathOrUrl();
167 #endif
168 
169  // remove file if already in list
170  foreach (QAction* action, selectableActionGroup()->actions())
171  {
172  if ( d->m_urls[action].pathOrUrl().endsWith(file) )
173  {
174  removeAction(action)->deleteLater();
175  break;
176  }
177  }
178  // remove oldest item if already maxitems in list
179  if( d->m_maxItems && selectableActionGroup()->actions().count() == d->m_maxItems )
180  {
181  // remove oldest added item
182  delete removeAction(selectableActionGroup()->actions().first());
183  }
184 
185  d->m_noEntriesAction->setVisible(false);
186  d->clearSeparator->setVisible(true);
187  d->clearAction->setVisible(true);
188  setEnabled(true);
189  // add file to list
190  const QString title = titleWithSensibleWidth(tmpName, file);
191  QAction* action = new QAction(title, selectableActionGroup());
192  addAction(action, url, tmpName);
193 }
194 
195 void KRecentFilesAction::addAction(QAction* action, const KUrl& url, const QString& name)
196 {
197  Q_D(KRecentFilesAction);
198  //kDebug (129) << "KRecentFilesAction::addAction(" << action << ")";
199 
200  action->setActionGroup(selectableActionGroup());
201 
202  // Keep in sync with createToolBarWidget()
203  foreach (QToolButton* button, d->m_buttons)
204  button->insertAction(button->actions().value(0), action);
205 
206  foreach (KComboBox* comboBox, d->m_comboBoxes)
207  comboBox->insertAction(comboBox->actions().value(0), action);
208 
209  menu()->insertAction(menu()->actions().value(0), action);
210 
211  d->m_shortNames.insert( action, name );
212  d->m_urls.insert( action, url );
213 }
214 
215 QAction* KRecentFilesAction::removeAction(QAction* action)
216 {
217  Q_D(KRecentFilesAction);
218  KSelectAction::removeAction( action );
219 
220  d->m_shortNames.remove( action );
221  d->m_urls.remove( action );
222 
223  return action;
224 }
225 
226 void KRecentFilesAction::removeUrl( const KUrl& url )
227 {
228  Q_D(KRecentFilesAction);
229  for (QMap<QAction*, KUrl>::ConstIterator it = d->m_urls.constBegin(); it != d->m_urls.constEnd(); ++it)
230  if (it.value() == url) {
231  delete removeAction(it.key());
232  return;
233  }
234 }
235 
236 KUrl::List KRecentFilesAction::urls() const
237 {
238  Q_D(const KRecentFilesAction);
239  return d->m_urls.values ();
240 }
241 
242 void KRecentFilesAction::clear()
243 {
244  clearEntries();
245  emit recentListCleared();
246 }
247 
248 void KRecentFilesAction::clearEntries()
249 {
250  Q_D(KRecentFilesAction);
251  KSelectAction::clear();
252  d->m_shortNames.clear();
253  d->m_urls.clear();
254  d->m_noEntriesAction->setVisible(true);
255  d->clearSeparator->setVisible(false);
256  d->clearAction->setVisible(false);
257  setEnabled(false);
258 }
259 
260 void KRecentFilesAction::loadEntries( const KConfigGroup& _config)
261 {
262  Q_D(KRecentFilesAction);
263  clearEntries();
264 
265  QString key;
266  QString value;
267  QString nameKey;
268  QString nameValue;
269  QString title;
270  KUrl url;
271 
272  KConfigGroup cg = _config;
273  if ( cg.name().isEmpty())
274  cg = KConfigGroup(cg.config(),"RecentFiles");
275 
276  bool thereAreEntries=false;
277  // read file list
278  for( int i = 1 ; i <= d->m_maxItems ; i++ )
279  {
280  key = QString( "File%1" ).arg( i );
281  value = cg.readPathEntry( key, QString() );
282  if (value.isEmpty()) continue;
283  url = KUrl( value );
284 
285  // Don't restore if file doesn't exist anymore
286  if (url.isLocalFile() && !QFile::exists(url.toLocalFile()))
287  continue;
288 
289  // Don't restore where the url is already known (eg. broken config)
290  if (d->m_urls.values().contains(url))
291  continue;
292 
293 #ifdef Q_OS_WIN
294  // convert to backslashes
295  if ( url.isLocalFile() )
296  value = QDir::toNativeSeparators( value );
297 #endif
298 
299  nameKey = QString( "Name%1" ).arg( i );
300  nameValue = cg.readPathEntry( nameKey, url.fileName() );
301  title = titleWithSensibleWidth(nameValue, value);
302  if (!value.isNull())
303  {
304  thereAreEntries=true;
305  addAction(new QAction(title, selectableActionGroup()), url, nameValue);
306  }
307  }
308  if (thereAreEntries)
309  {
310  d->m_noEntriesAction->setVisible(false);
311  d->clearSeparator->setVisible(true);
312  d->clearAction->setVisible(true);
313  setEnabled(true);
314  }
315 }
316 
317 void KRecentFilesAction::saveEntries( const KConfigGroup &_cg )
318 {
319  Q_D(KRecentFilesAction);
320  QString key;
321  QString value;
322  QStringList lst = items();
323 
324  KConfigGroup cg = _cg;
325  if (cg.name().isEmpty())
326  cg = KConfigGroup(cg.config(),"RecentFiles");
327 
328  cg.deleteGroup();
329 
330  // write file list
331  for ( int i = 1 ; i <= selectableActionGroup()->actions().count() ; i++ )
332  {
333  key = QString( "File%1" ).arg( i );
334  // i - 1 because we started from 1
335  value = d->m_urls[ selectableActionGroup()->actions()[ i - 1 ] ].pathOrUrl();
336  cg.writePathEntry( key, value );
337  key = QString( "Name%1" ).arg( i );
338  value = d->m_shortNames[ selectableActionGroup()->actions()[ i - 1 ] ];
339  cg.writePathEntry( key, value );
340  }
341 
342 }
343 
344 /* vim: et sw=2 ts=2
345  */
346 
347 #include "krecentfilesaction.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Wed Mar 20 2013 07:17:36 by doxygen 1.8.3.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.10.1 API Reference

Skip menu "kdelibs-4.10.1 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
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