mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-24 19:02:48 +00:00

was previously included by qcontiguouscache header Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
334 lines
10 KiB
C++
334 lines
10 KiB
C++
/* This file is part of the KDE libraries
|
|
Copyright (C) 1999 Reginald Stadlbauer <reggie@kde.org>
|
|
(C) 1999 Simon Hausmann <hausmann@kde.org>
|
|
(C) 2000 Nicolas Hadacek <haadcek@kde.org>
|
|
(C) 2000 Kurt Granroth <granroth@kde.org>
|
|
(C) 2000 Michael Koch <koch@kde.org>
|
|
(C) 2001 Holger Freyther <freyther@kde.org>
|
|
(C) 2002 Ellis Whitehead <ellis@kde.org>
|
|
(C) 2002 Joseph Wenninger <jowenn@kde.org>
|
|
(C) 2003 Andras Mantia <amantia@kde.org>
|
|
(C) 2005-2006 Hamish Rodda <rodda@kde.org>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License version 2 as published by the Free Software Foundation.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "krecentfilesaction.h"
|
|
#include "krecentfilesaction_p.h"
|
|
#include "kconfig.h"
|
|
#include "kconfiggroup.h"
|
|
#include "kdebug.h"
|
|
#include "kicon.h"
|
|
#include "klocale.h"
|
|
#include "kstandarddirs.h"
|
|
#include "kmenu.h"
|
|
|
|
#include <QtCore/QFile>
|
|
#include <QtGui/QDesktopWidget>
|
|
|
|
#include <limits.h>
|
|
|
|
KRecentFilesAction::KRecentFilesAction(QObject *parent)
|
|
: KSelectAction(*new KRecentFilesActionPrivate, parent)
|
|
{
|
|
Q_D(KRecentFilesAction);
|
|
d->init();
|
|
}
|
|
|
|
KRecentFilesAction::KRecentFilesAction(const QString &text, QObject *parent)
|
|
: KSelectAction(*new KRecentFilesActionPrivate, parent)
|
|
{
|
|
Q_D(KRecentFilesAction);
|
|
d->init();
|
|
|
|
// Want to keep the ampersands
|
|
setText(text);
|
|
}
|
|
|
|
KRecentFilesAction::KRecentFilesAction(const KIcon &icon, const QString &text, QObject *parent)
|
|
: KSelectAction(*new KRecentFilesActionPrivate, parent)
|
|
{
|
|
Q_D(KRecentFilesAction);
|
|
d->init();
|
|
|
|
setIcon(icon);
|
|
// Want to keep the ampersands
|
|
setText(text);
|
|
}
|
|
|
|
void KRecentFilesActionPrivate::init()
|
|
{
|
|
Q_Q(KRecentFilesAction);
|
|
delete q->menu();
|
|
q->setMenu(new KMenu());
|
|
q->setToolBarMode(KSelectAction::MenuMode);
|
|
m_noEntriesAction = q->menu()->addAction(i18n("No Entries"));
|
|
m_noEntriesAction->setEnabled(false);
|
|
clearSeparator = q->menu()->addSeparator();
|
|
clearSeparator->setVisible(false);
|
|
clearAction = q->menu()->addAction(i18n("Clear List"), q, SLOT(clear()));
|
|
clearAction->setVisible(false);
|
|
q->setEnabled(false);
|
|
q->connect(q, SIGNAL(triggered(QAction*)), SLOT(_k_urlSelected(QAction*)));
|
|
}
|
|
|
|
KRecentFilesAction::~KRecentFilesAction()
|
|
{
|
|
}
|
|
|
|
void KRecentFilesActionPrivate::_k_urlSelected( QAction* action )
|
|
{
|
|
Q_Q(KRecentFilesAction);
|
|
emit q->urlSelected(m_urls[action]);
|
|
}
|
|
|
|
int KRecentFilesAction::maxItems() const
|
|
{
|
|
Q_D(const KRecentFilesAction);
|
|
return d->m_maxItems;
|
|
}
|
|
|
|
void KRecentFilesAction::setMaxItems( int maxItems )
|
|
{
|
|
Q_D(KRecentFilesAction);
|
|
// set new maxItems
|
|
d->m_maxItems = maxItems;
|
|
|
|
// remove all excess items
|
|
while( selectableActionGroup()->actions().count() > maxItems )
|
|
delete removeAction(selectableActionGroup()->actions().last());
|
|
}
|
|
|
|
static QString titleWithSensibleWidth(const QString& nameValue, const QString& value)
|
|
{
|
|
// Calculate 3/4 of screen geometry, we do not want
|
|
// action titles to be bigger than that
|
|
// Since we do not know in which screen we are going to show
|
|
// we choose the min of all the screens
|
|
const QDesktopWidget desktopWidget;
|
|
int maxWidthForTitles = INT_MAX;
|
|
for (int i = 0; i < desktopWidget.screenCount(); ++i) {
|
|
maxWidthForTitles = qMin(maxWidthForTitles, desktopWidget.availableGeometry(i).width() * 3 / 4);
|
|
}
|
|
const QFontMetrics fontMetrics = QFontMetrics(QFont());
|
|
|
|
QString title = nameValue + " [" + value + ']';
|
|
if (fontMetrics.width(title) > maxWidthForTitles){
|
|
// If it does not fit, try to cut only the whole path, though if the
|
|
// name is too long (more than 3/4 of the whole text) we cut it a bit too
|
|
const int nameValueMaxWidth = maxWidthForTitles * 3 / 4;
|
|
const int nameWidth = fontMetrics.width(nameValue);
|
|
QString cutNameValue, cutValue;
|
|
if (nameWidth > nameValueMaxWidth) {
|
|
cutNameValue = fontMetrics.elidedText(nameValue, Qt::ElideMiddle, nameValueMaxWidth);
|
|
cutValue = fontMetrics.elidedText(value, Qt::ElideMiddle, maxWidthForTitles - nameValueMaxWidth);
|
|
} else {
|
|
cutNameValue = nameValue;
|
|
cutValue = fontMetrics.elidedText(value, Qt::ElideMiddle, maxWidthForTitles - nameWidth);
|
|
}
|
|
title = cutNameValue + " [" + cutValue + ']';
|
|
}
|
|
return title;
|
|
}
|
|
|
|
void KRecentFilesAction::addUrl( const KUrl& _url, const QString& name )
|
|
{
|
|
Q_D(KRecentFilesAction);
|
|
/**
|
|
* Create a deep copy here, because if _url is the parameter from
|
|
* urlSelected() signal, we will delete it in the removeAction() call below.
|
|
* but access it again in the addAction call... => crash
|
|
*/
|
|
const KUrl url( _url );
|
|
|
|
if ( url.isLocalFile() && KGlobal::dirs()->relativeLocation("tmp", url.toLocalFile()) != url.toLocalFile() )
|
|
return;
|
|
const QString tmpName = name.isEmpty() ? url.fileName() : name;
|
|
const QString file = url.pathOrUrl();
|
|
|
|
// remove file if already in list
|
|
foreach (QAction* action, selectableActionGroup()->actions())
|
|
{
|
|
if ( d->m_urls[action].pathOrUrl().endsWith(file) )
|
|
{
|
|
removeAction(action)->deleteLater();
|
|
break;
|
|
}
|
|
}
|
|
// remove oldest item if already maxitems in list
|
|
if( d->m_maxItems && selectableActionGroup()->actions().count() == d->m_maxItems )
|
|
{
|
|
// remove oldest added item
|
|
delete removeAction(selectableActionGroup()->actions().first());
|
|
}
|
|
|
|
d->m_noEntriesAction->setVisible(false);
|
|
d->clearSeparator->setVisible(true);
|
|
d->clearAction->setVisible(true);
|
|
setEnabled(true);
|
|
// add file to list
|
|
const QString title = titleWithSensibleWidth(tmpName, file);
|
|
QAction* action = new QAction(title, selectableActionGroup());
|
|
addAction(action, url, tmpName);
|
|
}
|
|
|
|
void KRecentFilesAction::addAction(QAction* action, const KUrl& url, const QString& name)
|
|
{
|
|
Q_D(KRecentFilesAction);
|
|
//kDebug (129) << "KRecentFilesAction::addAction(" << action << ")";
|
|
|
|
action->setActionGroup(selectableActionGroup());
|
|
|
|
// Keep in sync with createToolBarWidget()
|
|
foreach (QToolButton* button, d->m_buttons)
|
|
button->insertAction(button->actions().value(0), action);
|
|
|
|
foreach (KComboBox* comboBox, d->m_comboBoxes)
|
|
comboBox->insertAction(comboBox->actions().value(0), action);
|
|
|
|
menu()->insertAction(menu()->actions().value(0), action);
|
|
|
|
d->m_shortNames.insert( action, name );
|
|
d->m_urls.insert( action, url );
|
|
}
|
|
|
|
QAction* KRecentFilesAction::removeAction(QAction* action)
|
|
{
|
|
Q_D(KRecentFilesAction);
|
|
KSelectAction::removeAction( action );
|
|
|
|
d->m_shortNames.remove( action );
|
|
d->m_urls.remove( action );
|
|
|
|
return action;
|
|
}
|
|
|
|
void KRecentFilesAction::removeUrl( const KUrl& url )
|
|
{
|
|
Q_D(KRecentFilesAction);
|
|
for (QMap<QAction*, KUrl>::ConstIterator it = d->m_urls.constBegin(); it != d->m_urls.constEnd(); ++it)
|
|
if (it.value() == url) {
|
|
delete removeAction(it.key());
|
|
return;
|
|
}
|
|
}
|
|
|
|
KUrl::List KRecentFilesAction::urls() const
|
|
{
|
|
Q_D(const KRecentFilesAction);
|
|
return d->m_urls.values ();
|
|
}
|
|
|
|
void KRecentFilesAction::clear()
|
|
{
|
|
clearEntries();
|
|
emit recentListCleared();
|
|
}
|
|
|
|
void KRecentFilesAction::clearEntries()
|
|
{
|
|
Q_D(KRecentFilesAction);
|
|
KSelectAction::clear();
|
|
d->m_shortNames.clear();
|
|
d->m_urls.clear();
|
|
d->m_noEntriesAction->setVisible(true);
|
|
d->clearSeparator->setVisible(false);
|
|
d->clearAction->setVisible(false);
|
|
setEnabled(false);
|
|
}
|
|
|
|
void KRecentFilesAction::loadEntries( const KConfigGroup& _config)
|
|
{
|
|
Q_D(KRecentFilesAction);
|
|
clearEntries();
|
|
|
|
QString key;
|
|
QString value;
|
|
QString nameKey;
|
|
QString nameValue;
|
|
QString title;
|
|
KUrl url;
|
|
|
|
KConfigGroup cg = _config;
|
|
if ( cg.name().isEmpty())
|
|
cg = KConfigGroup(cg.config(),"RecentFiles");
|
|
|
|
bool thereAreEntries=false;
|
|
// read file list
|
|
for( int i = 1 ; i <= d->m_maxItems ; i++ )
|
|
{
|
|
key = QString( "File%1" ).arg( i );
|
|
value = cg.readPathEntry( key, QString() );
|
|
if (value.isEmpty()) continue;
|
|
url = KUrl( value );
|
|
|
|
// Don't restore if file doesn't exist anymore
|
|
if (url.isLocalFile() && !QFile::exists(url.toLocalFile()))
|
|
continue;
|
|
|
|
// Don't restore where the url is already known (eg. broken config)
|
|
if (d->m_urls.values().contains(url))
|
|
continue;
|
|
|
|
|
|
nameKey = QString( "Name%1" ).arg( i );
|
|
nameValue = cg.readPathEntry( nameKey, url.fileName() );
|
|
title = titleWithSensibleWidth(nameValue, value);
|
|
if (!value.isNull())
|
|
{
|
|
thereAreEntries=true;
|
|
addAction(new QAction(title, selectableActionGroup()), url, nameValue);
|
|
}
|
|
}
|
|
if (thereAreEntries)
|
|
{
|
|
d->m_noEntriesAction->setVisible(false);
|
|
d->clearSeparator->setVisible(true);
|
|
d->clearAction->setVisible(true);
|
|
setEnabled(true);
|
|
}
|
|
}
|
|
|
|
void KRecentFilesAction::saveEntries( const KConfigGroup &_cg )
|
|
{
|
|
Q_D(KRecentFilesAction);
|
|
QString key;
|
|
QString value;
|
|
QStringList lst = items();
|
|
|
|
KConfigGroup cg = _cg;
|
|
if (cg.name().isEmpty())
|
|
cg = KConfigGroup(cg.config(),"RecentFiles");
|
|
|
|
cg.deleteGroup();
|
|
|
|
// write file list
|
|
for ( int i = 1 ; i <= selectableActionGroup()->actions().count() ; i++ )
|
|
{
|
|
key = QString( "File%1" ).arg( i );
|
|
// i - 1 because we started from 1
|
|
value = d->m_urls[ selectableActionGroup()->actions()[ i - 1 ] ].pathOrUrl();
|
|
cg.writePathEntry( key, value );
|
|
key = QString( "Name%1" ).arg( i );
|
|
value = d->m_shortNames[ selectableActionGroup()->actions()[ i - 1 ] ];
|
|
cg.writePathEntry( key, value );
|
|
}
|
|
|
|
}
|
|
|
|
/* vim: et sw=2 ts=2
|
|
*/
|
|
|
|
#include "moc_krecentfilesaction.cpp"
|