Page MenuHomePhorge

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/kdeui/actions/kaction.cpp b/kdeui/actions/kaction.cpp
index 4096ab2ccc..42d6e46d8c 100644
--- a/kdeui/actions/kaction.cpp
+++ b/kdeui/actions/kaction.cpp
@@ -1,431 +1,431 @@
/* 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) 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 "kaction.h"
#include "kaction_p.h"
#include "kglobalaccel_p.h"
#include "klocale.h"
#include "kmessagebox.h"
#include "kauthaction.h"
#include "kauthactionwatcher.h"
#include <QApplication>
#include <QHBoxLayout>
#include <QShortcutEvent>
#include <QToolBar>
#include <kdebug.h>
#include "kguiitem.h"
#include "kicon.h"
//---------------------------------------------------------------------
// KActionPrivate
//---------------------------------------------------------------------
void KActionPrivate::init(KAction *q_ptr)
{
q = q_ptr;
globalShortcutEnabled = false;
neverSetGlobalShortcut = true;
QObject::connect(q, SIGNAL(triggered(bool)), q, SLOT(slotTriggered()));
q->setProperty("isShortcutConfigurable", true);
}
void KActionPrivate::setActiveGlobalShortcutNoEnable(const KShortcut &cut)
{
globalShortcut = cut;
emit q->globalShortcutChanged(cut.primary());
}
void KActionPrivate::slotTriggered()
{
#ifdef KDE3_SUPPORT
emit q->activated();
#endif
emit q->triggered(QApplication::mouseButtons(), QApplication::keyboardModifiers());
if (authAction) {
KAuth::Action::AuthStatus s = authAction->earlyAuthorize();
switch(s) {
case KAuth::Action::Denied:
q->setEnabled(false);
break;
case KAuth::Action::Authorized:
emit q->authorized(authAction);
break;
default:
break;
}
}
}
void KActionPrivate::authStatusChanged(int status)
{
KAuth::Action::AuthStatus s = (KAuth::Action::AuthStatus)status;
switch(s) {
case KAuth::Action::Authorized:
q->setEnabled(true);
if(!oldIcon.isNull()) {
q->setIcon(oldIcon);
oldIcon = KIcon();
}
break;
case KAuth::Action::AuthRequired:
q->setEnabled(true);
oldIcon = KIcon(q->icon());
q->setIcon(KIcon("dialog-password"));
break;
default:
q->setEnabled(false);
if(!oldIcon.isNull()) {
q->setIcon(oldIcon);
oldIcon = KIcon();
}
}
}
bool KAction::event(QEvent *event)
{
if (event->type() == QEvent::Shortcut) {
QShortcutEvent *se = static_cast<QShortcutEvent*>(event);
if(se->isAmbiguous()) {
KMessageBox::information(
NULL, // No widget to be seen around here
i18n( "The key sequence '%1' is ambiguous. Use 'Configure Shortcuts'\n"
"from the 'Settings' menu to solve the ambiguity.\n"
"No action will be triggered.",
se->key().toString(QKeySequence::NativeText)),
i18n("Ambiguous shortcut detected"));
return true;
}
}
return QAction::event(event);
}
//---------------------------------------------------------------------
// KAction
//---------------------------------------------------------------------
KAction::KAction(QObject *parent)
: QWidgetAction(parent), d(new KActionPrivate)
{
d->init(this);
}
KAction::KAction(const QString &text, QObject *parent)
: QWidgetAction(parent), d(new KActionPrivate)
{
d->init(this);
setText(text);
}
-KAction::KAction(const KIcon &icon, const QString &text, QObject *parent)
+KAction::KAction(const QIcon &icon, const QString &text, QObject *parent)
: QWidgetAction(parent), d(new KActionPrivate)
{
d->init(this);
setIcon(icon);
setText(text);
}
KAction::~KAction()
{
if (d->globalShortcutEnabled) {
// - remove the action from KGlobalAccel
d->globalShortcutEnabled = false;
KGlobalAccel::self()->d->remove(this, KGlobalAccelPrivate::SetInactive);
}
KGestureMap::self()->removeGesture(d->shapeGesture, this);
KGestureMap::self()->removeGesture(d->rockerGesture, this);
delete d;
}
bool KAction::isShortcutConfigurable() const
{
return property("isShortcutConfigurable").toBool();
}
void KAction::setShortcutConfigurable( bool b )
{
setProperty("isShortcutConfigurable", b);
}
KShortcut KAction::shortcut(ShortcutTypes type) const
{
Q_ASSERT(type);
if (type == DefaultShortcut) {
QKeySequence primary = property("defaultPrimaryShortcut").value<QKeySequence>();
QKeySequence secondary = property("defaultAlternateShortcut").value<QKeySequence>();
return KShortcut(primary, secondary);
}
QKeySequence primary = shortcuts().value(0);
QKeySequence secondary = shortcuts().value(1);
return KShortcut(primary, secondary);
}
void KAction::setShortcut( const KShortcut & shortcut, ShortcutTypes type )
{
Q_ASSERT(type);
if (type & DefaultShortcut) {
setProperty("defaultPrimaryShortcut", shortcut.primary());
setProperty("defaultAlternateShortcut", shortcut.alternate());
}
if (type & ActiveShortcut) {
QAction::setShortcuts(shortcut);
}
}
void KAction::setShortcut( const QKeySequence & keySeq, ShortcutTypes type )
{
Q_ASSERT(type);
if (type & DefaultShortcut)
setProperty("defaultPrimaryShortcut", keySeq);
if (type & ActiveShortcut) {
QAction::setShortcut(keySeq);
}
}
void KAction::setShortcuts(const QList<QKeySequence>& shortcuts, ShortcutTypes type)
{
setShortcut(KShortcut(shortcuts), type);
}
const KShortcut & KAction::globalShortcut(ShortcutTypes type) const
{
Q_ASSERT(type);
if (type == DefaultShortcut)
return d->defaultGlobalShortcut;
return d->globalShortcut;
}
void KAction::setGlobalShortcut( const KShortcut & shortcut, ShortcutTypes type,
GlobalShortcutLoading load )
{
Q_ASSERT(type);
bool changed = false;
// protect against garbage keycode -1 that Qt sometimes produces for exotic keys;
// at the moment (~mid 2008) Multimedia PlayPause is one of those keys.
int shortcutKeys[8];
for (int i = 0; i < 4; i++) {
shortcutKeys[i] = shortcut.primary()[i];
shortcutKeys[i + 4] = shortcut.alternate()[i];
}
for (int i = 0; i < 8; i++) {
if (shortcutKeys[i] == -1) {
qWarning() << "Encountered garbage keycode (keycode = -1) in input, not doing anything.";
return;
}
}
if (!d->globalShortcutEnabled) {
changed = true;
if (objectName().isEmpty() || objectName().startsWith(QLatin1String("unnamed-"))) {
qWarning() << "Attempt to set global shortcut for action without objectName()."
" Read the setGlobalShortcut() documentation.";
return;
}
d->globalShortcutEnabled = true;
KGlobalAccel::self()->d->doRegister(this);
}
if ((type & DefaultShortcut) && d->defaultGlobalShortcut != shortcut) {
d->defaultGlobalShortcut = shortcut;
changed = true;
}
if ((type & ActiveShortcut) && d->globalShortcut != shortcut) {
d->globalShortcut = shortcut;
changed = true;
}
//We want to have updateGlobalShortcuts called on a new action in any case so that
//it will be registered properly. In the case of the first setShortcut() call getting an
//empty shortcut parameter this would not happen...
if (changed || d->neverSetGlobalShortcut) {
KGlobalAccel::self()->d->updateGlobalShortcut(this, type | load);
d->neverSetGlobalShortcut = false;
}
}
#ifndef KDE_NO_DEPRECATED
bool KAction::globalShortcutAllowed() const
{
return d->globalShortcutEnabled;
}
#endif
bool KAction::isGlobalShortcutEnabled() const
{
return d->globalShortcutEnabled;
}
#ifndef KDE_NO_DEPRECATED
void KAction::setGlobalShortcutAllowed( bool allowed, GlobalShortcutLoading /* load */ )
{
if (allowed) {
//### no-op
} else {
forgetGlobalShortcut();
}
}
#endif
void KAction::forgetGlobalShortcut()
{
d->globalShortcut = KShortcut();
d->defaultGlobalShortcut = KShortcut();
if (d->globalShortcutEnabled) {
d->globalShortcutEnabled = false;
d->neverSetGlobalShortcut = true; //it's a fresh start :)
KGlobalAccel::self()->d->remove(this, KGlobalAccelPrivate::UnRegister);
}
}
KShapeGesture KAction::shapeGesture( ShortcutTypes type ) const
{
Q_ASSERT(type);
if ( type & DefaultShortcut )
return d->defaultShapeGesture;
return d->shapeGesture;
}
KRockerGesture KAction::rockerGesture( ShortcutTypes type ) const
{
Q_ASSERT(type);
if ( type & DefaultShortcut )
return d->defaultRockerGesture;
return d->rockerGesture;
}
void KAction::setShapeGesture( const KShapeGesture& gest, ShortcutTypes type )
{
Q_ASSERT(type);
if( type & DefaultShortcut )
d->defaultShapeGesture = gest;
if ( type & ActiveShortcut ) {
if ( KGestureMap::self()->findAction( gest ) ) {
qDebug() << "New mouse gesture already in use, won't change gesture.";
return;
}
KGestureMap::self()->removeGesture( d->shapeGesture, this );
KGestureMap::self()->addGesture( gest, this );
d->shapeGesture = gest;
}
}
void KAction::setRockerGesture( const KRockerGesture& gest, ShortcutTypes type )
{
Q_ASSERT(type);
if( type & DefaultShortcut )
d->defaultRockerGesture = gest;
if ( type & ActiveShortcut ) {
if ( KGestureMap::self()->findAction( gest ) ) {
qDebug() << "New mouse gesture already in use, won't change gesture.";
return;
}
KGestureMap::self()->removeGesture( d->rockerGesture, this );
KGestureMap::self()->addGesture( gest, this );
d->rockerGesture = gest;
}
}
void KAction::setHelpText(const QString& text)
{
setStatusTip(text);
setToolTip(text);
if (whatsThis().isEmpty())
setWhatsThis(text);
}
KAuth::Action *KAction::authAction() const
{
return d->authAction;
}
void KAction::setAuthAction(const QString &actionName)
{
if (actionName.isEmpty()) {
setAuthAction(0);
} else {
setAuthAction(new KAuth::Action(actionName));
}
}
void KAction::setAuthAction(KAuth::Action *action)
{
if (d->authAction == action) {
return;
}
if (d->authAction) {
disconnect(d->authAction->watcher(), SIGNAL(statusChanged(int)),
this, SLOT(authStatusChanged(int)));
//delete d->authAction;
d->authAction = 0;
if (!d->oldIcon.isNull()) {
setIcon(d->oldIcon);
d->oldIcon = KIcon();
}
}
if (action != 0) {
d->authAction = action;
// Set the parent widget
d->authAction->setParentWidget(parentWidget());
connect(d->authAction->watcher(), SIGNAL(statusChanged(int)),
this, SLOT(authStatusChanged(int)));
d->authStatusChanged(d->authAction->status());
}
}
/* vim: et sw=2 ts=2
*/
#include "moc_kaction.cpp"
diff --git a/kdeui/actions/kaction.h b/kdeui/actions/kaction.h
index 14a68efb7f..1f90532041 100644
--- a/kdeui/actions/kaction.h
+++ b/kdeui/actions/kaction.h
@@ -1,556 +1,556 @@
/* 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) 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.
*/
#ifndef KACTION_H
#define KACTION_H
#include <kdeui_export.h>
#include <kguiitem.h>
#include <kshortcut.h>
#include <QWidgetAction>
-class KIcon;
+
class KShapeGesture;
class KRockerGesture;
namespace KAuth {
class Action;
}
//TODO Reduce the word count. This is not very focused and takes too long to read.
//Keep in mind that QAction also has documentation that we don't need to repeat here.
/**
* @short Class to encapsulate user-driven action or event
* @extends QAction
*
* The KAction class (and derived and super classes) extends QAction,
* which provides a way to easily encapsulate a "real" user-selected
* action or event in your program.
*
* For instance, a user may want to @p paste the contents of
* the clipboard, @p scroll @p down a document, or @p quit the
* application. These are all \b actions -- events that the
* user causes to happen. The KAction class allows the developer to
* deal with these actions in an easy and intuitive manner, and conforms
* to KDE's extended functionality requirements - including supporting
* multiple user-configurable shortcuts, and KDE named icons. Actions
* also improve accessibility.
*
* Specifically, QAction (and thus KAction) encapsulates the various attributes
* of an event/action. For instance, an action might have an icon()
* that provides a visual representation (a clipboard for a "paste" action or
* scissors for a "cut" action). The action should also be described by some text().
* It will certainly be connected to a method that actually @p executes the action!
* All these attributes are contained within the action object.
*
* The advantage of dealing with actions is that you can manipulate
* the Action without regard to the GUI representation of it. For
* instance, in the "normal" way of dealing with actions like "cut",
* you would manually insert a item for Cut into a menu and a button
* into a toolbar. If you want to disable the cut action for a moment
* (maybe nothing is selected), you would have to hunt down the pointer
* to the menu item and the toolbar button and disable both
* individually. Setting the menu item and toolbar item up uses very
* similar code - but has to be done twice!
*
* With the action concept, you simply add the action to whatever
* GUI element you want. The KAction class will then take care of
* correctly defining the menu item (with icons, accelerators, text,
* etc), toolbar button, or other. From then on, if you
* manipulate the action at all, the effect will propagate through all
* GUI representations of it. Back to the "cut" example: if you want
* to disable the Cut Action, you would simply call
* 'cutAction->setEnabled(false)' and both the menuitem and button would
* instantly be disabled!
*
* This is the biggest advantage to the action concept -- there is a
* one-to-one relationship between the "real" action and @p all
* GUI representations of it.
*
* KAction emits the hovered() signal on mouseover, and the triggered(bool checked)
* signal on activation of a corresponding GUI element ( menu item, toolbar button, etc. )
*
* If you are in the situation of wanting to map the triggered()
* signal of multiple action objects to one slot, with a special
* argument bound to each action, you have several options:
*
* Using QActionGroup:
* \li Create a QActionGroup and assign it to each of the actions with setActionGroup(), then
* \li Connect the QActionGroup::triggered(QAction*) signal to your slot.
*
* Using QSignalMapper:
* \code
* QSignalMapper *desktopNumberMapper = new QSignalMapper( this );
* connect( desktopNumberMapper, SIGNAL( mapped( int ) ),
* this, SLOT( moveWindowToDesktop( int ) ) );
*
* for ( uint i = 0; i < numberOfDesktops; ++i ) {
* KAction *desktopAction = new KAction( i18n( "Move Window to Desktop %i" ).arg( i ), ... );
* connect( desktopAction, SIGNAL( triggered(bool) ), desktopNumberMapper, SLOT( map() ) );
* desktopNumberMapper->setMapping( desktopAction, i );
* }
* \endcode
*
* \section kaction_general General Usage
*
* The steps to using actions are roughly as follows:
*
* @li Decide which attributes you want to associate with a given
* action (icons, text, keyboard shortcut, etc)
* @li Create the action using KAction (or derived or super class).
* @li Add the action into whatever GUI element you want. Typically,
* this will be a menu or toolbar.
*
* \section kaction_general The kinds of shortcuts
*
* Local shortcuts are active if their context has the focus, global shortcus
* are active even if the program does not have the focus. If a global
* shortcut and a local shortcut are ambiguous the global shortcut wins.
*
* @li Active shortcuts trigger a KAction if activated.
* @li Default shortcuts are what the active shortcuts revert to if the user chooses
* to reset shortcuts to default.
*
* \section kaction_example Detailed Example
*
* Here is an example of enabling a "New [document]" action
* \code
* KAction *newAct = actionCollection()->addAction(
* KStandardAction::New, //< see KStandardAction
* this, //< Receiver
* SLOT(fileNew()) ); //< SLOT
* \endcode
*
* This section creates our action. Text, Icon and Shortcut will be set from
* KStandardAction. KStandardAction ensures your application complies to the
* platform standards. When triggered the \c fileNew() slot will be called.
*
* @see KStandardAction for more information.
*
* If you want to create your own actions use
* \code
* KAction *newAct = actionCollection()->addAction("quick-connect");
* newAct->setText(i18n("Quick Connect"))
* newAct->setIcon(KIcon("quick-connect"));
* newAct->setShortcut(Qt::Key_F6);
* connect(newAct, SIGNAL(triggered()), this, SLOT(quickConnect()));
* \endcode
*
* This section creates our action. It displays the text "Quick Connect",
* uses the Icon "quick-connect" and pressing \c F6 will trigger it. When
* invoked, the slot quickConnect() is called.
*
* \code
* QMenu *file = new QMenu;
* file->addAction(newAct);
* \endcode
* That just inserted the action into the File menu. The point is, it's not
* important in which menu it is: all manipulation of the item is
* done through the newAct object.
*
* \code
* toolBar()->addAction(newAct);
* \endcode
* And this added the action into the main toolbar as a button.
*
* That's it!
*
* If you want to disable that action sometime later, you can do so
* with
* \code
* newAct->setEnabled(false)
* \endcode
* and both the menuitem in File and the toolbar button will instantly
* be disabled.
*
* Unlike with previous versions of KDE, the action can simply be deleted
* when you have finished with it - the destructor takes care of all
* of the cleanup.
*
* \warning calling QAction::setShortcut() on a KAction may lead to unexpected
* behavior. There is nothing we can do about it because QAction::setShortcut()
* is not virtual.
*
* \note if you are using a "standard" action like "new", "paste",
* "quit", or any other action described in the KDE UI Standards,
* please use the methods in the KStandardAction class rather than
* defining your own.
*
* \section Using QActions
*
* Mixing QActions and KActions in an application is not a
* good idea. KShortcutsEditor doesn't handle QActions at all.
*
* \section kaction_xmlgui Usage Within the XML Framework
*
* If you are using KAction within the context of the XML menu and
* toolbar building framework, you do not ever
* have to add your actions to containers manually. The framework
* does that for you.
*
* @see KStandardAction
*/
class KDEUI_EXPORT KAction : public QWidgetAction
{
Q_OBJECT
Q_PROPERTY( KShortcut shortcut READ shortcut WRITE setShortcut )
Q_PROPERTY( bool shortcutConfigurable READ isShortcutConfigurable WRITE setShortcutConfigurable )
Q_PROPERTY( KShortcut globalShortcut READ globalShortcut WRITE setGlobalShortcut )
#ifndef KDE_NO_DEPRECATED
Q_PROPERTY( bool globalShortcutAllowed READ globalShortcutAllowed WRITE setGlobalShortcutAllowed )
#endif
Q_PROPERTY( bool globalShortcutEnabled READ isGlobalShortcutEnabled )
Q_FLAGS( ShortcutType )
public:
/**
* An enumeration about the two types of shortcuts in a KAction
*/
enum ShortcutType {
/// The shortcut will immediately become active but may be reset to "default".
ActiveShortcut = 0x1,
/// The shortcut is a default shortcut - it becomes active when somebody decides to
/// reset shortcuts to default.
DefaultShortcut = 0x2
};
Q_DECLARE_FLAGS(ShortcutTypes, ShortcutType)
/**
* An enum about global shortcut setter semantics
*/
//This enum will be ORed with ShortcutType in calls to KGlobalAccel, so it must not contain
//any value equal to a value in ShortcutType.
enum GlobalShortcutLoading {
/// Look up the action in global settings (using its main component's name and text())
/// and set the shortcut as saved there.
/// @see setGlobalShortcut()
Autoloading = 0x0,
/// Prevent autoloading of saved global shortcut for action
NoAutoloading = 0x4
};
/**
* Constructs an action.
*/
explicit KAction(QObject *parent);
/**
* Constructs an action with the specified parent and visible text.
*
* @param text The visible text for this action.
* @param parent The parent for this action.
*/
KAction(const QString& text, QObject *parent);
/**
* Constructs an action with text and icon; a shortcut may be specified by
* the ampersand character (e.g. \"&amp;Option\" creates a shortcut with key \e O )
*
* This is the other common KAction constructor used. Use it when you
* \e do have a corresponding icon.
*
* @param icon The icon to display.
* @param text The text that will be displayed.
* @param parent The parent for this action.
*/
- KAction(const KIcon& icon, const QString& text, QObject *parent);
+ KAction(const QIcon& icon, const QString& text, QObject *parent);
/**
* Standard destructor
*/
virtual ~KAction();
/**
* Sets the help text for the action.
* This help text will be set for all help mechanisms:
* - the status-bar help text
* - the tooltip (for toolbar buttons)
* - the "WhatsThis" help text (unless one was already set)
*
* This is more convenient than calling all three methods with the
* same text, and this level of abstraction can allow to change
* the default implementation of help one day more easily.
* Of course you can also call setStatusTip, setToolTip and setWhatsThis
* separately for more flexibility.
*
* This method is also the easiest way to port from KDE3's KAction::setToolTip.
*
* @since 4.3
*/
void setHelpText(const QString& text);
/**
* Get the shortcut for this action.
*
* This is preferred over QAction::shortcut(), as it allows for multiple shortcuts
* per action. The first and second shortcut as reported by shortcuts() will be the
* primary and alternate shortcut of the shortcut returned.
*
* \param types the type of shortcut to return. Should both be specified, only the
* active shortcut will be returned. Defaults to the active shortcut, if one exists.
* \sa shortcuts()
*/
KShortcut shortcut(ShortcutTypes types = ActiveShortcut) const;
/**
* Set the shortcut for this action.
*
* This is preferred over QAction::setShortcut(), as it allows for multiple shortcuts
* per action.
*
* \param shortcut shortcut(s) to use for this action in its specified shortcutContext()
* \param type type of shortcut to be set: active shortcut,
* default shortcut, or both (the default).
*/
void setShortcut(const KShortcut& shortcut, ShortcutTypes type = ShortcutTypes(ActiveShortcut | DefaultShortcut));
/**
* \overload void setShortcut(const KShortcut& shortcut)
*
* Set the primary shortcut only for this action.
*
* This function is there to explicitly override QAction::setShortcut(const QKeySequence&).
* QAction::setShortcut() will bypass everything in KAction and may lead to unexpected behavior.
*
* \param shortcut shortcut(s) to use for this action in its specified shortcutContext()
* \param type type of shortcut to be set: active shortcut,
* default shortcut, or both (default argument value).
*/
void setShortcut(const QKeySequence& shortcut, ShortcutTypes type = ShortcutTypes(ActiveShortcut | DefaultShortcut));
/**
* \overload void setShortcuts(const QList\<QKeySequence\>& shortcuts).
*
* Set the shortcuts for this action.
*
* This function is there to explicitly override QAction::setShortcut(const QList\<QKeySequence\>&).
* QAction::setShortcuts() will bypass everything in KAction and may lead to unexpected behavior.
*
* \param shortcut shortcut(s) to use for this action in its specified shortcutContext()
* \param type type of shortcut to be set: active shortcut,
* default shortcut, or both (default argument value).
*/
void setShortcuts(const QList<QKeySequence>& shortcuts, ShortcutTypes type = ShortcutTypes(ActiveShortcut | DefaultShortcut));
/**
* Returns true if this action's shortcut is configurable.
*/
bool isShortcutConfigurable() const;
/**
* Indicate whether the user may configure the action's shortcut.
*
* \param configurable set to \e true if this shortcut may be configured by the user, otherwise \e false.
*/
void setShortcutConfigurable(bool configurable);
/**
* Get the global shortcut for this action, if one exists. Global shortcuts
* allow your actions to respond to accellerators independently of the focused window.
* Unlike regular shortcuts, the application's window does not need focus
* for them to be activated.
*
* \param type the type of shortcut to be returned. Should both be specified, only the
* active shortcut will be returned. Defaults to the active shortcut,
* if one exists.
*
* \sa KGlobalAccel
* \sa setGlobalShortcut()
*/
const KShortcut& globalShortcut(ShortcutTypes type = ActiveShortcut) const;
/**
* Assign a global shortcut for this action. Global shortcuts
* allow an action to respond to key shortcuts independently of the focused window,
* i.e. the action will trigger if the keys were pressed no matter where in the X session.
*
* The action must have a per main component unique
* objectName() to enable cross-application bookeeping. If the objectName() is empty this method will
* do nothing, otherwise the isGlobalShortcutEnabled() property will be set to true and the
* shortcut will be enabled.
* It is mandatory that the objectName() doesn't change once isGlobalshortcutEnabled()
* has become true.
*
* \note KActionCollection::insert(name, action) will set action's objectName to name so you often
* don't have to set an objectName explicitly.
*
* When an action, identified by main component name and objectName(), is assigned
* a global shortcut for the first time on a KDE installation the assignment will
* be saved. The shortcut will then be restored every time setGlobalShortcut() is
* called with @p loading == Autoloading.
*
* If you actually want to change the global shortcut you have to set
* @p loading to NoAutoloading. The new shortcut will be automatically saved again.
*
* \param shortcut global shortcut(s) to assign. Will be ignored unless \p loading is set to NoAutoloading or this is the first time ever you call this method (see above).
* \param type the type of shortcut to be set, whether the active shortcut, the default shortcut,
* or both (the default).
* \param loading if Autoloading, assign the global shortcut this action has previously had if any.
* That way user preferences and changes made to avoid clashes will be conserved.
* if NoAutoloading the given shortcut will be assigned without looking up old values.
* You should only do this if the user wants to change the shortcut or if you have
* another very good reason. Key combinations that clash with other shortcuts will be
* dropped.
*
* \note the default shortcut will never be influenced by autoloading - it will be set as given.
* \sa globalShortcut()
*/
void setGlobalShortcut(const KShortcut& shortcut, ShortcutTypes type =
ShortcutTypes(ActiveShortcut | DefaultShortcut),
GlobalShortcutLoading loading = Autoloading);
/**
* Returns true if this action is permitted to have a global shortcut.
* Defaults to false.
* Use isGlobalShortcutEnabled() instead.
*/
#ifndef KDE_NO_DEPRECATED
KDEUI_DEPRECATED bool globalShortcutAllowed() const;
#endif
/**
* Indicate whether the programmer and/or user may define a global shortcut for this action.
* Defaults to false. Note that calling setGlobalShortcut() turns this on automatically.
*
* \param allowed set to \e true if this action may have a global shortcut, otherwise \e false.
* \param loading if Autoloading, assign to this action the global shortcut it has previously had
* if any.
*/
#ifndef KDE_NO_DEPRECATED
KDEUI_DEPRECATED void setGlobalShortcutAllowed(bool allowed, GlobalShortcutLoading loading = Autoloading);
#endif
/**
* Returns true if this action is enabled to have a global shortcut.
* This will be respected by \class KGlobalShortcutsEditor.
* Defaults to false.
*/
bool isGlobalShortcutEnabled() const;
/**
* Sets the globalShortcutEnabled property to false and sets the global shortcut to an
* empty shortcut.
* This will also wipe out knowlegde about the existence of this action's global shortcut
* so it will not be considered anymore for shortcut conflict resolution. It will also not be
* visible anymore in the shortcuts KControl module.
* This method should not be used unless these effects are explicitly desired.
* @since 4.1
*/
void forgetGlobalShortcut();
KShapeGesture shapeGesture(ShortcutTypes type = ActiveShortcut) const;
KRockerGesture rockerGesture(ShortcutTypes type = ActiveShortcut) const;
void setShapeGesture(const KShapeGesture& gest, ShortcutTypes type = ShortcutTypes(ActiveShortcut | DefaultShortcut));
void setRockerGesture(const KRockerGesture& gest, ShortcutTypes type = ShortcutTypes(ActiveShortcut | DefaultShortcut));
/**
* Returns the action object associated with this action, or 0 if it does not have one
*
* @returns the KAuth::Action associated with this action.
*/
KAuth::Action *authAction() const;
/**
* Sets the action object associated with this action
*
* By setting a KAuth::Action, this action will become associated with it, and
* whenever it gets clicked, it will trigger the authorization and execution process
* for the action. The signal activated will also be emitted whenever the action gets
* clicked and the action gets authorized. Pass 0 to this function to disassociate the action
*
* @param action the KAuth::Action to associate with this action.
*/
void setAuthAction(KAuth::Action *action);
/**
* Sets the action object associated with this action
*
* Overloaded member to allow creating the action by name
*
* @param actionName the name of the action to associate
*/
void setAuthAction(const QString &actionName);
/**
* @reimp
*/
bool event(QEvent*);
Q_SIGNALS:
#ifdef KDE3_SUPPORT
/**
* Emitted when this action is activated
*
* \deprecated use triggered(bool checked) instead.
*/
QT_MOC_COMPAT void activated();
#endif
/**
* Emitted when the action is triggered. Also provides the state of the
* keyboard modifiers and mouse buttons at the time.
*/
void triggered(Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers);
/**
* Signal emitted when the action is triggered and authorized
*
* If the action needs authorization, when the user triggers the action,
* the authorization process automatically begins.
* If it succeeds, this signal is emitted. The KAuth::Action object is provided for convenience
* if you have multiple KAuthorizedAction objects, but of course it's always the same set with
* setAuthAction().
*
* WARNING: If your action needs authorization you should connect eventual slots processing
* stuff to this signal, and NOT triggered. Triggered will be emitted even if the user has not
* been authorized
*
* @param action The object set with setAuthAction()
*/
void authorized(KAuth::Action *action);
/**
* Emitted when the global shortcut is changed. A global shortcut is
* subject to be changed by the global shortcuts kcm.
*/
void globalShortcutChanged(const QKeySequence&);
private:
friend class KGlobalAccelPrivate; // Needs access to the component
friend class KActionCollectionPrivate; // Needs access to the component
friend class KShortcutsEditorDelegate; // Needs access to the component
Q_PRIVATE_SLOT(d, void slotTriggered())
Q_PRIVATE_SLOT(d, void authStatusChanged(int))
class KActionPrivate* const d;
friend class KActionPrivate;
friend class KGlobalShortcutTest;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(KAction::ShortcutTypes)
#endif
diff --git a/kdeui/actions/kaction_p.h b/kdeui/actions/kaction_p.h
index 26f2b77ed3..224a31c365 100644
--- a/kdeui/actions/kaction_p.h
+++ b/kdeui/actions/kaction_p.h
@@ -1,67 +1,67 @@
/* This file is part of the KDE libraries
Copyright (c) 2007 Tobias Koenig <tokoe@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.
*/
#ifndef KACTION_P_H
#define KACTION_P_H
#include "kglobalaccel.h"
#include "kgesturemap.h"
#include <kcomponentdata.h>
class KAction;
namespace KAuth {
class Action;
}
class KActionPrivate
{
public:
KActionPrivate()
: componentData(KGlobal::mainComponent()), globalShortcutEnabled(false), q(0), authAction(0)
{
}
void slotTriggered();
void authStatusChanged(int status);
void init(KAction *q_ptr);
void setActiveGlobalShortcutNoEnable(const KShortcut &cut);
void maybeSetComponentData(const KComponentData &kcd)
{
if (neverSetGlobalShortcut) {
componentData = kcd;
}
}
KComponentData componentData; //this is **way** more lightweight than it looks
KShortcut globalShortcut, defaultGlobalShortcut;
KShapeGesture shapeGesture, defaultShapeGesture;
KRockerGesture rockerGesture, defaultRockerGesture;
bool globalShortcutEnabled : 1;
bool neverSetGlobalShortcut : 1;
KAction *q;
KAuth::Action *authAction;
// TODO: Remove whenever QIcon overlays will get fixed
- KIcon oldIcon;
+ QIcon oldIcon;
};
#endif
diff --git a/kdeui/actions/kactionmenu.cpp b/kdeui/actions/kactionmenu.cpp
index 0bfd89332a..ef4c856349 100644
--- a/kdeui/actions/kactionmenu.cpp
+++ b/kdeui/actions/kactionmenu.cpp
@@ -1,177 +1,177 @@
/* 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 "kactionmenu.h"
#include <QToolButton>
#include <QToolBar>
#include <kdebug.h>
#include <klocale.h>
#include <kmenu.h>
class KActionMenuPrivate
{
public:
KActionMenuPrivate()
{
m_delayed = true;
m_stickyMenu = true;
}
~KActionMenuPrivate()
{
}
bool m_delayed;
bool m_stickyMenu;
};
KActionMenu::KActionMenu(QObject *parent)
: KAction(parent)
, d(new KActionMenuPrivate)
{
setShortcutConfigurable( false );
}
KActionMenu::KActionMenu(const QString &text, QObject *parent)
: KAction(parent)
, d(new KActionMenuPrivate)
{
setShortcutConfigurable( false );
setText(text);
}
-KActionMenu::KActionMenu(const KIcon & icon, const QString & text, QObject *parent)
+KActionMenu::KActionMenu(const QIcon & icon, const QString & text, QObject *parent)
: KAction(icon, text, parent)
, d(new KActionMenuPrivate)
{
setShortcutConfigurable( false );
}
KActionMenu::~KActionMenu()
{
delete d;
delete menu();
}
QWidget * KActionMenu::createWidget( QWidget * _parent )
{
QToolBar *parent = qobject_cast<QToolBar *>(_parent);
if (!parent)
return KAction::createWidget(_parent);
QToolButton* button = new QToolButton(parent);
button->setAutoRaise(true);
button->setFocusPolicy(Qt::NoFocus);
button->setIconSize(parent->iconSize());
button->setToolButtonStyle(parent->toolButtonStyle());
QObject::connect(parent, SIGNAL(iconSizeChanged(const QSize&)),
button, SLOT(setIconSize(const QSize&)));
QObject::connect(parent, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
button, SLOT(setToolButtonStyle(Qt::ToolButtonStyle)));
button->setDefaultAction(this);
QObject::connect(button, SIGNAL(triggered(QAction*)), parent, SIGNAL(actionTriggered(QAction*)));
if (delayed())
button->setPopupMode(QToolButton::DelayedPopup);
else if (stickyMenu())
button->setPopupMode(QToolButton::InstantPopup);
else
button->setPopupMode(QToolButton::MenuButtonPopup);
return button;
}
#ifndef KDE_NO_DEPRECATED
void KActionMenu::remove( KAction* cmd )
{
if ( cmd )
menu()->removeAction(cmd);
}
#endif
void KActionMenu::addAction( QAction * action )
{
menu()->addAction(action);
}
QAction* KActionMenu::addSeparator()
{
QAction* separator = new QAction(this);
separator->setSeparator(true);
addAction(separator);
return separator;
}
QAction* KActionMenu::insertSeparator(QAction* before)
{
QAction* separator = new QAction(this);
separator->setSeparator(true);
insertAction(before, separator);
return separator;
}
void KActionMenu::insertAction( QAction * before, QAction * action )
{
menu()->insertAction(before, action);
}
void KActionMenu::removeAction( QAction * action )
{
menu()->removeAction(action);
}
bool KActionMenu::delayed() const {
return d->m_delayed;
}
void KActionMenu::setDelayed(bool _delayed) {
d->m_delayed = _delayed;
}
bool KActionMenu::stickyMenu() const {
return d->m_stickyMenu;
}
void KActionMenu::setStickyMenu(bool sticky) {
d->m_stickyMenu = sticky;
}
KMenu* KActionMenu::menu()
{
if (!KAction::menu())
setMenu(new KMenu());
return qobject_cast<KMenu*>(KAction::menu());
}
void KActionMenu::setMenu(KMenu *menu)
{
KAction::setMenu( menu );
}
/* vim: et sw=2 ts=2
*/
diff --git a/kdeui/actions/kactionmenu.h b/kdeui/actions/kactionmenu.h
index 7e50d8b675..ef6c1b2c0a 100644
--- a/kdeui/actions/kactionmenu.h
+++ b/kdeui/actions/kactionmenu.h
@@ -1,135 +1,135 @@
/* 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) 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.
*/
#ifndef KACTIONMENU_H
#define KACTIONMENU_H
#include <kaction.h>
class KMenu;
/**
* A KActionMenu is an action that has several properties specific to holding a
* sub-menu of other actions.
*
* Any QAction can be used to create a submenu.
*
* Plugged in a popupmenu, it will create a submenu.
* Plugged in a toolbar, it will create a button with a popup menu.
*
* This is the action used by the XMLGUI since it holds other actions.
* If you want a submenu for selecting one tool among many (without icons), see KSelectAction.
* See also setDelayed about the main action.
*/
class KDEUI_EXPORT KActionMenu : public KAction
{
Q_OBJECT
Q_PROPERTY( bool delayed READ delayed WRITE setDelayed )
Q_PROPERTY( bool stickyMenu READ stickyMenu WRITE setStickyMenu )
public:
explicit KActionMenu(QObject *parent);
KActionMenu(const QString& text, QObject *parent);
- KActionMenu(const KIcon& icon, const QString& text, QObject *parent);
+ KActionMenu(const QIcon& icon, const QString& text, QObject *parent);
virtual ~KActionMenu();
/**
* @deprecated
*/
#ifndef KDE_NO_DEPRECATED
KDEUI_DEPRECATED void remove( KAction* );
#endif
void addAction(QAction* action);
QAction* addSeparator();
void insertAction(QAction* before, QAction* action);
QAction* insertSeparator(QAction* before);
void removeAction(QAction* action);
/**
* Returns this action's menu as a KMenu, if it is one.
* If none exists, one will be created.
* @deprecated use menu() instead.
*/
#ifndef KDE_NO_DEPRECATED
inline KDEUI_DEPRECATED KMenu* popupMenu() { return menu(); }
#endif
/**
* Returns this action's menu as a KMenu, if it is one.
* If none exists, one will be created.
*/
KMenu* menu();
/*
* Overload of QAction::setMenu to make sure a KMenu is passed
**/
void setMenu( KMenu *menu );
/**
* Returns true if this action creates a delayed popup menu
* when plugged in a KToolBar.
*/
bool delayed() const;
/**
* If set to true, this action will create a delayed popup menu
* when plugged in a KToolBar. Otherwise it creates a normal popup.
* Default: delayed
*
* Remember that if the "main" action (the toolbar button itself)
* cannot be clicked, then you should call setDelayed(false).
*
* In the other case, if the main action can be clicked, it can only happen
* in a toolbar: in a menu, the parent of a submenu can't be activated.
* To get a "normal" menu item when plugged a menu (and no submenu)
* use KToolBarPopupAction.
*/
void setDelayed(bool delayed);
/**
* Returns true if this action creates a sticky popup menu.
* @see setStickyMenu().
*/
bool stickyMenu() const;
/**
* If set to true, this action will create a sticky popup menu
* when plugged in a KToolBar.
* "Sticky", means it's visible until a selection is made or the mouse is
* clicked elsewhere. This feature allows you to make a selection without
* having to press and hold down the mouse while making a selection.
* Default: sticky.
*/
void setStickyMenu(bool sticky);
virtual QWidget* createWidget(QWidget* parent);
private:
class KActionMenuPrivate* const d;
};
#endif
diff --git a/kdeui/actions/kcodecaction.cpp b/kdeui/actions/kcodecaction.cpp
index 0befd0edaa..10547e1dbb 100644
--- a/kdeui/actions/kcodecaction.cpp
+++ b/kdeui/actions/kcodecaction.cpp
@@ -1,281 +1,281 @@
/*
kcodecaction.cpp
Copyright (c) 2003 Jason Keirstead <jason@keirstead.org>
Copyrigth (c) 2006 Michel Hermier <michel.hermier@gmail.com>
Copyright (c) 2007 Nick Shaforostoff <shafff@ukr.net>
********************************************************************
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* 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 Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the *
* Free Software Foundation, Inc., 51 Franklin Street, *
* Fifth Floor, Boston, MA 02110-1301 USA *
* *
********************************************************************
*/
#include "kcodecaction.h"
#include <kcharsets.h>
#include <kdebug.h>
#include <klocale.h>
#include <kglobal.h>
#include <QMenu>
#include <QVariant>
#include <QtCore/QTextCodec>
// Acording to http://www.iana.org/assignments/ianacharset-mib
// the default/unknown mib value is 2.
#define MIB_DEFAULT 2
class KCodecAction::Private
{
public:
Private(KCodecAction *parent)
: q(parent),
defaultAction(0),
currentSubAction(0)
{
}
void init(bool);
void _k_subActionTriggered(QAction*);
KCodecAction *q;
QAction *defaultAction;
QAction *currentSubAction;
};
KCodecAction::KCodecAction(QObject *parent,bool showAutoOptions)
: KSelectAction(parent)
, d(new Private(this))
{
d->init(showAutoOptions);
}
KCodecAction::KCodecAction(const QString &text, QObject *parent,bool showAutoOptions)
: KSelectAction(text, parent)
, d(new Private(this))
{
d->init(showAutoOptions);
}
-KCodecAction::KCodecAction(const KIcon &icon, const QString &text, QObject *parent,bool showAutoOptions)
+KCodecAction::KCodecAction(const QIcon &icon, const QString &text, QObject *parent,bool showAutoOptions)
: KSelectAction(icon, text, parent)
, d(new Private(this))
{
d->init(showAutoOptions);
}
KCodecAction::~KCodecAction()
{
delete d;
}
void KCodecAction::Private::init(bool showAutoOptions)
{
q->setToolBarMode(MenuMode);
defaultAction = q->addAction(i18nc("Encodings menu", "Default"));
int i;
foreach(const QStringList &encodingsForScript, KCharsets::charsets()->encodingsByScript())
{
KSelectAction* tmp = new KSelectAction(encodingsForScript.at(0),q);
if (showAutoOptions)
{
KEncodingDetector::AutoDetectScript scri=KEncodingDetector::scriptForName(encodingsForScript.at(0));
if (KEncodingDetector::hasAutoDetectionForScript(scri))
{
tmp->addAction(i18nc("Encodings menu","Autodetect"))->setData(QVariant((uint)scri));
tmp->menu()->addSeparator();
}
}
for (i=1; i<encodingsForScript.size(); ++i)
{
tmp->addAction(encodingsForScript.at(i));
}
q->connect(tmp,SIGNAL(triggered(QAction*)),q,SLOT(_k_subActionTriggered(QAction*)));
tmp->setCheckable(true);
q->addAction(tmp);
}
q->setCurrentItem(0);
}
int KCodecAction::mibForName(const QString &codecName, bool *ok) const
{
// FIXME logic is good but code is ugly
bool success = false;
int mib = MIB_DEFAULT;
KCharsets *charsets = KCharsets::charsets();
if (codecName == d->defaultAction->text())
success = true;
else
{
QTextCodec *codec = charsets->codecForName(codecName, success);
if (!success)
{
// Maybe we got a description name instead
codec = charsets->codecForName(charsets->encodingForName(codecName), success);
}
if (codec)
mib = codec->mibEnum();
}
if (ok)
*ok = success;
if (success)
return mib;
qWarning() << "Invalid codec name: " << codecName;
return MIB_DEFAULT;
}
QTextCodec *KCodecAction::codecForMib(int mib) const
{
if (mib == MIB_DEFAULT)
{
// FIXME offer to change the default codec
return QTextCodec::codecForLocale();
}
else
return QTextCodec::codecForMib(mib);
}
void KCodecAction::actionTriggered(QAction *action)
{
//we don't want to emit any signals from top-level items
//except for the default one
if (action==d->defaultAction)
{
emit triggered(KEncodingDetector::SemiautomaticDetection);
emit defaultItemTriggered();
}
}
void KCodecAction::Private::_k_subActionTriggered(QAction *action)
{
if (currentSubAction==action)
return;
currentSubAction=action;
bool ok = false;
int mib = q->mibForName(action->text(), &ok);
if (ok)
{
emit q->triggered(action->text());
emit q->triggered(q->codecForMib(mib));
}
else
{
if (!action->data().isNull())
emit q->triggered((KEncodingDetector::AutoDetectScript) action->data().toUInt());
}
}
QTextCodec *KCodecAction::currentCodec() const
{
return codecForMib(currentCodecMib());
}
bool KCodecAction::setCurrentCodec( QTextCodec *codec )
{
if (!codec)
return false;
int i,j;
for (i=0;i<actions().size();++i)
{
if (actions().at(i)->menu())
{
for (j=0;j<actions().at(i)->menu()->actions().size();++j)
{
if (!j && !actions().at(i)->menu()->actions().at(j)->data().isNull())
continue;
if (codec==KCharsets::charsets()->codecForName(actions().at(i)->menu()->actions().at(j)->text()))
{
d->currentSubAction=actions().at(i)->menu()->actions().at(j);
d->currentSubAction->trigger();
return true;
}
}
}
}
return false;
}
QString KCodecAction::currentCodecName() const
{
return d->currentSubAction->text();
}
bool KCodecAction::setCurrentCodec( const QString &codecName )
{
return setCurrentCodec(KCharsets::charsets()->codecForName(codecName));
}
int KCodecAction::currentCodecMib() const
{
return mibForName(currentCodecName());
}
bool KCodecAction::setCurrentCodec( int mib )
{
if (mib == MIB_DEFAULT)
return setCurrentAction(d->defaultAction);
else
return setCurrentCodec(codecForMib(mib));
}
KEncodingDetector::AutoDetectScript KCodecAction::currentAutoDetectScript() const
{
return d->currentSubAction->data().isNull()?
KEncodingDetector::None :
(KEncodingDetector::AutoDetectScript)d->currentSubAction->data().toUInt();
}
bool KCodecAction::setCurrentAutoDetectScript(KEncodingDetector::AutoDetectScript scri)
{
if (scri==KEncodingDetector::SemiautomaticDetection)
{
d->currentSubAction=d->defaultAction;
d->currentSubAction->trigger();
return true;
}
int i;
for (i=0;i<actions().size();++i)
{
if (actions().at(i)->menu())
{
if (!actions().at(i)->menu()->actions().isEmpty()
&&!actions().at(i)->menu()->actions().at(0)->data().isNull()
&&actions().at(i)->menu()->actions().at(0)->data().toUInt()==(uint)scri
)
{
d->currentSubAction=actions().at(i)->menu()->actions().at(0);
d->currentSubAction->trigger();
return true;
}
}
}
return false;
}
#include "moc_kcodecaction.cpp"
diff --git a/kdeui/actions/kcodecaction.h b/kdeui/actions/kcodecaction.h
index 53e0f819ad..627d7708eb 100644
--- a/kdeui/actions/kcodecaction.h
+++ b/kdeui/actions/kcodecaction.h
@@ -1,117 +1,117 @@
/*
kcodecaction.h
Copyright (c) 2003 Jason Keirstead <jason@keirstead.org>
Copyright (c) 2003-2006 Michel Hermier <michel.hermier@gmail.com>
Copyright (c) 2007 Nick Shaforostoff <shafff@ukr.net>
********************************************************************
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* 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 Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the *
* Free Software Foundation, Inc., 51 Franklin Street, *
* Fifth Floor, Boston, MA 02110-1301 USA *
* *
********************************************************************
*/
#ifndef KCODECACTION_H
#define KCODECACTION_H
#include <kencodingdetector.h>
#include <kselectaction.h>
/**
* @short Action for selecting one of several QTextCodec.
*
* This action shows up a submenu with a list of the available codecs on the system.
*/
class KDEUI_EXPORT KCodecAction
: public KSelectAction
{
Q_OBJECT
Q_PROPERTY(QString codecName READ currentCodecName WRITE setCurrentCodec)
Q_PROPERTY(int codecMib READ currentCodecMib)
public:
explicit KCodecAction(QObject *parent,bool showAutoOptions=false);
KCodecAction(const QString &text, QObject *parent,bool showAutoOptions=false);
- KCodecAction(const KIcon &icon, const QString &text, QObject *parent,bool showAutoOptions=false);
+ KCodecAction(const QIcon &icon, const QString &text, QObject *parent,bool showAutoOptions=false);
virtual ~KCodecAction();
public:
int mibForName(const QString &codecName, bool *ok = 0) const;
QTextCodec *codecForMib(int mib) const;
QTextCodec *currentCodec() const;
bool setCurrentCodec(QTextCodec *codec);
QString currentCodecName() const;
bool setCurrentCodec(const QString &codecName);
int currentCodecMib() const;
bool setCurrentCodec(int mib);
/**
* Applicable only if showAutoOptions in c'tor was true
*
* @returns KEncodingDetector::None if specific encoding is selected, not autodetection, otherwise... you know it!
*/
KEncodingDetector::AutoDetectScript currentAutoDetectScript() const;
/**
* Applicable only if showAutoOptions in c'tor was true
*
* KEncodingDetector::SemiautomaticDetection means 'Default' item
*/
bool setCurrentAutoDetectScript(KEncodingDetector::AutoDetectScript);
Q_SIGNALS:
/**
* Specific (proper) codec was selected
*
* Note that triggered(const QString&) is emitted too (as defined in KSelectAction)
*/
void triggered(QTextCodec *codec);
/**
* Autodetection has been selected.
* emits KEncodingDetector::SemiautomaticDetection if Default was selected.
*
* Applicable only if showAutoOptions in c'tor was true
*/
void triggered(KEncodingDetector::AutoDetectScript);
/**
* If showAutoOptions==true, then better handle triggered(KEncodingDetector::AutoDetectScript) signal
*/
void defaultItemTriggered();
protected Q_SLOTS:
virtual void actionTriggered(QAction*);
protected:
using KSelectAction::triggered;
private:
class Private;
Private* const d;
Q_PRIVATE_SLOT( d, void _k_subActionTriggered(QAction*) )
};
#endif
diff --git a/kdeui/actions/kdualaction_p.h b/kdeui/actions/kdualaction_p.h
index 01237fe394..04fd916909 100644
--- a/kdeui/actions/kdualaction_p.h
+++ b/kdeui/actions/kdualaction_p.h
@@ -1,69 +1,71 @@
/* This file is part of the KDE libraries
*
* Copyright (c) 2010 Aurélien Gâteau <agateau@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef KDUALACTION_P_H
#define KDUALACTION_P_H
+#include <kicon.h>
+
class KDualActionPrivate
{
public:
KDualAction *q;
KGuiItem items[2];
bool autoToggle;
bool isActive;
void init(KDualAction *q_ptr);
void updateFromCurrentState();
KGuiItem& item(bool active) { return active ? items[1] : items[0]; }
void slotTriggered();
void updatedItem(bool active)
{
if (active == isActive) {
updateFromCurrentState();
}
}
void setGuiItem(bool active, const KGuiItem &_item)
{
item(active) = _item;
updatedItem(active);
}
void setIcon(bool active, const QIcon &icon)
{
item(active).setIcon(KIcon(icon));
updatedItem(active);
}
void setText(bool active, const QString &text)
{
item(active).setText(text);
updatedItem(active);
}
void setToolTip(bool active, const QString &toolTip)
{
item(active).setToolTip(toolTip);
updatedItem(active);
}
};
#endif /* KDUALACTION_P_H */
diff --git a/kdeui/actions/kfontaction.cpp b/kdeui/actions/kfontaction.cpp
index 00763cacc2..be37ff1dd3 100644
--- a/kdeui/actions/kfontaction.cpp
+++ b/kdeui/actions/kfontaction.cpp
@@ -1,181 +1,181 @@
/* 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>
(C) 2007 Clarence Dang <dang@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 "kfontaction.h"
#include <QToolBar>
#include <kdebug.h>
#include <kfontdialog.h>
#include <kicon.h>
#include <klocale.h>
#include <kfontchooser.h>
#include <kfontcombobox.h>
class KFontAction::KFontActionPrivate
{
public:
KFontActionPrivate(KFontAction *parent)
: q(parent),
settingFont(0)
{
}
void _k_slotFontChanged(const QFont &font)
{
qDebug() << "KFontComboBox - slotFontChanged("
<< font.family() << ") settingFont=" << settingFont;
if (settingFont)
return;
q->setFont(font.family());
q->triggered(font.family());
qDebug() << "\tslotFontChanged done";
}
KFontAction *q;
int settingFont;
};
KFontAction::KFontAction(uint fontListCriteria, QObject *parent)
: KSelectAction(parent), d(new KFontActionPrivate(this))
{
QStringList list;
KFontChooser::getFontList( list, fontListCriteria );
KSelectAction::setItems( list );
setEditable( true );
}
KFontAction::KFontAction(QObject *parent)
: KSelectAction(parent), d(new KFontActionPrivate(this))
{
QStringList list;
KFontChooser::getFontList( list, 0 );
KSelectAction::setItems( list );
setEditable( true );
}
KFontAction::KFontAction(const QString & text, QObject *parent)
: KSelectAction(text, parent), d(new KFontActionPrivate(this))
{
QStringList list;
KFontChooser::getFontList( list, 0 );
KSelectAction::setItems( list );
setEditable( true );
}
-KFontAction::KFontAction(const KIcon &icon, const QString &text, QObject *parent)
+KFontAction::KFontAction(const QIcon &icon, const QString &text, QObject *parent)
: KSelectAction(icon, text, parent), d(new KFontActionPrivate(this))
{
QStringList list;
KFontChooser::getFontList( list, 0 );
KSelectAction::setItems( list );
setEditable( true );
}
KFontAction::~KFontAction()
{
delete d;
}
QString KFontAction::font() const
{
return currentText();
}
QWidget* KFontAction::createWidget(QWidget* parent)
{
qDebug() << "KFontAction::createWidget()";
#ifdef __GNUC__
#warning FIXME: items need to be converted
#endif
// This is the visual element on the screen. This method overrides
// the KSelectAction one, preventing KSelectAction from creating its
// regular KComboBox.
KFontComboBox *cb = new KFontComboBox( parent );
qDebug() << "\tset=" << font();
// Do this before connecting the signal so that nothing will fire.
cb->setCurrentFont( QFont( font().toLower() ) );
qDebug() << "\tspit back=" << cb->currentFont().family();
connect( cb, SIGNAL( currentFontChanged( const QFont & ) ), SLOT(_k_slotFontChanged( const QFont& ) ) );
cb->setMinimumWidth( cb->sizeHint().width() );
return cb;
}
/*
* Maintenance note: Keep in sync with KFontComboBox::setCurrentFont()
*/
void KFontAction::setFont( const QString &family )
{
qDebug() << "KFontAction::setFont(" << family << ")";
// Suppress triggered(QString) signal and prevent recursive call to ourself.
d->settingFont++;
foreach(QWidget *w, createdWidgets())
{
KFontComboBox *cb = qobject_cast<KFontComboBox *>(w);
qDebug() << "\tw=" << w << "cb=" << cb;
if(!cb) continue;
cb->setCurrentFont(QFont(family.toLower()));
qDebug() << "\t\tw spit back=" << cb->currentFont().family();
}
d->settingFont--;
qDebug() << "\tcalling setCurrentAction()";
QString lowerName = family.toLower();
if (setCurrentAction(lowerName, Qt::CaseInsensitive))
return;
int i = lowerName.indexOf(" [");
if (i > -1)
{
lowerName = lowerName.left(i);
i = 0;
if (setCurrentAction(lowerName, Qt::CaseInsensitive))
return;
}
lowerName += " [";
if (setCurrentAction(lowerName, Qt::CaseInsensitive))
return;
// TODO: Inconsistent state if KFontComboBox::setCurrentFont() succeeded
// but setCurrentAction() did not and vice-versa.
qDebug() << "Font not found " << family.toLower();
}
#include "moc_kfontaction.cpp"
diff --git a/kdeui/actions/kfontaction.h b/kdeui/actions/kfontaction.h
index 8eaab11424..90487263fd 100644
--- a/kdeui/actions/kfontaction.h
+++ b/kdeui/actions/kfontaction.h
@@ -1,61 +1,61 @@
/* 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) 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.
*/
#ifndef KFONTACTION_H
#define KFONTACTION_H
#include <kselectaction.h>
/**
* An action to select a font family.
* On a toolbar this will show a combobox with all the fonts on the system.
*/
class KDEUI_EXPORT KFontAction : public KSelectAction
{
Q_OBJECT
Q_PROPERTY( QString font READ font WRITE setFont )
public:
KFontAction(uint fontListCriteria, QObject *parent);
explicit KFontAction(QObject *parent);
KFontAction(const QString& text, QObject *parent);
- KFontAction(const KIcon &icon, const QString &text, QObject *parent);
+ KFontAction(const QIcon &icon, const QString &text, QObject *parent);
virtual ~KFontAction();
QString font() const;
void setFont( const QString &family );
virtual QWidget* createWidget(QWidget* parent);
private:
class KFontActionPrivate;
KFontActionPrivate * const d;
Q_PRIVATE_SLOT( d, void _k_slotFontChanged(const QFont&) )
};
#endif
diff --git a/kdeui/actions/kfontsizeaction.cpp b/kdeui/actions/kfontsizeaction.cpp
index 2e75348a36..0d74d2bd70 100644
--- a/kdeui/actions/kfontsizeaction.cpp
+++ b/kdeui/actions/kfontsizeaction.cpp
@@ -1,147 +1,147 @@
/* 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 "kfontsizeaction.h"
#include <QFontDatabase>
#include <QToolBar>
#include <QToolButton>
#include <kdebug.h>
#include <kicon.h>
#include <klocale.h>
#include "kmenu.h"
class KFontSizeAction::Private
{
public:
Private(KFontSizeAction *parent)
: q(parent)
{
}
void init();
KFontSizeAction *q;
};
// BEGIN KFontSizeAction
KFontSizeAction::KFontSizeAction(QObject *parent)
: KSelectAction(parent),
d(new Private(this))
{
d->init();
}
KFontSizeAction::KFontSizeAction(const QString &text, QObject *parent)
: KSelectAction(text, parent),
d(new Private(this))
{
d->init();
}
-KFontSizeAction::KFontSizeAction(const KIcon &icon, const QString &text, QObject *parent)
+KFontSizeAction::KFontSizeAction(const QIcon &icon, const QString &text, QObject *parent)
: KSelectAction(icon, text, parent),
d(new Private(this))
{
d->init();
}
KFontSizeAction::~KFontSizeAction()
{
delete d;
}
void KFontSizeAction::Private::init()
{
q->setEditable( true );
QFontDatabase fontDB;
const QList<int> sizes = fontDB.standardSizes();
QStringList lst;
for ( QList<int>::ConstIterator it = sizes.begin(); it != sizes.end(); ++it )
lst.append( QString::number( *it ) );
q->setItems( lst );
}
void KFontSizeAction::setFontSize( int size )
{
if ( size == fontSize() ) {
const QString test = QString::number( size );
Q_FOREACH(QAction* action, actions())
{
if (action->text() == test)
{
setCurrentAction(action);
return;
}
}
}
if ( size < 1 ) {
qWarning() << "KFontSizeAction: Size " << size << " is out of range";
return;
}
QAction* a = action( QString::number( size ) );
if ( !a ) {
// Insert at the correct position in the list (to keep sorting)
QList<int> lst;
// Convert to list of ints
QStringListIterator itemsIt( items() );
while ( itemsIt.hasNext() )
lst.append( itemsIt.next().toInt() );
// New size
lst.append( size );
// Sort the list
qSort( lst );
Q_FOREACH( int it, lst ) {
KAction* const action = addAction( QString::number(it) );
if (it == size)
setCurrentAction(action);
}
} else {
setCurrentAction( a );
}
}
int KFontSizeAction::fontSize() const
{
return currentText().toInt();
}
void KFontSizeAction::actionTriggered( QAction* action )
{
emit fontSizeChanged( action->text().toInt() );
KSelectAction::actionTriggered( action );
}
/* vim: et sw=2 ts=2
*/
diff --git a/kdeui/actions/kfontsizeaction.h b/kdeui/actions/kfontsizeaction.h
index f925c1a8ac..448a86a299 100644
--- a/kdeui/actions/kfontsizeaction.h
+++ b/kdeui/actions/kfontsizeaction.h
@@ -1,66 +1,66 @@
/* 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) 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.
*/
#ifndef KFONTSIZEACTION_H
#define KFONTSIZEACTION_H
#include <kselectaction.h>
/**
* An action to allow changing of the font size.
* This action will be shown as a combobox on a toolbar with a proper set of font sizes.
*/
class KDEUI_EXPORT KFontSizeAction : public KSelectAction
{
Q_OBJECT
Q_PROPERTY( int fontSize READ fontSize WRITE setFontSize )
public:
explicit KFontSizeAction(QObject *parent);
KFontSizeAction(const QString &text, QObject *parent);
- KFontSizeAction(const KIcon &icon, const QString &text, QObject *parent);
+ KFontSizeAction(const QIcon &icon, const QString &text, QObject *parent);
virtual ~KFontSizeAction();
int fontSize() const;
void setFontSize( int size );
Q_SIGNALS:
void fontSizeChanged( int );
protected Q_SLOTS:
/**
* This function is called whenever an action from the selections is triggered.
*/
virtual void actionTriggered(QAction* action);
private:
class Private;
Private* const d;
};
#endif
diff --git a/kdeui/actions/kpastetextaction.cpp b/kdeui/actions/kpastetextaction.cpp
index fb84dd8d1d..e94812e348 100644
--- a/kdeui/actions/kpastetextaction.cpp
+++ b/kdeui/actions/kpastetextaction.cpp
@@ -1,146 +1,146 @@
/* 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 "kpastetextaction.h"
#include <QClipboard>
#include <QtDBus/QtDBus>
#include <kapplication.h>
#include <kdebug.h>
#include <kicon.h>
#include <klocale.h>
#include "kmenu.h"
class KPasteTextActionPrivate
{
public:
KPasteTextActionPrivate(KPasteTextAction *parent)
: q(parent)
{
}
~KPasteTextActionPrivate()
{
delete m_popup;
}
void _k_menuAboutToShow();
void _k_slotTriggered(QAction*);
void init();
KPasteTextAction *q;
KMenu *m_popup;
bool m_mixedMode;
};
KPasteTextAction::KPasteTextAction(QObject *parent)
: KAction(parent), d(new KPasteTextActionPrivate(this))
{
d->init();
}
KPasteTextAction::KPasteTextAction(const QString &text, QObject *parent)
: KAction(parent), d(new KPasteTextActionPrivate(this))
{
d->init();
setText(text);
}
-KPasteTextAction::KPasteTextAction(const KIcon &icon, const QString &text, QObject *parent)
+KPasteTextAction::KPasteTextAction(const QIcon &icon, const QString &text, QObject *parent)
: KAction(icon, text, parent), d(new KPasteTextActionPrivate(this))
{
d->init();
}
void KPasteTextActionPrivate::init()
{
m_popup = new KMenu;
q->connect(m_popup, SIGNAL(aboutToShow()), q, SLOT(_k_menuAboutToShow()));
q->connect(m_popup, SIGNAL(triggered(QAction*)), q, SLOT(_k_slotTriggered(QAction*)));
m_mixedMode = true;
}
KPasteTextAction::~KPasteTextAction()
{
delete d;
}
void KPasteTextAction::setMixedMode(bool mode)
{
d->m_mixedMode = mode;
}
void KPasteTextActionPrivate::_k_menuAboutToShow()
{
m_popup->clear();
QStringList list;
QDBusInterface klipper("org.kde.klipper", "/klipper", "org.kde.klipper.klipper");
if (klipper.isValid()) {
QDBusReply<QStringList> reply = klipper.call("getClipboardHistoryMenu");
if (reply.isValid())
list = reply;
}
QString clipboardText = qApp->clipboard()->text(QClipboard::Clipboard);
if (list.isEmpty())
list << clipboardText;
bool found = false;
const QFontMetrics fm = m_popup->fontMetrics();
foreach (const QString& string, list)
{
QString text = fm.elidedText(string.simplified(), Qt::ElideMiddle, fm.maxWidth() * 20);
text.replace('&', "&&");
QAction* action = m_popup->addAction(text);
if (!found && string == clipboardText)
{
action->setChecked(true);
found = true;
}
}
}
void KPasteTextActionPrivate::_k_slotTriggered(QAction* action)
{
QDBusInterface klipper("org.kde.klipper", "/klipper", "org.kde.klipper.klipper");
if (klipper.isValid()) {
QDBusReply<QString> reply = klipper.call("getClipboardHistoryItem",
m_popup->actions().indexOf(action));
if (!reply.isValid())
return;
QString clipboardText = reply;
reply = klipper.call("setClipboardContents", clipboardText);
if (reply.isValid())
qDebug() << "Clipboard: " << qApp->clipboard()->text(QClipboard::Clipboard);
}
}
/* vim: et sw=2 ts=2
*/
#include "moc_kpastetextaction.cpp"
diff --git a/kdeui/actions/kpastetextaction.h b/kdeui/actions/kpastetextaction.h
index 80f059d8df..a38d1fe8f9 100644
--- a/kdeui/actions/kpastetextaction.h
+++ b/kdeui/actions/kpastetextaction.h
@@ -1,101 +1,101 @@
/* 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) 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.
*/
#ifndef KPASTETEXTACTION_H
#define KPASTETEXTACTION_H
#include <kaction.h>
class KPasteTextActionPrivate;
/**
* An action for pasting text from the clipboard.
* It's useful for text handling applications as
* when plugged into a toolbar it provides a menu
* with the clipboard history if klipper is running.
* If klipper is not running, the menu has only one
* item: the current clipboard content.
*/
class KDEUI_EXPORT KPasteTextAction: public KAction
{
Q_OBJECT
public:
/**
* Constructs an action with the specified parent.
*
* @param parent The parent of this action.
*/
explicit KPasteTextAction(QObject *parent);
/**
* Constructs an action with text; a shortcut may be specified by
* the ampersand character (e.g. \"&amp;Option\" creates a shortcut with key \e O )
*
* This is the most common KAction used when you do not have a
* corresponding icon (note that it won't appear in the current version
* of the "Edit ToolBar" dialog, because an action needs an icon to be
* plugged in a toolbar...).
*
* @param text The text that will be displayed.
* @param parent The parent of this action.
*/
KPasteTextAction(const QString &text, QObject *parent);
/**
* Constructs an action with text and an icon; a shortcut may be specified by
* the ampersand character (e.g. \"&amp;Option\" creates a shortcut with key \e O )
*
* This is the other common KAction used. Use it when you
* \e do have a corresponding icon.
*
* @param icon The icon to display.
* @param text The text that will be displayed.
* @param parent The parent of this action.
*/
- KPasteTextAction(const KIcon &icon, const QString &text, QObject *parent);
+ KPasteTextAction(const QIcon &icon, const QString &text, QObject *parent);
virtual ~KPasteTextAction();
/**
* Controls the behavior of the clipboard history menu popup.
*
* @param mode If false and the clipboard contains a non-text object
* the popup menu with the clipboard history will appear
* immediately as the user clicks the toolbar action; if
* true, the action works like the standard paste action
* even if the current clipboard object is not text.
* Default value is true.
*/
void setMixedMode(bool mode);
private:
KPasteTextActionPrivate * const d;
Q_PRIVATE_SLOT( d, void _k_menuAboutToShow() )
Q_PRIVATE_SLOT( d, void _k_slotTriggered(QAction*) )
};
#endif
diff --git a/kdeui/actions/krecentfilesaction.h b/kdeui/actions/krecentfilesaction.h
index 7486af8f7b..c67466bd17 100644
--- a/kdeui/actions/krecentfilesaction.h
+++ b/kdeui/actions/krecentfilesaction.h
@@ -1,189 +1,190 @@
/* 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) 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.
*/
#ifndef KRECENTFILESACTION_H
#define KRECENTFILESACTION_H
#include <kselectaction.h>
#include <kurl.h>
class KConfigGroup;
class KRecentFilesActionPrivate;
+class KIcon;
/**
* @short Recent files action
*
* This class is an action to handle a recent files submenu.
* The best way to create the action is to use KStandardAction::openRecent.
* Then you simply need to call loadEntries on startup, saveEntries
* on shutdown, addURL when your application loads/saves a file.
*
* @author Michael Koch
*/
class KDEUI_EXPORT KRecentFilesAction : public KSelectAction
{
Q_OBJECT
Q_PROPERTY( int maxItems READ maxItems WRITE setMaxItems )
Q_DECLARE_PRIVATE(KRecentFilesAction)
public:
/**
* Constructs an action with the specified parent.
*
* @param parent The parent of this action.
*/
explicit KRecentFilesAction(QObject *parent);
/**
* Constructs an action with text; a shortcut may be specified by
* the ampersand character (e.g. \"&amp;Option\" creates a shortcut with key \e O )
*
* This is the most common KAction used when you do not have a
* corresponding icon (note that it won't appear in the current version
* of the "Edit ToolBar" dialog, because an action needs an icon to be
* plugged in a toolbar...).
*
* @param text The text that will be displayed.
* @param parent The parent of this action.
*/
KRecentFilesAction(const QString &text, QObject *parent);
/**
* Constructs an action with text and an icon; a shortcut may be specified by
* the ampersand character (e.g. \"&amp;Option\" creates a shortcut with key \e O )
*
* This is the other common KAction used. Use it when you
* \e do have a corresponding icon.
*
* @param icon The icon to display.
* @param text The text that will be displayed.
* @param parent The parent of this action.
*/
KRecentFilesAction(const KIcon &icon, const QString &text, QObject *parent);
/**
* Destructor.
*/
virtual ~KRecentFilesAction();
/**
* Adds \a action to the list of URLs, with \a url and title \a name.
*
* Do not use addAction(QAction*), as no url will be associated, and
* consequently urlSelected() will not be emitted when \a action is selected.
*/
void addAction(QAction* action, const KUrl& url, const QString& name);
/**
* Reimplemented for internal reasons.
*/
virtual QAction* removeAction(QAction* action);
public Q_SLOTS:
/**
* Clears the recent files list.
* Note that there is also an action shown to the user for clearing the list.
*/
virtual void clear();
public:
/**
* Returns the maximum of items in the recent files list.
*/
int maxItems() const;
/**
* Sets the maximum of items in the recent files list.
* The default for this value is 10 set in the constructor.
*
* If this value is lesser than the number of items currently
* in the recent files list the last items are deleted until
* the number of items are equal to the new maximum.
*/
void setMaxItems( int maxItems );
/**
* Loads the recent files entries from a given KConfigGroup object.
* You can provide the name of the group used to load the entries.
* If the groupname is empty, entries are load from a group called 'RecentFiles'
*
*/
void loadEntries( const KConfigGroup &config );
/**
* Saves the current recent files entries to a given KConfigGroup object.
* You can provide the name of the group used to load the entries.
* If the groupname is empty, entries are saved to a group called 'RecentFiles'
*
*/
void saveEntries( const KConfigGroup &config );
/**
* Add URL to recent files list.
*
* @param url The URL of the file
* @param name The user visible pretty name that appears before the URL
*/
void addUrl( const KUrl& url, const QString& name = QString() );
/**
* Remove an URL from the recent files list.
*
* @param url The URL of the file
*/
void removeUrl( const KUrl& url );
/**
* Retrieve a list of all URLs in the recent files list.
*/
KUrl::List urls() const;
Q_SIGNALS:
/**
* This signal gets emitted when the user selects an URL.
*
* @param url The URL thats the user selected.
*/
void urlSelected( const KUrl& url );
/**
* This signal gets emitted when the user clear list.
* So when user store url in specific config file it can saveEntry.
* @since 4.3
*/
void recentListCleared();
private:
//Internal
void clearEntries();
// Don't warn about the virtual overload. As the comment of the other
// addAction() says, addAction( QAction* ) should not be used.
using KSelectAction::addAction;
Q_PRIVATE_SLOT( d_func(), void _k_urlSelected(QAction*) )
};
#endif
diff --git a/kdeui/actions/kselectaction.cpp b/kdeui/actions/kselectaction.cpp
index 3f380ce968..b59b581ad8 100644
--- a/kdeui/actions/kselectaction.cpp
+++ b/kdeui/actions/kselectaction.cpp
@@ -1,761 +1,761 @@
/* 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>
(C) 2006 Albert Astals Cid <aacid@kde.org>
(C) 2006 Clarence Dang <dang@kde.org>
(C) 2006 Michel Hermier <michel.hermier@gmail.com>
(C) 2007 Nick Shaforostoff <shafff@ukr.net>
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 "kselectaction.h"
#include "kselectaction_p.h"
#include <QActionEvent>
#include <QEvent>
#include <QToolButton>
#include <QToolBar>
#include <QStandardItem>
#include <kicon.h>
#include <klocale.h>
#include <kdebug.h>
#include "kcombobox.h"
#include "kmenu.h"
// QAction::setText("Hi") and then KPopupAccelManager exec'ing, causes
// QAction::text() to return "&Hi" :( Comboboxes don't have accels and
// display ampersands literally.
static QString DropAmpersands(const QString &text)
{
return KGlobal::locale()->removeAcceleratorMarker(text);
}
KSelectAction::KSelectAction(QObject *parent)
: KAction(parent)
, d_ptr(new KSelectActionPrivate())
{
Q_D(KSelectAction);
d->init(this);
}
KSelectAction::KSelectAction(const QString &text, QObject *parent)
: KAction(parent)
, d_ptr(new KSelectActionPrivate())
{
Q_D(KSelectAction);
d->init(this);
setText(text);
}
-KSelectAction::KSelectAction(const KIcon & icon, const QString &text, QObject *parent)
+KSelectAction::KSelectAction(const QIcon & icon, const QString &text, QObject *parent)
: KAction(icon, text, parent)
, d_ptr(new KSelectActionPrivate())
{
Q_D(KSelectAction);
d->init(this);
}
KSelectAction::KSelectAction(KSelectActionPrivate &dd, QObject *parent)
: KAction(parent)
, d_ptr(&dd)
{
Q_D(KSelectAction);
d->init(this);
}
KSelectAction::~KSelectAction()
{
delete d_ptr;
delete menu();
}
void KSelectActionPrivate::init(KSelectAction *q)
{
q_ptr = q;
QObject::connect(q_ptr->selectableActionGroup(), SIGNAL(triggered(QAction*)), q_ptr, SLOT(actionTriggered(QAction*)));
QObject::connect(q_ptr, SIGNAL(toggled(bool)), q_ptr, SLOT(slotToggled(bool)));
q_ptr->setMenu(new KMenu());
q_ptr->setEnabled( false );
}
QActionGroup * KSelectAction::selectableActionGroup( ) const
{
Q_D(const KSelectAction);
return d->m_actionGroup;
}
QList<QAction*> KSelectAction::actions( ) const
{
return selectableActionGroup()->actions();
}
QAction* KSelectAction::currentAction() const
{
return selectableActionGroup()->checkedAction();
}
int KSelectAction::currentItem() const
{
return selectableActionGroup()->actions().indexOf(currentAction());
}
QString KSelectAction::currentText( ) const
{
if (QAction* a = currentAction())
return ::DropAmpersands(a->text());
return QString();
}
bool KSelectAction::setCurrentAction(QAction* action)
{
//qDebug () << "KSelectAction::setCurrentAction(" << action << ")";
if (action) {
if (actions().contains(action)) {
if (action->isVisible() && action->isEnabled() && action->isCheckable()) {
action->setChecked(true);
if (isCheckable())
setChecked(true);
return true;
} else
qWarning() << "Action does not have the correct properties to be current:" << action->text();
} else
qWarning() << "Action does not belong to group:" << action->text();
return false;
}
if (currentAction())
currentAction()->setChecked(false);
return false;
}
bool KSelectAction::setCurrentItem( int index )
{
//qDebug () << "KSelectAction::setCurrentIndex(" << index << ")";
return setCurrentAction(action(index));
}
QAction * KSelectAction::action( int index ) const
{
if (index >= 0 && index < selectableActionGroup()->actions().count())
return selectableActionGroup()->actions().at(index);
return 0L;
}
QAction * KSelectAction::action( const QString & text, Qt::CaseSensitivity cs ) const
{
QString compare;
if (cs == Qt::CaseSensitive)
compare = text;
else
compare = text.toLower();
foreach (QAction* action, selectableActionGroup()->actions()) {
const QString text = ::DropAmpersands(action->text());
if (cs == Qt::CaseSensitive) {
if (text == compare) {
return action;
}
} else if (cs == Qt::CaseInsensitive) {
if (text.toLower() == compare) {
return action;
}
}
}
return 0L;
}
bool KSelectAction::setCurrentAction( const QString & text, Qt::CaseSensitivity cs)
{
//qDebug () << "KSelectAction::setCurrentAction(" << text << ",cs=" << cs << ")";
return setCurrentAction(action(text, cs));
}
void KSelectAction::setComboWidth( int width )
{
Q_D(KSelectAction);
if ( width < 0 )
return;
d->m_comboWidth = width;
foreach (KComboBox* box, d->m_comboBoxes)
box->setMaximumWidth(d->m_comboWidth);
emit changed();
}
void KSelectAction::setMaxComboViewCount( int n )
{
Q_D(KSelectAction);
d->m_maxComboViewCount = n;
foreach (KComboBox* box, d->m_comboBoxes)
if ( d->m_maxComboViewCount != -1 )
box->setMaxVisibleItems(d->m_maxComboViewCount);
else
// hardcoded qt default
box->setMaxVisibleItems(10);
emit changed();
}
void KSelectAction::addAction(QAction* action)
{
Q_D(KSelectAction);
//qDebug () << "KSelectAction::addAction(" << action << ")";
action->setActionGroup(selectableActionGroup());
// Re-Enable when an action is added
setEnabled(true);
// Keep in sync with createToolBarWidget()
foreach (QToolButton* button, d->m_buttons) {
button->setEnabled(true);
button->addAction(action);
}
foreach (KComboBox* comboBox, d->m_comboBoxes) {
comboBox->setEnabled(true);
comboBox->addAction(action);
}
menu()->addAction(action);
}
KAction* KSelectAction::addAction(const QString &text)
{
Q_D(KSelectAction);
KAction* newAction = new KAction(parent());
newAction->setText(text);
newAction->setCheckable( true );
newAction->setShortcutConfigurable(false);
if (!d->m_menuAccelsEnabled) {
newAction->setText(text);
newAction->setShortcut(QKeySequence());
}
addAction(newAction);
return newAction;
}
-KAction* KSelectAction::addAction(const KIcon& icon, const QString& text)
+KAction* KSelectAction::addAction(const QIcon& icon, const QString& text)
{
KAction* newAction = addAction(text);
newAction->setIcon(icon);
return newAction;
}
QAction* KSelectAction::removeAction(QAction* action)
{
Q_D(KSelectAction);
//qDebug () << "KSelectAction::removeAction(" << action << ")";
//int index = selectableActionGroup()->actions().indexOf(action);
//qDebug () << "\tindex=" << index;
// Removes the action from the group and sets its parent to null.
d->m_actionGroup->removeAction(action);
// Disable when no action is in the group
bool hasActions = selectableActionGroup()->actions().isEmpty();
setEnabled( !hasActions );
foreach (QToolButton* button, d->m_buttons) {
button->setEnabled( !hasActions );
button->removeAction(action);
}
foreach (KComboBox* comboBox, d->m_comboBoxes)
{
comboBox->setEnabled( !hasActions );
comboBox->removeAction(action);
}
menu()->removeAction(action);
return action;
}
void KSelectAction::actionTriggered(QAction* action)
{
// cache values so we don't need access to members in the action
// after we've done an emit()
const QString text = ::DropAmpersands(action->text());
const int index = selectableActionGroup()->actions().indexOf(action);
//qDebug () << "KSelectAction::actionTriggered(" << action << ") text=" << text
// << " index=" << index << " emitting triggered()" << endl;
if (isCheckable()) // if this is subsidiary of other KSelectAction-derived class
trigger(); // then imitate usual QAction behaviour so that other submenus (and their items) become unchecked
emit triggered(action);
emit triggered(index);
emit triggered(text);
}
QStringList KSelectAction::items() const
{
Q_D(const KSelectAction);
QStringList ret;
foreach (QAction* action, d->m_actionGroup->actions())
ret << ::DropAmpersands(action->text());
return ret;
}
void KSelectAction::changeItem( int index, const QString& text )
{
Q_D(KSelectAction);
if ( index < 0 || index >= actions().count() )
{
qWarning() << "KSelectAction::changeItem Index out of scope";
return;
}
actions()[index]->setText( d->makeMenuText( text ) );
}
void KSelectAction::setItems( const QStringList &lst )
{
Q_D(KSelectAction);
//qDebug () << "KSelectAction::setItems(" << lst << ")";
clear();
foreach (const QString& string, lst) {
if ( !string.isEmpty() ) {
addAction(string);
} else {
QAction* action = new QAction(this);
action->setSeparator(true);
addAction(action);
}
}
// Disable if empty and not editable
setEnabled( lst.count() > 0 || d->m_edit );
}
int KSelectAction::comboWidth() const
{
Q_D(const KSelectAction);
return d->m_comboWidth;
}
void KSelectAction::clear()
{
Q_D(KSelectAction);
//qDebug () << "KSelectAction::clear()";
// we need to delete the actions later since we may get a call to clear()
// from a method called due to a triggered(...) signal
const QList<QAction*> actions = d->m_actionGroup->actions();
for (int i = 0; i < actions.count(); ++i)
{
// deleteLater() only removes us from the actions() list (among
// other things) on the next entry into the event loop. Until then,
// e.g. action() and setCurrentItem() will be working on items
// that are supposed to have been deleted. So detach the action to
// prevent this from happening.
removeAction(actions[i]);
actions[i]->deleteLater();
}
}
void KSelectAction::removeAllActions( )
{
Q_D(KSelectAction);
while (d->m_actionGroup->actions().count())
removeAction(d->m_actionGroup->actions().first());
}
void KSelectAction::setEditable( bool edit )
{
Q_D(KSelectAction);
d->m_edit = edit;
foreach (KComboBox* comboBox, d->m_comboBoxes)
comboBox->setEditable(edit);
emit changed();
}
bool KSelectAction::isEditable() const
{
Q_D(const KSelectAction);
return d->m_edit;
}
void KSelectAction::slotToggled(bool checked)
{
//if (checked && selectableActionGroup()->checkedAction())
if (!checked && currentAction()) // other's submenu item has been selected
currentAction()->setChecked(false);
}
KSelectAction::ToolBarMode KSelectAction::toolBarMode() const
{
Q_D(const KSelectAction);
return d->m_toolBarMode;
}
void KSelectAction::setToolBarMode( ToolBarMode mode )
{
Q_D(KSelectAction);
d->m_toolBarMode = mode;
}
QToolButton::ToolButtonPopupMode KSelectAction::toolButtonPopupMode( ) const
{
Q_D(const KSelectAction);
return d->m_toolButtonPopupMode;
}
void KSelectAction::setToolButtonPopupMode( QToolButton::ToolButtonPopupMode mode )
{
Q_D(KSelectAction);
d->m_toolButtonPopupMode = mode;
}
void KSelectActionPrivate::_k_comboBoxDeleted(QObject* object)
{
foreach (KComboBox* comboBox, m_comboBoxes)
if (object == comboBox) {
m_comboBoxes.removeAll(static_cast<KComboBox*>(object));
break;
}
}
void KSelectActionPrivate::_k_comboBoxCurrentIndexChanged(int index)
{
Q_Q(KSelectAction);
//qDebug () << "KSelectActionPrivate::_k_comboBoxCurrentIndexChanged(" << index << ")";
KComboBox *triggeringCombo = qobject_cast <KComboBox *> (q->sender ());
QAction *a = q->action(index);
//qDebug () << "\ta=" << a;
if (a) {
//qDebug () << "\t\tsetting as current action";
a->trigger();
} else if (q->isEditable () &&
triggeringCombo && triggeringCombo->count () > 0 &&
index == triggeringCombo->count () - 1) {
// User must have added a new item by typing and pressing enter.
const QString newItemText = triggeringCombo->currentText ();
//qDebug () << "\t\tuser typed new item '" << newItemText << "'";
// Only 1 combobox contains this and it's not a proper action.
bool blocked = triggeringCombo->blockSignals (true);
triggeringCombo->removeItem (index);
triggeringCombo->blockSignals (blocked);
KAction *newAction = q->addAction (newItemText);
newAction->trigger();
} else {
if (q->selectableActionGroup()->checkedAction())
q->selectableActionGroup()->checkedAction()->setChecked(false);
}
}
// TODO: DropAmpersands() certainly makes sure this doesn't work. But I don't
// think it did anyway esp. in the presence KCheckAccelerator - Clarence.
void KSelectAction::setMenuAccelsEnabled( bool b )
{
Q_D(KSelectAction);
d->m_menuAccelsEnabled = b;
}
bool KSelectAction::menuAccelsEnabled() const
{
Q_D(const KSelectAction);
return d->m_menuAccelsEnabled;
}
QWidget * KSelectAction::createWidget( QWidget * parent )
{
Q_D(KSelectAction);
QMenu *menu = qobject_cast<QMenu *>(parent);
if (menu) // If used in a menu want to return 0 and use only the text, not a widget
return 0;
ToolBarMode mode = toolBarMode();
QToolBar *toolBar = qobject_cast<QToolBar *>(parent);
if (!toolBar && mode != ComboBoxMode) { // we can return a combobox just fine.
return 0;
}
switch (mode) {
case MenuMode: {
QToolButton* button = new QToolButton(toolBar);
button->setToolTip(toolTip());
button->setWhatsThis(whatsThis());
button->setStatusTip(statusTip());
button->setAutoRaise(true);
button->setFocusPolicy(Qt::NoFocus);
button->setIconSize(toolBar->iconSize());
button->setToolButtonStyle(toolBar->toolButtonStyle());
QObject::connect(toolBar, SIGNAL(iconSizeChanged(const QSize&)),
button, SLOT(setIconSize(const QSize&)));
QObject::connect(toolBar, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
button, SLOT(setToolButtonStyle(Qt::ToolButtonStyle)));
button->setDefaultAction(this);
QObject::connect(button, SIGNAL(triggered(QAction*)), toolBar, SIGNAL(actionTriggered(QAction*)));
button->setPopupMode(toolButtonPopupMode());
button->addActions(selectableActionGroup()->actions());
d->m_buttons.append(button);
return button;
}
case ComboBoxMode: {
KComboBox* comboBox = new KComboBox(parent);
comboBox->installEventFilter (this);
if ( d->m_maxComboViewCount != -1 )
comboBox->setMaxVisibleItems( d->m_maxComboViewCount );
if ( d->m_comboWidth > 0 )
comboBox->setMaximumWidth( d->m_comboWidth );
comboBox->setEditable(isEditable());
comboBox->setToolTip(toolTip());
comboBox->setWhatsThis(whatsThis());
comboBox->setStatusTip(statusTip());
foreach (QAction* action, selectableActionGroup()->actions())
comboBox->addAction(action);
if (selectableActionGroup()->actions().isEmpty())
comboBox->setEnabled(false);
connect(comboBox, SIGNAL(destroyed(QObject*)), SLOT(_k_comboBoxDeleted(QObject*)));
connect(comboBox, SIGNAL(currentIndexChanged(int)), SLOT(_k_comboBoxCurrentIndexChanged(int)));
d->m_comboBoxes.append(comboBox);
return comboBox;
}
}
return 0L;
}
void KSelectAction::deleteWidget(QWidget *widget)
{
Q_D(KSelectAction);
if (QToolButton *toolButton = qobject_cast<QToolButton *>(widget))
d->m_buttons.removeAll(toolButton);
else if (KComboBox *comboBox = qobject_cast<KComboBox *>(widget))
d->m_comboBoxes.removeAll(comboBox);
KAction::deleteWidget(widget);
}
bool KSelectAction::event(QEvent *event)
{
Q_D(KSelectAction);
if (event->type() == QEvent::ActionChanged) {
Q_FOREACH(KComboBox* comboBox, d->m_comboBoxes) {
comboBox->setToolTip(toolTip());
comboBox->setWhatsThis(whatsThis());
comboBox->setStatusTip(statusTip());
}
Q_FOREACH(QToolButton* toolButton, d->m_buttons) {
toolButton->setToolTip(toolTip());
toolButton->setWhatsThis(whatsThis());
toolButton->setStatusTip(statusTip());
}
}
return KAction::event(event);
}
// KSelectAction::eventFilter() is called before action->setChecked()
// invokes the signal to update QActionGroup so KSelectAction::currentItem()
// returns an old value. There are 3 possibilities, where n actions will
// report QAction::isChecked() where n is:
//
// 0: the checked action was unchecked
// 1: the checked action did not change
// 2: another action was checked but QActionGroup has not been invoked yet
// to uncheck the one that was checked before
//
// TODO: we might want to cache this since QEvent::ActionChanged is fired
// often.
static int TrueCurrentItem (KSelectAction *sa)
{
QAction *curAction = sa->currentAction ();
//qDebug () << "\tTrueCurrentItem(" << sa << ") curAction=" << curAction;
foreach (QAction *action, sa->actions ())
{
if (action->isChecked ())
{
//qDebug () << "\t\taction " << action << " (text=" << action->text () << ") isChecked";
// 2 actions checked case?
if (action != curAction)
{
//qDebug () << "\t\t\tmust be newly selected one";
return sa->actions ().indexOf (action);
}
}
}
//qDebug () << "\t\tcurrent action still selected? " << (curAction && curAction->isChecked ());
// 1 or 0 actions checked case (in that order)?
return (curAction && curAction->isChecked ()) ? sa->actions ().indexOf (curAction) : -1;
}
// We store the QAction* as the userData of each combobox item
Q_DECLARE_METATYPE(QAction*)
bool KSelectAction::eventFilter (QObject *watched, QEvent *event)
{
KComboBox *comboBox = qobject_cast <KComboBox *> (watched);
if (!comboBox)
return false/*propagate event*/;
// If focus is lost, replace any edited text with the currently selected
// item.
if (event->type () == QEvent::FocusOut) {
QFocusEvent * const e = static_cast <QFocusEvent *> (event);
//qDebug () << "KSelectAction::eventFilter(FocusOut)"
// << " comboBox: ptr=" << comboBox
// << " reason=" << e->reason ()
// << endl;
if (e->reason () != Qt::ActiveWindowFocusReason/*switch window*/ &&
e->reason () != Qt::PopupFocusReason/*menu*/ &&
e->reason () != Qt::OtherFocusReason/*inconsistently reproduceable actions...*/) {
//qDebug () << "\tkilling text";
comboBox->setEditText (comboBox->itemText (comboBox->currentIndex ()));
}
return false/*propagate event*/;
}
bool blocked = comboBox->blockSignals (true);
if (event->type () == QEvent::ActionAdded)
{
QActionEvent * const e = static_cast <QActionEvent *> (event);
const int index = e->before () ?
comboBox->findData (QVariant::fromValue (e->before ())) :
comboBox->count ();
const int newItem = ::TrueCurrentItem (this);
//qDebug () << "KSelectAction::eventFilter(ActionAdded)"
// << " comboBox: ptr=" << comboBox
// << " currentItem=" << comboBox->currentIndex ()
// << " add index=" << index
// << " action new: e->before=" << e->before ()
// << " ptr=" << e->action ()
// << " icon=" << e->action ()->icon ()
// << " text=" << e->action ()->text ()
// << " currentItem=" << newItem
// << endl;
comboBox->insertItem (index,
e->action()->icon(),
::DropAmpersands (e->action()->text()),
QVariant::fromValue (e->action ()));
if (QStandardItemModel *model = qobject_cast<QStandardItemModel *>(comboBox->model())) {
QStandardItem *item = model->item(index);
item->setEnabled(e->action()->isEnabled());
}
// Inserting an item into a combobox can change the current item so
// make sure the item corresponding to the checked action is selected.
comboBox->setCurrentIndex (newItem);
}
else if (event->type () == QEvent::ActionChanged)
{
QActionEvent * const e = static_cast <QActionEvent *> (event);
const int index = comboBox->findData (QVariant::fromValue (e->action ()));
const int newItem = ::TrueCurrentItem (this);
//qDebug () << "KSelectAction::eventFilter(ActionChanged)"
// << " comboBox: ptr=" << comboBox
// << " currentItem=" << comboBox->currentIndex ()
// << " changed action's index=" << index
// << " action new: ptr=" << e->action ()
// << " icon=" << e->action ()->icon ()
// << " text=" << e->action ()->text ()
// << " currentItem=" << newItem
// << endl;
comboBox->setItemIcon (index, e->action ()->icon ());
comboBox->setItemText (index, ::DropAmpersands (e->action ()->text ()));
if (QStandardItemModel *model = qobject_cast<QStandardItemModel *>(comboBox->model())) {
QStandardItem *item = model->item(index);
item->setEnabled(e->action()->isEnabled());
}
// The checked action may have become unchecked so
// make sure the item corresponding to the checked action is selected.
comboBox->setCurrentIndex (newItem);
}
else if (event->type () == QEvent::ActionRemoved)
{
QActionEvent * const e = static_cast <QActionEvent *> (event);
const int index = comboBox->findData (QVariant::fromValue (e->action ()));
const int newItem = ::TrueCurrentItem (this);
//qDebug () << "KSelectAction::eventFilter(ActionRemoved)"
// << " comboBox: ptr=" << comboBox
// << " currentItem=" << comboBox->currentIndex ()
// << " delete action index=" << index
// << " new: currentItem=" << newItem
// << endl;
comboBox->removeItem (index);
// Removing an item from a combobox can change the current item so
// make sure the item corresponding to the checked action is selected.
comboBox->setCurrentIndex (newItem);
}
comboBox->blockSignals (blocked);
return false/*propagate event*/;
}
// END
/* vim: et sw=2 ts=2
*/
#include "moc_kselectaction.cpp"
diff --git a/kdeui/actions/kselectaction.h b/kdeui/actions/kselectaction.h
index d4f286bf9c..c0995a0f54 100644
--- a/kdeui/actions/kselectaction.h
+++ b/kdeui/actions/kselectaction.h
@@ -1,383 +1,383 @@
/* 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) 2003 Andras Mantia <amantia@kde.org>
(C) 2005-2006 Hamish Rodda <rodda@kde.org>
(C) 2006 Albert Astals Cid <aacid@kde.org>
(C) 2006 Clarence Dang <dang@kde.org>
(C) 2006 Michel Hermier <michel.hermier@gmail.com>
(C) 2007 Nick Shaforostoff <shafff@ukr.net>
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.
*/
#ifndef KSELECTACTION_H
#define KSELECTACTION_H
#include <QToolButton>
#include <kaction.h>
class KSelectActionPrivate;
/**
* @short Action for selecting one of several items
*
* Action for selecting one of several items.
*
* This action shows up a submenu with a list of items.
* One of them can be checked. If the user clicks on an item
* this item will automatically be checked,
* the formerly checked item becomes unchecked.
* There can be only one item checked at a time.
*/
class KDEUI_EXPORT KSelectAction : public KAction
{
Q_OBJECT
Q_PROPERTY( QAction* currentAction READ currentAction WRITE setCurrentAction )
Q_PROPERTY( bool editable READ isEditable WRITE setEditable )
Q_PROPERTY( int comboWidth READ comboWidth WRITE setComboWidth )
Q_PROPERTY( QString currentText READ currentText )
Q_ENUMS( ToolbarMode )
Q_PROPERTY( ToolBarMode toolBarMode READ toolBarMode WRITE setToolBarMode )
Q_PROPERTY( QToolButton::ToolButtonPopupMode toolButtonPopupMode READ toolButtonPopupMode WRITE setToolButtonPopupMode )
Q_PROPERTY( int currentItem READ currentItem WRITE setCurrentItem )
Q_PROPERTY( QStringList items READ items WRITE setItems )
Q_DECLARE_PRIVATE(KSelectAction)
public:
/**
* Constructs a selection action with the specified parent.
*
* @param parent The action's parent object.
*/
explicit KSelectAction(QObject *parent);
/**
* Constructs a selection action with text; a shortcut may be specified by
* the ampersand character (e.g. \"&amp;Option\" creates a shortcut with key \e O )
*
* This is the most common KSelectAction used when you do not have a
* corresponding icon (note that it won't appear in the current version
* of the "Edit ToolBar" dialog, because an action needs an icon to be
* plugged in a toolbar...).
*
* @param text The text that will be displayed.
* @param parent The action's parent object.
*/
KSelectAction(const QString& text, QObject *parent);
/**
* Constructs a selection action with text and an icon; a shortcut may be specified by
* the ampersand character (e.g. \"&amp;Option\" creates a shortcut with key \e O )
*
* This is the other common KSelectAction used. Use it when you
* \e do have a corresponding icon.
*
* @param icon The icon to display.
* @param text The text that will be displayed.
* @param parent The action's parent object.
*/
- KSelectAction(const KIcon& icon, const QString& text, QObject *parent);
+ KSelectAction(const QIcon& icon, const QString& text, QObject *parent);
/**
* Destructor
*/
virtual ~KSelectAction();
enum ToolBarMode {
/// Creates a button which pops up a menu when interacted with, as defined by toolButtonPopupMode().
MenuMode,
/// Creates a combo box which contains the actions.
/// This is the default.
ComboBoxMode
};
/**
* Returns which type of widget (combo box or button with drop-down menu) will be inserted
* in a toolbar.
*/
ToolBarMode toolBarMode() const;
/**
* Set the type of widget to be inserted in a toolbar to \a mode.
*/
void setToolBarMode(ToolBarMode mode);
/**
* Returns the style for the list of actions, when this action is plugged
* into a KToolBar. The default value is QToolButton::InstantPopup
*
* \sa QToolButton::setPopupMode()
*/
QToolButton::ToolButtonPopupMode toolButtonPopupMode() const;
/**
* Set how this list of actions should behave when in popup mode and plugged into a toolbar.
*/
void setToolButtonPopupMode(QToolButton::ToolButtonPopupMode mode);
/**
* The action group used to create exclusivity between the actions associated with this action.
*/
QActionGroup* selectableActionGroup() const;
/**
* Returns the current QAction.
* @see setCurrentAction
*/
QAction* currentAction() const;
/**
* Returns the index of the current item.
*
* @sa currentItem and currentAction
*/
int currentItem() const;
/**
* Returns the text of the currently selected item.
*
* @sa currentItem and currentAction
*/
QString currentText() const;
/**
* Returns the list of selectable actions
*/
QList<QAction*> actions() const;
/**
* Returns the action at \a index, if one exists.
*/
QAction* action(int index) const;
/**
* Searches for an action with the specified \a text, using a search whose
* case sensitivity is defined by \a cs.
*/
QAction* action(const QString& text, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
/**
* Sets the currently checked item.
*
* @param action the QAction to become the currently checked item.
*
* \return \e true if a corresponding action was found and successfully checked.
*/
bool setCurrentAction(QAction* action);
/**
* \overload setCurrentAction(QAction*)
*
* Convenience function to set the currently checked action to be the action
* at index \p index.
*
* If there is no action at that index, the currently checked action (if any) will
* be deselected.
*
* \return \e true if a corresponding action was found and thus set to the current action, otherwise \e false
*/
bool setCurrentItem(int index);
/**
* \overload setCurrentAction(QAction*)
*
* Convenience function to set the currently checked action to be the action
* which has \p text as its text().
*
* If there is no action at that index, the currently checked action (if any) will
* be deselected.
*
* \return \e true if a corresponding action was found, otherwise \e false
*/
bool setCurrentAction(const QString& text, Qt::CaseSensitivity cs = Qt::CaseSensitive);
/**
* Add \a action to the list of selectable actions.
*/
virtual void addAction(QAction* action);
/**
* \overload addAction(QAction* action)
*
* Convenience function which creates an action from \a text and inserts it into
* the list of selectable actions.
*
* The newly created action is checkable and not user configurable.
*/
KAction* addAction(const QString& text);
/**
* \overload addAction(QAction* action)
*
* Convenience function which creates an action from \a text and \a icon and inserts it into
* the list of selectable actions.
*
* The newly created action is checkable and not user configurable.
*/
- KAction* addAction(const KIcon& icon, const QString& text);
+ KAction* addAction(const QIcon& icon, const QString& text);
/**
* Remove the specified \a action from this action selector.
*
* You take ownership here, so save or delete it in order to not leak the action.
*/
virtual QAction* removeAction(QAction* action);
/**
* Convenience function to create the list of selectable items.
* Any previously existing items will be cleared.
*/
void setItems( const QStringList &lst );
/**
* Convenience function which returns the items that can be selected with this action.
* It is the same as iterating selectableActionGroup()->actions() and looking at each
* action's text().
*/
QStringList items() const;
/**
* When this action is plugged into a toolbar, it creates a combobox.
* @return true if the combo editable.
*/
bool isEditable() const;
/**
* When this action is plugged into a toolbar, it creates a combobox.
* This makes the combo editable or read-only.
*/
void setEditable( bool );
/**
* When this action is plugged into a toolbar, it creates a combobox.
* This returns the maximum width set by setComboWidth
*/
int comboWidth() const;
/**
* When this action is plugged into a toolbar, it creates a combobox.
* This gives a _maximum_ size to the combobox.
* The minimum size is automatically given by the contents (the items).
*/
void setComboWidth( int width );
/**
* Sets the maximum items that are visible at once if the action
* is a combobox, that is the number of items in the combobox's viewport
*/
void setMaxComboViewCount( int n );
/**
* Clears up all the items in this action.
* \warning The actions will be deleted for backwards compatibility with KDE3.
* If you just want to remove all actions, use removeAllActions()
*/
void clear();
void removeAllActions();
/**
* Sets whether any occurrence of the ampersand character ( &amp; ) in items
* should be interpreted as keyboard accelerator for items displayed in a
* menu or not. Only applies to (overloaded) methods dealing with QStrings,
* not those dealing with QActions.
*
* Defaults to true.
*
* \param b true if ampersands indicate a keyboard accelerator, otherwise false.
*/
void setMenuAccelsEnabled( bool b );
/**
* Returns whether ampersands passed to methods using QStrings are interpreted
* as keyboard accelerator indicators or as literal ampersands.
*/
bool menuAccelsEnabled() const;
/**
* Changes the text of item @param index to @param text .
*/
void changeItem( int index, const QString& text );
Q_SIGNALS:
/**
* This signal is emitted when an item is selected; @param action
* indicates the item selected.
*/
void triggered( QAction* action );
/**
* This signal is emitted when an item is selected; @param index indicates
* the item selected.
*/
void triggered( int index );
/**
* This signal is emitted when an item is selected; @param text indicates
* the item selected.
*/
void triggered( const QString& text );
protected Q_SLOTS:
/**
* This function is called whenever an action from the selections is triggered.
*/
virtual void actionTriggered(QAction* action);
/**
* For structured menu building. Deselects all items if the action was unchecked by the top menu
*/
void slotToggled(bool);
protected:
/**
* Reimplemented from @see QWidgetAction.
*/
virtual QWidget *createWidget(QWidget *parent);
/**
* Reimplemented from @see QWidgetAction.
*/
virtual void deleteWidget(QWidget *widget);
virtual bool event(QEvent *event);
virtual bool eventFilter (QObject *watched, QEvent *event);
/**
* @internal
* Creates a new KSelectAction object.
*
* @param dd the private d member
* @param parent The action's parent object.
*/
KSelectAction(KSelectActionPrivate &dd, QObject *parent);
KSelectActionPrivate *d_ptr;
private:
Q_PRIVATE_SLOT( d_func(), void _k_comboBoxDeleted(QObject*) )
Q_PRIVATE_SLOT( d_func(), void _k_comboBoxCurrentIndexChanged(int) )
};
#endif
diff --git a/kdeui/actions/kstandardaction.cpp b/kdeui/actions/kstandardaction.cpp
index 7e006fd563..d227f024c9 100644
--- a/kdeui/actions/kstandardaction.cpp
+++ b/kdeui/actions/kstandardaction.cpp
@@ -1,632 +1,632 @@
// vim: sw=2 et
/* This file is part of the KDE libraries
Copyright (C) 1999,2000 Kurt Granroth <granroth@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 "kstandardaction.h"
#include "kstandardaction_p.h"
#include "moc_kstandardaction_p.cpp"
#include <QtCore/QMutableStringListIterator>
#include <QToolButton>
#include <kaboutdata.h>
#include <kaction.h>
#include <QApplication>
#include <kcomponentdata.h>
#include <kdebug.h>
#include <kglobal.h>
#include <kguiitem.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kstandardshortcut.h>
#include <kmainwindow.h>
#include <kicon.h>
#include "kdualaction.h"
#include "krecentfilesaction.h"
#include "ktogglefullscreenaction.h"
#include "kpastetextaction.h"
#include "kactioncollection.h"
namespace KStandardAction
{
-AutomaticAction::AutomaticAction(const KIcon &icon, const QString &text, const KShortcut &shortcut, const char *slot,
+AutomaticAction::AutomaticAction(const QIcon &icon, const QString &text, const KShortcut &shortcut, const char *slot,
QObject *parent)
: KAction(parent)
{
setText(text);
setIcon(icon);
setShortcut(shortcut);
connect(this, SIGNAL(triggered()), this, slot);
}
QStringList stdNames()
{
return internal_stdNames();
}
QList<StandardAction> actionIds()
{
QList<StandardAction> result;
for ( uint i = 0; g_rgActionInfo[i].id != ActionNone; i++ )
{
result.append(g_rgActionInfo[i].id);
}
return result;
}
KDEUI_EXPORT KStandardShortcut::StandardShortcut shortcutForActionId(StandardAction id)
{
const KStandardActionInfo* pInfo = infoPtr( id );
return (pInfo) ? pInfo->idAccel : KStandardShortcut::AccelNone;
}
KAction *create(StandardAction id, const QObject *recvr, const char *slot, QObject *parent)
{
KAction *pAction = 0;
const KStandardActionInfo* pInfo = infoPtr(id);
// qDebug(125) << "KStandardAction::create( " << id << "=" << (pInfo ? pInfo->psName : (const char*)0) << ", " << parent << " )"; // ellis
if ( pInfo ) {
QString sLabel, iconName = pInfo->psIconName;
switch( id ) {
case Back:
sLabel = i18nc( "go back", "&Back");
if ( QApplication::isRightToLeft() )
iconName = "go-next";
break;
case Forward:
sLabel = i18nc( "go forward", "&Forward" );
if ( QApplication::isRightToLeft() )
iconName = "go-previous";
break;
case Home:
sLabel = i18nc( "home page", "&Home" );
break;
case Help:
sLabel = i18nc( "show help", "&Help" );
break;
case Preferences:
case AboutApp:
case HelpContents:
{
const KAboutData *aboutData = KGlobal::mainComponent().aboutData();
/* TODO KDE4
const KAboutData *aboutData;
if ( parent )
aboutData = parent->componentData().aboutData();
else
aboutData = KGlobal::aboutData();
*/
QString appName = (aboutData) ? aboutData->programName() : qApp->applicationName();
sLabel = i18n( pInfo->psLabel, appName );
}
break;
default:
sLabel = i18n( pInfo->psLabel );
}
if ( QApplication::isRightToLeft() ) {
switch ( id ) {
case Prior: iconName = "go-next-view-page"; break;
case Next: iconName = "go-previous-view-page"; break;
case FirstPage: iconName = "go-last-view-page"; break;
case LastPage: iconName = "go-first-view-page"; break;
case DocumentBack: iconName = "go-next"; break;
case DocumentForward: iconName = "go-previous"; break;
default: break;
}
}
QIcon icon = iconName.isEmpty() ? KIcon() : KIcon(iconName);
switch ( id ) {
case OpenRecent:
pAction = new KRecentFilesAction(parent);
break;
case ShowMenubar:
case ShowToolbar:
case ShowStatusbar:
pAction = new KAction(parent);
pAction->setCheckable(true);
pAction->setChecked(true);
break;
case FullScreen:
pAction = new KToggleFullScreenAction(parent);
pAction->setCheckable(true);
break;
case PasteText:
pAction = new KPasteTextAction(parent);
break;
// Same as default, but with the app icon
case AboutApp:
pAction = new KAction(parent);
icon = qApp->windowIcon();
break;
default:
pAction = new KAction(parent);
break;
}
switch ( id ) {
case Quit:
pAction->setMenuRole(QAction::QuitRole);
break;
case Preferences:
pAction->setMenuRole(QAction::PreferencesRole);
break;
case AboutApp:
pAction->setMenuRole(QAction::AboutRole);
break;
default:
pAction->setMenuRole(QAction::NoRole);
break;
}
pAction->setText(sLabel);
pAction->setIcon(icon);
KShortcut cut = KStandardShortcut::shortcut(pInfo->idAccel);
if (!cut.isEmpty())
pAction->setShortcut(cut);
pAction->setObjectName(pInfo->psName);
}
if (recvr && slot) {
if (id == OpenRecent) {
// FIXME KAction port: probably a good idea to find a cleaner way to do this
// Open Recent is a special case - provide the selected URL
QObject::connect(pAction, SIGNAL(urlSelected(const KUrl &)), recvr, slot);
} else if (id == ConfigureToolbars) { // #200815
QObject::connect(pAction, SIGNAL(triggered(bool)), recvr, slot, Qt::QueuedConnection);
} else {
QObject::connect(pAction, SIGNAL(triggered(bool)), recvr, slot);
}
}
KActionCollection *collection = qobject_cast<KActionCollection *>(parent);
if (pAction && collection)
collection->addAction(pAction->objectName(), pAction);
return pAction;
}
const char* name( StandardAction id )
{
const KStandardActionInfo* pInfo = infoPtr( id );
return (pInfo) ? pInfo->psName : 0;
}
KAction *openNew(const QObject *recvr, const char *slot, QObject *parent)
{
return KStandardAction::create(New, recvr, slot, parent);
}
KAction *open(const QObject *recvr, const char *slot, QObject *parent)
{
return KStandardAction::create(Open, recvr, slot, parent);
}
KRecentFilesAction *openRecent(const QObject *recvr, const char *slot, QObject *parent)
{
return (KRecentFilesAction*) KStandardAction::create( OpenRecent, recvr, slot, parent );
}
KAction *save(const QObject *recvr, const char *slot, QObject *parent)
{
return KStandardAction::create(Save, recvr, slot, parent);
}
KAction *saveAs(const QObject *recvr, const char *slot, QObject *parent)
{
return KStandardAction::create(SaveAs, recvr, slot, parent);
}
KAction *revert(const QObject *recvr, const char *slot, QObject *parent)
{
return KStandardAction::create(Revert, recvr, slot, parent);
}
KAction *print(const QObject *recvr, const char *slot, QObject *parent)
{
return KStandardAction::create(Print, recvr, slot, parent);
}
KAction *printPreview( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( PrintPreview, recvr, slot, parent );
}
KAction *close( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Close, recvr, slot, parent );
}
KAction *mail( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Mail, recvr, slot, parent );
}
KAction *quit( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Quit, recvr, slot, parent );
}
KAction *undo( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Undo, recvr, slot, parent );
}
KAction *redo( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Redo, recvr, slot, parent );
}
KAction *cut( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Cut, recvr, slot, parent );
}
KAction *copy( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Copy, recvr, slot, parent );
}
KAction *paste( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Paste, recvr, slot, parent );
}
KAction *pasteText( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( PasteText, recvr, slot, parent );
}
KAction *clear( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Clear, recvr, slot, parent );
}
KAction *selectAll( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( SelectAll, recvr, slot, parent );
}
KAction *deselect( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Deselect, recvr, slot, parent );
}
KAction *find( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Find, recvr, slot, parent );
}
KAction *findNext( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( FindNext, recvr, slot, parent );
}
KAction *findPrev( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( FindPrev, recvr, slot, parent );
}
KAction *replace( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Replace, recvr, slot, parent );
}
KAction *actualSize( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( ActualSize, recvr, slot, parent );
}
KAction *fitToPage( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( FitToPage, recvr, slot, parent );
}
KAction *fitToWidth( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( FitToWidth, recvr, slot, parent );
}
KAction *fitToHeight( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( FitToHeight, recvr, slot, parent );
}
KAction *zoomIn( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( ZoomIn, recvr, slot, parent );
}
KAction *zoomOut( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( ZoomOut, recvr, slot, parent );
}
KAction *zoom( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Zoom, recvr, slot, parent );
}
KAction *redisplay( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Redisplay, recvr, slot, parent );
}
KAction *up( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Up, recvr, slot, parent );
}
KAction *back( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Back, recvr, slot, parent );
}
KAction *forward( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Forward, recvr, slot, parent );
}
KAction *home( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Home, recvr, slot, parent );
}
KAction *prior( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Prior, recvr, slot, parent );
}
KAction *next( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Next, recvr, slot, parent );
}
KAction *goTo( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Goto, recvr, slot, parent );
}
KAction *gotoPage( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( GotoPage, recvr, slot, parent );
}
KAction *gotoLine( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( GotoLine, recvr, slot, parent );
}
KAction *firstPage( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( FirstPage, recvr, slot, parent );
}
KAction *lastPage( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( LastPage, recvr, slot, parent );
}
KAction *documentBack( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( DocumentBack, recvr, slot, parent );
}
KAction *documentForward( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( DocumentForward, recvr, slot, parent );
}
KAction *addBookmark( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( AddBookmark, recvr, slot, parent );
}
KAction *editBookmarks( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( EditBookmarks, recvr, slot, parent );
}
KAction *spelling( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Spelling, recvr, slot, parent );
}
static KAction *buildAutomaticAction( QObject* parent, StandardAction id, const char* slot )
{
const KStandardActionInfo* p = infoPtr( id );
if ( !p )
return 0;
AutomaticAction *action = new AutomaticAction(
KIcon( p->psIconName ),
i18n(p->psLabel),
KStandardShortcut::shortcut( p->idAccel ),
slot,
parent);
action->setObjectName(p->psName);
action->setWhatsThis( i18n(p->psWhatsThis) );
KActionCollection *collection = qobject_cast<KActionCollection *>(parent);
if (collection)
collection->addAction(action->objectName(), action);
return action;
}
KAction *cut( QObject* parent )
{
return buildAutomaticAction( parent, Cut, SLOT( cut() ) );
}
KAction *copy( QObject* parent )
{
return buildAutomaticAction( parent, Copy, SLOT( copy() ) );
}
KAction *paste( QObject* parent )
{
return buildAutomaticAction( parent, Paste, SLOT( paste() ) );
}
KAction *clear( QObject* parent )
{
return buildAutomaticAction( parent, Clear, SLOT( clear() ) );
}
KAction *selectAll( QObject* parent )
{
return buildAutomaticAction( parent, SelectAll, SLOT( selectAll() ) );
}
KToggleAction *showMenubar(const QObject *recvr, const char *slot, QObject *parent)
{
KToggleAction *ret = new KToggleAction(i18n( "Show &Menubar" ), parent);
ret->setObjectName(name(ShowMenubar));
ret->setIcon( KIcon( "show-menu" ) );
ret->setShortcut( KStandardShortcut::shortcut( KStandardShortcut::ShowMenubar ) );
ret->setWhatsThis( i18n( "Show Menubar<p>"
"Shows the menubar again after it has been hidden</p>" ) );
ret->setChecked( true );
if ( recvr && slot )
QObject::connect( ret, SIGNAL( triggered( bool ) ), recvr, slot );
KActionCollection *collection = qobject_cast<KActionCollection *>(parent);
if (collection)
collection->addAction(ret->objectName(), ret);
return ret;
}
KToggleAction *showStatusbar(const QObject *recvr, const char *slot, QObject *parent)
{
KToggleAction *ret = new KToggleAction(i18n( "Show St&atusbar" ), parent);
ret->setObjectName(name(ShowStatusbar));
ret->setWhatsThis( i18n( "Show Statusbar<p>"
"Shows the statusbar, which is the bar at the bottom of the window used for status information.</p>" ) );
ret->setChecked( true );
if ( recvr && slot )
QObject::connect( ret, SIGNAL( triggered( bool ) ), recvr, slot );
KActionCollection *collection = qobject_cast<KActionCollection *>(parent);
if (collection)
collection->addAction(ret->objectName(), ret);
return ret;
}
KToggleFullScreenAction *fullScreen(const QObject *recvr, const char *slot, QWidget* window, QObject *parent)
{
KToggleFullScreenAction *ret;
ret = static_cast< KToggleFullScreenAction* >( KStandardAction::create( FullScreen, recvr, slot, parent ) );
ret->setWindow( window );
return ret;
}
KAction *saveOptions( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( SaveOptions, recvr, slot, parent );
}
KAction *keyBindings( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( KeyBindings, recvr, slot, parent );
}
KAction *preferences( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Preferences, recvr, slot, parent );
}
KAction *configureToolbars( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( ConfigureToolbars, recvr, slot, parent );
}
KAction *configureNotifications( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( ConfigureNotifications, recvr, slot, parent );
}
KAction *help( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( Help, recvr, slot, parent );
}
KAction *helpContents( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( HelpContents, recvr, slot, parent );
}
KAction *whatsThis( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( WhatsThis, recvr, slot, parent );
}
KAction *tipOfDay( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( TipofDay, recvr, slot, parent );
}
KAction *reportBug( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( ReportBug, recvr, slot, parent );
}
KAction *switchApplicationLanguage( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( SwitchApplicationLanguage, recvr, slot, parent );
}
KAction *aboutApp( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( AboutApp, recvr, slot, parent );
}
KAction *aboutKDE( const QObject *recvr, const char *slot, QObject *parent )
{
return KStandardAction::create( AboutKDE, recvr, slot, parent );
}
}
diff --git a/kdeui/actions/kstandardaction_p.h b/kdeui/actions/kstandardaction_p.h
index 41800f1883..d9198dc4dc 100644
--- a/kdeui/actions/kstandardaction_p.h
+++ b/kdeui/actions/kstandardaction_p.h
@@ -1,171 +1,171 @@
/* This file is part of the KDE libraries
Copyright (C) 1999,2000 Kurt Granroth <granroth@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.
*/
#ifndef KSTANDARDACTION_PRIVATE_H
#define KSTANDARDACTION_PRIVATE_H
#include <QApplication>
#include <kaction.h>
#include <klocale.h>
#include <kstandardshortcut.h>
namespace KStandardAction
{
struct KStandardActionInfo
{
StandardAction id;
KStandardShortcut::StandardShortcut idAccel;
const char* psName;
const char* psLabel;
const char* psWhatsThis;
const char* psIconName;
};
static const KStandardActionInfo g_rgActionInfo[] =
{
{ New, KStandardShortcut::New, "file_new", I18N_NOOP("&New"), 0, "document-new" },
{ Open, KStandardShortcut::Open, "file_open", I18N_NOOP("&Open..."), 0, "document-open" },
{ OpenRecent, KStandardShortcut::AccelNone, "file_open_recent", I18N_NOOP("Open &Recent"), 0, "document-open-recent" },
{ Save, KStandardShortcut::Save, "file_save", I18N_NOOP("&Save"), 0, "document-save" },
{ SaveAs, KStandardShortcut::SaveAs, "file_save_as", I18N_NOOP("Save &As..."), 0, "document-save-as" },
{ Revert, KStandardShortcut::Revert, "file_revert", I18N_NOOP("Re&vert"), 0, "document-revert" },
{ Close, KStandardShortcut::Close, "file_close", I18N_NOOP("&Close"), 0, "window-close" },
{ Print, KStandardShortcut::Print, "file_print", I18N_NOOP("&Print..."), 0, "document-print" },
{ PrintPreview, KStandardShortcut::PrintPreview, "file_print_preview", I18N_NOOP("Print Previe&w"), 0, "document-print-preview" },
{ Mail, KStandardShortcut::Mail, "file_mail", I18N_NOOP("&Mail..."), 0, "mail-send" },
{ Quit, KStandardShortcut::Quit, "file_quit", I18N_NOOP("&Quit"), 0, "application-exit" },
{ Undo, KStandardShortcut::Undo, "edit_undo", I18N_NOOP("&Undo"), 0, "edit-undo" },
{ Redo, KStandardShortcut::Redo, "edit_redo", I18N_NOOP("Re&do"), 0, "edit-redo" },
{ Cut, KStandardShortcut::Cut, "edit_cut", I18N_NOOP("Cu&t"), 0, "edit-cut" },
{ Copy, KStandardShortcut::Copy, "edit_copy", I18N_NOOP("&Copy"), 0, "edit-copy" },
{ Paste, KStandardShortcut::Paste, "edit_paste", I18N_NOOP("&Paste"), 0, "edit-paste" },
{ PasteText, KStandardShortcut::Paste, "edit_paste", I18N_NOOP("&Paste"), 0, "edit-paste" },
{ Clear, KStandardShortcut::Clear, "edit_clear", I18N_NOOP("C&lear"), 0, "edit-clear" },
{ SelectAll, KStandardShortcut::SelectAll, "edit_select_all", I18N_NOOP("Select &All"), 0, "edit-select-all" },
{ Deselect, KStandardShortcut::Deselect, "edit_deselect", I18N_NOOP("Dese&lect"), 0, 0 },
{ Find, KStandardShortcut::Find, "edit_find", I18N_NOOP("&Find..."), 0, "edit-find" },
{ FindNext, KStandardShortcut::FindNext, "edit_find_next", I18N_NOOP("Find &Next"), 0, "go-down-search" },
{ FindPrev, KStandardShortcut::FindPrev, "edit_find_prev", I18N_NOOP("Find Pre&vious"), 0, "go-up-search" },
{ Replace, KStandardShortcut::Replace, "edit_replace", I18N_NOOP("&Replace..."), 0, 0 },
{ ActualSize, KStandardShortcut::ActualSize, "view_actual_size", I18N_NOOP("&Actual Size"), 0, "zoom-original" },
{ FitToPage, KStandardShortcut::FitToPage, "view_fit_to_page", I18N_NOOP("&Fit to Page"), 0, 0 },
{ FitToWidth, KStandardShortcut::FitToWidth, "view_fit_to_width", I18N_NOOP("Fit to Page &Width"), 0, 0 },
{ FitToHeight, KStandardShortcut::FitToHeight, "view_fit_to_height", I18N_NOOP("Fit to Page &Height"), 0, 0 },
{ ZoomIn, KStandardShortcut::ZoomIn, "view_zoom_in", I18N_NOOP("Zoom &In"), 0, "zoom-in" },
{ ZoomOut, KStandardShortcut::ZoomOut, "view_zoom_out", I18N_NOOP("Zoom &Out"), 0, "zoom-out" },
{ Zoom, KStandardShortcut::Zoom, "view_zoom", I18N_NOOP("&Zoom..."), 0, 0 },
{ Redisplay, KStandardShortcut::Reload, "view_redisplay", I18N_NOOP("&Redisplay"), 0, "view-refresh" },
{ Up, KStandardShortcut::Up, "go_up", I18N_NOOP("&Up"), 0, "go-up" },
// The following three have special i18n() needs for sLabel
{ Back, KStandardShortcut::Back, "go_back", 0, 0, "go-previous" },
{ Forward, KStandardShortcut::Forward, "go_forward", 0, 0, "go-next" },
{ Home, KStandardShortcut::Home, "go_home", 0, 0, "go-home" },
{ Prior, KStandardShortcut::Prior, "go_previous", I18N_NOOP("&Previous Page"), 0, "go-previous-view-page" },
{ Next, KStandardShortcut::Next, "go_next", I18N_NOOP("&Next Page"), 0, "go-next-view-page" },
{ Goto, KStandardShortcut::Goto, "go_goto", I18N_NOOP("&Go To..."), 0, 0 },
{ GotoPage, KStandardShortcut::GotoPage, "go_goto_page", I18N_NOOP("&Go to Page..."), 0, "go-jump" },
{ GotoLine, KStandardShortcut::GotoLine, "go_goto_line", I18N_NOOP("&Go to Line..."), 0, 0 },
{ FirstPage, KStandardShortcut::Begin, "go_first", I18N_NOOP("&First Page"), 0, "go-first-view-page" },
{ LastPage, KStandardShortcut::End, "go_last", I18N_NOOP("&Last Page"), 0, "go-last-view-page" },
{ DocumentBack, KStandardShortcut::DocumentBack, "go_document_back", I18N_NOOP("&Back in the Document"), 0, "go-previous" },
{ DocumentForward, KStandardShortcut::DocumentForward, "go_document_forward", I18N_NOOP("&Forward in the Document"), 0, "go-next" },
{ AddBookmark, KStandardShortcut::AddBookmark, "bookmark_add", I18N_NOOP("&Add Bookmark"), 0, "bookmark-new" },
{ EditBookmarks, KStandardShortcut::EditBookmarks, "bookmark_edit", I18N_NOOP("&Edit Bookmarks..."), 0, "bookmarks-organize" },
{ Spelling, KStandardShortcut::Spelling, "tools_spelling", I18N_NOOP("&Spelling..."), 0, "tools-check-spelling" },
{ ShowMenubar, KStandardShortcut::ShowMenubar, "options_show_menubar", I18N_NOOP("Show &Menubar"), 0, "show-menu" },
{ ShowToolbar, KStandardShortcut::ShowToolbar, "options_show_toolbar", I18N_NOOP("Show &Toolbar"), 0, 0 },
{ ShowStatusbar, KStandardShortcut::ShowStatusbar, "options_show_statusbar", I18N_NOOP("Show St&atusbar"), 0, 0 },
{ FullScreen, KStandardShortcut::FullScreen, "fullscreen", I18N_NOOP("F&ull Screen Mode"), 0, "view-fullscreen" },
{ SaveOptions, KStandardShortcut::SaveOptions, "options_save_options", I18N_NOOP("&Save Settings"), 0, 0 },
{ KeyBindings, KStandardShortcut::KeyBindings, "options_configure_keybinding", I18N_NOOP("Configure S&hortcuts..."), 0,"configure-shortcuts" },
{ Preferences, KStandardShortcut::Preferences, "options_configure", I18N_NOOP("&Configure %1..."), 0, "configure" },
{ ConfigureToolbars, KStandardShortcut::ConfigureToolbars, "options_configure_toolbars", I18N_NOOP("Configure Tool&bars..."), 0,"configure-toolbars" },
{ ConfigureNotifications, KStandardShortcut::ConfigureNotifications, "options_configure_notifications", I18N_NOOP("Configure &Notifications..."), 0, "preferences-desktop-notification" },
// the idea here is that Contents is used in menus, and Help in dialogs, so both share the same
// shortcut
{ Help, KStandardShortcut::Help, "help", 0, 0, "help-contents" },
{ HelpContents, KStandardShortcut::Help, "help_contents", I18N_NOOP("%1 &Handbook"), 0, "help-contents" },
{ WhatsThis, KStandardShortcut::WhatsThis, "help_whats_this", I18N_NOOP("What's &This?"), 0, "help-contextual" },
{ TipofDay, KStandardShortcut::TipofDay, "help_show_tip", I18N_NOOP("Tip of the &Day"), 0, "help-hint" },
{ ReportBug, KStandardShortcut::ReportBug, "help_report_bug", I18N_NOOP("&Report Bug..."), 0, "tools-report-bug" },
{ SwitchApplicationLanguage, KStandardShortcut::SwitchApplicationLanguage, "switch_application_language", I18N_NOOP("Switch Application &Language..."), 0, "preferences-desktop-locale" },
{ AboutApp, KStandardShortcut::AccelNone, "help_about_app", I18N_NOOP("&About %1"), 0, 0 },
{ AboutKDE, KStandardShortcut::AccelNone, "help_about_kde", I18N_NOOP("About &KDE"), 0, "kde" },
{ ActionNone, KStandardShortcut::AccelNone, 0, 0, 0, 0 }
};
inline const KStandardActionInfo* infoPtr( StandardAction id )
{
for ( uint i = 0; g_rgActionInfo[i].id != ActionNone; i++ ) {
if( g_rgActionInfo[i].id == id )
return &g_rgActionInfo[i];
}
return 0;
}
static inline QStringList internal_stdNames()
{
QStringList result;
for ( uint i = 0; g_rgActionInfo[i].id != ActionNone; i++ )
if (g_rgActionInfo[i].psLabel) {
if (QByteArray(g_rgActionInfo[i].psLabel).contains("%1"))
// Prevents i18n from complaining about unsubstituted placeholder.
result.append(i18n(g_rgActionInfo[i].psLabel, QString()));
else
result.append(i18n(g_rgActionInfo[i].psLabel));
}
return result;
}
class AutomaticAction : public KAction
{
Q_OBJECT
public:
- AutomaticAction(const KIcon &icon, const QString &text, const KShortcut &shortcut, const char *slot,
+ AutomaticAction(const QIcon &icon, const QString &text, const KShortcut &shortcut, const char *slot,
QObject *parent);
public Q_SLOTS:
inline void cut() { invokeEditSlot( "cut" ); }
inline void copy() { invokeEditSlot( "copy" ); }
inline void paste() { invokeEditSlot( "paste" ); }
inline void clear() { invokeEditSlot( "clear" ); }
inline void selectAll() { invokeEditSlot( "selectAll" ); }
void invokeEditSlot( const char *slot )
{
if ( qApp->focusWidget() )
QMetaObject::invokeMethod( qApp->focusWidget(), slot );
}
};
}
#endif
diff --git a/kdeui/actions/ktoggleaction.cpp b/kdeui/actions/ktoggleaction.cpp
index d4fffd4e91..2b2e2a8d01 100644
--- a/kdeui/actions/ktoggleaction.cpp
+++ b/kdeui/actions/ktoggleaction.cpp
@@ -1,111 +1,111 @@
/* 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 "ktoggleaction.h"
#include <kdebug.h>
#include <kguiitem.h>
#include <kicon.h>
#include <klocale.h>
class KToggleAction::Private
{
public:
Private( KToggleAction *_parent )
: parent( _parent ), checkedGuiItem( 0L )
{
}
~Private()
{
delete checkedGuiItem;
}
void init()
{
parent->setCheckable( true );
connect( parent, SIGNAL( toggled( bool ) ),
parent, SLOT( slotToggled( bool ) ) );
}
KToggleAction* parent;
KGuiItem* checkedGuiItem;
};
KToggleAction::KToggleAction( QObject *parent )
: KAction( parent ),
d( new Private( this ) )
{
d->init();
}
KToggleAction::KToggleAction( const QString & text, QObject *parent )
: KAction( text, parent ),
d( new Private( this ) )
{
d->init();
}
-KToggleAction::KToggleAction( const KIcon & icon, const QString & text, QObject *parent )
+KToggleAction::KToggleAction( const QIcon & icon, const QString & text, QObject *parent )
: KAction( icon, text, parent ),
d( new Private( this ) )
{
d->init();
}
KToggleAction::~KToggleAction()
{
delete d;
}
void KToggleAction::setCheckedState( const KGuiItem& checkedItem )
{
delete d->checkedGuiItem;
d->checkedGuiItem = new KGuiItem( checkedItem );
}
void KToggleAction::slotToggled( bool )
{
if ( d->checkedGuiItem ) {
QString string = d->checkedGuiItem->text();
d->checkedGuiItem->setText( text() );
setText( string );
string = d->checkedGuiItem->toolTip();
d->checkedGuiItem->setToolTip( toolTip() );
setToolTip( string );
if ( d->checkedGuiItem->hasIcon() ) {
- KIcon icon = d->checkedGuiItem->icon();
+ QIcon icon = d->checkedGuiItem->icon();
d->checkedGuiItem->setIcon( KIcon(this->icon()) );
QAction::setIcon( icon );
}
}
}
diff --git a/kdeui/actions/ktoggleaction.h b/kdeui/actions/ktoggleaction.h
index 8e429130b0..40afacc11f 100644
--- a/kdeui/actions/ktoggleaction.h
+++ b/kdeui/actions/ktoggleaction.h
@@ -1,104 +1,104 @@
/* 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) 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.
*/
#ifndef KTOGGLEACTION_H
#define KTOGGLEACTION_H
#include <kaction.h>
class KGuiItem;
/**
* @short Checkbox like action.
*
* This action provides two states: checked or not.
*
*/
class KDEUI_EXPORT KToggleAction : public KAction
{
Q_OBJECT
public:
/**
* Constructs an action with the specified parent.
*
* @param parent The action's parent object.
*/
explicit KToggleAction( QObject *parent );
/**
* Constructs an action with text; a shortcut may be specified by
* the ampersand character (e.g. \"&amp;Option\" creates a shortcut with key \e O )
*
* This is the most common KAction used when you do not have a
* corresponding icon (note that it won't appear in the current version
* of the "Edit ToolBar" dialog, because an action needs an icon to be
* plugged in a toolbar...).
*
* @param text The text that will be displayed.
* @param parent The action's parent object.
*/
KToggleAction( const QString& text, QObject *parent );
/**
* Constructs an action with text and an icon; a shortcut may be specified by
* the ampersand character (e.g. \"&amp;Option\" creates a shortcut with key \e O )
*
* This is the other common KAction used. Use it when you
* \e do have a corresponding icon.
*
* @param icon The icon to display.
* @param text The text that will be displayed.
* @param parent The action's parent object.
*/
- KToggleAction( const KIcon& icon, const QString& text, QObject *parent );
+ KToggleAction( const QIcon& icon, const QString& text, QObject *parent );
/**
* Destructor
*/
virtual ~KToggleAction();
/**
* Defines the text (and icon, tooltip, whatsthis) that should be displayed
* instead of the normal text, when the action is checked.
* Note that this does <em>not</em> replace the check box in front of the
* menu. So you should not use it to replace the text "Show <foo>" with
* "Hide <foo>", for example.
*
* If hasIcon(), the icon is kept for the 'checked state', unless
* @p checkedItem defines an icon explicitly. Same thing for tooltip and whatsthis.
*/
void setCheckedState( const KGuiItem& checkedItem );
protected Q_SLOTS:
virtual void slotToggled( bool checked );
private:
class Private;
Private* const d;
};
#endif
diff --git a/kdeui/actions/ktoolbarpopupaction.cpp b/kdeui/actions/ktoolbarpopupaction.cpp
index d9d9a68380..595e57d9ef 100644
--- a/kdeui/actions/ktoolbarpopupaction.cpp
+++ b/kdeui/actions/ktoolbarpopupaction.cpp
@@ -1,119 +1,119 @@
/* 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 "ktoolbarpopupaction.h"
#include "kmenu.h"
#include <QToolBar>
#include <QToolButton>
#include <kdebug.h>
#include <klocale.h>
#include <kicon.h>
class KToolBarPopupAction::Private
{
public:
Private()
: delayed( true ), stickyMenu( true )
{
}
bool delayed:1;
bool stickyMenu:1;
};
-KToolBarPopupAction::KToolBarPopupAction(const KIcon& icon, const QString& text, QObject *parent)
+KToolBarPopupAction::KToolBarPopupAction(const QIcon& icon, const QString& text, QObject *parent)
: KAction(icon, text, parent),
d( new Private )
{
setMenu( new KMenu );
}
KToolBarPopupAction::~KToolBarPopupAction()
{
delete d;
delete menu();
}
#ifndef KDE_NO_DEPRECATED
KMenu* KToolBarPopupAction::popupMenu() const
{
return qobject_cast<KMenu*>( menu() );
}
#endif
QWidget * KToolBarPopupAction::createWidget( QWidget * _parent )
{
QToolBar *parent = qobject_cast<QToolBar *>(_parent);
if (!parent)
return KAction::createWidget(_parent);
QToolButton* button = new QToolButton( parent );
button->setAutoRaise( true );
button->setFocusPolicy( Qt::NoFocus );
button->setIconSize( parent->iconSize() );
button->setToolButtonStyle( parent->toolButtonStyle() );
button->setDefaultAction( this );
connect( parent, SIGNAL( iconSizeChanged( const QSize& ) ),
button, SLOT( setIconSize( const QSize& ) ) );
connect( parent, SIGNAL( toolButtonStyleChanged( Qt::ToolButtonStyle ) ),
button, SLOT( setToolButtonStyle( Qt::ToolButtonStyle ) ) );
connect( button, SIGNAL( triggered( QAction* ) ),
parent, SIGNAL( actionTriggered( QAction* ) ) );
if ( d->delayed )
if ( d->stickyMenu )
button->setPopupMode( QToolButton::MenuButtonPopup );
else
button->setPopupMode( QToolButton::DelayedPopup );
else
button->setPopupMode( QToolButton::InstantPopup );
return button;
}
bool KToolBarPopupAction::delayed() const
{
return d->delayed;
}
void KToolBarPopupAction::setDelayed( bool delayed )
{
d->delayed = delayed;
}
bool KToolBarPopupAction::stickyMenu() const
{
return d->stickyMenu;
}
void KToolBarPopupAction::setStickyMenu( bool sticky )
{
d->stickyMenu = sticky;
}
diff --git a/kdeui/actions/ktoolbarpopupaction.h b/kdeui/actions/ktoolbarpopupaction.h
index d9b1929b89..723ae3c5d6 100644
--- a/kdeui/actions/ktoolbarpopupaction.h
+++ b/kdeui/actions/ktoolbarpopupaction.h
@@ -1,123 +1,123 @@
/* 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) 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.
*/
#ifndef KTOOLBARPOPUPACTION_H
#define KTOOLBARPOPUPACTION_H
#include <kaction.h>
class KMenu;
/**
* This action is a normal action everywhere, except in a toolbar
* where it also has a popupmenu (optionally delayed). This action is designed
* for history actions (back/forward, undo/redo) and for any other action
* that has more detail in a toolbar than in a menu (e.g. tool chooser
* with "Other" leading to a dialog...).
*
* In contrast to KActionMenu, this action is a \e simple menuitem when plugged
* into a menu, and has a popup only in a toolbar.
*
* Use cases include Back/Forward, and Undo/Redo. Simple click is what's most commonly
* used, and enough for menus, but in toolbars there is \e also an optional popup
* to go back N steps or undo N steps.
*/
class KDEUI_EXPORT KToolBarPopupAction : public KAction
{
Q_OBJECT
Q_PROPERTY( bool delayed READ delayed WRITE setDelayed )
Q_PROPERTY( bool stickyMenu READ stickyMenu WRITE setStickyMenu )
public:
//Not all constructors - because we need an icon, since this action only makes
// sense when being plugged at least in a toolbar.
/**
* Create a KToolBarPopupAction, with a text, an icon, a
* parent and a name.
*
* @param icon The icon to display.
* @param text The text that will be displayed.
* @param parent This action's parent.
*/
- KToolBarPopupAction(const KIcon& icon, const QString& text, QObject *parent);
+ KToolBarPopupAction(const QIcon& icon, const QString& text, QObject *parent);
/**
* Destroys the toolbar popup action.
*/
virtual ~KToolBarPopupAction();
/**
* The popup menu that is shown when clicking (some time) on the toolbar
* button. You may want to plug items into it on creation, or connect to
* aboutToShow for a more dynamic menu.
*
* \deprecated use menu() instead
*/
#ifndef KDE_NO_DEPRECATED
KDEUI_DEPRECATED KMenu *popupMenu() const;
#endif
/**
* Returns true if this action creates a delayed popup menu
* when plugged in a KToolBar.
*/
bool delayed() const;
/**
* If set to true, this action will create a delayed popup menu
* when plugged in a KToolBar. Otherwise it creates a normal popup.
* Default: delayed.
*/
void setDelayed(bool delayed);
/**
* Returns true if this action creates a sticky popup menu.
* @see setStickyMenu().
*/
bool stickyMenu() const;
/**
* If set to true, this action will create a sticky popup menu
* when plugged in a KToolBar.
* "Sticky", means it's visible until a selection is made or the mouse is
* clicked elsewhere. This feature allows you to make a selection without
* having to press and hold down the mouse while making a selection.
* Only available if delayed() is true.
* Default: sticky.
*/
void setStickyMenu(bool sticky);
/**
* Reimplemented from @see QActionWidgetFactory.
*/
virtual QWidget* createWidget(QWidget* parent);
private:
class Private;
Private* const d;
};
#endif
diff --git a/kdeui/colors/kcolordialog.cpp b/kdeui/colors/kcolordialog.cpp
index eaa8c3c83a..50a8b4e214 100644
--- a/kdeui/colors/kcolordialog.cpp
+++ b/kdeui/colors/kcolordialog.cpp
@@ -1,1831 +1,1832 @@
/* This file is part of the KDE libraries
Copyright (C) 1997 Martin Jones (mjones@kde.org)
Copyright (C) 2007 Roberto Raggi (roberto@kdevelop.org)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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.
*/
//-----------------------------------------------------------------------------
// KDE color selection dialog.
//
// 1999-09-27 Espen Sand <espensa@online.no>
// KColorDialog is now subclassed from KDialog. I have also extended
// KColorDialog::getColor() so that it contains a parent argument. This
// improves centering capability.
//
// layout management added Oct 1997 by Mario Weilguni
// <mweilguni@sime.com>
//
#include "kcolordialog.h"
#include "kcolordialog_p.h"
#include <stdio.h>
#include <stdlib.h>
#include <QButtonGroup>
#include <QCheckBox>
#include <QDesktopWidget>
#include <QRadioButton>
#include <qdrawutil.h>
#include <QActionEvent>
#include <QtCore/QFile>
#include <QHeaderView>
#include <QImage>
#include <QDrag>
#include <QStyledItemDelegate>
#include <QLabel>
#include <QLayout>
#include <QPainter>
#include <QPushButton>
#include <QScrollBar>
#include <QtCore/QTimer>
+#include <kicon.h>
#include <kapplication.h>
#include <kcombobox.h>
#include <kconfig.h>
#include <kglobal.h>
#include <kglobalsettings.h>
#include <khbox.h>
#include <kiconloader.h>
#include <klineedit.h>
#include <klistwidget.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <knuminput.h>
#include <kseparator.h>
#include <kstandarddirs.h>
#include <kcolorcollection.h>
#include <kcolorutils.h>
#include "kcolormimedata.h"
#include <config.h>
#include <kdebug.h>
#include "kcolorchoosermode_p.h"
#include "kcolorhelpers_p.h"
#include "kselector.h"
#include "kcolorvalueselector.h"
#include "khuesaturationselect.h"
#include "kxyselector.h"
#include <kconfiggroup.h>
#ifdef Q_WS_X11
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <QX11Info>
#include <fixx11h.h>
#endif
using namespace KDEPrivate;
using KDEPrivate::KColorTable;
struct ColorCollectionNameType {
const char* const m_fileName;
const char* const m_displayName;
};
static const ColorCollectionNameType colorCollectionName[] = {
{ "Recent_Colors", I18N_NOOP2("palette name", "* Recent Colors *") },
{ "Custom_Colors", I18N_NOOP2("palette name", "* Custom Colors *") },
{ "40.colors", I18N_NOOP2("palette name", "Forty Colors") },
{ "Oxygen.colors", I18N_NOOP2("palette name", "Oxygen Colors") },
{ "Rainbow.colors", I18N_NOOP2("palette name", "Rainbow Colors") },
{ "Royal.colors", I18N_NOOP2("palette name", "Royal Colors") },
{ "Web.colors", I18N_NOOP2("palette name", "Web Colors") },
{ 0, 0 } // end of data
};
enum ColorCollectionIndices
{
recentColorIndex,
customColorIndex,
fortyColorIndex
};
//-----------------------------------------------------------------------------
class KColorCells::KColorCellsPrivate
{
public:
KColorCellsPrivate(KColorCells *q): q(q) {
inMouse = false;
selected = -1;
shade = false;
}
KColorCells *q;
QPoint mousePos;
int selected;
bool shade;
bool inMouse;
};
class KColorCellsItemDelegate: public QStyledItemDelegate
{
public:
KColorCellsItemDelegate(KColorCells *parent): QStyledItemDelegate(parent) {}
virtual void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
{
QStyleOptionViewItemV4 opt(option);
initStyleOption(&opt,index);
//Get the current cell color
QColor backgroundColor = index.data(Qt::BackgroundRole).value<QColor>();
if (backgroundColor.isValid()) {
//Paint the general background
painter->fillRect(opt.rect, backgroundColor);
//Paint the selection mark (circle)
if (opt.state & QStyle::State_Selected) {
//Use black or white, depending on the contrast
QColor color = QColor(0, 0, 0, 220);
if (KColorUtils::contrastRatio(color, backgroundColor) < 5) {
color = QColor(255, 255, 255, 220);
}
//Draw the selection (radiobutton-like) circle
painter->save();
painter->setRenderHint(QPainter::Antialiasing, true);
painter->setRenderHint(QPainter::HighQualityAntialiasing, true);
painter->setPen(QPen(color, 1.2, Qt::SolidLine));
painter->setBrush(QBrush());
painter->drawEllipse(opt.rect.adjusted(2,2,-2,-2));
painter->restore();
}
} else {
//Paint the "X" (missing) cross on empty background color
backgroundColor = opt.palette.color(QPalette::Window);
painter->fillRect(opt.rect, backgroundColor);
painter->save();
QColor crossColor = qGray(backgroundColor.rgb()) > 192 ? backgroundColor.darker(106) :
backgroundColor.lighter(106);
painter->setPen(QPen(crossColor, 1.5));
painter->drawLine(opt.rect.topLeft(), opt.rect.bottomRight());
painter->drawLine(opt.rect.topRight(), opt.rect.bottomLeft());
painter->restore();
}
}
};
KColorCells::KColorCells(QWidget *parent, int rows, int cols)
: QTableWidget(parent), d(new KColorCellsPrivate(this))
{
setItemDelegate(new KColorCellsItemDelegate(this));
setFrameShape(QFrame::NoFrame);
d->shade = true;
setRowCount(rows);
setColumnCount(cols);
verticalHeader()->hide();
horizontalHeader()->hide();
d->selected = 0;
d->inMouse = false;
// Drag'n'Drop
setAcceptDrops(true);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
viewport()->setBackgroundRole(QPalette::Background);
setBackgroundRole(QPalette::Background);
setSelectionMode(QAbstractItemView::SingleSelection);
setDragEnabled(false);
}
KColorCells::~KColorCells()
{
delete d;
}
QColor KColorCells::color(int index) const
{
QTableWidgetItem * tmpItem = item(index / columnCount(), index % columnCount());
if (tmpItem != 0)
return tmpItem->data(Qt::BackgroundRole).value<QColor>();
return QColor();
}
int KColorCells::count() const
{
return rowCount() * columnCount();
}
void KColorCells::setShading(bool _shade)
{
d->shade = _shade;
}
void KColorCells::setAcceptDrags(bool _acceptDrags)
{
this->setDragEnabled(_acceptDrags);
}
void KColorCells::setSelected(int index)
{
Q_ASSERT(index >= 0 && index < count());
d->selected = index;
}
int KColorCells::selectedIndex() const
{
return d->selected;
}
void KColorCells::setColor(int column, const QColor &color)
{
const int tableRow = column / columnCount();
const int tableColumn = column % columnCount();
Q_ASSERT(tableRow >= 0 && tableRow < rowCount());
Q_ASSERT(tableColumn >= 0 && tableColumn < columnCount());
QTableWidgetItem * tableItem = item(tableRow, tableColumn);
if (tableItem == 0) {
tableItem = new QTableWidgetItem();
setItem(tableRow, tableColumn, tableItem);
}
tableItem->setData(Qt::BackgroundRole , color);
}
/*void KColorCells::paintCell( QPainter *painter, int row, int col )
{
painter->setRenderHint( QPainter::Antialiasing , true );
QBrush brush;
int w = 1;
if (shade)
{
qDrawShadePanel( painter, 1, 1, cellWidth()-2,
cellHeight()-2, palette(), true, 1, &brush );
w = 2;
}
QColor color = colors[ row * numCols() + col ];
if (!color.isValid())
{
if (!shade) return;
color = palette().color(backgroundRole());
}
const QRect colorRect( w, w, cellWidth()-w*2, cellHeight()-w*2 );
painter->fillRect( colorRect, color );
if ( row * numCols() + col == selected ) {
painter->setPen( qGray(color.rgb())>=127 ? Qt::black : Qt::white );
painter->drawLine( colorRect.topLeft(), colorRect.bottomRight() );
painter->drawLine( colorRect.topRight(), colorRect.bottomLeft() );
}
}*/
void KColorCells::resizeEvent(QResizeEvent*)
{
// According to the Qt doc:
// If you need to set the width of a given column to a fixed value, call
// QHeaderView::resizeSection() on the table's {horizontal,vertical}
// header.
// Therefore we iterate over each row and column and set the header section
// size, as the sizeHint does indeed appear to be ignored in favor of a
// minimum size that is larger than what we want.
for (int index = 0 ; index < columnCount() ; index++)
horizontalHeader()->resizeSection(index, sizeHintForColumn(index));
for (int index = 0 ; index < rowCount() ; index++)
verticalHeader()->resizeSection(index, sizeHintForRow(index));
}
int KColorCells::sizeHintForColumn(int /*column*/) const
{
return width() / columnCount() ;
}
int KColorCells::sizeHintForRow(int /*row*/) const
{
return height() / rowCount() ;
}
void KColorCells::mousePressEvent(QMouseEvent *e)
{
d->inMouse = true;
d->mousePos = e->pos();
QTableWidget::mousePressEvent(e);
}
int KColorCells::positionToCell(const QPoint &pos, bool ignoreBorders) const
{
//TODO ignoreBorders not yet handled
Q_UNUSED(ignoreBorders)
QTableWidgetItem* tableItem = itemAt(pos);
if (!tableItem)
return -1;
const int itemRow = row(tableItem);
const int itemColumn = column(tableItem);
int cell = itemRow * columnCount() + itemColumn;
/*if (!ignoreBorders)
{
int border = 2;
int x = pos.x() - col * cellWidth();
int y = pos.y() - row * cellHeight();
if ( (x < border) || (x > cellWidth()-border) ||
(y < border) || (y > cellHeight()-border))
return -1;
}*/
return cell;
}
void KColorCells::mouseMoveEvent(QMouseEvent *e)
{
if (this->dragEnabled() || this->acceptDrops()) {
if (!(e->buttons() & Qt::LeftButton)) return;
if (d->inMouse) {
int delay = KGlobalSettings::dndEventDelay();
if (e->x() > d->mousePos.x() + delay || e->x() < d->mousePos.x() - delay ||
e->y() > d->mousePos.y() + delay || e->y() < d->mousePos.y() - delay) {
// Drag color object
QTableWidgetItem * tableItem = itemAt(d->mousePos);
if (tableItem) {
QVariant var = tableItem->data(Qt::BackgroundRole);
QColor tmpCol = var.value<QColor>();
if (tmpCol.isValid())
KColorMimeData::createDrag(tmpCol, this)->start();
}
}
}
} else
QTableWidget::mouseMoveEvent(e);
}
void KColorCells::dragEnterEvent(QDragEnterEvent *event)
{
kDebug() << "KColorCells::dragEnterEvent() acceptDrags="
<< this->dragEnabled()
<< " canDecode=" << KColorMimeData::canDecode(event->mimeData())
<< endl;
event->setAccepted(this->dragEnabled() && KColorMimeData::canDecode(event->mimeData()));
}
// Reimplemented to override QTableWidget's override. Else dropping doesn't work.
void KColorCells::dragMoveEvent(QDragMoveEvent *event)
{
kDebug() << "KColorCells::dragMoveEvent() acceptDrags="
<< this->dragEnabled()
<< " canDecode=" << KColorMimeData::canDecode(event->mimeData())
<< endl;
event->setAccepted(this->dragEnabled() && KColorMimeData::canDecode(event->mimeData()));
}
void KColorCells::dropEvent(QDropEvent *event)
{
QColor c = KColorMimeData::fromMimeData(event->mimeData());
kDebug() << "KColorCells::dropEvent() color.isValid=" << c.isValid();
if (c.isValid()) {
QTableWidgetItem * tableItem = itemAt(event->pos());
if (tableItem)
tableItem->setData(Qt::BackgroundRole , c);
}
}
void KColorCells::mouseReleaseEvent(QMouseEvent *e)
{
if (selectionMode() != QAbstractItemView::NoSelection) {
int cell = positionToCell(d->mousePos);
int currentCell = positionToCell(e->pos());
// If we release the mouse in another cell and we don't have
// a drag we should ignore this event.
if (currentCell != cell)
cell = -1;
if ((cell != -1) && (d->selected != cell)) {
d->selected = cell;
const int newRow = cell / columnCount();
const int newColumn = cell % columnCount();
clearSelection(); // we do not want old violet selected cells
item(newRow, newColumn)->setSelected(true);
}
d->inMouse = false;
if (cell != -1)
emit colorSelected(cell , color(cell));
}
QTableWidget::mouseReleaseEvent(e);
}
void KColorCells::mouseDoubleClickEvent(QMouseEvent * /*e*/)
{
int cell = positionToCell(d->mousePos);
if (cell != -1)
emit colorDoubleClicked(cell , color(cell));
}
//-----------------------------------------------------------------------------
class KColorPatch::KColorPatchPrivate
{
public:
KColorPatchPrivate(KColorPatch *q): q(q) {}
KColorPatch *q;
QColor color;
};
KColorPatch::KColorPatch(QWidget *parent) : QFrame(parent), d(new KColorPatchPrivate(this))
{
setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
setAcceptDrops(true);
setMinimumSize(12, 12);
}
KColorPatch::~KColorPatch()
{
delete d;
}
QColor KColorPatch::color() const
{
return d->color;
}
void KColorPatch::setColor(const QColor &col)
{
d->color = col.toRgb();
update();
}
void KColorPatch::paintEvent(QPaintEvent* pe)
{
QFrame::paintEvent(pe);
QPainter painter(this);
fillOpaqueRect(&painter, contentsRect(), d->color);
}
void KColorPatch::mouseMoveEvent(QMouseEvent *e)
{
// Drag color object
if (!(e->buttons() & Qt::LeftButton))
return;
KColorMimeData::createDrag(d->color, this)->start();
}
void KColorPatch::dragEnterEvent(QDragEnterEvent *event)
{
event->setAccepted(KColorMimeData::canDecode(event->mimeData()));
}
void KColorPatch::dropEvent(QDropEvent *event)
{
QColor c = KColorMimeData::fromMimeData(event->mimeData());
if (c.isValid()) {
setColor(c);
emit colorChanged(c);
}
}
class KColorTable::KColorTablePrivate
{
public:
KColorTablePrivate(KColorTable *q): q(q) {}
void slotColorCellSelected(int index , const QColor&);
void slotColorCellDoubleClicked(int index , const QColor&);
void slotColorTextSelected(const QString &colorText);
void slotSetColors(const QString &_collectionName);
void slotShowNamedColorReadError(void);
KColorTable *q;
QString i18n_namedColors;
KComboBox *combo;
KColorCells *cells;
QScrollArea *sv;
KListWidget *mNamedColorList;
KColorCollection *mPalette;
int mMinWidth;
int mCols;
QMap<QString, QColor> m_namedColorMap;
};
KColorTable::KColorTable(QWidget *parent, int minWidth, int cols)
: QWidget(parent), d(new KColorTablePrivate(this))
{
d->cells = 0;
d->mPalette = 0;
d->mMinWidth = minWidth;
d->mCols = cols;
d->i18n_namedColors = i18n("Named Colors");
QStringList diskPaletteList = KColorCollection::installedCollections();
QStringList paletteList;
// We must replace the untranslated file names by translate names (of course only for KDE's standard palettes)
for (int i = 0; colorCollectionName[i].m_fileName; ++i) {
diskPaletteList.removeAll(colorCollectionName[i].m_fileName);
paletteList.append(i18nc("palette name", colorCollectionName[i].m_displayName));
}
paletteList += diskPaletteList;
paletteList.append(d->i18n_namedColors);
QVBoxLayout *layout = new QVBoxLayout(this);
d->combo = new KComboBox(this);
d->combo->setEditable(false);
d->combo->addItems(paletteList);
layout->addWidget(d->combo);
d->sv = new QScrollArea(this);
QSize cellSize = QSize(d->mMinWidth, 120);
d->sv->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
d->sv->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
QSize minSize = QSize(d->sv->verticalScrollBar()->sizeHint().width(), 0);
minSize += QSize(d->sv->frameWidth() * 2, 0);
minSize += QSize(cellSize);
d->sv->setFixedSize(minSize);
layout->addWidget(d->sv);
d->mNamedColorList = new KListWidget(this);
d->mNamedColorList->setObjectName("namedColorList");
d->mNamedColorList->setFixedSize(minSize);
d->mNamedColorList->hide();
layout->addWidget(d->mNamedColorList);
connect(d->mNamedColorList, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(slotColorTextSelected(const QString &)));
setFixedSize(sizeHint());
connect(d->combo, SIGNAL(activated(const QString &)),
this, SLOT(slotSetColors(const QString &)));
}
KColorTable::~KColorTable()
{
delete d->mPalette;
delete d;
}
QString
KColorTable::name() const
{
return d->combo->currentText();
}
static const char * const *namedColorFilePath(void)
{
//
// 2000-02-05 Espen Sand.
// Add missing filepaths here. Make sure the last entry is 0, 0!
//
// 2009-06-16 Pino Toscano
//
// You can specify either absolute paths or relative locations
// wrt KStandardDirs resources. In either way, there should be two
// "strings" for each path.
// - absolute path: specify it directly, then add 0 as second item
// * example: "/usr/share/X11/rgb.txt", 0,
// - KStandardDirs location: specify the filename as first item,
// then add the resource as second
// * example: "kdeui/rgb.txt", "data",
//
static const char * const path[] = {
#ifdef Q_WS_X11
#ifdef X11_RGBFILE
X11_RGBFILE, 0,
#endif
"/usr/share/X11/rgb.txt", 0,
"/usr/X11R6/lib/X11/rgb.txt", 0,
"/usr/openwin/lib/X11/rgb.txt", 0, // for Solaris.
#else /* systems without X11 */
"kdeui/rgb.txt", "data",
#endif
0, 0
};
return path;
}
void
KColorTable::readNamedColor(void)
{
if (d->mNamedColorList->count() != 0) {
return; // Strings already present
}
KGlobal::locale()->insertCatalog("kdelibs_colors4");
//
// Code somewhat inspired by KColorCollection.
//
const char * const *path = namedColorFilePath();
for (int i = 0; path[i]; i += 2) {
QString file;
if (path[i + 1]) {
file = KStandardDirs::locate(path[i + 1], QString::fromLatin1(path[i]));
if (file.isEmpty()) {
continue;
}
} else {
file = QString::fromLatin1(path[i]);
}
QFile paletteFile(file);
if (!paletteFile.open(QIODevice::ReadOnly)) {
continue;
}
QByteArray line;
QStringList list;
while (!paletteFile.atEnd()) {
line = paletteFile.readLine();
int red, green, blue;
int pos = 0;
if (sscanf(line, "%d %d %d%n", &red, &green, &blue, &pos) == 3) {
//
// Remove duplicates. Every name with a space and every name
// that start with "gray".
//
QString name = line.mid(pos).trimmed();
QByteArray s1 = line.mid(pos);
if (name.isNull() || name.indexOf(' ') != -1 ||
name.indexOf("gray") != -1 || name.indexOf("grey") != -1) {
continue;
}
const QColor color(red, green, blue);
if (color.isValid()) {
const QString colorName(i18nc("color", name.toLatin1().data()));
list.append(colorName);
d->m_namedColorMap[ colorName ] = color;
}
}
}
list.sort();
d->mNamedColorList->addItems(list);
break;
}
if (d->mNamedColorList->count() == 0) {
//
// Give the error dialog box a chance to center above the
// widget (or dialog). If we had displayed it now we could get a
// situation where the (modal) error dialog box pops up first
// preventing the real dialog to become visible until the
// error dialog box is removed (== bad UI).
//
QTimer::singleShot(10, this, SLOT(slotShowNamedColorReadError()));
}
}
void
KColorTable::KColorTablePrivate::slotShowNamedColorReadError(void)
{
if (mNamedColorList->count() == 0) {
QString pathMsg;
int pathCount = 0;
const char * const *path = namedColorFilePath();
for (int i = 0; path[i]; i += 2, ++pathCount) {
if (path[i + 1]) {
pathMsg += QLatin1String(path[i + 1]) + ", " + QString::fromLatin1(path[i]);
} else {
pathMsg += QLatin1String(path[i]);
}
pathMsg += '\n';
}
QString finalMsg = i18ncp("%1 is the number of paths, %2 is the list of paths (with newlines between them)",
"Unable to read X11 RGB color strings. The following "
"file location was examined:\n%2",
"Unable to read X11 RGB color strings. The following "
"file locations were examined:\n%2",
pathCount, pathMsg );
KMessageBox::sorry(q, finalMsg);
}
}
//
// 2000-02-12 Espen Sand
// Set the color in two steps. The setColors() slot will not emit a signal
// with the current color setting. The reason is that setColors() is used
// by the color selector dialog on startup. In the color selector dialog
// we normally want to display a startup color which we specify
// when the dialog is started. The slotSetColors() slot below will
// set the palette and then use the information to emit a signal with the
// new color setting. It is only used by the combobox widget.
//
void
KColorTable::KColorTablePrivate::slotSetColors(const QString &_collectionName)
{
q->setColors(_collectionName);
if (mNamedColorList->count() && mNamedColorList->isVisible()) {
int item = mNamedColorList->currentRow();
mNamedColorList->setCurrentRow(item < 0 ? 0 : item);
slotColorTextSelected(mNamedColorList->currentItem()->text());
} else {
slotColorCellSelected(0, QColor()); // FIXME: We need to save the current value!!
}
}
void
KColorTable::setColors(const QString &_collectionName)
{
QString collectionName(_collectionName);
if (d->combo->currentText() != collectionName) {
bool found = false;
for (int i = 0; i < d->combo->count(); i++) {
if (d->combo->itemText(i) == collectionName) {
d->combo->setCurrentIndex(i);
found = true;
break;
}
}
if (!found) {
d->combo->addItem(collectionName);
d->combo->setCurrentIndex(d->combo->count() - 1);
}
}
// We must again find the file name of the palette from the eventual translation
for (int i = 0; colorCollectionName[i].m_fileName; ++i) {
if (collectionName == i18nc("palette name", colorCollectionName[i].m_displayName)) {
collectionName = colorCollectionName[i].m_fileName;
break;
}
}
//
// 2000-02-12 Espen Sand
// The palette mode "i18n_namedColors" does not use the KColorCollection
// class. In fact, 'mPalette' and 'cells' are 0 when in this mode. The reason
// for this is maninly that KColorCollection reads from and writes to files
// using "locate()". The colors used in "i18n_namedColors" mode comes from
// the X11 diretory and is not writable. I don't think this fit in
// KColorCollection.
//
if (!d->mPalette || d->mPalette->name() != collectionName) {
if (collectionName == d->i18n_namedColors) {
d->sv->hide();
d->mNamedColorList->show();
readNamedColor();
delete d->cells; d->cells = 0;
delete d->mPalette; d->mPalette = 0;
} else {
d->mNamedColorList->hide();
d->sv->show();
delete d->cells;
delete d->mPalette;
d->mPalette = new KColorCollection(collectionName);
int rows = (d->mPalette->count() + d->mCols - 1) / d->mCols;
if (rows < 1) rows = 1;
d->cells = new KColorCells(d->sv->viewport(), rows, d->mCols);
d->cells->setShading(false);
d->cells->setAcceptDrags(false);
QSize cellSize = QSize(d->mMinWidth, d->mMinWidth * rows / d->mCols);
d->cells->setFixedSize(cellSize);
for (int i = 0; i < d->mPalette->count(); i++) {
d->cells->setColor(i, d->mPalette->color(i));
}
connect(d->cells, SIGNAL(colorSelected(int , const QColor&)),
SLOT(slotColorCellSelected(int , const QColor&)));
connect(d->cells, SIGNAL(colorDoubleClicked(int , const QColor&)),
SLOT(slotColorCellDoubleClicked(int , const QColor&)));
d->sv->setWidget(d->cells);
d->cells->show();
//d->sv->updateScrollBars();
}
}
}
void
KColorTable::KColorTablePrivate::slotColorCellSelected(int index , const QColor& /*color*/)
{
if (!mPalette || (index >= mPalette->count()))
return;
emit q->colorSelected(mPalette->color(index), mPalette->name(index));
}
void
KColorTable::KColorTablePrivate::slotColorCellDoubleClicked(int index , const QColor& /*color*/)
{
if (!mPalette || (index >= mPalette->count()))
return;
emit q->colorDoubleClicked(mPalette->color(index), mPalette->name(index));
}
void
KColorTable::KColorTablePrivate::slotColorTextSelected(const QString &colorText)
{
emit q->colorSelected(m_namedColorMap[ colorText ], colorText);
}
void
KColorTable::addToCustomColors(const QColor &color)
{
setColors(i18nc("palette name", colorCollectionName[customColorIndex].m_displayName));
d->mPalette->addColor(color);
d->mPalette->save();
delete d->mPalette;
d->mPalette = 0;
setColors(i18nc("palette name", colorCollectionName[customColorIndex].m_displayName));
}
void
KColorTable::addToRecentColors(const QColor &color)
{
//
// 2000-02-12 Espen Sand.
// The 'mPalette' is always 0 when current mode is i18n_namedColors
//
bool recentIsSelected = false;
if (d->mPalette && d->mPalette->name() == colorCollectionName[ recentColorIndex ].m_fileName) {
delete d->mPalette;
d->mPalette = 0;
recentIsSelected = true;
}
KColorCollection *recentPal = new KColorCollection(colorCollectionName[ recentColorIndex ].m_fileName);
if (recentPal->findColor(color) == -1) {
recentPal->addColor(color);
recentPal->save();
}
delete recentPal;
if (recentIsSelected)
setColors(i18nc("palette name", colorCollectionName[ recentColorIndex ].m_displayName));
}
class KCDPickerFilter;
class KColorDialog::KColorDialogPrivate
{
public:
KColorDialogPrivate(KColorDialog *q): q(q) {}
void setRgbEdit(const QColor &col);
void setHsvEdit(const QColor &col);
void setHtmlEdit(const QColor &col);
void _setColor(const QColor &col, const QString &name = QString());
void showColor(const QColor &color, const QString &name);
void slotRGBChanged(void);
void slotAlphaChanged(void);
void slotHSVChanged(void);
void slotHtmlChanged(void);
void slotHSChanged(int, int);
void slotVChanged(int);
void slotAChanged(int);
void slotModeChanged(int);
void slotColorSelected(const QColor &col);
void slotColorSelected(const QColor &col, const QString &name);
void slotColorDoubleClicked(const QColor &col, const QString &name);
void slotColorPicker();
void slotAddToCustomColors();
void slotDefaultColorClicked();
/**
* Write the settings of the dialog to config file.
**/
void slotWriteSettings();
/**
* Returns the mode.
*/
KColorChooserMode chooserMode();
/**
* Sets a mode. Updates the color picker and the color bar.
*/
void setChooserMode(KColorChooserMode c);
KColorDialog *q;
KColorTable *table;
QString originalPalette;
bool bRecursion;
bool bEditRgb;
bool bEditHsv;
bool bEditHtml;
bool bColorPicking;
bool bAlphaEnabled;
QLabel *colorName;
KLineEdit *htmlName;
KIntSpinBox *hedit;
KIntSpinBox *sedit;
KIntSpinBox *vedit;
KIntSpinBox *redit;
KIntSpinBox *gedit;
KIntSpinBox *bedit;
QWidget *alphaLabel;
KIntSpinBox *aedit;
KColorPatch *patch;
KColorPatch *comparePatch;
KColorChooserMode _mode;
QButtonGroup *modeGroup;
KHueSaturationSelector *hsSelector;
KColorCollection *palette;
KColorValueSelector *valuePal;
KGradientSelector *alphaSelector;
QVBoxLayout* l_right;
QGridLayout* tl_layout;
QCheckBox *cbDefaultColor;
QColor defaultColor;
QColor selColor;
#ifdef Q_WS_X11
KCDPickerFilter* filter;
#endif
};
#ifdef Q_WS_X11
class KCDPickerFilter: public QWidget
{
public:
KCDPickerFilter(QWidget* parent): QWidget(parent) {}
virtual bool x11Event(XEvent* event) {
if (event->type == ButtonRelease) {
QMouseEvent e(QEvent::MouseButtonRelease, QPoint(),
QPoint(event->xmotion.x_root, event->xmotion.y_root) , Qt::NoButton, Qt::NoButton, Qt::NoModifier);
QApplication::sendEvent(parentWidget(), &e);
return true;
} else return false;
}
};
#endif
KColorDialog::KColorDialog(QWidget *parent, bool modal)
: KDialog(parent), d(new KColorDialogPrivate(this))
{
setCaption(i18n("Select Color"));
setButtons(modal ? Ok | Cancel : Close);
setModal(modal);
d->bRecursion = true;
d->bColorPicking = false;
d->bAlphaEnabled = false;
#ifdef Q_WS_X11
d->filter = 0;
#endif
d->cbDefaultColor = 0L;
d->_mode = ChooserClassic;
connect(this, SIGNAL(okClicked(void)), this, SLOT(slotWriteSettings(void)));
connect(this, SIGNAL(closeClicked(void)), this, SLOT(slotWriteSettings(void)));
QLabel *label;
//
// Create the top level page and its layout
//
QWidget *page = new QWidget(this);
setMainWidget(page);
QGridLayout *tl_layout = new QGridLayout(page);
tl_layout->setMargin(0);
d->tl_layout = tl_layout;
tl_layout->addItem(new QSpacerItem(spacingHint()*2, 0), 0, 1);
//
// the more complicated part: the left side
// add a V-box
//
QVBoxLayout *l_left = new QVBoxLayout();
tl_layout->addLayout(l_left, 0, 0);
//
// add a H-Box for the XY-Selector and a grid for the
// entry fields
//
QHBoxLayout *l_ltop = new QHBoxLayout();
l_left->addLayout(l_ltop);
//
// the palette and value selector go into the H-box
//
d->hsSelector = new KHueSaturationSelector(page);
d->hsSelector->setMinimumSize(256, 256);
l_ltop->addWidget(d->hsSelector, 8);
connect(d->hsSelector, SIGNAL(valueChanged(int, int)),
SLOT(slotHSChanged(int, int)));
d->valuePal = new KColorValueSelector(page);
d->valuePal->setMinimumSize(26, 70);
d->valuePal->setIndent(false);
d->valuePal->setArrowDirection(Qt::RightArrow);
l_ltop->addWidget(d->valuePal, 1);
connect(d->valuePal, SIGNAL(valueChanged(int)),
SLOT(slotVChanged(int)));
d->alphaSelector = new KGradientSelector(Qt::Horizontal, page);
d->alphaSelector->setFixedSize(256, 26);
d->alphaSelector->setIndent(false);
d->alphaSelector->setArrowDirection(Qt::DownArrow);
d->alphaSelector->setRange(0, 255);
l_left->addWidget(d->alphaSelector, 1);
connect(d->alphaSelector, SIGNAL(valueChanged(int)),
SLOT(slotAChanged(int)));
// a little space between
l_left->addSpacing(10); // FIXME: remove hardcoded values
QGridLayout *l_lbot = new QGridLayout();
l_left->addLayout(l_lbot);
// button group that manages the radio buttons
QRadioButton *modeButton;
d->modeGroup = new QButtonGroup(page);
connect(d->modeGroup, SIGNAL(buttonClicked(int)), SLOT(slotModeChanged(int)));
//
// add the HSV fields
//
l_lbot->setColumnStretch(2, 10);
modeButton = new QRadioButton(i18n("Hue:"), page);
l_lbot->addWidget(modeButton, 0, 0);
d->modeGroup->addButton(modeButton, ChooserHue);
d->hedit = new KIntSpinBox(page);
d->hedit->setMaximum(359);
d->hedit->setSuffix(i18nc("The angular degree unit (for hue)", "\302\260")); // U+00B0 DEGREE SIGN
l_lbot->addWidget(d->hedit, 0, 1);
connect(d->hedit, SIGNAL(valueChanged(int)),
SLOT(slotHSVChanged()));
modeButton = new QRadioButton(i18n("Saturation:"), page);
l_lbot->addWidget(modeButton, 1, 0);
d->modeGroup->addButton(modeButton, ChooserSaturation);
d->sedit = new KIntSpinBox(page);
d->sedit->setMaximum(255);
l_lbot->addWidget(d->sedit, 1, 1);
connect(d->sedit, SIGNAL(valueChanged(int)),
SLOT(slotHSVChanged()));
modeButton = new QRadioButton(i18nc("This is the V of HSV", "Value:"), page);
l_lbot->addWidget(modeButton, 2, 0);
d->modeGroup->addButton(modeButton, ChooserValue);
d->vedit = new KIntSpinBox(page);
d->vedit->setMaximum(255);
l_lbot->addWidget(d->vedit, 2, 1);
connect(d->vedit, SIGNAL(valueChanged(int)),
SLOT(slotHSVChanged()));
//
// add the RGB fields
//
modeButton = new QRadioButton(i18n("Red:"), page);
l_lbot->addWidget(modeButton, 0, 3);
d->modeGroup->addButton(modeButton, ChooserRed);
d->redit = new KIntSpinBox(page);
d->redit->setMaximum(255);
l_lbot->addWidget(d->redit, 0, 4);
connect(d->redit, SIGNAL(valueChanged(int)),
SLOT(slotRGBChanged()));
modeButton = new QRadioButton(i18n("Green:"), page);
l_lbot->addWidget(modeButton, 1, 3);
d->modeGroup->addButton(modeButton, ChooserGreen);
d->gedit = new KIntSpinBox(page);
d->gedit->setMaximum(255);
l_lbot->addWidget(d->gedit, 1, 4);
connect(d->gedit, SIGNAL(valueChanged(int)),
SLOT(slotRGBChanged()));
modeButton = new QRadioButton(i18n("Blue:"), page);
l_lbot->addWidget(modeButton, 2, 3);
d->modeGroup->addButton(modeButton, ChooserBlue);
d->bedit = new KIntSpinBox(page);
d->bedit->setMaximum(255);
l_lbot->addWidget(d->bedit, 2, 4);
connect(d->bedit, SIGNAL(valueChanged(int)),
SLOT(slotRGBChanged()));
d->alphaLabel = new KHBox(page);
QWidget *spacer = new QWidget(d->alphaLabel);
label = new QLabel(i18n("Alpha:"), d->alphaLabel);
QStyleOptionButton option;
option.initFrom(modeButton);
QRect labelRect = modeButton->style()->subElementRect(QStyle::SE_RadioButtonContents, &option, modeButton);
int indent = layoutDirection() == Qt::LeftToRight ? labelRect.left() : modeButton->geometry().right() - labelRect.right();
spacer->setFixedWidth(indent);
l_lbot->addWidget(d->alphaLabel, 3, 3);
d->aedit = new KIntSpinBox(page);
d->aedit->setMaximum(255);
label->setBuddy(d->aedit);
l_lbot->addWidget(d->aedit, 3, 4);
connect(d->aedit, SIGNAL(valueChanged(int)),
SLOT(slotAlphaChanged()));
d->aedit->setVisible(false);
d->alphaLabel->setVisible(false);
d->alphaSelector->setVisible(false);
//
// add a layout for the right side
//
d->l_right = new QVBoxLayout;
tl_layout->addLayout(d->l_right, 0, 2);
//
// Add the palette table
//
d->table = new KColorTable(page);
d->l_right->addWidget(d->table, 10);
connect(d->table, SIGNAL(colorSelected(const QColor &, const QString &)),
SLOT(slotColorSelected(const QColor &, const QString &)));
connect(
d->table,
SIGNAL(colorDoubleClicked(const QColor &, const QString &)),
SLOT(slotColorDoubleClicked(const QColor &, const QString &))
);
// Store the default value for saving time.
d->originalPalette = d->table->name();
//
// a little space between
//
d->l_right->addSpacing(10);
QHBoxLayout *l_hbox = new QHBoxLayout();
d->l_right->addItem(l_hbox);
//
// The add to custom colors button
//
QPushButton *addButton = new QPushButton(page);
addButton->setText(i18n("&Add to Custom Colors"));
l_hbox->addWidget(addButton, 0, Qt::AlignLeft);
connect(addButton, SIGNAL(clicked()), SLOT(slotAddToCustomColors()));
//
// The color picker button
//
QPushButton* button = new QPushButton(page);
button->setIcon(KIcon("color-picker"));
int commonHeight = addButton->sizeHint().height();
button->setFixedSize(commonHeight, commonHeight);
l_hbox->addWidget(button, 0, Qt::AlignHCenter);
connect(button, SIGNAL(clicked()), SLOT(slotColorPicker()));
//
// a little space between
//
d->l_right->addSpacing(10);
//
// and now the entry fields and the patch (=colored box)
//
QGridLayout *l_grid = new QGridLayout();
d->l_right->addLayout(l_grid);
l_grid->setColumnStretch(2, 1);
label = new QLabel(page);
label->setText(i18n("Name:"));
l_grid->addWidget(label, 0, 1, Qt::AlignLeft);
d->colorName = new QLabel(page);
l_grid->addWidget(d->colorName, 0, 2, Qt::AlignLeft);
label = new QLabel(page);
label->setText(i18n("HTML:"));
l_grid->addWidget(label, 1, 1, Qt::AlignLeft);
d->htmlName = new KLineEdit(page);
d->htmlName->setMaxLength(13); // Qt's QColor allows 12 hexa-digits
d->htmlName->setText("#FFFFFF"); // But HTML uses only 6, so do not worry about the size
int w = d->htmlName->fontMetrics().width(QLatin1String("#DDDDDDD"));
d->htmlName->setFixedWidth(w);
l_grid->addWidget(d->htmlName, 1, 2, Qt::AlignLeft);
connect(d->htmlName, SIGNAL(textChanged(const QString &)),
SLOT(slotHtmlChanged()));
d->patch = new KColorPatch(page);
d->patch->setFixedSize(48, 48);
l_grid->addWidget(d->patch, 0, 0, 2, 1, Qt::AlignHCenter | Qt::AlignVCenter);
connect(d->patch, SIGNAL(colorChanged(const QColor&)),
SLOT(setColor(const QColor&)));
//
// chain fields together
//
setTabOrder(d->hedit, d->sedit);
setTabOrder(d->sedit, d->vedit);
setTabOrder(d->vedit, d->redit);
setTabOrder(d->redit, d->gedit);
setTabOrder(d->gedit, d->bedit);
setTabOrder(d->bedit, d->aedit);
tl_layout->activate();
page->setMinimumSize(page->sizeHint());
readSettings();
d->bRecursion = false;
d->bEditHsv = false;
d->bEditRgb = false;
d->bEditHtml = false;
setFixedSize(sizeHint());
QColor col;
col.setHsv(0, 0, 255);
d->_setColor(col);
// FIXME: with enabled event filters, it crashes after ever enter of a drag.
// better disable drag and drop than crashing it...
// d->htmlName->installEventFilter(this);
// d->hsSelector->installEventFilter(this);
d->hsSelector->setAcceptDrops(true);
d->setChooserMode(ChooserValue);
}
KColorDialog::~KColorDialog()
{
#ifdef Q_WS_X11
if (d->bColorPicking && kapp)
kapp->removeX11EventFilter(d->filter);
#endif
delete d;
}
bool
KColorDialog::eventFilter(QObject *obj, QEvent *ev)
{
if ((obj == d->htmlName) || (obj == d->hsSelector))
switch (ev->type()) {
case QEvent::DragEnter:
case QEvent::DragMove:
case QEvent::DragLeave:
case QEvent::Drop:
case QEvent::DragResponse:
qApp->sendEvent(d->patch, ev);
return true;
default:
break;
}
return KDialog::eventFilter(obj, ev);
}
void
KColorDialog::setDefaultColor(const QColor& col)
{
if (!d->cbDefaultColor) {
//
// a little space between
//
d->l_right->addSpacing(10);
//
// and the "default color" checkbox, under all items on the right side
//
d->cbDefaultColor = new QCheckBox(i18n("Default color"), mainWidget());
d->l_right->addWidget(d->cbDefaultColor);
mainWidget()->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); // cancel setFixedSize()
d->tl_layout->activate();
mainWidget()->setMinimumSize(mainWidget()->sizeHint());
setFixedSize(sizeHint());
connect(d->cbDefaultColor, SIGNAL(clicked()), SLOT(slotDefaultColorClicked()));
}
d->defaultColor = col;
d->slotDefaultColorClicked();
}
QColor KColorDialog::defaultColor() const
{
return d->defaultColor;
}
void KColorDialog::setAlphaChannelEnabled(bool alpha)
{
if (d->bAlphaEnabled != alpha) {
d->bAlphaEnabled = alpha;
d->aedit->setVisible(d->bAlphaEnabled);
d->alphaLabel->setVisible(d->bAlphaEnabled);
d->alphaSelector->setVisible(d->bAlphaEnabled);
mainWidget()->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); // cancel setFixedSize()
d->tl_layout->activate();
mainWidget()->setMinimumSize(mainWidget()->sizeHint());
setFixedSize(sizeHint());
}
}
bool KColorDialog::isAlphaChannelEnabled() const
{
return d->bAlphaEnabled;
}
void KColorDialog::KColorDialogPrivate::setChooserMode(KColorChooserMode c)
{
_mode = c;
hsSelector->setChooserMode(c);
valuePal->setChooserMode(c);
modeGroup->button(valuePal->chooserMode())->setChecked(true);
valuePal->updateContents();
hsSelector->updateContents();
valuePal->update();
hsSelector->update();
slotHSVChanged();
}
KColorChooserMode KColorDialog::KColorDialogPrivate::chooserMode()
{
return _mode;
}
void KColorDialog::KColorDialogPrivate::slotDefaultColorClicked()
{
if (cbDefaultColor->isChecked()) {
selColor = defaultColor;
showColor(selColor, i18n("-default-"));
} else {
showColor(selColor, QString());
}
emit q->colorSelected(selColor);
}
void
KColorDialog::KColorDialogPrivate::slotModeChanged(int id)
{
setChooserMode(KColorChooserMode(id));
}
void
KColorDialog::readSettings()
{
KConfigGroup group(KGlobal::config(), "Colors");
QString collectionName = group.readEntry("CurrentPalette");
if (collectionName.isEmpty()) {
collectionName = i18nc("palette name", colorCollectionName[fortyColorIndex].m_displayName);
} else {
for (int i = 0; colorCollectionName[i].m_fileName; ++i) {
if (collectionName == colorCollectionName[i].m_displayName) {
collectionName = i18nc("palette name", colorCollectionName[i].m_displayName);
break;
}
}
}
d->table->setColors(collectionName);
}
void
KColorDialog::KColorDialogPrivate::slotWriteSettings()
{
KConfigGroup group(KGlobal::config(), "Colors");
QString collectionName = table->name();
if (!group.hasDefault("CurrentPalette") && table->name() == originalPalette) {
group.revertToDefault("CurrentPalette");
} else {
QString collectionName(table->name());
for (int i = 0; colorCollectionName[i].m_fileName; ++i) {
if (collectionName == i18nc("palette name", colorCollectionName[i].m_displayName)) {
collectionName = colorCollectionName[i].m_displayName;
break;
}
}
group.writeEntry("CurrentPalette", collectionName); //Make sure the untranslated name is saved, assuming there is one
}
}
QColor
KColorDialog::color() const
{
if (d->cbDefaultColor && d->cbDefaultColor->isChecked())
return QColor();
if (d->selColor.isValid())
d->table->addToRecentColors(d->selColor);
return d->selColor;
}
void KColorDialog::setColor(const QColor &col)
{
d->_setColor(col);
}
//
// static function to display dialog and return color
//
int KColorDialog::getColor(QColor &theColor, QWidget *parent)
{
KColorDialog dlg(parent, true);
dlg.setObjectName("Color Selector");
if (theColor.isValid())
dlg.setColor(theColor);
int result = dlg.exec();
if (result == Accepted) {
theColor = dlg.color();
}
return result;
}
//
// static function to display dialog and return color
//
int KColorDialog::getColor(QColor &theColor, const QColor& defaultCol, QWidget *parent)
{
KColorDialog dlg(parent, true);
dlg.setObjectName("Color Selector");
dlg.setDefaultColor(defaultCol);
dlg.setColor(theColor);
int result = dlg.exec();
if (result == Accepted)
theColor = dlg.color();
return result;
}
void KColorDialog::KColorDialogPrivate::slotRGBChanged(void)
{
if (bRecursion) return;
int red = redit->value();
int grn = gedit->value();
int blu = bedit->value();
if (red > 255 || red < 0) return;
if (grn > 255 || grn < 0) return;
if (blu > 255 || blu < 0) return;
QColor col;
col.setRgb(red, grn, blu, aedit->value());
bEditRgb = true;
_setColor(col);
bEditRgb = false;
}
void KColorDialog::KColorDialogPrivate::slotAlphaChanged(void)
{
if (bRecursion) return;
int alpha = aedit->value();
if (alpha > 255 || alpha < 0) return;
QColor col = selColor;
col.setAlpha(alpha);
_setColor(col);
}
void KColorDialog::KColorDialogPrivate::slotHtmlChanged(void)
{
if (bRecursion || htmlName->text().isEmpty()) return;
QString strColor(htmlName->text());
// Assume that a user does not want to type the # all the time
if (strColor[0] != '#') {
bool signalsblocked = htmlName->blockSignals(true);
strColor.prepend("#");
htmlName->setText(strColor);
htmlName->blockSignals(signalsblocked);
}
const QColor color(strColor);
if (color.isValid()) {
QColor col(color);
bEditHtml = true;
_setColor(col);
bEditHtml = false;
}
}
void KColorDialog::KColorDialogPrivate::slotHSVChanged(void)
{
if (bRecursion) return;
int hue = hedit->value();
int sat = sedit->value();
int val = vedit->value();
if (hue > 359 || hue < 0) return;
if (sat > 255 || sat < 0) return;
if (val > 255 || val < 0) return;
QColor col;
col.setHsv(hue, sat, val, aedit->value());
bEditHsv = true;
_setColor(col);
bEditHsv = false;
}
void KColorDialog::KColorDialogPrivate::slotHSChanged(int x, int y)
{
QColor col = selColor;
KColorChooserMode xMode = chooserXMode(chooserMode());
KColorChooserMode yMode = chooserYMode(chooserMode());
setComponentValue(col, xMode, x / (xMode == ChooserHue ? 360.0 : 255.0));
setComponentValue(col, yMode, y / (yMode == ChooserHue ? 360.0 : 255.0));
_setColor(col);
}
void KColorDialog::KColorDialogPrivate::slotVChanged(int v)
{
QColor col = selColor;
setComponentValue(col, chooserMode(), v / (chooserMode() == ChooserHue ? 360.0 : 255.0));
_setColor(col);
}
void KColorDialog::KColorDialogPrivate::slotAChanged(int value)
{
QColor col = selColor;
col.setAlpha(value);
_setColor(col);
}
void KColorDialog::KColorDialogPrivate::slotColorSelected(const QColor &color)
{
_setColor(color);
}
void KColorDialog::KColorDialogPrivate::slotAddToCustomColors()
{
table->addToCustomColors(selColor);
}
void KColorDialog::KColorDialogPrivate::slotColorSelected(const QColor &color, const QString &name)
{
_setColor(color, name);
}
void KColorDialog::KColorDialogPrivate::slotColorDoubleClicked
(
const QColor & color,
const QString & name
)
{
_setColor(color, name);
q->accept();
}
void KColorDialog::KColorDialogPrivate::_setColor(const QColor &color, const QString &name)
{
if (color.isValid()) {
if (cbDefaultColor && cbDefaultColor->isChecked())
cbDefaultColor->setChecked(false);
selColor = color;
} else {
if (cbDefaultColor && cbDefaultColor->isChecked())
cbDefaultColor->setChecked(true);
selColor = defaultColor;
}
showColor(selColor, name);
emit q->colorSelected(selColor);
}
// show but don't set into selColor, nor emit colorSelected
void KColorDialog::KColorDialogPrivate::showColor(const QColor &color, const QString &name)
{
bRecursion = true;
if (name.isEmpty())
colorName->setText(i18n("-unnamed-"));
else
colorName->setText(name);
patch->setColor(color);
setRgbEdit(color);
setHsvEdit(color);
setHtmlEdit(color);
aedit->setValue(color.alpha());
QColor rgbColor = color.toRgb();
bool ltr = q->layoutDirection() == Qt::LeftToRight;
rgbColor.setAlpha(ltr ? 0 : 255);
alphaSelector->setFirstColor(rgbColor);
rgbColor.setAlpha(ltr ? 255 : 0);
alphaSelector->setSecondColor(rgbColor);
alphaSelector->setValue(color.alpha());
KColorChooserMode xMode = chooserXMode(chooserMode());
KColorChooserMode yMode = chooserYMode(chooserMode());
int xValue = qRound(getComponentValue(color, xMode) * (xMode == ChooserHue ? 360.0 : 255.0));
int yValue = qRound(getComponentValue(color, yMode) * (yMode == ChooserHue ? 360.0 : 255.0));
int value = qRound(getComponentValue(color, chooserMode()) * (chooserMode() == ChooserHue ? 360.0 : 255.0));
hsSelector->setValues(xValue, yValue);
valuePal->setValue(value);
bool blocked = valuePal->blockSignals(true);
valuePal->setHue(color.hue());
valuePal->setSaturation(color.saturation());
valuePal->setColorValue(color.value());
valuePal->updateContents();
valuePal->blockSignals(blocked);
valuePal->update();
blocked = hsSelector->blockSignals(true);
hsSelector->setHue(color.hue());
hsSelector->setSaturation(color.saturation());
hsSelector->setColorValue(color.value());
hsSelector->updateContents();
hsSelector->blockSignals(blocked);
hsSelector->update();
bRecursion = false;
}
void
KColorDialog::KColorDialogPrivate::slotColorPicker()
{
bColorPicking = true;
#ifdef Q_WS_X11
filter = new KCDPickerFilter(q);
kapp->installX11EventFilter(filter);
#endif
q->grabMouse(Qt::CrossCursor);
q->grabKeyboard();
}
void
KColorDialog::mouseMoveEvent(QMouseEvent *e)
{
if (d->bColorPicking) {
d->_setColor(grabColor(e->globalPos()));
return;
}
KDialog::mouseMoveEvent(e);
}
void
KColorDialog::mouseReleaseEvent(QMouseEvent *e)
{
if (d->bColorPicking) {
d->bColorPicking = false;
#ifdef Q_WS_X11
kapp->removeX11EventFilter(d->filter);
delete d->filter; d->filter = 0;
#endif
releaseMouse();
releaseKeyboard();
d->_setColor(grabColor(e->globalPos()));
return;
}
KDialog::mouseReleaseEvent(e);
}
QColor
KColorDialog::grabColor(const QPoint &p)
{
#ifdef Q_WS_X11
// we use the X11 API directly in this case as we are not getting back a valid
// return from QPixmap::grabWindow in the case where the application is using
// an argb visual
if( !qApp->desktop()->geometry().contains( p ))
return QColor();
Window root = RootWindow(QX11Info::display(), QX11Info::appScreen());
XImage *ximg = XGetImage(QX11Info::display(), root, p.x(), p.y(), 1, 1, -1, ZPixmap);
unsigned long xpixel = XGetPixel(ximg, 0, 0);
XDestroyImage(ximg);
XColor xcol;
xcol.pixel = xpixel;
xcol.flags = DoRed | DoGreen | DoBlue;
XQueryColor(QX11Info::display(),
DefaultColormap(QX11Info::display(), QX11Info::appScreen()),
&xcol);
return QColor::fromRgbF(xcol.red / 65535.0, xcol.green / 65535.0, xcol.blue / 65535.0);
#else
QWidget *desktop = QApplication::desktop();
QPixmap pm = QPixmap::grabWindow(desktop->winId(), p.x(), p.y(), 1, 1);
QImage i = pm.toImage();
return i.pixel(0, 0);
#endif
}
void
KColorDialog::keyPressEvent(QKeyEvent *e)
{
if (d->bColorPicking) {
if (e->key() == Qt::Key_Escape) {
d->bColorPicking = false;
#ifdef Q_WS_X11
kapp->removeX11EventFilter(d->filter);
delete d->filter; d->filter = 0;
#endif
releaseMouse();
releaseKeyboard();
}
e->accept();
return;
}
KDialog::keyPressEvent(e);
}
void KColorDialog::KColorDialogPrivate::setRgbEdit(const QColor &col)
{
if (bEditRgb) return;
int r, g, b;
col.getRgb(&r, &g, &b);
redit->setValue(r);
gedit->setValue(g);
bedit->setValue(b);
}
void KColorDialog::KColorDialogPrivate::setHtmlEdit(const QColor &col)
{
if (bEditHtml) return;
int r, g, b;
col.getRgb(&r, &g, &b);
QString num;
num.sprintf("#%02X%02X%02X", r, g, b);
htmlName->setText(num);
}
void KColorDialog::KColorDialogPrivate::setHsvEdit(const QColor &col)
{
if (bEditHsv) return;
int h, s, v;
col.getHsv(&h, &s, &v);
hedit->setValue(h);
sedit->setValue(s);
vedit->setValue(v);
}
#include "moc_kcolordialog.cpp"
#include "moc_kcolordialog_p.cpp"
diff --git a/kdeui/dialogs/kaboutkdedialog_p.cpp b/kdeui/dialogs/kaboutkdedialog_p.cpp
index 161f925233..d40c9efe2c 100644
--- a/kdeui/dialogs/kaboutkdedialog_p.cpp
+++ b/kdeui/dialogs/kaboutkdedialog_p.cpp
@@ -1,158 +1,159 @@
/* This file is part of the KDE libraries
Copyright (C) 2007 Urs Wolfer <uwolfer at kde.org>
Parts of this class have been take from the KAboutKDE class, which was
Copyright (C) 2000 Espen Sand <espen@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 "kaboutkdedialog_p.h"
#include <QFrame>
#include <QLabel>
#include <QLayout>
#include <QTabWidget>
#include <kdeversion.h>
#include <kglobalsettings.h>
#include <klocale.h>
+#include <kicon.h>
#include <kstandarddirs.h>
#include <ktitlewidget.h>
namespace KDEPrivate {
KAboutKdeDialog::KAboutKdeDialog(QWidget *parent)
: KDialog(parent),
d( 0 )
{
setPlainCaption(i18n("About KDE"));
setButtons(KDialog::Close);
KTitleWidget *titleWidget = new KTitleWidget(this);
titleWidget->setText(i18n("<html><font size=\"5\">KDE - Be Free!</font><br /><b>Platform Version %1</b></html>",
QString(KDE_VERSION_STRING)));
titleWidget->setPixmap(KIcon("kde").pixmap(48), KTitleWidget::ImageLeft);
QLabel *about = new QLabel;
about->setMargin(10);
about->setAlignment(Qt::AlignTop);
about->setWordWrap(true);
about->setOpenExternalLinks(true);
about->setTextInteractionFlags(Qt::TextBrowserInteraction);
about->setText(i18n("<html>"
"<b>KDE</b> is a world-wide network of software engineers, artists, writers, translators and facilitators "
"who are committed to <a href=\"%1\">Free Software</a> development. "
"This community has created hundreds of Free Software applications as part of the KDE "
"Development Platform and KDE Software Distribution.<br /><br />"
"KDE is a cooperative enterprise in which no single entity controls the "
"efforts or products of KDE to the exclusion of others. Everyone is welcome to join and "
"contribute to KDE, including you.<br /><br />"
"Visit <a href=\"%2\">%2</a> for "
"more information about the KDE community and the software we produce.</html>",
QLatin1String("http://www.gnu.org/philosophy/free-sw.html"),
QLatin1String("http://www.kde.org/")));
QLabel *report = new QLabel;
report->setMargin(10);
report->setAlignment(Qt::AlignTop);
report->setWordWrap(true);
report->setOpenExternalLinks(true);
report->setTextInteractionFlags(Qt::TextBrowserInteraction);
report->setText(i18n("<html>"
"Software can always be improved, and the KDE team is ready to "
"do so. However, you - the user - must tell us when "
"something does not work as expected or could be done better.<br /><br />"
"KDE has a bug tracking system. Visit "
"<a href=\"%1\">%1</a> or "
"use the \"Report Bug...\" dialog from the \"Help\" menu to report bugs.<br /><br />"
"If you have a suggestion for improvement then you are welcome to use "
"the bug tracking system to register your wish. Make sure you use the "
"severity called \"Wishlist\".</html>",
QLatin1String("https://bugs.kde.org/")));
QLabel *join = new QLabel;
join->setMargin(10);
join->setAlignment(Qt::AlignTop);
join->setWordWrap(true);
join->setOpenExternalLinks(true);
join->setTextInteractionFlags(Qt::TextBrowserInteraction);
join->setText(i18n("<html>"
"You do not have to be a software developer to be a member of the "
"KDE team. You can join the national teams that translate "
"program interfaces. You can provide graphics, themes, sounds, and "
"improved documentation. You decide!"
"<br /><br />"
"Visit "
"<a href=\"%1\">%1</a> "
"for information on some projects in which you can participate."
"<br /><br />"
"If you need more information or documentation, then a visit to "
"<a href=\"%2\">%2</a> "
"will provide you with what you need.</html>",
QLatin1String("http://www.kde.org/community/getinvolved/"),
QLatin1String("http://techbase.kde.org/")));
QLabel *support = new QLabel;
support->setMargin(10);
support->setAlignment(Qt::AlignTop);
support->setWordWrap(true);
support->setOpenExternalLinks(true);
support->setTextInteractionFlags(Qt::TextBrowserInteraction);
support->setText(i18n("<html>"
"KDE software is and will always be available free of charge, however creating it is not free.<br /><br />"
"To support development the KDE community has formed the KDE e.V., a non-profit organization "
"legally founded in Germany. KDE e.V. represents the KDE community in legal and financial matters. "
"See <a href=\"%1\">%1</a>"
" for information on KDE e.V.<br /><br />"
"KDE benefits from many kinds of contributions, including financial. "
"We use the funds to reimburse members and others for expenses "
"they incur when contributing. Further funds are used for legal "
"support and organizing conferences and meetings. <br /> <br />"
"We would like to encourage you to support our efforts with a "
"financial donation, using one of the ways described at "
"<a href=\"%2\">%2</a>."
"<br /><br />Thank you very much in advance for your support.</html>",
QLatin1String("http://ev.kde.org/"),
QLatin1String("http://www.kde.org/community/donations/")) + "<br /><br />"); // FIXME: ugly <br /> at the end...
QTabWidget *tabWidget = new QTabWidget;
tabWidget->setUsesScrollButtons(false);
tabWidget->addTab(about, i18nc("About KDE","&About"));
tabWidget->addTab(report, i18n("&Report Bugs or Wishes"));
tabWidget->addTab(join, i18n("&Join KDE"));
tabWidget->addTab(support, i18n("&Support KDE"));
QLabel *image = new QLabel;
image->setPixmap(KStandardDirs::locate("data", "kdeui/pics/aboutkde.png"));
QHBoxLayout *midLayout = new QHBoxLayout;
midLayout->addWidget(image);
midLayout->addWidget(tabWidget);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(titleWidget);
mainLayout->addLayout(midLayout);
mainLayout->setMargin(0);
QWidget *mainWidget = new QWidget;
mainWidget->setLayout(mainLayout);
setMainWidget(mainWidget);
}
}
diff --git a/kdeui/dialogs/kassistantdialog.cpp b/kdeui/dialogs/kassistantdialog.cpp
index afa72b0257..e91d9c7543 100644
--- a/kdeui/dialogs/kassistantdialog.cpp
+++ b/kdeui/dialogs/kassistantdialog.cpp
@@ -1,167 +1,168 @@
/* This file is part of the KDE libraries
Copyright (C) 2006 Olivier Goffart <ogoffart at 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 "kassistantdialog.h"
#include <kstandardguiitem.h>
#include <klocale.h>
#include <kdebug.h>
+#include <kicon.h>
#include <QHash>
class KAssistantDialog::Private
{
public:
Private(KAssistantDialog *q)
: q(q)
{
}
KAssistantDialog *q;
QHash<KPageWidgetItem*, bool> valid;
QHash<KPageWidgetItem*, bool> appropriate;
KPageWidgetModel *pageModel;
void init();
void _k_slotUpdateButtons();
QModelIndex getNext(QModelIndex nextIndex)
{
QModelIndex currentIndex;
do {
currentIndex=nextIndex;
nextIndex=currentIndex.child(0, 0);
if (!nextIndex.isValid())
nextIndex=currentIndex.sibling(currentIndex.row() + 1, 0);
} while (nextIndex.isValid() && !appropriate.value(pageModel->item(nextIndex), true));
return nextIndex;
}
QModelIndex getPrevious(QModelIndex nextIndex)
{
QModelIndex currentIndex;
do {
currentIndex=nextIndex;
nextIndex=currentIndex.sibling(currentIndex.row() - 1, 0);
if (!nextIndex.isValid())
nextIndex=currentIndex.parent();
} while (nextIndex.isValid() && !appropriate.value(pageModel->item(nextIndex), true));
return nextIndex;
}
};
KAssistantDialog::KAssistantDialog(QWidget * parent, Qt::WFlags flags)
: KPageDialog(parent, flags), d(new Private(this))
{
d->init();
//workaround to get the page model
KPageWidget *pagewidget=findChild<KPageWidget*>();
Q_ASSERT(pagewidget);
d->pageModel=static_cast<KPageWidgetModel*>(pagewidget->model());
}
KAssistantDialog::KAssistantDialog(KPageWidget *widget, QWidget *parent, Qt::WFlags flags)
: KPageDialog(widget, parent, flags), d(new Private(this))
{
d->init();
d->pageModel=static_cast<KPageWidgetModel*>(widget->model());
}
KAssistantDialog::~KAssistantDialog()
{
delete d;
}
void KAssistantDialog::Private::init()
{
q->setButtons(KDialog::Cancel | KDialog::User1 | KDialog::User2 | KDialog::User3 | KDialog::Help);
q->setButtonGuiItem( KDialog::User3, KStandardGuiItem::back(KStandardGuiItem::UseRTL) );
q->setButtonText( KDialog::User2, i18nc("Opposite to Back", "Next") );
q->setButtonText(KDialog::User1, i18n("Finish"));
q->setButtonIcon( KDialog::User2, KStandardGuiItem::forward(KStandardGuiItem::UseRTL).icon() );
q->setButtonIcon( KDialog::User1, KIcon("dialog-ok-apply") );
q->setDefaultButton(KDialog::User2);
q->setFaceType(KPageDialog::Plain);
q->connect(q, SIGNAL(user3Clicked()), q, SLOT(back()));
q->connect(q, SIGNAL(user2Clicked()), q, SLOT(next()));
q->connect(q, SIGNAL(user1Clicked()), q, SLOT(accept()));
q->connect(q, SIGNAL(currentPageChanged(KPageWidgetItem *, KPageWidgetItem *)), q, SLOT(_k_slotUpdateButtons()));
}
void KAssistantDialog::back()
{
QModelIndex nextIndex=d->getPrevious(d->pageModel->index(currentPage()));
if (nextIndex.isValid())
setCurrentPage(d->pageModel->item(nextIndex));
}
void KAssistantDialog::next()
{
QModelIndex nextIndex=d->getNext(d->pageModel->index(currentPage()));
if (nextIndex.isValid())
setCurrentPage(d->pageModel->item(nextIndex));
else if (isValid(currentPage()))
accept();
}
void KAssistantDialog::setValid(KPageWidgetItem * page, bool enable)
{
d->valid[page]=enable;
if (page == currentPage())
d->_k_slotUpdateButtons();
}
bool KAssistantDialog::isValid(KPageWidgetItem * page) const
{
return d->valid.value(page, true);
}
void KAssistantDialog::Private::_k_slotUpdateButtons()
{
QModelIndex currentIndex=pageModel->index(q->currentPage());
//change the caption of the next/finish button
QModelIndex nextIndex=getNext(currentIndex);
q->enableButton(KDialog::User1, !nextIndex.isValid() && q->isValid(q->currentPage()));
q->enableButton(KDialog::User2, nextIndex.isValid() && q->isValid(q->currentPage()));
q->setDefaultButton(nextIndex.isValid() ? KDialog::User2 : KDialog::User1);
//enable or disable the back button;
nextIndex=getPrevious(currentIndex);
q->enableButton(KDialog::User3, nextIndex.isValid());
}
void KAssistantDialog::showEvent(QShowEvent * event)
{
d->_k_slotUpdateButtons(); //called because last time that function was called is when the first page was added, so the next button show "finish"
KPageDialog::showEvent(event);
}
void KAssistantDialog::setAppropriate(KPageWidgetItem * page, bool appropriate)
{
d->appropriate[page]=appropriate;
d->_k_slotUpdateButtons();
}
bool KAssistantDialog::isAppropriate(KPageWidgetItem * page) const
{
return d->appropriate.value(page, true);
}
#include "moc_kassistantdialog.cpp"
diff --git a/kdeui/dialogs/kbugreport.cpp b/kdeui/dialogs/kbugreport.cpp
index c099c99c7c..a13ebb426a 100644
--- a/kdeui/dialogs/kbugreport.cpp
+++ b/kdeui/dialogs/kbugreport.cpp
@@ -1,563 +1,564 @@
/* This file is part of the KDE project
Copyright (C) 1999 David Faure <faure@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 as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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 "kbugreport.h"
#include <QtCore/QProcess>
#include <QtCore/QCoreApplication>
#include <QPushButton>
#include <QLayout>
#include <QRadioButton>
#include <QGroupBox>
#include <QCloseEvent>
+#include <kicon.h>
#include <kaboutdata.h>
#include <kcombobox.h>
#include <ktoolinvocation.h>
#include <kdebug.h>
#include <klineedit.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kstandarddirs.h>
#include <kcomponentdata.h>
#include <kurllabel.h>
#include <ktextedit.h>
#include <ktitlewidget.h>
#include <stdio.h>
#include <pwd.h>
#include <unistd.h>
#include <sys/utsname.h>
#include "kdepackages.h"
#include "kdeversion.h"
#include <config-compiler.h>
class KBugReportPrivate {
public:
KBugReportPrivate(KBugReport *q): q(q) {}
void _k_slotConfigureEmail();
void _k_slotSetFrom();
void _k_appChanged(int);
void _k_updateUrl();
KBugReport *q;
QProcess * m_process;
const KAboutData * m_aboutData;
KTextEdit * m_lineedit;
KLineEdit * m_subject;
QLabel * m_from;
QLabel * m_version;
QString m_strVersion;
QGroupBox * m_bgSeverity;
QPushButton * m_configureEmail;
KComboBox *appcombo;
QString lastError;
QString kde_version;
QString appname;
QString os;
KUrl url;
QList<QRadioButton*> severityButtons;
int currentSeverity() {
for (int i=0;i<severityButtons.count();i++)
if (severityButtons[i]->isChecked()) return i;
return -1;
}
bool submitBugWeb;
};
KBugReport::KBugReport( QWidget * _parent, bool modal, const KAboutData *aboutData )
: KDialog( _parent ), d( new KBugReportPrivate(this) )
{
setCaption( i18n("Submit Bug Report") );
setButtons( Ok | Cancel );
setModal(modal);
// Use supplied aboutdata, otherwise the one from the active componentData
// otherwise the KGlobal one. _activeInstance should neved be 0L in theory.
d->m_aboutData = aboutData ? aboutData
: (KGlobal::activeComponent().isValid() ? KGlobal::activeComponent().aboutData()
: KGlobal::mainComponent().aboutData());
d->m_process = 0;
QWidget * parent = new QWidget(this);
d->submitBugWeb = false;
if ( d->m_aboutData->bugAddress() == QLatin1String("submit@bugs.kde.org") )
{
// This is a core KDE application -> redirect to the web form
d->submitBugWeb = true;
setButtonGuiItem( Cancel, KStandardGuiItem::close() );
}
QLabel * tmpLabel;
QVBoxLayout * lay = new QVBoxLayout( parent);
KTitleWidget *title = new KTitleWidget( this );
title->setText(i18n( "Submit Bug Report" ) );
title->setPixmap( KIcon( "tools-report-bug" ).pixmap( 32 ) );
lay->addWidget( title );
QGridLayout *glay = new QGridLayout();
lay->addLayout(glay);
int row = 0;
if ( !d->submitBugWeb )
{
// From
QString qwtstr = i18n( "Your email address. If incorrect, use the Configure Email button to change it" );
tmpLabel = new QLabel( i18nc("Email sender address", "From:"), parent );
glay->addWidget( tmpLabel, row,0 );
tmpLabel->setWhatsThis(qwtstr );
d->m_from = new QLabel( parent );
glay->addWidget( d->m_from, row, 1 );
d->m_from->setWhatsThis(qwtstr );
// Configure email button
d->m_configureEmail = new QPushButton( i18n("Configure Email..."),
parent );
connect( d->m_configureEmail, SIGNAL( clicked() ), this,
SLOT( _k_slotConfigureEmail() ) );
glay->addWidget( d->m_configureEmail, 0, 2, 3, 1, Qt::AlignTop|Qt::AlignRight );
// To
qwtstr = i18n( "The email address this bug report is sent to." );
tmpLabel = new QLabel( i18nc("Email receiver address", "To:"), parent );
glay->addWidget( tmpLabel, ++row,0 );
tmpLabel->setWhatsThis(qwtstr );
tmpLabel = new QLabel( d->m_aboutData->bugAddress(), parent );
tmpLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
glay->addWidget( tmpLabel, row, 1 );
tmpLabel->setWhatsThis(qwtstr );
setButtonGuiItem( Ok, KGuiItem( i18n("&Send"), "mail-send", i18n( "Send bug report." ),
i18n( "Send this bug report to %1." , d->m_aboutData->bugAddress() ) ) );
row++;
}
else
{
d->m_configureEmail = 0;
d->m_from = 0;
}
// Program name
QString qwtstr = i18n( "The application for which you wish to submit a bug report - if incorrect, please use the Report Bug menu item of the correct application" );
tmpLabel = new QLabel( i18n("Application: "), parent );
glay->addWidget( tmpLabel, row, 0 );
tmpLabel->setWhatsThis(qwtstr );
d->appcombo = new KComboBox( false, parent );
d->appcombo->setWhatsThis(qwtstr );
QStringList packageList;
for (int c = 0; packages[c]; ++c)
packageList << QString::fromLatin1(packages[c]);
d->appcombo->addItems(packageList);
connect(d->appcombo, SIGNAL(activated(int)), SLOT(_k_appChanged(int)));
d->appname = d->m_aboutData
? d->m_aboutData->productName()
: qApp->applicationName() ;
glay->addWidget( d->appcombo, row, 1 );
int index = 0;
for (; index < d->appcombo->count(); index++) {
if (d->appcombo->itemText(index) == d->appname) {
break;
}
}
if (index == d->appcombo->count()) { // not present
d->appcombo->addItem(d->appname);
}
d->appcombo->setCurrentIndex(index);
tmpLabel->setWhatsThis(qwtstr );
// Version
qwtstr = i18n( "The version of this application - please make sure that no newer version is available before sending a bug report" );
tmpLabel = new QLabel( i18n("Version:"), parent );
glay->addWidget( tmpLabel, ++row, 0 );
tmpLabel->setWhatsThis(qwtstr );
if (d->m_aboutData)
d->m_strVersion = d->m_aboutData->version();
else
d->m_strVersion = i18n("no version set (programmer error)");
d->kde_version = QString::fromLatin1( KDE_VERSION_STRING );
d->kde_version += ", " + QString::fromLatin1( KDE_DISTRIBUTION_TEXT );
if ( !d->submitBugWeb )
d->m_strVersion += ' ' + d->kde_version;
d->m_version = new QLabel( d->m_strVersion, parent );
d->m_version->setTextInteractionFlags(Qt::TextBrowserInteraction);
//glay->addWidget( d->m_version, row, 1 );
glay->addWidget( d->m_version, row, 1, 1, 2 );
d->m_version->setWhatsThis(qwtstr );
tmpLabel = new QLabel(i18n("OS:"), parent);
glay->addWidget( tmpLabel, ++row, 0 );
struct utsname unameBuf;
uname( &unameBuf );
d->os = QString::fromLatin1( unameBuf.sysname ) +
" (" + QString::fromLatin1( unameBuf.machine ) + ") "
"release " + QString::fromLatin1( unameBuf.release );
tmpLabel = new QLabel(d->os, parent);
tmpLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
glay->addWidget( tmpLabel, row, 1, 1, 2 );
tmpLabel = new QLabel(i18n("Compiler:"), parent);
glay->addWidget( tmpLabel, ++row, 0 );
tmpLabel = new QLabel(QString::fromLatin1(KDE_COMPILER_VERSION), parent);
tmpLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
glay->addWidget( tmpLabel, row, 1, 1, 2 );
if ( !d->submitBugWeb )
{
// Severity
d->m_bgSeverity = new QGroupBox( i18n("Se&verity"), parent );
static const char * const sevNames[5] = { "critical", "grave", "normal", "wishlist", "i18n" };
const QString sevTexts[5] = { i18n("Critical"), i18n("Grave"), i18nc("normal severity","Normal"), i18n("Wishlist"), i18n("Translation") };
QHBoxLayout *severityLayout=new QHBoxLayout(d->m_bgSeverity);
for (int i = 0 ; i < 5 ; i++ )
{
// Store the severity string as the name
QRadioButton *rb = new QRadioButton( sevTexts[i], d->m_bgSeverity);
rb->setObjectName(sevNames[i] );
d->severityButtons.append(rb);
severityLayout->addWidget(rb);
if (i==2) rb->setChecked(true); // default : "normal"
}
lay->addWidget( d->m_bgSeverity );
// Subject
QHBoxLayout * hlay = new QHBoxLayout();
lay->addItem(hlay);
tmpLabel = new QLabel( i18n("S&ubject: "), parent );
hlay->addWidget( tmpLabel );
d->m_subject = new KLineEdit( parent );
d->m_subject->setClearButtonShown(true);
d->m_subject->setFocus();
tmpLabel->setBuddy( d->m_subject );
hlay->addWidget( d->m_subject );
QString text = i18n("Enter the text (in English if possible) that you wish to submit for the "
"bug report.\n"
"If you press \"Send\", a mail message will be sent to the maintainer of "
"this program.\n");
QLabel * label = new QLabel( parent);
label->setText( text );
lay->addWidget( label );
// The multiline-edit
d->m_lineedit = new KTextEdit( parent);
d->m_lineedit->setMinimumHeight( 180 ); // make it big
d->m_lineedit->setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
d->m_lineedit->setLineWrapMode(QTextEdit::WidgetWidth);
d->m_lineedit->setCheckSpellingEnabled(true);
d->m_lineedit->setSpellCheckingLanguage("en");
lay->addWidget( d->m_lineedit, 10 /*stretch*/ );
d->_k_slotSetFrom();
} else {
// Point to the web form
lay->addSpacing(10);
QString text = i18n("<qt>To submit a bug report, click on the button below. This will open a web browser "
"window on <a href=\"http://bugs.kde.org\">http://bugs.kde.org</a> where you will find "
"a form to fill in. The information displayed above will be transferred to that server.</qt>");
QLabel * label = new QLabel( text, parent);
label->setOpenExternalLinks( true );
label->setTextInteractionFlags( Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard );
label->setWordWrap( true );
lay->addWidget( label );
lay->addSpacing(10);
d->appcombo->setFocus();
d->_k_updateUrl();
setButtonText(Ok, i18n("&Launch Bug Report Wizard"));
setButtonIcon(Ok, KIcon("tools-report-bug"));
}
parent->setMinimumHeight( parent->sizeHint().height() + 20 ); // WORKAROUND: prevent "cropped" kcombobox
setMainWidget(parent);
}
KBugReport::~KBugReport()
{
delete d;
}
QString KBugReport::messageBody() const
{
if ( !d->submitBugWeb )
return d->m_lineedit->toPlainText();
else
return QString();
}
void KBugReport::setMessageBody(const QString &messageBody)
{
if ( !d->submitBugWeb )
d->m_lineedit->setPlainText(messageBody);
}
void KBugReportPrivate::_k_updateUrl()
{
url = KUrl( "https://bugs.kde.org/wizard.cgi" );
url.addQueryItem( "os", os );
url.addQueryItem( "compiler", KDE_COMPILER_VERSION );
url.addQueryItem( "kdeVersion", kde_version );
url.addQueryItem( "appVersion", m_strVersion );
url.addQueryItem( "package", appcombo->currentText() );
url.addQueryItem( "kbugreport", "1" );
}
void KBugReportPrivate::_k_appChanged(int i)
{
QString appName = appcombo->itemText(i);
int index = appName.indexOf( '/' );
if ( index > 0 )
appName = appName.left( index );
kDebug() << "appName " << appName;
QString strDisplayVersion; //Version string to show in the UI
if (appname == appName && m_aboutData) {
m_strVersion = m_aboutData->version();
strDisplayVersion = m_strVersion;
} else {
m_strVersion = QLatin1String("unknown"); //English string to put in the bug report
strDisplayVersion = i18nc("unknown program name", "unknown");
}
if ( !submitBugWeb ) {
m_strVersion += ' ' + kde_version;
strDisplayVersion += ' ' + kde_version;
}
m_version->setText(strDisplayVersion);
if ( submitBugWeb )
_k_updateUrl();
}
void KBugReportPrivate::_k_slotConfigureEmail()
{
if (m_process) return;
m_process = new QProcess;
QObject::connect( m_process, SIGNAL(finished( int, QProcess::ExitStatus )), q, SLOT(_k_slotSetFrom()) );
m_process->start( QString::fromLatin1("kcmshell4"), QStringList() << QString::fromLatin1("kcm_useraccount") );
if ( !m_process->waitForStarted() )
{
kDebug() << "Couldn't start kcmshell4..";
delete m_process;
m_process = 0;
return;
}
m_configureEmail->setEnabled(false);
}
void KBugReportPrivate::_k_slotSetFrom()
{
delete m_process;
m_process = 0;
m_configureEmail->setEnabled(true);
// ### KDE4: why oh why is KEMailSettings in kio?
KConfig emailConf( QString::fromLatin1("emaildefaults") );
KConfigGroup cg(&emailConf, "Defaults");
// find out the default profile
QString profile = QString::fromLatin1("PROFILE_");
profile += cg.readEntry( QString::fromLatin1("Profile"),
QString::fromLatin1("Default") );
KConfigGroup profileGrp(&emailConf, profile );
QString fromaddr = profileGrp.readEntry( "EmailAddress" );
if (fromaddr.isEmpty()) {
struct passwd *p;
p = getpwuid(getuid());
fromaddr = QString::fromLatin1(p->pw_name);
} else {
QString name = profileGrp.readEntry( "FullName" );
if (!name.isEmpty())
fromaddr = name + QString::fromLatin1(" <") + fromaddr + QString::fromLatin1(">");
}
m_from->setText( fromaddr );
}
void KBugReport::accept()
{
if ( d->submitBugWeb ) {
KToolInvocation::invokeBrowser( d->url.url() );
return;
}
if( d->m_lineedit->toPlainText().isEmpty() ||
d->m_subject->text().isEmpty() )
{
QString msg = i18n("You must specify both a subject and a description "
"before the report can be sent.");
KMessageBox::error(this,msg);
return;
}
switch ( d->currentSeverity())
{
case 0: // critical
if ( KMessageBox::questionYesNo( this, i18n(
"<p>You chose the severity <b>Critical</b>. "
"Please note that this severity is intended only for bugs that:</p>"
"<ul><li>break unrelated software on the system (or the whole system)</li>"
"<li>cause serious data loss</li>"
"<li>introduce a security hole on the system where the affected package is installed</li></ul>\n"
"<p>Does the bug you are reporting cause any of the above damage? "
"If it does not, please select a lower severity. Thank you.</p>" ),QString(),KStandardGuiItem::cont(),KStandardGuiItem::cancel() ) == KMessageBox::No )
return;
break;
case 1: // grave
if ( KMessageBox::questionYesNo( this, i18n(
"<p>You chose the severity <b>Grave</b>. "
"Please note that this severity is intended only for bugs that:</p>"
"<ul><li>make the package in question unusable or mostly so</li>"
"<li>cause data loss</li>"
"<li>introduce a security hole allowing access to the accounts of users who use the affected package</li></ul>\n"
"<p>Does the bug you are reporting cause any of the above damage? "
"If it does not, please select a lower severity. Thank you.</p>" ),QString(),KStandardGuiItem::cont(),KStandardGuiItem::cancel() ) == KMessageBox::No )
return;
break;
default:
break;
}
if( !sendBugReport() )
{
QString msg = i18n("Unable to send the bug report.\n"
"Please submit a bug report manually....\n"
"See http://bugs.kde.org/ for instructions.");
KMessageBox::error(this, msg + "\n\n" + d->lastError);
return;
}
KMessageBox::information(this,
i18n("Bug report sent, thank you for your input."));
KDialog::accept();
}
void KBugReport::closeEvent( QCloseEvent * e)
{
if( !d->submitBugWeb && ( (d->m_lineedit->toPlainText().length()>0) || d->m_subject->isModified() ) )
{
int rc = KMessageBox::warningYesNo( this,
i18n( "Close and discard\nedited message?" ),
i18n( "Close Message" ), KStandardGuiItem::discard(), KStandardGuiItem::cont() );
if( rc == KMessageBox::No )
{
e->ignore();
return;
}
}
KDialog::closeEvent(e);
}
QString KBugReport::text() const
{
kDebug() << d->severityButtons[d->currentSeverity()]->objectName();
// Prepend the pseudo-headers to the contents of the mail
QString severity = d->severityButtons[d->currentSeverity()]->objectName();
QString appname = d->appcombo->currentText();
QString os = QString::fromLatin1("OS: %1 (%2)\n").
arg(KDE_COMPILING_OS).
arg(KDE_DISTRIBUTION_TEXT);
QString bodyText;
/* for(int i = 0; i < m_lineedit->numLines(); i++)
{
QString line = m_lineedit->textLine(i);
if (!line.endsWith("\n"))
line += '\n';
bodyText += line;
}
*/
bodyText=d->m_lineedit->toPlainText();
if (bodyText.length()>0)
if (bodyText[bodyText.length()-1]!='\n') bodyText+='\n';
if (severity == QLatin1String("i18n") && KGlobal::locale()->language() != KLocale::defaultLanguage()) {
// Case 1 : i18n bug
QString package = QString::fromLatin1("i18n_%1").arg(KGlobal::locale()->language());
package = package.replace('_', '-');
return QString::fromLatin1("Package: %1").arg(package) +
QString::fromLatin1("\n"
"Application: %1\n"
// not really i18n's version, so better here IMHO
"Version: %2\n").arg(appname).arg(d->m_strVersion)+
os+QString::fromLatin1("\n")+bodyText;
} else {
appname = appname.replace('_', '-');
// Case 2 : normal bug
return QString::fromLatin1("Package: %1\n"
"Version: %2\n"
"Severity: %3\n")
.arg(appname).arg(d->m_strVersion).arg(severity)+
QString::fromLatin1("Compiler: %1\n").arg(KDE_COMPILER_VERSION)+
os+QString::fromLatin1("\n")+bodyText;
}
}
bool KBugReport::sendBugReport()
{
QString recipient ( d->m_aboutData ?
d->m_aboutData->bugAddress() :
QString::fromLatin1("submit@bugs.kde.org") );
QString command;
command = KStandardDirs::locate("exe", "ksendbugmail");
if (command.isEmpty())
command = KStandardDirs::findExe( QString::fromLatin1("ksendbugmail") ); // ### typically installed into libexec
QProcess proc;
QStringList args;
args << "--subject" << d->m_subject->text() << "--recipient" << recipient;
proc.start( command, args );
//kDebug() << command << args;
if (!proc.waitForStarted())
{
kError() << "Unable to open a pipe to " << command << endl;
return false;
}
proc.write( text().toUtf8() );
proc.closeWriteChannel();
proc.waitForFinished();
kDebug() << "kbugreport: sendbugmail exit, status " << proc.exitStatus() << " code " << proc.exitCode();
QByteArray line;
if (proc.exitStatus() == QProcess::NormalExit && proc.exitCode() != 0) {
// XXX not stderr?
while (!proc.atEnd())
line = proc.readLine();
d->lastError = QString::fromUtf8( line );
return false;
}
return true;
}
#include "moc_kbugreport.cpp"
diff --git a/kdeui/dialogs/kdialog.cpp b/kdeui/dialogs/kdialog.cpp
index d76bb21b40..9ea5ab5e4d 100644
--- a/kdeui/dialogs/kdialog.cpp
+++ b/kdeui/dialogs/kdialog.cpp
@@ -1,1112 +1,1113 @@
/* This file is part of the KDE Libraries
* Copyright (C) 1998 Thomas Tanghus (tanghus@earthling.net)
* Additions 1999-2000 by Espen Sand (espen@kde.org)
* by Holger Freyther <freyther@kde.org>
* 2005-2009 by Olivier Goffart (ogoffart at 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 as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* 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 "kdialog.h"
#include "kdialog_p.h"
#include <kdebug.h>
#include "kdialogqueue_p.h"
#include <config.h>
#include <QApplication>
#include <QDesktopWidget>
#include <QDialogButtonBox>
#include <QHBoxLayout>
#include <QHideEvent>
#include <QPointer>
#include <QStyle>
#include <QTimer>
#include <QVBoxLayout>
#include <QWhatsThis>
+#include <kicon.h>
#include <klocale.h>
#include <kpushbutton.h>
#include <kseparator.h>
#include <kstandardguiitem.h>
#include <ktoolinvocation.h>
#include <kurllabel.h>
#ifdef Q_WS_X11
#include <qx11info_x11.h>
#include <netwm.h>
#endif
static bool sAllowEmbeddingInGraphicsView = false;
void KDialogPrivate::setupLayout()
{
Q_Q(KDialog);
if (!dirty) {
QMetaObject::invokeMethod( q, "queuedLayoutUpdate", Qt::QueuedConnection );
dirty = true;
}
}
void KDialogPrivate::queuedLayoutUpdate()
{
if (!dirty)
return;
dirty = false;
Q_Q(KDialog);
// Don't lose the focus widget when re-creating the layout.
// Testcase: KOrganizer's "Select Categories" dialog
QPointer<QWidget> focusWidget = mMainWidget ? mMainWidget->focusWidget() : 0;
if (q->layout() && q->layout() != mTopLayout) {
kWarning(240) << q->metaObject()->className() << "created with a layout; don't do that, KDialog takes care of it, use mainWidget or setMainWidget instead";
delete q->layout();
}
delete mTopLayout;
if ( mButtonOrientation == Qt::Horizontal )
mTopLayout = new QVBoxLayout(q);
else
mTopLayout = new QHBoxLayout(q);
if ( mUrlHelp )
mTopLayout->addWidget( mUrlHelp, 0, Qt::AlignRight );
if ( mMainWidget )
mTopLayout->addWidget( mMainWidget, 10 );
if ( mDetailsWidget )
mTopLayout->addWidget( mDetailsWidget );
if ( mActionSeparator )
mTopLayout->addWidget( mActionSeparator );
if ( mButtonBox ) {
mButtonBox->setOrientation( mButtonOrientation );
mTopLayout->addWidget( mButtonBox );
}
if (focusWidget) {
focusWidget->setFocus();
}
}
void KDialogPrivate::appendButton(KDialog::ButtonCode key, const KGuiItem &item)
{
Q_Q(KDialog);
QDialogButtonBox::ButtonRole role = QDialogButtonBox::InvalidRole;
switch ( key ) {
case KDialog::Help:
case KDialog::Details:
role = QDialogButtonBox::HelpRole;
break;
case KDialog::Default:
case KDialog::Reset:
role = QDialogButtonBox::ResetRole;
break;
case KDialog::Ok:
role = QDialogButtonBox::AcceptRole;
break;
case KDialog::Apply:
role = QDialogButtonBox::ApplyRole;
break;
case KDialog::Try:
case KDialog::Yes:
role = QDialogButtonBox::YesRole;
break;
case KDialog::Close:
case KDialog::Cancel:
role = QDialogButtonBox::RejectRole;
break;
case KDialog::No:
role = QDialogButtonBox::NoRole;
break;
case KDialog::User1:
case KDialog::User2:
case KDialog::User3:
role = QDialogButtonBox::ActionRole;
break;
default:
role = QDialogButtonBox::InvalidRole;
break;
}
if ( role == QDialogButtonBox::InvalidRole )
return;
KPushButton *button = new KPushButton( item );
mButtonBox->addButton( button, role );
mButtonList.insert( key, button );
mButtonSignalMapper.setMapping( button, key );
QObject::connect(button, SIGNAL(clicked()),
&mButtonSignalMapper, SLOT( map() ) );
if (key == mDefaultButton) {
// Now that it exists, set it as default
q->setDefaultButton(mDefaultButton);
}
}
void KDialogPrivate::init(KDialog *q)
{
q_ptr = q;
dirty = false;
q->setButtons(KDialog::Ok | KDialog::Cancel);
q->setDefaultButton(KDialog::Ok);
q->connect(&mButtonSignalMapper, SIGNAL(mapped(int)), q, SLOT(slotButtonClicked(int)));
q->setPlainCaption(KGlobal::caption()); // set appropriate initial window title for case it gets not set later
}
void KDialogPrivate::helpLinkClicked()
{
q_ptr->slotButtonClicked(KDialog::Help);
}
KDialog::KDialog( QWidget *parent, Qt::WFlags flags )
: QDialog(parent, sAllowEmbeddingInGraphicsView ? flags : flags | Qt::BypassGraphicsProxyWidget ), d_ptr(new KDialogPrivate)
{
d_ptr->init(this);
}
KDialog::KDialog(KDialogPrivate &dd, QWidget *parent, Qt::WFlags flags)
: QDialog(parent, sAllowEmbeddingInGraphicsView ? flags : flags | Qt::BypassGraphicsProxyWidget), d_ptr(&dd)
{
d_ptr->init(this);
}
KDialog::~KDialog()
{
delete d_ptr;
}
void KDialog::setButtons( ButtonCodes buttonMask )
{
Q_D(KDialog);
if ( d->mButtonBox ) {
d->mButtonList.clear();
delete d->mButtonBox;
d->mButtonBox = 0;
}
if ( buttonMask & Cancel )
buttonMask &= ~Close;
if ( buttonMask & Apply )
buttonMask &= ~Try;
if ( buttonMask & Details )
buttonMask &= ~Default;
if ( buttonMask == None ) {
d->setupLayout();
return; // When we want no button box
}
d->mEscapeButton = (buttonMask & Cancel) ? Cancel : Close;
d->mButtonBox = new QDialogButtonBox( this );
if ( buttonMask & Help )
d->appendButton( Help, KStandardGuiItem::help() );
if ( buttonMask & Default )
d->appendButton( Default, KStandardGuiItem::defaults() );
if ( buttonMask & Reset )
d->appendButton( Reset, KStandardGuiItem::reset() );
if ( buttonMask & User3 )
d->appendButton( User3, KGuiItem() );
if ( buttonMask & User2 )
d->appendButton( User2, KGuiItem() );
if ( buttonMask & User1 )
d->appendButton( User1, KGuiItem() );
if ( buttonMask & Ok )
d->appendButton( Ok, KStandardGuiItem::ok() );
if ( buttonMask & Apply )
d->appendButton( Apply, KStandardGuiItem::apply() );
if ( buttonMask & Try )
d->appendButton( Try, KGuiItem(i18n( "&Try" )) );
if ( buttonMask & Cancel )
d->appendButton( Cancel, KStandardGuiItem::cancel() );
if ( buttonMask & Close )
d->appendButton( Close, KStandardGuiItem::close() );
if ( buttonMask & Yes )
d->appendButton( Yes, KStandardGuiItem::yes() );
if ( buttonMask & No )
d->appendButton( No, KStandardGuiItem::no() );
if ( buttonMask & Details ) {
d->appendButton( Details, KGuiItem(QString(), "help-about") );
setDetailsWidgetVisible( false );
}
d->setupLayout();
}
void KDialog::setButtonsOrientation( Qt::Orientation orientation )
{
Q_D(KDialog);
if ( d->mButtonOrientation != orientation ) {
d->mButtonOrientation = orientation;
if ( d->mActionSeparator )
d->mActionSeparator->setOrientation( d->mButtonOrientation );
if ( d->mButtonOrientation == Qt::Vertical )
enableLinkedHelp( false ); // 2000-06-18 Espen: No support for this yet.
}
}
void KDialog::setEscapeButton( ButtonCode id )
{
d_func()->mEscapeButton = id;
}
void KDialog::setDefaultButton( ButtonCode newDefaultButton )
{
Q_D(KDialog);
if (newDefaultButton == None)
newDefaultButton = NoDefault; // #148969
const KDialog::ButtonCode oldDefault = defaultButton();
bool oldDefaultHadFocus = false;
if (oldDefault != NoDefault) {
KPushButton *old = button(oldDefault);
if (old) {
oldDefaultHadFocus = (focusWidget() == old);
old->setDefault(false);
}
}
if (newDefaultButton != NoDefault) {
KPushButton *b = button(newDefaultButton);
if (b) {
b->setDefault(true);
if (focusWidget() == 0 || oldDefaultHadFocus) {
// No widget had focus yet, or the old default button had
// -> ok to give focus to the new default button, so that it's
// really default (Enter triggers it).
// But we don't do this if the kdialog user gave focus to a
// specific widget in the dialog.
b->setFocus();
}
}
}
d->mDefaultButton = newDefaultButton;
Q_ASSERT(defaultButton() == newDefaultButton);
}
KDialog::ButtonCode KDialog::defaultButton() const
{
Q_D(const KDialog);
QHashIterator<int, KPushButton*> it( d->mButtonList );
while ( it.hasNext() ) {
it.next();
if (it.value()->isDefault()) {
return (ButtonCode)it.key();
}
}
return d->mDefaultButton;
}
void KDialog::setMainWidget( QWidget *widget )
{
Q_D(KDialog);
if ( d->mMainWidget == widget )
return;
d->mMainWidget = widget;
if (d->mMainWidget && d->mMainWidget->layout()) {
// Avoid double-margin problem
d->mMainWidget->layout()->setMargin(0);
}
d->setupLayout();
}
QWidget *KDialog::mainWidget()
{
Q_D(KDialog);
if (!d->mMainWidget)
setMainWidget( new QWidget(this) );
return d->mMainWidget;
}
QSize KDialog::sizeHint() const
{
Q_D(const KDialog);
if (!d->mMinSize.isEmpty())
return d->mMinSize.expandedTo( minimumSizeHint() ) + d->mIncSize;
else {
if (d->dirty)
const_cast<KDialogPrivate*>(d)->queuedLayoutUpdate();
return QDialog::sizeHint() + d->mIncSize;
}
}
QSize KDialog::minimumSizeHint() const
{
Q_D(const KDialog);
if (d->dirty)
const_cast<KDialogPrivate*>(d)->queuedLayoutUpdate();
return QDialog::minimumSizeHint() + d->mIncSize;
}
//
// Grab QDialogs keypresses if non-modal.
//
void KDialog::keyPressEvent( QKeyEvent *event )
{
Q_D(KDialog);
if ( event->modifiers() == 0 ) {
if ( event->key() == Qt::Key_F1 ) {
KPushButton *button = this->button( Help );
if ( button ) {
button->animateClick();
event->accept();
return;
}
}
if ( event->key() == Qt::Key_Escape ) {
KPushButton *button = this->button( d->mEscapeButton );
if ( button ) {
button->animateClick();
event->accept();
return;
}
}
} else if ( event->key() == Qt::Key_F1 && event->modifiers() == Qt::ShiftModifier ) {
QWhatsThis::enterWhatsThisMode();
event->accept();
return;
} else if ( event->modifiers() == Qt::ControlModifier &&
( event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter ) ) {
// accept the dialog when Ctrl-Return is pressed
KPushButton *button = this->button( Ok );
if ( button ) {
button->animateClick();
event->accept();
return;
}
}
QDialog::keyPressEvent( event );
}
int KDialog::marginHint()
{
return QApplication::style()->pixelMetric( QStyle::PM_DefaultChildMargin );
}
int KDialog::spacingHint()
{
return QApplication::style()->pixelMetric( QStyle::PM_DefaultLayoutSpacing );
}
int KDialog::groupSpacingHint()
{
return QApplication::fontMetrics().lineSpacing();
}
QString KDialog::makeStandardCaption( const QString &userCaption,
QWidget* window,
CaptionFlags flags )
{
Q_UNUSED(window);
QString caption = KGlobal::caption();
QString captionString = userCaption.isEmpty() ? caption : userCaption;
// If the document is modified, add '[modified]'.
if (flags & ModifiedCaption)
captionString += QString::fromUtf8(" [") + i18n("modified") + QString::fromUtf8("]");
if ( !userCaption.isEmpty() ) {
// Add the application name if:
// User asked for it, it's not a duplication and the app name (caption()) is not empty
if ( flags & AppNameCaption &&
!caption.isEmpty() &&
!userCaption.endsWith(caption) ) {
// TODO: check to see if this is a transient/secondary window before trying to add the app name
// on platforms that need this
captionString += i18nc("Document/application separator in titlebar", " – ") + caption;
}
}
return captionString;
}
void KDialog::setCaption( const QString &_caption )
{
const QString caption = makeStandardCaption( _caption, this );
setPlainCaption( caption );
}
void KDialog::setCaption( const QString &caption, bool modified )
{
CaptionFlags flags = HIGCompliantCaption;
if ( modified )
{
flags |= ModifiedCaption;
}
setPlainCaption( makeStandardCaption(caption, this, flags) );
}
void KDialog::setPlainCaption( const QString &caption )
{
if (QWidget *win = window()) {
win->setWindowTitle( caption );
#ifdef Q_WS_X11
NETWinInfo info( QX11Info::display(), win->winId(), QX11Info::appRootWindow(), 0 );
info.setName( caption.toUtf8().constData() );
#endif
}
}
void KDialog::resizeLayout( QWidget *widget, int margin, int spacing ) //static
{
if ( widget->layout() )
resizeLayout( widget->layout(), margin, spacing );
if ( widget->children().count() > 0 ) {
const QList<QObject*> list = widget->children();
foreach ( QObject *object, list ) {
if ( object->isWidgetType() )
resizeLayout( (QWidget*)object, margin, spacing );
}
}
}
void KDialog::resizeLayout( QLayout *layout, int margin, int spacing ) //static
{
QLayoutItem *child;
int pos = 0;
while ( (child = layout->itemAt( pos ) ) ) {
if ( child->layout() )
resizeLayout( child->layout(), margin, spacing );
++pos;
}
if ( layout->layout() ) {
layout->layout()->setMargin( margin );
layout->layout()->setSpacing( spacing );
}
}
static QRect screenRect( QWidget *widget, int screen )
{
QDesktopWidget *desktop = QApplication::desktop();
KConfig gc( "kdeglobals", KConfig::NoGlobals );
KConfigGroup cg(&gc, "Windows" );
if ( desktop->isVirtualDesktop() &&
cg.readEntry( "XineramaEnabled", true ) &&
cg.readEntry( "XineramaPlacementEnabled", true ) ) {
if ( screen < 0 || screen >= desktop->numScreens() ) {
if ( screen == -1 )
screen = desktop->primaryScreen();
else if ( screen == -3 )
screen = desktop->screenNumber( QCursor::pos() );
else
screen = desktop->screenNumber( widget );
}
return desktop->availableGeometry( screen );
} else
return desktop->geometry();
}
void KDialog::centerOnScreen( QWidget *widget, int screen )
{
if ( !widget )
return;
#ifdef Q_WS_X11
if( !( widget->windowFlags() & Qt::X11BypassWindowManagerHint ) && widget->windowType() != Qt::Popup
&& NETRootInfo( QX11Info::display(), NET::Supported ).isSupported( NET::WM2FullPlacement )) {
return; // the WM can handle placement much better
}
#endif
QRect rect = screenRect( widget, screen );
widget->move( rect.center().x() - widget->width() / 2,
rect.center().y() - widget->height() / 2 );
}
bool KDialog::avoidArea( QWidget *widget, const QRect& area, int screen )
{
if ( !widget )
return false;
QRect fg = widget->frameGeometry();
if ( !fg.intersects( area ) )
return true; // nothing to do.
const QRect scr = screenRect( widget, screen );
QRect avoid( area ); // let's add some margin
avoid.translate( -5, -5 );
avoid.setRight( avoid.right() + 10 );
avoid.setBottom( avoid.bottom() + 10 );
if ( qMax( fg.top(), avoid.top() ) <= qMin( fg.bottom(), avoid.bottom() ) ) {
// We need to move the widget up or down
int spaceAbove = qMax( 0, avoid.top() - scr.top() );
int spaceBelow = qMax( 0, scr.bottom() - avoid.bottom() );
if ( spaceAbove > spaceBelow ) // where's the biggest side?
if ( fg.height() <= spaceAbove ) // big enough?
fg.setY( avoid.top() - fg.height() );
else
return false;
else
if ( fg.height() <= spaceBelow ) // big enough?
fg.setY( avoid.bottom() );
else
return false;
}
if ( qMax( fg.left(), avoid.left() ) <= qMin( fg.right(), avoid.right() ) ) {
// We need to move the widget left or right
const int spaceLeft = qMax( 0, avoid.left() - scr.left() );
const int spaceRight = qMax( 0, scr.right() - avoid.right() );
if ( spaceLeft > spaceRight ) // where's the biggest side?
if ( fg.width() <= spaceLeft ) // big enough?
fg.setX( avoid.left() - fg.width() );
else
return false;
else
if ( fg.width() <= spaceRight ) // big enough?
fg.setX( avoid.right() );
else
return false;
}
widget->move( fg.x(), fg.y() );
return true;
}
void KDialog::showButtonSeparator( bool state )
{
Q_D(KDialog);
if ( ( d->mActionSeparator != 0 ) == state )
return;
if ( state ) {
if ( d->mActionSeparator )
return;
d->mActionSeparator = new KSeparator( this );
d->mActionSeparator->setOrientation( d->mButtonOrientation );
} else {
delete d->mActionSeparator;
d->mActionSeparator = 0;
}
d->setupLayout();
}
void KDialog::setInitialSize( const QSize &size )
{
d_func()->mMinSize = size;
adjustSize();
}
void KDialog::incrementInitialSize( const QSize &size )
{
d_func()->mIncSize = size;
adjustSize();
}
KPushButton *KDialog::button( ButtonCode id ) const
{
Q_D(const KDialog);
return d->mButtonList.value( id, 0 );
}
void KDialog::enableButton( ButtonCode id, bool state )
{
KPushButton *button = this->button( id );
if ( button )
button->setEnabled( state );
}
bool KDialog::isButtonEnabled( ButtonCode id ) const
{
KPushButton *button = this->button( id );
if ( button )
return button->isEnabled();
return false;
}
void KDialog::enableButtonOk( bool state )
{
enableButton( Ok, state );
}
void KDialog::enableButtonApply( bool state )
{
enableButton( Apply, state );
}
void KDialog::enableButtonCancel( bool state )
{
enableButton( Cancel, state );
}
void KDialog::showButton( ButtonCode id, bool state )
{
KPushButton *button = this->button( id );
if ( button )
state ? button->show() : button->hide();
}
void KDialog::setButtonGuiItem( ButtonCode id, const KGuiItem &item )
{
KPushButton *button = this->button( id );
if ( !button )
return;
button->setGuiItem( item );
}
void KDialog::setButtonMenu( ButtonCode id, QMenu *menu, ButtonPopupMode popupmode)
{
KPushButton *button = this->button( id );
if ( button ) {
if (popupmode==InstantPopup)
button->setMenu( menu );
else
button->setDelayedMenu(menu);
}
}
void KDialog::setButtonText( ButtonCode id, const QString &text )
{
Q_D(KDialog);
if ( !d->mSettingDetails && (id == Details) ) {
d->mDetailsButtonText = text;
setDetailsWidgetVisible( d->mDetailsVisible );
return;
}
KPushButton *button = this->button( id );
if ( button )
button->setText( text );
}
QString KDialog::buttonText( ButtonCode id ) const
{
KPushButton *button = this->button( id );
if ( button )
return button->text();
else
return QString();
}
-void KDialog::setButtonIcon( ButtonCode id, const KIcon &icon )
+void KDialog::setButtonIcon( ButtonCode id, const QIcon &icon )
{
KPushButton *button = this->button( id );
if ( button )
button->setIcon( icon );
}
-KIcon KDialog::buttonIcon( ButtonCode id ) const
+QIcon KDialog::buttonIcon( ButtonCode id ) const
{
KPushButton *button = this->button( id );
if ( button )
return KIcon(button->icon());
else
return KIcon();
}
void KDialog::setButtonToolTip( ButtonCode id, const QString &text )
{
KPushButton *button = this->button( id );
if ( button ) {
if ( text.isEmpty() )
button->setToolTip( QString() );
else
button->setToolTip( text );
}
}
QString KDialog::buttonToolTip( ButtonCode id ) const
{
KPushButton *button = this->button( id );
if ( button )
return button->toolTip();
else
return QString();
}
void KDialog::setButtonWhatsThis( ButtonCode id, const QString &text )
{
KPushButton *button = this->button( id );
if ( button ) {
if ( text.isEmpty() )
button->setWhatsThis( QString() );
else
button->setWhatsThis( text );
}
}
QString KDialog::buttonWhatsThis( ButtonCode id ) const
{
KPushButton *button = this->button( id );
if ( button )
return button->whatsThis();
else
return QString();
}
void KDialog::setButtonFocus( ButtonCode id )
{
KPushButton *button = this->button( id );
if ( button ) {
button->setFocus();
}
}
void KDialog::setDetailsWidget( QWidget *detailsWidget )
{
Q_D(KDialog);
if ( d->mDetailsWidget == detailsWidget )
return;
delete d->mDetailsWidget;
d->mDetailsWidget = detailsWidget;
if ( d->mDetailsWidget->parentWidget() != this )
d->mDetailsWidget->setParent( this );
d->mDetailsWidget->hide();
d->setupLayout();
if ( !d->mSettingDetails )
setDetailsWidgetVisible( d->mDetailsVisible );
}
bool KDialog::isDetailsWidgetVisible() const
{
return d_func()->mDetailsVisible;
}
void KDialog::setDetailsWidgetVisible( bool visible )
{
Q_D(KDialog);
if ( d->mDetailsButtonText.isEmpty() )
d->mDetailsButtonText = i18n( "&Details" );
d->mSettingDetails = true;
d->mDetailsVisible = visible;
if ( d->mDetailsVisible ) {
emit aboutToShowDetails();
setButtonText( Details, d->mDetailsButtonText + " <<" );
if ( d->mDetailsWidget ) {
if ( layout() )
layout()->setEnabled( false );
d->mDetailsWidget->show();
adjustSize();
if ( layout() ) {
layout()->activate();
layout()->setEnabled( true );
}
}
} else {
setButtonText( Details, d->mDetailsButtonText + " >>" );
if ( d->mDetailsWidget )
d->mDetailsWidget->hide();
if ( layout() ) {
layout()->activate();
adjustSize();
}
}
d->mSettingDetails = false;
}
void KDialog::delayedDestruct()
{
if ( isVisible() )
hide();
deleteLater();
}
void KDialog::slotButtonClicked( int button )
{
Q_D(KDialog);
emit buttonClicked( static_cast<KDialog::ButtonCode>(button) );
switch( button ) {
case Ok:
emit okClicked();
accept();
break;
case Apply:
emit applyClicked();
break;
case Try:
emit tryClicked();
break;
case User3:
emit user3Clicked();
break;
case User2:
emit user2Clicked();
break;
case User1:
emit user1Clicked();
break;
case Yes:
emit yesClicked();
done( Yes );
break;
case No:
emit noClicked();
done( No );
break;
case Cancel:
emit cancelClicked();
reject();
break;
case Close:
emit closeClicked();
done(Close); // KDE5: call reject() instead; more QDialog-like.
break;
case Help:
emit helpClicked();
if ( !d->mAnchor.isEmpty() || !d->mHelpApp.isEmpty() )
KToolInvocation::invokeHelp( d->mAnchor, d->mHelpApp );
break;
case Default:
emit defaultClicked();
break;
case Reset:
emit resetClicked();
break;
case Details:
setDetailsWidgetVisible( !d->mDetailsVisible );
break;
}
// If we're here from the closeEvent, and auto-delete is on, well, auto-delete now.
if (d->mDeferredDelete) {
d->mDeferredDelete = false;
delayedDestruct();
}
}
void KDialog::enableLinkedHelp( bool state )
{
Q_D(KDialog);
if ( ( d->mUrlHelp != 0 ) == state )
return;
if ( state ) {
if ( d->mUrlHelp )
return;
d->mUrlHelp = new KUrlLabel( this );
d->mUrlHelp->setText( helpLinkText() );
d->mUrlHelp->setFloatEnabled( true );
d->mUrlHelp->setUnderline( true );
d->mUrlHelp->setMinimumHeight( fontMetrics().height() + marginHint() );
connect( d->mUrlHelp, SIGNAL(leftClickedUrl()), SLOT(helpLinkClicked()) );
d->mUrlHelp->show();
} else {
delete d->mUrlHelp;
d->mUrlHelp = 0;
}
d->setupLayout();
}
void KDialog::setHelp( const QString &anchor, const QString &appname )
{
Q_D(KDialog);
d->mAnchor = anchor;
d->mHelpApp = appname;
}
void KDialog::setHelpLinkText( const QString &text )
{
Q_D(KDialog);
d->mHelpLinkText = text;
if ( d->mUrlHelp )
d->mUrlHelp->setText( helpLinkText() );
}
QString KDialog::helpLinkText() const
{
Q_D(const KDialog);
return ( d->mHelpLinkText.isEmpty() ? i18n( "Get help..." ) : d->mHelpLinkText );
}
void KDialog::updateGeometry()
{
}
void KDialog::hideEvent( QHideEvent *event )
{
emit hidden();
if ( !event->spontaneous() )
emit finished();
}
void KDialog::closeEvent( QCloseEvent *event )
{
Q_D(KDialog);
KPushButton *button = this->button(d->mEscapeButton);
if (button && !isHidden()) {
button->animateClick();
if (testAttribute(Qt::WA_DeleteOnClose)) {
// Don't let QWidget::close do a deferred delete just yet, wait for the click first
d->mDeferredDelete = true;
setAttribute(Qt::WA_DeleteOnClose, false);
}
} else {
QDialog::closeEvent(event);
}
}
void KDialog::restoreDialogSize( const KConfigGroup& cfg )
{
int width, height;
int scnum = QApplication::desktop()->screenNumber( parentWidget() );
QRect desk = QApplication::desktop()->screenGeometry( scnum );
width = sizeHint().width();
height = sizeHint().height();
width = cfg.readEntry( QString::fromLatin1( "Width %1" ).arg( desk.width() ), width );
height = cfg.readEntry( QString::fromLatin1( "Height %1" ).arg( desk.height() ), height );
resize( width, height );
}
void KDialog::saveDialogSize( KConfigGroup& config, KConfigGroup::WriteConfigFlags options ) const
{
int scnum = QApplication::desktop()->screenNumber( parentWidget() );
QRect desk = QApplication::desktop()->screenGeometry( scnum );
const QSize sizeToSave = size();
config.writeEntry( QString::fromLatin1("Width %1").arg( desk.width() ), sizeToSave.width(), options );
config.writeEntry( QString::fromLatin1("Height %1").arg( desk.height() ), sizeToSave.height(), options );
}
void KDialog::setAllowEmbeddingInGraphicsView( bool allowEmbedding )
{
sAllowEmbeddingInGraphicsView = allowEmbedding;
}
class KDialogQueue::Private
{
public:
Private(KDialogQueue *q): q(q) {}
void slotShowQueuedDialog();
KDialogQueue *q;
QList< QPointer<QDialog> > queue;
bool busy;
};
KDialogQueue* KDialogQueue::self()
{
K_GLOBAL_STATIC(KDialogQueue, _self)
return _self;
}
KDialogQueue::KDialogQueue()
: d( new Private(this) )
{
d->busy = false;
}
KDialogQueue::~KDialogQueue()
{
delete d;
}
// static
void KDialogQueue::queueDialog( QDialog *dialog )
{
KDialogQueue *_this = self();
_this->d->queue.append( dialog );
QTimer::singleShot( 0, _this, SLOT( slotShowQueuedDialog() ) );
}
void KDialogQueue::Private::slotShowQueuedDialog()
{
if ( busy )
return;
QDialog *dialog;
do {
if ( queue.isEmpty() )
return;
dialog = queue.first();
queue.pop_front();
} while( !dialog );
busy = true;
dialog->exec();
busy = false;
delete dialog;
if ( !queue.isEmpty() )
QTimer::singleShot( 20, q, SLOT( slotShowQueuedDialog() ) );
}
#include "moc_kdialog.cpp"
#include "moc_kdialogqueue_p.cpp"
diff --git a/kdeui/dialogs/kdialog.h b/kdeui/dialogs/kdialog.h
index 3af16bd68b..823dbb232b 100644
--- a/kdeui/dialogs/kdialog.h
+++ b/kdeui/dialogs/kdialog.h
@@ -1,866 +1,866 @@
/* This file is part of the KDE Libraries
* Copyright (C) 1998 Thomas Tanghus (tanghus@earthling.net)
* Additions 1999-2000 by Espen Sand (espen@kde.org)
* and Holger Freyther <freyther@kde.org>
* 2005-2009 Olivier Goffart <ogoffart @ kde.org>
* 2006 Tobias Koenig <tokoe@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 as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* 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.
*/
#ifndef KDIALOG_H
#define KDIALOG_H
class KPushButton;
class QMenu;
class KDialogPrivate;
#include <kdeui_export.h>
#include <kconfiggroup.h>
#include <kguiitem.h>
#include <QDialog>
/**
* @short A dialog base class with standard buttons and predefined layouts.
*
* Provides basic functionality needed by nearly all dialogs.
*
* It offers the standard action buttons you'd expect to find in a
* dialog as well as the capability to define at most three configurable
* buttons. You can define a main widget that contains your specific
* dialog layout
*
* The class takes care of the geometry management. You only need to define
* a minimum size for the widget you want to use as the main widget.
*
* By default, the dialog is non-modal.
*
* <b>Standard buttons (action buttons):</b>\n
*
* You select which buttons should be displayed, but you do not choose the
* order in which they are displayed. This ensures a standard interface in
* KDE. The button order can be changed, but this ability is only available
* for a central KDE control tool. The following buttons are available:
* OK, Cancel/Close, Apply/Try, Default, Help and three user definable
* buttons: User1, User2 and User3. You must specify the text of the UserN
* buttons. Each button emit a signal, so you can choose to connect that signal.
*
* The default action of the Help button will open the help system if you have
* provided a path to the help text.
* The default action of Ok and Cancel will run QDialog::accept() and QDialog::reject(),
* which you can override by reimplementing slotButtonClicked(). The default
* action of the Close button will close the dialog.
*
* Note that the KDialog will animate a button press
* when the user presses Escape. The button that is enabled is either Cancel,
* Close or the button that is defined by setEscapeButton().
* Your custom dialog code should reimplement the keyPressEvent and
* animate the cancel button so that the dialog behaves like regular
* dialogs.
*
* <b>Layout:</b>\n
*
* The dialog consists of a help area on top (becomes visible if you define
* a help path and use enableLinkedHelp()), the main area which is
* the built-in dialog face or your own widget in the middle and by default
* a button box at the bottom. The button box can also be placed at the
* right edge (to the right of the main widget). Use
* setButtonsOrientation() to control this behavior. A separator
* can be placed above the button box (or to the left when the button box
* is at the right edge).
*
* <b>Standard compliance:</b>\n
*
* The marginHint() and spacingHint() sizes shall be used
* whenever you lay out the interior of a dialog. One special note. If
* you make your own action buttons (OK, Cancel etc), the space
* between the buttons shall be spacingHint(), whereas the space
* above, below, to the right and to the left shall be marginHint().
* If you add a separator line above the buttons, there shall be a
* marginHint() between the buttons and the separator and a
* marginHint() above the separator as well.
*
* <b>Example:</b>\n
*
* \code
* KDialog *dialog = new KDialog( this );
* dialog->setCaption( "My title" );
* dialog->setButtons( KDialog::Ok | KDialog::Cancel | KDialog::Apply );
*
* FooWidget *widget = new FooWidget( dialog );
* dialog->setMainWidget( widget );
* connect( dialog, SIGNAL( applyClicked() ), widget, SLOT( save() ) );
* connect( dialog, SIGNAL( okClicked() ), widget, SLOT( save() ) );
* connect( widget, SIGNAL( changed( bool ) ), dialog, SLOT( enableButtonApply( bool ) ) );
*
* dialog->enableButtonApply( false );
* dialog->show();
* \endcode
*
* \image html kdialog.png "KDE Dialog example"
*
* This class can be used in many ways. Note that most KDE ui widgets
* and many of KDE core applications use the KDialog so for more
* inspiration you should study the code for these.
*
*
* @see KPageDialog
* @author Thomas Tanghus <tanghus@earthling.net>
* @author Espen Sand <espensa@online.no>
* @author Mirko Boehm <mirko@kde.org>
* @author Olivier Goffart <ogoffart at kde.org>
* @author Tobias Koenig <tokoe@kde.org>
*/
class KDEUI_EXPORT KDialog : public QDialog //krazy:exclude=qclasses
{
Q_OBJECT
Q_ENUMS(ButtonCode)
Q_DECLARE_PRIVATE(KDialog)
public:
enum ButtonCode
{
None = 0x00000000,
Help = 0x00000001, ///< Show Help button. (this button will run the help set with setHelp)
Default = 0x00000002, ///< Show Default button.
Ok = 0x00000004, ///< Show Ok button. (this button accept()s the dialog; result set to QDialog::Accepted)
Apply = 0x00000008, ///< Show Apply button.
Try = 0x00000010, ///< Show Try button.
Cancel = 0x00000020, ///< Show Cancel-button. (this button reject()s the dialog; result set to QDialog::Rejected)
Close = 0x00000040, ///< Show Close-button. (this button closes the dialog)
No = 0x00000080, ///< Show No button. (this button closes the dialog and sets the result to KDialog::No)
Yes = 0x00000100, ///< Show Yes button. (this button closes the dialog and sets the result to KDialog::Yes)
Reset = 0x00000200, ///< Show Reset button
Details = 0x00000400, ///< Show Details button. (this button will show the detail widget set with setDetailsWidget)
User1 = 0x00001000, ///< Show User defined button 1.
User2 = 0x00002000, ///< Show User defined button 2.
User3 = 0x00004000, ///< Show User defined button 3.
NoDefault = 0x00008000 ///< Used when specifying a default button; indicates that no button should be marked by default.
};
// TODO KDE5: remove NoDefault and use the value None instead
Q_DECLARE_FLAGS(ButtonCodes, ButtonCode)
enum ButtonPopupMode
{
InstantPopup = 0,
DelayedPopup = 1
};
Q_DECLARE_FLAGS(ButtonPopupModes, ButtonPopupMode)
public:
/**
* Creates a dialog.
*
* @param parent The parent of the dialog.
* @param flags The widget flags passed to the QDialog constructor
*/
explicit KDialog( QWidget *parent = 0, Qt::WFlags flags = 0 );
/**
* Destroys the dialog.
*/
~KDialog();
/**
* Creates (or recreates) the button box and all the buttons in it.
*
* Note that some combinations are not possible. That means, you can't
* have the following pairs of buttons in a dialog:
* - Default and Details
* - Cancel and Close
* - Ok and Try
*
* This will reset all default KGuiItem of all button.
*
* @param buttonMask Specifies what buttons will be made.
*/
void setButtons( ButtonCodes buttonMask );
/**
* Sets the orientation of the button box.
*
* It can be @p Vertical or @p Horizontal. If @p Horizontal
* (default), the button box is positioned at the bottom of the
* dialog. If @p Vertical it will be placed at the right edge of the
* dialog.
*
* @param orientation The button box orientation.
*/
void setButtonsOrientation( Qt::Orientation orientation );
/**
* Sets the button that will be activated when the Escape key
* is pressed.
*
* By default, the Escape key is mapped to either the Cancel or the Close button
* if one of these buttons are defined. The user expects that Escape will
* cancel an operation so use this function with caution.
*
* @param id The button code.
*/
void setEscapeButton( ButtonCode id );
/**
* Sets the button that will be activated when the Enter key
* is pressed.
*
* By default, this is the Ok button if it is present
*
* @param id The button code.
*/
void setDefaultButton( ButtonCode id );
/**
* Returns the button code of the default button,
* or NoDefault if there is no default button.
*/
ButtonCode defaultButton() const;
/**
* Hide or display the a separator line drawn between the action
* buttons an the main widget.
*/
void showButtonSeparator( bool state );
/**
* Hide or display a general action button.
*
* Only buttons that have
* been created in the constructor can be displayed. This method will
* not create a new button.
*
* @param id Button identifier.
* @param state true display the button(s).
*/
void showButton( ButtonCode id, bool state );
/**
* Sets the text of any button.
*
* @param id The button identifier.
* @param text Button text.
*/
void setButtonText( ButtonCode id, const QString &text );
/**
* Returns the text of any button.
*/
QString buttonText( ButtonCode id ) const;
/**
* Sets the icon of any button.
*
* @param id The button identifier.
* @param icon Button icon.
*/
- void setButtonIcon( ButtonCode id, const KIcon &icon );
+ void setButtonIcon( ButtonCode id, const QIcon &icon );
/**
* Returns the icon of any button.
*/
- KIcon buttonIcon( ButtonCode id ) const;
+ QIcon buttonIcon( ButtonCode id ) const;
/**
* Sets the tooltip text of any button.
*
* @param id The button identifier.
* @param text Button text.
*/
void setButtonToolTip( ButtonCode id, const QString &text );
/**
* Returns the tooltip of any button.
*/
QString buttonToolTip( ButtonCode id ) const;
/**
* Sets the "What's this?" text of any button.
*
* @param id The button identifier.
* @param text Button text.
*/
void setButtonWhatsThis( ButtonCode id, const QString &text );
/**
* Returns the "What's this?" text of any button.
*/
QString buttonWhatsThis( ButtonCode id ) const;
/**
* Sets the KGuiItem directly for the button instead of using 3 methods to
* set the text, tooltip and whatsthis strings. This also allows to set an
* icon for the button which is otherwise not possible for the extra
* buttons beside Ok, Cancel and Apply.
*
* @param id The button identifier.
* @param item The KGuiItem for the button.
*/
void setButtonGuiItem( ButtonCode id, const KGuiItem &item );
/**
* Sets the menu of any button.
*
* @param id The button identifier.
* @param menu The menu.
* @param popupmode Choose if KPushButton setMenu or setDelayedMenu is used
*/
void setButtonMenu( ButtonCode id, QMenu *menu, ButtonPopupMode popupmode=InstantPopup);
/**
* Sets the focus to the button of the passed @p id.
*/
void setButtonFocus( ButtonCode id );
/**
* Convenience method. Sets the initial dialog size.
*
* This method should only be called right before show() or exec().
* The initial size will be ignored if smaller than
* the dialog's minimum size.
*
* @param size Startup size.
*/
void setInitialSize( const QSize &size );
/**
* Convenience method. Add a size to the default minimum size of a
* dialog.
*
* This method should only be called right before show() or exec().
*
* @param size Size added to minimum size.
*/
void incrementInitialSize( const QSize &size );
/**
* Restores the dialog's size from the configuration according to
* the screen size.
*
* @note the group must be set before calling
*
* @param config The config group to read from.
*/
void restoreDialogSize( const KConfigGroup& config ) ;
/**
* Saves the dialog's size dependent on the screen dimension either to the
* global or application config file.
*
* @note the group must be set before calling
*
* @param config The config group to read from.
* @param options passed to KConfigGroup::writeEntry()
*/
void saveDialogSize( KConfigGroup& config, KConfigGroup::WriteConfigFlags options = KConfigGroup::Normal ) const;
/**
* Returns the help link text.
*
* If no text has been defined,
* "Get help..." (internationalized) is returned.
*
* @return The help link text.
*
* @see enableLinkedHelp()
* @see setHelpLinkText()
* @see setHelp()
*/
QString helpLinkText() const;
/**
* Returns whether any button is enabled.
*/
bool isButtonEnabled( ButtonCode id ) const;
/**
* Returns the button that corresponds to the @p id.
*
* Normally you should not use this function.
* @em Never delete the object returned by this function.
* See also enableButton(), showButton(), setButtonGuiItem().
*
* @param id Identifier of the button.
* @return The button or 0 if the button does not exist.
*/
KPushButton* button( ButtonCode id ) const;
/**
* Returns the number of pixels that should be used between a
* dialog edge and the outermost widget(s) according to the KDE standard.
*
* @deprecated Use the style's pixelMetric() function to query individual margins.
* Different platforms may use different values for the four margins.
*/
static int marginHint();
/**
* Returns the number of pixels that should be used between
* widgets inside a dialog according to the KDE standard.
*
* @deprecated Use the style's layoutSpacing() function to query individual spacings.
* Different platforms may use different values depending on widget types and pairs.
*/
static int spacingHint();
/**
* Returns the number of pixels that should be used to visually
* separate groups of related options in a dialog according to
* the KDE standard.
* @since 4.2
*/
static int groupSpacingHint();
/**
* @enum StandardCaptionFlag
* Used to specify how to construct a window caption
*
* @value AppName Indicates that the method shall include
* the application name when making the caption string.
* @value Modified Causes a 'modified' sign will be included in the
* returned string. This is useful when indicating that a file is
* modified, i.e., it contains data that has not been saved.
* @value HIGCompliant The base minimum flags required to align a
* caption with the KDE Human Interface Guidelines
*/
enum CaptionFlag
{
NoCaptionFlags = 0,
AppNameCaption = 1,
ModifiedCaption = 2,
HIGCompliantCaption = AppNameCaption
};
Q_DECLARE_FLAGS(CaptionFlags, CaptionFlag)
/**
* Builds a caption that contains the application name along with the
* userCaption using a standard layout.
*
* To make a compliant caption for your window, simply do:
* @p setWindowTitle(KDialog::makeStandardCaption(yourCaption));
*
* To ensure that the caption is appropriate to the desktop in which the
* application is running, pass in a pointer to the window the caption will
* be applied to.
*
* If using a KDialog or KMainWindow subclass, call setCaption instead and
* an appropraite standard caption will be created for you
*
* @param userCaption The caption string you want to display in the
* window caption area. Do not include the application name!
* @param window a pointer to the window this application will apply to
* @param flags
* @return the created caption
*/
static QString makeStandardCaption( const QString &userCaption,
QWidget* window = 0,
CaptionFlags flags = HIGCompliantCaption );
/**
* Resize every layout manager used in @p widget and its nested children.
*
* @param widget The widget used.
* @param margin The new layout margin.
* @param spacing The new layout spacing.
*
* @deprecated Use QLayout functions where necessary. Setting margin and spacing
* values recursively for all children prevents QLayout from creating platform native
* layouts.
*/
static void resizeLayout( QWidget *widget, int margin, int spacing );
/**
* Resize every layout associated with @p lay and its children.
*
* @param lay layout to be resized
* @param margin The new layout margin
* @param spacing The new layout spacing
*
* @deprecated Use QLayout functions where necessary. Setting margin and spacing
* values recursively for all children prevents QLayout from creating platform native
* layouts.
*/
static void resizeLayout( QLayout *lay, int margin, int spacing );
/**
* Centers @p widget on the desktop, taking multi-head setups into
* account. If @p screen is -1, @p widget will be centered on its
* current screen (if it was shown already) or on the primary screen.
* If @p screen is -3, @p widget will be centered on the screen that
* currently contains the mouse pointer.
* @p screen will be ignored if a merged display (like Xinerama) is not
* in use, or merged display placement is not enabled in kdeglobals.
*/
static void centerOnScreen( QWidget *widget, int screen = -1 );
/**
* Places @p widget so that it doesn't cover a certain @p area of the screen.
* This is typically used by the "find dialog" so that the match it finds can
* be read.
* For @p screen, see centerOnScreen
* @return true on success (widget doesn't cover area anymore, or never did),
* false on failure (not enough space found)
*/
static bool avoidArea( QWidget *widget, const QRect& area, int screen = -1 );
/**
* Sets the main widget of the dialog.
*/
void setMainWidget( QWidget *widget );
/**
* @return The current main widget. Will create a QWidget as the mainWidget
* if none was set before. This way you can write
* \code
* ui.setupUi(mainWidget());
* \endcode
* when using designer.
*/
QWidget *mainWidget();
/**
* Reimplemented from QDialog.
*/
virtual QSize sizeHint() const;
/**
* Reimplemented from QDialog.
*/
virtual QSize minimumSizeHint() const;
/**
* Allow embedding the dialogs based on KDialog into a graphics view. By default embedding is not allowed, dialogs
* will appear as separate windows.
* @since 4.6
*/
static void setAllowEmbeddingInGraphicsView( bool allowEmbedding );
public Q_SLOTS:
/**
* Make a KDE compliant caption.
*
* @param caption Your caption. Do @p not include the application name
* in this string. It will be added automatically according to the KDE
* standard.
*/
virtual void setCaption( const QString &caption );
/**
* Makes a KDE compliant caption.
*
* @param caption Your caption. @em Do @em not include the application name
* in this string. It will be added automatically according to the KDE
* standard.
* @param modified Specify whether the document is modified. This displays
* an additional sign in the title bar, usually "**".
*/
virtual void setCaption( const QString &caption, bool modified );
/**
* Make a plain caption without any modifications.
*
* @param caption Your caption. This is the string that will be
* displayed in the window title.
*/
virtual void setPlainCaption( const QString &caption );
/**
* Enable or disable (gray out) a general action button.
*
* @param id Button identifier.
* @param state @p true enables the button(s).
*/
void enableButton( ButtonCode id, bool state );
/**
* Enable or disable (gray out) the OK button.
*
* @param state @p true enables the button.
*/
void enableButtonOk( bool state );
/**
* Enable or disable (gray out) the Apply button.
*
* @param state true enables the button.
*/
void enableButtonApply( bool state );
/**
* Enable or disable (gray out) the Cancel button.
*
* @param state true enables the button.
*/
void enableButtonCancel( bool state );
/**
* Display or hide the help link area on the top of the dialog.
*
* @param state @p true will display the area.
*
* @see helpLinkText()
* @see setHelpLinkText()
* @see setHelp()
*/
void enableLinkedHelp( bool state );
/**
* Sets the text that is shown as the linked text.
*
* If text is empty,
* the text "Get help..." (internationalized) is used instead.
*
* @param text The link text.
*
* @see helpLinkText()
* @see enableLinkedHelp()
* @see setHelp()
*/
void setHelpLinkText( const QString &text );
/**
* Sets the help path and topic.
*
* @param anchor Defined anchor in your docbook sources
* @param appname Defines the appname the help belongs to
* If empty it's the current one
*
* @note The help button works differently for the class
* KCMultiDialog, so it does not make sense to call this
* function for Dialogs of that type. See
* KCMultiDialog::slotHelp() for more information.
*/
void setHelp( const QString &anchor, const QString &appname = QString() );
/**
* Returns the status of the Details button.
*/
bool isDetailsWidgetVisible() const;
/**
* Sets the status of the Details button.
*/
void setDetailsWidgetVisible( bool visible );
/**
* Sets the widget that gets shown when "Details" is enabled.
*
* The dialog takes over ownership of the widget.
* Any previously set widget gets deleted.
*/
void setDetailsWidget( QWidget *detailsWidget );
/**
* Destruct the dialog delayed.
*
* You can call this function from slots like closeClicked() and hidden().
* You should not use the dialog any more after calling this function.
*/
void delayedDestruct();
Q_SIGNALS:
/**
* Emitted when the margin size and/or spacing size
* have changed.
*
* Use marginHint() and spacingHint() in your slot
* to get the new values.
*
* @deprecated This signal is not emitted. Listen to QEvent::StyleChange events instead.
*/
void layoutHintChanged();
/**
* The Help button was pressed. This signal is only emitted if
* slotButtonClicked() is not replaced
*/
void helpClicked();
/**
* The Default button was pressed. This signal is only emitted if
* slotButtonClicked() is not replaced
*/
void defaultClicked();
/**
* The Reset button was pressed. This signal is only emitted if
* slotButtonClicked() is not replaced
*/
void resetClicked();
/**
* The User3 button was pressed. This signal is only emitted if
* slotButtonClicked() is not replaced
*/
void user3Clicked();
/**
* The User2 button was pressed. This signal is only emitted if
* slotButtonClicked() is not replaced
*/
void user2Clicked();
/**
* The User1 button was pressed. This signal is only emitted if
* slotButtonClicked() is not replaced
*/
void user1Clicked();
/**
* The Apply button was pressed. This signal is only emitted if
* slotButtonClicked() is not replaced
*/
void applyClicked();
/**
* The Try button was pressed. This signal is only emitted if
* slotButtonClicked() is not replaced
*/
void tryClicked();
/**
* The OK button was pressed. This signal is only emitted if
* slotButtonClicked() is not replaced
*/
void okClicked();
/**
* The Yes button was pressed. This signal is only emitted if
* slotButtonClicked() is not replaced
*/
void yesClicked();
/**
* The No button was pressed. This signal is only emitted if
* slotButtonClicked() is not replaced
*/
void noClicked();
/**
* The Cancel button was pressed. This signal is only emitted if
* slotButtonClicked() is not replaced
*/
void cancelClicked();
/**
* The Close button was pressed. This signal is only emitted if
* slotButtonClicked() is not replaced
*/
void closeClicked();
/**
* A button has been pressed. This signal is only emitted if
* slotButtonClicked() is not replaced
* @param button is the code of the pressed button.
*/
void buttonClicked( KDialog::ButtonCode button);
/**
* The dialog is about to be hidden.
*
* A dialog is hidden after a user clicks a button that ends
* the dialog or when the user switches to another desktop or
* minimizes the dialog.
*/
void hidden();
/**
* The dialog has finished.
*
* A dialog emits finished after a user clicks a button that ends
* the dialog.
*
* This signal is also emitted when you call hide()
*
* If you have stored a pointer to the
* dialog do @em not try to delete the pointer in the slot that is
* connected to this signal.
*
* You should use deleteLater() instead.
*/
void finished();
/**
* The detailsWidget is about to get shown. This is your last chance
* to call setDetailsWidget if you haven't done so yet.
*/
void aboutToShowDetails();
protected:
/**
* Emits the #hidden signal. You can connect to that signal to
* detect when a dialog has been closed.
*/
virtual void hideEvent( QHideEvent * );
/**
* Detects when a dialog is being closed from the window manager
* controls. If the Cancel or Close button is present then the button
* is activated. Otherwise standard QDialog behavior
* will take place.
*/
virtual void closeEvent( QCloseEvent *e );
/**
* @internal
*/
virtual void keyPressEvent( QKeyEvent* );
protected Q_SLOTS:
/**
* Activated when the button @p button is clicked
*
* Sample that shows how to catch and handle button clicks within
* an own dialog;
* @code
* class MyDialog : public KDialog {
* protected Q_SLOTS:
* virtual void slotButtonClicked(int button) {
* if (button == KDialog::Ok)
* accept();
* else
* KDialog::slotButtonClicked(button);
* }
* }
* @endcode
*
* @param button is the type @a KDialog::ButtonCode
*/
virtual void slotButtonClicked(int button);
/**
* Updates the margins and spacings.
*
* @deprecated KDialog respects the style's margins and spacings automatically. Calling
* this function has no effect.
*/
void updateGeometry();
protected:
KDialog(KDialogPrivate &dd, QWidget *parent, Qt::WFlags flags = 0);
KDialogPrivate *const d_ptr;
private:
Q_DISABLE_COPY(KDialog)
Q_PRIVATE_SLOT(d_ptr, void queuedLayoutUpdate())
Q_PRIVATE_SLOT(d_ptr, void helpLinkClicked())
};
Q_DECLARE_OPERATORS_FOR_FLAGS(KDialog::ButtonCodes)
Q_DECLARE_OPERATORS_FOR_FLAGS(KDialog::CaptionFlags)
#endif // KDIALOG_H
diff --git a/kdeui/dialogs/kpassworddialog.cpp b/kdeui/dialogs/kpassworddialog.cpp
index 971b651a37..e97ff782fa 100644
--- a/kdeui/dialogs/kpassworddialog.cpp
+++ b/kdeui/dialogs/kpassworddialog.cpp
@@ -1,412 +1,413 @@
/* This file is part of the KDE libraries
Copyright (C) 2000 David Faure <faure@kde.org>
Copyright (C) 2007 Olivier Goffart <ogoffart at 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 "kpassworddialog.h"
#include <QCheckBox>
#include <QLabel>
#include <QLayout>
#include <QTextDocument>
#include <QTimer>
+#include <kicon.h>
#include <kcombobox.h>
#include <kconfig.h>
#include <kiconloader.h>
#include <klineedit.h>
#include <klocale.h>
#include <khbox.h>
#include <kdebug.h>
#include <kconfiggroup.h>
#include <ktitlewidget.h>
#include "ui_kpassworddialog.h"
/** @internal */
class KPasswordDialog::KPasswordDialogPrivate
{
public:
KPasswordDialogPrivate(KPasswordDialog *q)
: q(q),
userEditCombo(0),
pixmapLabel(0),
commentRow(0)
{}
void actuallyAccept();
void activated( const QString& userName );
void updateFields();
void init();
KPasswordDialog *q;
KPasswordDialogFlags m_flags;
Ui_KPasswordDialog ui;
QMap<QString,QString> knownLogins;
KComboBox* userEditCombo;
QLabel* pixmapLabel;
unsigned int commentRow;
};
KPasswordDialog::KPasswordDialog( QWidget* parent ,
const KPasswordDialogFlags& flags,
const KDialog::ButtonCodes otherButtons )
: KDialog( parent ), d(new KPasswordDialogPrivate(this))
{
setCaption( i18n("Password") );
setWindowIcon(KIcon("dialog-password"));
setButtons( Ok | Cancel | otherButtons );
setDefaultButton( Ok );
d->m_flags = flags;
d->init ();
}
KPasswordDialog::~KPasswordDialog()
{
delete d;
}
void KPasswordDialog::KPasswordDialogPrivate::updateFields()
{
if (q->anonymousMode())
{
ui.userEdit->setEnabled( false );
ui.domainEdit->setEnabled( false );
ui.passEdit->setEnabled( false );
ui.keepCheckBox->setEnabled( false );
}
else
{
ui.userEdit->setEnabled(!( m_flags & KPasswordDialog::UsernameReadOnly ));
ui.domainEdit->setEnabled(!( m_flags & KPasswordDialog::DomainReadOnly ));
ui.passEdit->setEnabled( true );
ui.keepCheckBox->setEnabled( true );
}
}
void KPasswordDialog::KPasswordDialogPrivate::init()
{
ui.setupUi( q->mainWidget() );
ui.errorMessage->setHidden(true);
// Row 4: Username field
if ( m_flags & KPasswordDialog::ShowUsernameLine ) {
ui.userEdit->setFocus();
QObject::connect( ui.userEdit, SIGNAL(returnPressed()), ui.passEdit, SLOT(setFocus()) );
} else {
ui.userNameLabel->hide();
ui.userEdit->hide();
ui.domainLabel->hide();
ui.domainEdit->hide();
ui.passEdit->setFocus();
}
if ( !( m_flags & KPasswordDialog::ShowAnonymousLoginCheckBox ) )
{
ui.anonymousCheckBox->hide();
}
else
{
QObject::connect( ui.anonymousCheckBox, SIGNAL(stateChanged (int)), q, SLOT(updateFields()) );
}
if ( !( m_flags & KPasswordDialog::ShowDomainLine ) )
{
ui.domainLabel->hide();
ui.domainEdit->hide();
}
if ( !( m_flags & KPasswordDialog::ShowKeepPassword ) )
{
ui.keepCheckBox->hide();
}
updateFields();
QRect desktop = KGlobalSettings::desktopGeometry(q->topLevelWidget());
q->setMinimumWidth(qMin(1000, qMax(q->sizeHint().width(), desktop.width() / 4)));
q->setPixmap(KIcon("dialog-password").pixmap(KIconLoader::SizeHuge));
}
void KPasswordDialog::setPixmap(const QPixmap &pixmap)
{
if ( !d->pixmapLabel )
{
d->pixmapLabel = new QLabel( mainWidget() );
d->pixmapLabel->setAlignment( Qt::AlignLeft | Qt::AlignTop );
d->ui.hboxLayout->insertWidget( 0, d->pixmapLabel );
}
d->pixmapLabel->setPixmap( pixmap );
}
QPixmap KPasswordDialog::pixmap() const
{
if ( !d->pixmapLabel ) {
return QPixmap();
}
return *d->pixmapLabel->pixmap();
}
void KPasswordDialog::setUsername(const QString& user)
{
d->ui.userEdit->setText(user);
if ( user.isEmpty() )
return;
d->activated(user);
if ( d->ui.userEdit->isVisibleTo( this ) )
{
d->ui.passEdit->setFocus();
}
}
QString KPasswordDialog::username() const
{
return d->ui.userEdit->text();
}
QString KPasswordDialog::password() const
{
return d->ui.passEdit->text();
}
void KPasswordDialog::setDomain(const QString& domain)
{
d->ui.domainEdit->setText(domain);
}
QString KPasswordDialog::domain() const
{
return d->ui.domainEdit->text();
}
void KPasswordDialog::setAnonymousMode(bool anonymous)
{
d->ui.anonymousCheckBox->setChecked( anonymous );
}
bool KPasswordDialog::anonymousMode() const
{
return d->ui.anonymousCheckBox->isChecked();
}
void KPasswordDialog::setKeepPassword( bool b )
{
d->ui.keepCheckBox->setChecked( b );
}
bool KPasswordDialog::keepPassword() const
{
return d->ui.keepCheckBox->isChecked();
}
void KPasswordDialog::addCommentLine( const QString& label,
const QString& comment )
{
int gridMarginLeft, gridMarginTop, gridMarginRight, gridMarginBottom;
d->ui.formLayout->getContentsMargins(&gridMarginLeft, &gridMarginTop, &gridMarginRight, &gridMarginBottom);
int spacing = d->ui.formLayout->horizontalSpacing();
if (spacing < 0) {
// same inter-column spacing for all rows, see comment in qformlayout.cpp
spacing = style()->combinedLayoutSpacing(QSizePolicy::Label, QSizePolicy::LineEdit, Qt::Horizontal, 0, this);
}
QLabel* c = new QLabel(comment, mainWidget());
c->setWordWrap(true);
d->ui.formLayout->insertRow(d->commentRow, label, c);
++d->commentRow;
// cycle through column 0 widgets and see the max width so we can set the minimum height of
// column 2 wordwrapable labels
int firstColumnWidth = 0;
for (int i = 0; i < d->ui.formLayout->rowCount(); ++i) {
QLayoutItem *li = d->ui.formLayout->itemAt(i, QFormLayout::LabelRole);
if (li) {
QWidget *w = li->widget();
if (w && !w->isHidden()) {
firstColumnWidth = qMax(firstColumnWidth, w->sizeHint().width());
}
}
}
for (int i = 0; i < d->ui.formLayout->rowCount(); ++i) {
QLayoutItem *li = d->ui.formLayout->itemAt(i, QFormLayout::FieldRole);
if (li) {
QLabel *l = qobject_cast<QLabel*>(li->widget());
if (l && l->wordWrap()) {
int w = sizeHint().width() - firstColumnWidth - ( 2 * marginHint() ) - gridMarginLeft - gridMarginRight - spacing;
l->setMinimumSize( w, l->heightForWidth(w) );
}
}
}
}
void KPasswordDialog::showErrorMessage( const QString& message, const ErrorType type )
{
d->ui.errorMessage->setText( message, KTitleWidget::ErrorMessage );
QFont bold = font();
bold.setBold( true );
switch ( type ) {
case PasswordError:
d->ui.passwordLabel->setFont( bold );
d->ui.passEdit->clear();
d->ui.passEdit->setFocus();
break;
case UsernameError:
if ( d->ui.userEdit->isVisibleTo( this ) )
{
d->ui.userNameLabel->setFont( bold );
d->ui.userEdit->setFocus();
}
break;
case DomainError:
if ( d->ui.domainEdit->isVisibleTo( this ) )
{
d->ui.domainLabel->setFont( bold );
d->ui.domainEdit->setFocus();
}
break;
case FatalError:
d->ui.userNameLabel->setEnabled( false );
d->ui.userEdit->setEnabled( false );
d->ui.passwordLabel->setEnabled( false );
d->ui.passEdit->setEnabled( false );
d->ui.keepCheckBox->setEnabled( false );
enableButton( Ok, false );
break;
default:
break;
}
adjustSize();
}
void KPasswordDialog::setPrompt(const QString& prompt)
{
d->ui.prompt->setText( prompt );
d->ui.prompt->setWordWrap( true );
d->ui.prompt->setMinimumHeight( d->ui.prompt->heightForWidth( width() - ( 2 * marginHint() ) ) );
}
QString KPasswordDialog::prompt() const
{
return d->ui.prompt->text();
}
void KPasswordDialog::setPassword(const QString &p)
{
d->ui.passEdit->setText(p);
}
void KPasswordDialog::setUsernameReadOnly( bool readOnly )
{
d->ui.userEdit->setReadOnly( readOnly );
if ( readOnly && d->ui.userEdit->hasFocus() ) {
d->ui.passEdit->setFocus();
}
}
void KPasswordDialog::setKnownLogins( const QMap<QString, QString>& knownLogins )
{
const int nr = knownLogins.count();
if ( nr == 0 ) {
return;
}
if ( nr == 1 ) {
d->ui.userEdit->setText( knownLogins.begin().key() );
setPassword( knownLogins.begin().value() );
return;
}
Q_ASSERT( !d->ui.userEdit->isReadOnly() );
if ( !d->userEditCombo ) {
d->ui.formLayout->removeWidget(d->ui.userEdit);
delete d->ui.userEdit;
d->userEditCombo = new KComboBox( true, mainWidget() );
d->ui.userEdit = d->userEditCombo->lineEdit();
// QSize s = d->userEditCombo->sizeHint();
// d->ui.userEditCombo->setFixedHeight( s.height() );
// d->ui.userEditCombo->setMinimumWidth( s.width() );
d->ui.userNameLabel->setBuddy( d->userEditCombo );
d->ui.formLayout->setWidget( d->commentRow, QFormLayout::FieldRole, d->userEditCombo );
setTabOrder( d->ui.userEdit, d->ui.anonymousCheckBox );
setTabOrder( d->ui.anonymousCheckBox, d->ui.domainEdit );
setTabOrder( d->ui.domainEdit, d->ui.passEdit );
setTabOrder( d->ui.passEdit, d->ui.keepCheckBox );
connect( d->ui.userEdit, SIGNAL(returnPressed()), d->ui.passEdit, SLOT(setFocus()) );
}
d->knownLogins = knownLogins;
d->userEditCombo->addItems( knownLogins.keys() );
d->userEditCombo->setFocus();
connect( d->userEditCombo, SIGNAL( activated( const QString& ) ),
this, SLOT( activated( const QString& ) ) );
}
void KPasswordDialog::KPasswordDialogPrivate::activated( const QString& userName )
{
QMap<QString, QString>::ConstIterator it = knownLogins.constFind( userName );
if ( it != knownLogins.constEnd() ) {
q->setPassword( it.value() );
}
}
void KPasswordDialog::accept()
{
if (!d->ui.errorMessage->isHidden()) d->ui.errorMessage->setText( QString() );
// reset the font in case we had an error previously
if (!d->ui.passwordLabel->isHidden()) d->ui.passwordLabel->setFont( font() );
if (!d->ui.passwordLabel->isHidden()) d->ui.userNameLabel->setFont( font() );
// we do this to allow the error message, if any, to go away
// checkPassword() may block for a period of time
QTimer::singleShot( 0, this, SLOT(actuallyAccept()) );
}
void KPasswordDialog::KPasswordDialogPrivate::actuallyAccept()
{
if ( !q->checkPassword() )
{
return;
}
bool keep = ui.keepCheckBox->isVisibleTo( q ) && ui.keepCheckBox->isChecked();
emit q->gotPassword( q->password(), keep);
if ( ui.userEdit->isVisibleTo( q ) ) {
emit q->gotUsernameAndPassword( q->username(), q->password() , keep);
}
q->KDialog::accept();
}
bool KPasswordDialog::checkPassword()
{
return true;
}
#include "moc_kpassworddialog.cpp"
diff --git a/kdeui/dialogs/kshortcutsdialog.cpp b/kdeui/dialogs/kshortcutsdialog.cpp
index e05d8d4438..684414711d 100644
--- a/kdeui/dialogs/kshortcutsdialog.cpp
+++ b/kdeui/dialogs/kshortcutsdialog.cpp
@@ -1,198 +1,199 @@
/* This file is part of the KDE libraries Copyright (C) 1998 Mark Donohoe <donohoe@kde.org>
Copyright (C) 1997 Nicolas Hadacek <hadacek@kde.org>
Copyright (C) 1998 Matthias Ettrich <ettrich@kde.org>
Copyright (C) 2001 Ellis Whitehead <ellis@kde.org>
Copyright (C) 2006 Hamish Rodda <rodda@kde.org>
Copyright (C) 2007 Roberto Raggi <roberto@kdevelop.org>
Copyright (C) 2007 Andreas Hartmetz <ahartmetz@gmail.com>
Copyright (C) 2008 Michael Jansen <kde@michael-jansen.biz>
Copyright (C) 2008 Alexander Dymo <adymo@kdevelop.org>
Copyright (C) 2009 Chani Armitage <chani@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 as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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 "kshortcutsdialog.h"
#include "kshortcutsdialog_p.h"
#include "kshortcutschemeshelper_p.h"
#include "kdebug.h"
#include "klocale.h"
#include <QApplication>
#include <QDomDocument>
+#include <kicon.h>
#include <kmessagebox.h>
#include <kxmlguiclient.h>
#include <kxmlguifactory.h>
#include <kactioncollection.h>
/************************************************************************/
/* KShortcutsDialog */
/* */
/* Originally by Nicolas Hadacek <hadacek@via.ecp.fr> */
/* */
/* Substantially revised by Mark Donohoe <donohoe@kde.org> */
/* */
/* And by Espen Sand <espen@kde.org> 1999-10-19 */
/* (by using KDialog there is almost no code left ;) */
/* */
/************************************************************************/
class KShortcutsDialog::KShortcutsDialogPrivate
{
public:
KShortcutsDialogPrivate(KShortcutsDialog *q): q(q), m_keyChooser(0), m_schemeEditor(0)
{}
QList<KActionCollection*> m_collections;
void changeShortcutScheme(const QString &scheme)
{
if (m_keyChooser->isModified() && KMessageBox::questionYesNo(q,
i18n("The current shortcut scheme is modified. Save before switching to the new one?")) == KMessageBox::Yes) {
m_keyChooser->save();
} else {
m_keyChooser->undoChanges();
}
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
m_keyChooser->clearCollections();
foreach (KActionCollection *collection, m_collections) {
// passing an empty stream forces the clients to reread the XML
KXMLGUIClient *client = const_cast<KXMLGUIClient *>(collection->parentGUIClient());
if (client) {
client->setXMLGUIBuildDocument( QDomDocument() );
}
}
//get xmlguifactory
if (!m_collections.isEmpty()) {
const KXMLGUIClient *client = m_collections.first()->parentGUIClient();
if (client) {
KXMLGUIFactory *factory = client->factory();
if (factory) {
factory->changeShortcutScheme(scheme);
}
}
}
foreach (KActionCollection *collection, m_collections) {
m_keyChooser->addCollection(collection);
}
QApplication::restoreOverrideCursor();
}
void undoChanges()
{
m_keyChooser->undoChanges();
}
void save()
{
m_keyChooser->save();
emit q->saved();
}
KShortcutsDialog *q;
KShortcutsEditor* m_keyChooser; // ### move
KShortcutSchemesEditor* m_schemeEditor;
};
KShortcutsDialog::KShortcutsDialog( KShortcutsEditor::ActionTypes types, KShortcutsEditor::LetterShortcuts allowLetterShortcuts, QWidget *parent )
: KDialog( parent ), d(new KShortcutsDialogPrivate(this))
{
setCaption(i18n("Configure Shortcuts"));
setButtons(Details|Reset|Ok|Cancel|KDialog::User1);
setButtonText(KDialog::User1, i18n("Print"));
setButtonIcon(KDialog::User1, KIcon("document-print"));
setModal(true);
d->m_keyChooser = new KShortcutsEditor( this, types, allowLetterShortcuts );
setMainWidget( d->m_keyChooser );
setButtonText(Reset,i18n("Reset to Defaults"));
d->m_schemeEditor = new KShortcutSchemesEditor(this);
connect( d->m_schemeEditor, SIGNAL(shortcutsSchemeChanged(const QString&)),
this, SLOT(changeShortcutScheme(const QString&)) );
setDetailsWidget(d->m_schemeEditor);
connect( this, SIGNAL(resetClicked()), d->m_keyChooser, SLOT(allDefault()) );
connect( this, SIGNAL(user1Clicked()), d->m_keyChooser, SLOT(printShortcuts()) );
connect(this, SIGNAL(cancelClicked()), SLOT(undoChanges()));
KConfigGroup group( KGlobal::config(), "KShortcutsDialog Settings" );
resize( group.readEntry( "Dialog Size", sizeHint() ) );
}
KShortcutsDialog::~KShortcutsDialog()
{
KConfigGroup group( KGlobal::config(), "KShortcutsDialog Settings" );
group.writeEntry( "Dialog Size", size(), KConfigGroup::Persistent|KConfigGroup::Global );
delete d;
}
void KShortcutsDialog::addCollection(KActionCollection *collection, const QString &title)
{
d->m_keyChooser->addCollection(collection, title);
d->m_collections << collection;
}
QList<KActionCollection*> KShortcutsDialog::actionCollections() const
{
return d->m_collections;
}
//FIXME should there be a setSaveSettings method?
bool KShortcutsDialog::configure(bool saveSettings)
{
disconnect(this, SIGNAL(okClicked()), this, SLOT(save()));
if (saveSettings) {
connect(this, SIGNAL(okClicked()), this, SLOT(save()));
}
if (isModal()) {
int retcode = exec();
return retcode;
} else {
show();
return false;
}
}
QSize KShortcutsDialog::sizeHint() const
{
return QSize(600, 480);
}
int KShortcutsDialog::configure(KActionCollection *collection, KShortcutsEditor::LetterShortcuts allowLetterShortcuts,
QWidget *parent, bool saveSettings)
{
kDebug(125) << "KShortcutsDialog::configureKeys( KActionCollection*, " << saveSettings << " )";
KShortcutsDialog dlg(KShortcutsEditor::AllActions, allowLetterShortcuts, parent);
dlg.d->m_keyChooser->addCollection(collection);
return dlg.configure(saveSettings);
}
#include "moc_kshortcutsdialog.cpp"
#include "moc_kshortcutsdialog_p.cpp"
//kate: space-indent on; indent-width 4; replace-tabs on;tab-width 4;
diff --git a/kdeui/dialogs/kshortcutseditoritem.cpp b/kdeui/dialogs/kshortcutseditoritem.cpp
index fd02f6a9f5..c79c807edb 100644
--- a/kdeui/dialogs/kshortcutseditoritem.cpp
+++ b/kdeui/dialogs/kshortcutseditoritem.cpp
@@ -1,356 +1,357 @@
/* This file is part of the KDE libraries Copyright (C) 1998 Mark Donohoe <donohoe@kde.org>
Copyright (C) 1997 Nicolas Hadacek <hadacek@kde.org>
Copyright (C) 1998 Matthias Ettrich <ettrich@kde.org>
Copyright (C) 2001 Ellis Whitehead <ellis@kde.org>
Copyright (C) 2006 Hamish Rodda <rodda@kde.org>
Copyright (C) 2007 Roberto Raggi <roberto@kdevelop.org>
Copyright (C) 2007 Andreas Hartmetz <ahartmetz@gmail.com>
Copyright (C) 2008 Michael Jansen <kde@michael-jansen.biz>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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 "kshortcutsdialog_p.h"
+#include <kicon.h>
#include <kaction.h>
#include <kdebug.h>
#include <kstringhandler.h>
#include <QTreeWidgetItem>
KShortcutsEditorItem::KShortcutsEditorItem(QTreeWidgetItem *parent, KAction *action)
: QTreeWidgetItem(parent, ActionItem)
, m_action(action)
, m_isNameBold(false)
, m_oldLocalShortcut(0)
, m_oldGlobalShortcut(0)
, m_oldShapeGesture(0)
, m_oldRockerGesture(0)
{
// Filtering message requested by translators (scripting).
m_id = m_action->objectName();
m_actionNameInTable = i18nc("@item:intable Action name in shortcuts configuration", "%1", KGlobal::locale()->removeAcceleratorMarker(m_action->text()));
if (m_actionNameInTable.isEmpty()) {
kWarning() << "Action without text!" << m_action->objectName();
m_actionNameInTable = m_id;
}
}
KShortcutsEditorItem::~KShortcutsEditorItem()
{
delete m_oldLocalShortcut;
delete m_oldGlobalShortcut;
delete m_oldShapeGesture;
delete m_oldRockerGesture;
}
bool KShortcutsEditorItem::isModified() const
{
return m_oldLocalShortcut || m_oldGlobalShortcut || m_oldShapeGesture || m_oldRockerGesture;
}
QVariant KShortcutsEditorItem::data(int column, int role) const
{
switch (role) {
case Qt::DisplayRole:
switch(column) {
case Name:
return m_actionNameInTable;
case Id:
return m_id;
case LocalPrimary:
case LocalAlternate:
case GlobalPrimary:
case GlobalAlternate:
return keySequence(column);
case ShapeGesture:
return m_action->shapeGesture().shapeName();
case RockerGesture:
return m_action->rockerGesture().rockerName();
default:
break;
}
break;
case Qt::DecorationRole:
if (column == Name)
return m_action->icon();
else
return KIcon();
break;
case Qt::WhatsThisRole:
return m_action->whatsThis();
case Qt::ToolTipRole:
// There is no such thing as a KAction::description(). So we have
// nothing to display here.
return QVariant();
case Qt::FontRole:
if (column == Name && m_isNameBold) {
QFont modifiedFont = treeWidget()->font();
modifiedFont.setBold(true);
return modifiedFont;
}
break;
case KExtendableItemDelegate::ShowExtensionIndicatorRole:
switch (column) {
case Name:
return false;
case LocalPrimary:
case LocalAlternate:
if (!m_action->isShortcutConfigurable()) {
return false;
}
return true;
case GlobalPrimary:
case GlobalAlternate:
if (!m_action->isGlobalShortcutEnabled()) {
return false;
}
return true;
default:
return false;
}
//the following are custom roles, defined in this source file only
case ShortcutRole:
switch(column) {
case LocalPrimary:
case LocalAlternate:
case GlobalPrimary:
case GlobalAlternate:
return keySequence(column);
case ShapeGesture: { //scoping for "ret"
QVariant ret;
ret.setValue(m_action->shapeGesture());
return ret; }
case RockerGesture: {
QVariant ret;
ret.setValue(m_action->rockerGesture());
return ret; }
default:
// Column not valid for this role
Q_ASSERT(false);
return QVariant();
}
case DefaultShortcutRole:
switch(column) {
case LocalPrimary:
return m_action->shortcut(KAction::DefaultShortcut).primary();
case LocalAlternate:
return m_action->shortcut(KAction::DefaultShortcut).alternate();
case GlobalPrimary:
return m_action->globalShortcut(KAction::DefaultShortcut).primary();
case GlobalAlternate:
return m_action->globalShortcut(KAction::DefaultShortcut).alternate();
case ShapeGesture: {
QVariant ret;
ret.setValue(m_action->shapeGesture(KAction::DefaultShortcut));
return ret; }
case RockerGesture: {
QVariant ret;
ret.setValue(m_action->rockerGesture(KAction::DefaultShortcut));
return ret; }
default:
// Column not valid for this role
Q_ASSERT(false);
return QVariant();
}
case ObjectRole:
return qVariantFromValue((QObject*)m_action);
default:
break;
}
return QVariant();
}
bool KShortcutsEditorItem::operator<(const QTreeWidgetItem &other) const
{
const int column = treeWidget() ? treeWidget()->sortColumn() : 0;
return KStringHandler::naturalCompare(text(column), other.text(column)) < 0;
}
QKeySequence KShortcutsEditorItem::keySequence(uint column) const
{
switch (column) {
case LocalPrimary:
return m_action->shortcut().primary();
case LocalAlternate:
return m_action->shortcut().alternate();
case GlobalPrimary:
return m_action->globalShortcut().primary();
case GlobalAlternate:
return m_action->globalShortcut().alternate();
default:
return QKeySequence();
}
}
void KShortcutsEditorItem::setKeySequence(uint column, const QKeySequence &seq)
{
KShortcut ks;
if (column == GlobalPrimary || column == GlobalAlternate) {
ks = m_action->globalShortcut();
if (!m_oldGlobalShortcut)
m_oldGlobalShortcut = new KShortcut(ks);
} else {
ks = m_action->shortcut();
if (!m_oldLocalShortcut)
m_oldLocalShortcut = new KShortcut(ks);
}
if (column == LocalAlternate || column == GlobalAlternate)
ks.setAlternate(seq);
else
ks.setPrimary(seq);
//avoid also setting the default shortcut - what we are setting here is custom by definition
if (column == GlobalPrimary || column == GlobalAlternate) {
m_action->setGlobalShortcut(ks, KAction::ActiveShortcut, KAction::NoAutoloading);
} else {
m_action->setShortcut(ks, KAction::ActiveShortcut);
}
updateModified();
}
void KShortcutsEditorItem::setShapeGesture(const KShapeGesture &gst)
{
if (!m_oldShapeGesture) {
m_oldShapeGesture = new KShapeGesture(gst);
}
m_action->setShapeGesture(gst);
updateModified();
}
void KShortcutsEditorItem::setRockerGesture(const KRockerGesture &gst)
{
if (!m_oldRockerGesture) {
m_oldRockerGesture = new KRockerGesture(gst);
}
m_action->setRockerGesture(gst);
updateModified();
}
//our definition of modified is "modified since the chooser was shown".
void KShortcutsEditorItem::updateModified()
{
if (m_oldLocalShortcut && *m_oldLocalShortcut == m_action->shortcut()) {
delete m_oldLocalShortcut;
m_oldLocalShortcut = 0;
}
if (m_oldGlobalShortcut && *m_oldGlobalShortcut == m_action->globalShortcut()) {
delete m_oldGlobalShortcut;
m_oldGlobalShortcut = 0;
}
if (m_oldShapeGesture && *m_oldShapeGesture == m_action->shapeGesture()) {
delete m_oldShapeGesture;
m_oldShapeGesture = 0;
}
if (m_oldRockerGesture && *m_oldRockerGesture == m_action->rockerGesture()) {
delete m_oldRockerGesture;
m_oldRockerGesture = 0;
}
}
bool KShortcutsEditorItem::isModified(uint column) const
{
switch (column) {
case Name:
return false;
case LocalPrimary:
case LocalAlternate:
if (!m_oldLocalShortcut)
return false;
if (column == LocalPrimary)
return m_oldLocalShortcut->primary() != m_action->shortcut().primary();
else
return m_oldLocalShortcut->alternate() != m_action->shortcut().alternate();
case GlobalPrimary:
case GlobalAlternate:
if (!m_oldGlobalShortcut)
return false;
if (column == GlobalPrimary)
return m_oldGlobalShortcut->primary() != m_action->globalShortcut().primary();
else
return m_oldGlobalShortcut->alternate() != m_action->globalShortcut().alternate();
case ShapeGesture:
return static_cast<bool>(m_oldShapeGesture);
case RockerGesture:
return static_cast<bool>(m_oldRockerGesture);
default:
return false;
}
}
void KShortcutsEditorItem::undo()
{
#ifndef NDEBUG
if (m_oldLocalShortcut || m_oldGlobalShortcut || m_oldShapeGesture || m_oldRockerGesture ) {
kDebug(125) << "Undoing changes for " << data(Name, Qt::DisplayRole).toString();
}
#endif
if (m_oldLocalShortcut) {
// We only ever reset the active Shortcut
m_action->setShortcut(*m_oldLocalShortcut, KAction::ActiveShortcut);
}
if (m_oldGlobalShortcut) {
m_action->setGlobalShortcut(*m_oldGlobalShortcut, KAction::ActiveShortcut,
KAction::NoAutoloading);
}
if (m_oldShapeGesture) {
m_action->setShapeGesture(*m_oldShapeGesture);
}
if (m_oldRockerGesture) {
m_action->setRockerGesture(*m_oldRockerGesture);
}
updateModified();
}
void KShortcutsEditorItem::commit()
{
#ifndef NDEBUG
if (m_oldLocalShortcut || m_oldGlobalShortcut || m_oldShapeGesture || m_oldRockerGesture ) {
kDebug(125) << "Committing changes for " << data(Name, Qt::DisplayRole).toString();
}
#endif
delete m_oldLocalShortcut;
m_oldLocalShortcut = 0;
delete m_oldGlobalShortcut;
m_oldGlobalShortcut = 0;
delete m_oldShapeGesture;
m_oldShapeGesture = 0;
delete m_oldRockerGesture;
m_oldRockerGesture = 0;
}
diff --git a/kdeui/dialogs/ktip.cpp b/kdeui/dialogs/ktip.cpp
index c19073a5cc..8d39893ee1 100644
--- a/kdeui/dialogs/ktip.cpp
+++ b/kdeui/dialogs/ktip.cpp
@@ -1,415 +1,416 @@
/*****************************************************************
Copyright (c) 2000-2003 Matthias Hoelzer-Kluepfel <mhk@kde.org>
Tobias Koenig <tokoe@kde.org>
Daniel Molkentin <molkentin@kde.org>
Copyright (c) 2008 Urs Wolfer <uwolfer @ kde.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************/
#include "ktip.h"
#include <QtCore/QFile>
#include <QCheckBox>
#include <QKeyEvent>
#include <QLabel>
#include <QLayout>
+#include <kicon.h>
#include <kaboutdata.h>
#include <kconfig.h>
#include <kdebug.h>
#include <kglobalsettings.h>
#include <kcomponentdata.h>
#include <klocale.h>
#include <kpushbutton.h>
#include <krandom.h>
#include <kseparator.h>
#include <kstandarddirs.h>
#include <ktextbrowser.h>
class KTipDatabase::Private
{
public:
void loadTips( const QString &tipFile );
void addTips( const QString &tipFile );
QStringList tips;
int currentTip;
};
void KTipDatabase::Private::loadTips( const QString &tipFile )
{
tips.clear();
addTips( tipFile );
}
/**
* If you change something here, please update the script
* preparetips, which depends on extracting exactly the same
* text as done here.
*/
void KTipDatabase::Private::addTips( const QString &tipFile )
{
QString fileName = KStandardDirs::locate( "data", tipFile );
if ( fileName.isEmpty() ) {
kDebug() << "KTipDatabase::addTips: can't find '" << tipFile << "' in standard dirs";
return;
}
QFile file( fileName );
if ( !file.open( QIODevice::ReadOnly ) ) {
kDebug() << "KTipDatabase::addTips: can't open '" << fileName << "' for reading";
return;
}
QByteArray data = file.readAll();
QString content = QString::fromUtf8( data.constData(), data.size() );
const QRegExp rx( "\\n+" );
int pos = -1;
while ( ( pos = content.indexOf( "<html>", pos + 1, Qt::CaseInsensitive ) ) != -1 ) {
/**
* To make translations work, tip extraction here must exactly
* match what is done by the preparetips script.
*/
QString tip = content
.mid( pos + 6, content.indexOf( "</html>", pos, Qt::CaseInsensitive ) - pos - 6 )
.replace( rx, "\n" );
if ( !tip.endsWith( '\n' ) )
tip += '\n';
if ( tip.startsWith( '\n' ) )
tip = tip.mid( 1 );
if ( tip.isEmpty() ) {
kDebug() << "Empty tip found! Skipping! " << pos;
continue;
}
tips.append( tip );
}
file.close();
}
KTipDatabase::KTipDatabase( const QString &_tipFile )
: d( new Private )
{
QString tipFile = _tipFile;
if ( tipFile.isEmpty() )
tipFile = KGlobal::mainComponent().aboutData()->appName() + "/tips";
d->loadTips( tipFile );
if ( !d->tips.isEmpty() )
d->currentTip = KRandom::random() % d->tips.count();
}
KTipDatabase::KTipDatabase( const QStringList& tipsFiles )
: d( new Private )
{
if ( tipsFiles.isEmpty() || ( ( tipsFiles.count() == 1 ) && tipsFiles.first().isEmpty() ) ) {
d->addTips( KGlobal::mainComponent().aboutData()->appName() + "/tips" );
} else {
for ( QStringList::ConstIterator it = tipsFiles.begin(); it != tipsFiles.end(); ++it )
d->addTips( *it );
}
if ( !d->tips.isEmpty() )
d->currentTip = KRandom::random() % d->tips.count();
}
KTipDatabase::~KTipDatabase()
{
delete d;
}
void KTipDatabase::nextTip()
{
if ( d->tips.isEmpty() )
return;
d->currentTip += 1;
if ( d->currentTip >= (int) d->tips.count() )
d->currentTip = 0;
}
void KTipDatabase::prevTip()
{
if ( d->tips.isEmpty() )
return;
d->currentTip -= 1;
if ( d->currentTip < 0 )
d->currentTip = d->tips.count() - 1;
}
QString KTipDatabase::tip() const
{
if ( d->tips.isEmpty() )
return QString();
return d->tips[ d->currentTip ];
}
class KTipDialog::Private
{
public:
Private( KTipDialog *_parent )
: parent( _parent )
{
}
~Private()
{
delete database;
}
void _k_nextTip();
void _k_prevTip();
void _k_showOnStart( bool );
KTipDialog *parent;
KTipDatabase *database;
QCheckBox *tipOnStart;
KTextBrowser *tipText;
static KTipDialog *mInstance;
};
KTipDialog *KTipDialog::Private::mInstance = 0;
void KTipDialog::Private::_k_prevTip()
{
database->prevTip();
tipText->setHtml( QString::fromLatin1( "<html><body>%1</body></html>" )
.arg( i18n( database->tip().toUtf8() ) ) );
}
void KTipDialog::Private::_k_nextTip()
{
database->nextTip();
tipText->setHtml( QString::fromLatin1( "<html><body>%1</body></html>" )
.arg( i18n( database->tip().toUtf8() ) ) );
}
void KTipDialog::Private::_k_showOnStart( bool on )
{
parent->setShowOnStart( on );
}
KTipDialog::KTipDialog( KTipDatabase *database, QWidget *parent )
: KDialog( parent ),
d( new Private( this ) )
{
setButtons( KDialog::None );
setCaption( i18n( "Tip of the Day" ) );
/**
* Parent is 0L when TipDialog is used as a mainWidget. This should
* be the case only in ktip, so let's use the ktip layout.
*/
bool isTipDialog = (parent != 0);
d->database = database;
setWindowIcon(KIcon("ktip"));
QWidget *widget = new QWidget( this );
setMainWidget( widget );
QVBoxLayout *mainLayout = new QVBoxLayout( widget );
mainLayout->setMargin( 0 );
if ( isTipDialog ) {
QLabel *titleLabel = new QLabel( this );
titleLabel->setText( i18n( "Did you know...?\n" ) );
titleLabel->setFont( QFont( KGlobalSettings::generalFont().family(), 20, QFont::Bold ) );
titleLabel->setAlignment( Qt::AlignCenter );
mainLayout->addWidget( titleLabel );
}
QHBoxLayout *browserLayout = new QHBoxLayout();
mainLayout->addLayout( browserLayout );
d->tipText = new KTextBrowser( this );
d->tipText->setOpenExternalLinks( true );
d->tipText->setWordWrapMode( QTextOption::WrapAtWordBoundaryOrAnywhere );
QStringList paths;
paths << KGlobal::dirs()->resourceDirs( "icon" )
<< KGlobal::dirs()->findResourceDir( "data", "kdewizard/pics" ) + "kdewizard/pics/";
d->tipText->setSearchPaths( paths );
d->tipText->setFrameStyle( QFrame::NoFrame );
d->tipText->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
QPalette tipPal(d->tipText->palette());
tipPal.setColor(QPalette::Base, Qt::transparent);
tipPal.setColor(QPalette::Text, tipPal.color(QPalette::WindowText));
d->tipText->setPalette(tipPal);
browserLayout->addWidget( d->tipText );
QLabel *label = new QLabel( this );
label->setPixmap( KStandardDirs::locate( "data", "kdeui/pics/ktip-bulb.png" ) );
label->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
browserLayout->addWidget( label );
if ( !isTipDialog ) {
resize( 520, 280 );
QSize sh = size();
QRect rect = KGlobalSettings::splashScreenDesktopGeometry();
move( rect.x() + ( rect.width() - sh.width() ) / 2,
rect.y() + ( rect.height() - sh.height() ) / 2 );
}
KSeparator* sep = new KSeparator( Qt::Horizontal );
mainLayout->addWidget( sep );
QHBoxLayout *buttonLayout = new QHBoxLayout();
mainLayout->addLayout( buttonLayout );
d->tipOnStart = new QCheckBox( i18n( "&Show tips on startup" ) );
buttonLayout->addWidget( d->tipOnStart, 1 );
KPushButton *prev = new KPushButton( KStandardGuiItem::back( KStandardGuiItem::UseRTL ) );
prev->setText( i18n( "&Previous" ) );
buttonLayout->addWidget( prev );
KPushButton *next = new KPushButton( KStandardGuiItem::forward( KStandardGuiItem::UseRTL ));
next->setText( i18nc( "Opposite to Previous", "&Next" ) );
buttonLayout->addWidget( next );
KPushButton *ok = new KPushButton( KStandardGuiItem::close());
ok->setDefault( true );
buttonLayout->addWidget( ok );
KConfigGroup config( KGlobal::config(), "TipOfDay" );
d->tipOnStart->setChecked( config.readEntry( "RunOnStart", true ) );
connect( next, SIGNAL( clicked() ), this, SLOT( _k_nextTip() ) );
connect( prev, SIGNAL( clicked() ), this, SLOT( _k_prevTip() ) );
connect( ok, SIGNAL( clicked() ), this, SLOT( accept() ) );
connect( d->tipOnStart, SIGNAL( toggled( bool ) ), this, SLOT( _k_showOnStart( bool ) ) );
ok->setFocus();
d->_k_nextTip();
}
KTipDialog::~KTipDialog()
{
if ( Private::mInstance == this )
Private::mInstance = 0L;
delete d;
}
/**
* use the one with a parent window as parameter instead of this one
* or you will get focus problems
*/
void KTipDialog::showTip( const QString &tipFile, bool force )
{
showTip( 0, tipFile, force );
}
void KTipDialog::showTip( QWidget *parent, const QString &tipFile, bool force )
{
showMultiTip( parent, QStringList( tipFile ), force );
}
void KTipDialog::showMultiTip( QWidget *parent, const QStringList &tipFiles, bool force )
{
KConfigGroup configGroup( KGlobal::config(), "TipOfDay" );
const bool runOnStart = configGroup.readEntry( "RunOnStart", true );
if ( !force ) {
if ( !runOnStart )
return;
// showing the tooltips on startup suggests the tooltip
// will be shown *each time* on startup, not $random days later
// TODO either remove or uncomment this code, but make the situation clear
/*bool hasLastShown = configGroup.hasKey( "TipLastShown" );
if ( hasLastShown ) {
const int oneDay = 24 * 60 * 60;
QDateTime lastShown = configGroup.readEntry( "TipLastShown", QDateTime() );
// Show tip roughly once a week
if ( lastShown.secsTo( QDateTime::currentDateTime() ) < (oneDay + (KRandom::random() % (10 * oneDay))) )
return;
}
configGroup.writeEntry( "TipLastShown", QDateTime::currentDateTime() );
if ( !hasLastShown )
return; // Don't show tip on first start*/
}
if ( !Private::mInstance )
Private::mInstance = new KTipDialog( new KTipDatabase( tipFiles ), parent );
else
// The application might have changed the RunOnStart option in its own
// configuration dialog, so we should update the checkbox.
Private::mInstance->d->tipOnStart->setChecked( runOnStart );
Private::mInstance->show();
Private::mInstance->raise();
}
void KTipDialog::setShowOnStart( bool on )
{
KConfigGroup config( KGlobal::config(), "TipOfDay" );
config.writeEntry( "RunOnStart", on );
}
bool KTipDialog::eventFilter( QObject *object, QEvent *event )
{
if ( object == d->tipText && event->type() == QEvent::KeyPress &&
(((QKeyEvent *)event)->key() == Qt::Key_Return ||
((QKeyEvent *)event)->key() == Qt::Key_Space ))
accept();
/**
* If the user presses Return or Space, we close the dialog as if the
* default button was pressed even if the KTextBrowser has the keyboard
* focus. This could have the bad side-effect that the user cannot use the
* keyboard to open urls in the KTextBrowser, so we just let it handle
* the key event _additionally_. (Antonio)
*/
return QWidget::eventFilter( object, event );
}
#include "moc_ktip.cpp"
diff --git a/kdeui/icons/kicon.cpp b/kdeui/icons/kicon.cpp
index 98bf97a95d..268efb35a7 100644
--- a/kdeui/icons/kicon.cpp
+++ b/kdeui/icons/kicon.cpp
@@ -1,68 +1,68 @@
/* This file is part of the KDE libraries
Copyright (C) 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 "kicon.h"
#include <kglobal.h>
#include "kiconloader.h"
#include "kiconengine_p.h"
KIcon::KIcon(const QString& iconName, KIconLoader* iconLoader, const QStringList &overlays)
: QIcon(new KIconEngine(iconName, iconLoader ? iconLoader : KIconLoader::global(), overlays)),
d(0)
{
}
KIcon::KIcon(const QString& iconName, KIconLoader* iconLoader)
: QIcon(new KIconEngine(iconName, iconLoader ? iconLoader : KIconLoader::global())),
d(0)
{
}
KIcon::KIcon(const QString& iconName)
: QIcon(new KIconEngine(iconName, KIconLoader::global())),
d(0)
{
}
KIcon::KIcon()
: d(0)
{
}
KIcon::KIcon(const QIcon& copy)
: QIcon(copy),
d(0)
{
}
KIcon::~KIcon()
{
//delete d;
}
-KIcon& KIcon::operator=( const KIcon &other )
+KIcon& KIcon::operator=( const QIcon &other )
{
if (this != &other) {
// copy d-pointer
QIcon::operator=(other);
}
return *this;
}
diff --git a/kdeui/icons/kicon.h b/kdeui/icons/kicon.h
index 01e47d4ef1..41a621343d 100644
--- a/kdeui/icons/kicon.h
+++ b/kdeui/icons/kicon.h
@@ -1,92 +1,92 @@
/* This file is part of the KDE libraries
Copyright (C) 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.
*/
#ifndef KICON_H
#define KICON_H
#include <kdeui_export.h>
#include <QIcon>
class KIconLoader;
class QStringList;
/**
* \short A wrapper around QIcon that provides KDE icon features
*
* KIcon is a convenience class for creating a QIcon with an appropriate
* KIconEngine to perform loading and rendering. KIcons thus adhere to
* KDE style and effect standards.
*
* \sa KIconEngine, KIconLoader, KIconTheme
*
* \author Hamish Rodda <rodda@kde.org>
*/
class KDEUI_EXPORT KIcon : public QIcon
{
public:
/**
* Constructor which takes a kde style icon name, and optionally
* a custom icon loader.
*
* \param iconName The name of the kde icon to load
* \param iconLoader The icon loader to use in loading this icon, or
* null to use the default global icon loader.
* @param overlays A list of overlays to apply to this icon. They are
* loaded from the emblems icons and up to four (one per
* corner) is currently supported
*/
explicit KIcon(const QString& iconName, KIconLoader* iconLoader,
const QStringList& overlays);
/**
* \overload
*/
explicit KIcon(const QString& iconName, KIconLoader* iconLoader);
/**
* \overload
*/
explicit KIcon(const QString& iconName);
/**
* Copy constructor which takes any QIcon.
*
* \param copy the icon to copy. This should have once been a KIcon,
* if you want to preserve KDE icon effects.
*/
explicit KIcon(const QIcon& copy);
/**
* Constructor for a null icon.
*/
KIcon();
/**
* Destroys the icon.
*/
~KIcon();
- KIcon& operator=( const KIcon &other );
+ KIcon& operator=( const QIcon &other );
private:
class Private;
Private* const d;
};
#endif
diff --git a/kdeui/icons/kiconbutton.cpp b/kdeui/icons/kiconbutton.cpp
index 895a31e638..55fa356665 100644
--- a/kdeui/icons/kiconbutton.cpp
+++ b/kdeui/icons/kiconbutton.cpp
@@ -1,189 +1,190 @@
/* vi: ts=8 sts=4 sw=4
*
* This file is part of the KDE project, module kfile.
* Copyright (C) 2000 Geert Jansen <jansen@kde.org>
* (C) 2000 Kurt Granroth <granroth@kde.org>
* (C) 1997 Christoph Neerfeld <chris@kde.org>
* (C) 2002 Carsten Pfeiffer <pfeiffer@kde.org>
*
* This is free software; it comes under the GNU Library General
* Public License, version 2. See the file "COPYING.LIB" for the
* exact licensing terms.
*/
#include "kiconbutton.h"
#include <QtCore/QFileInfo>
+#include <kicon.h>
#include <kiconloader.h>
#include "kicondialog.h"
class KIconButton::KIconButtonPrivate
{
public:
KIconButtonPrivate(KIconButton *qq, KIconLoader *loader);
~KIconButtonPrivate();
// slots
void _k_slotChangeIcon();
void _k_newIconName(const QString&);
KIconButton *q;
int iconSize;
int buttonIconSize;
bool m_bStrictIconSize;
bool mbUser;
KIconLoader::Group mGroup;
KIconLoader::Context mContext;
QString mIcon;
KIconDialog *mpDialog;
KIconLoader *mpLoader;
};
/*
* KIconButton: A "choose icon" pushbutton.
*/
KIconButton::KIconButton(QWidget *parent)
: QPushButton(parent), d(new KIconButtonPrivate(this, KIconLoader::global()))
{
QPushButton::setIconSize(QSize(48, 48));
}
KIconButton::KIconButton(KIconLoader *loader, QWidget *parent)
: QPushButton(parent), d(new KIconButtonPrivate(this, loader))
{
QPushButton::setIconSize(QSize(48, 48));
}
KIconButton::KIconButtonPrivate::KIconButtonPrivate(KIconButton *qq, KIconLoader *loader)
: q(qq)
{
m_bStrictIconSize = false;
iconSize = 0; // let KIconLoader choose the default
buttonIconSize = -1; //When buttonIconSize is -1, iconSize will be used for the button
mGroup = KIconLoader::Desktop;
mContext = KIconLoader::Application;
mbUser = false;
mpLoader = loader;
mpDialog = 0L;
connect(q, SIGNAL(clicked()), q, SLOT(_k_slotChangeIcon()));
}
KIconButton::KIconButtonPrivate::~KIconButtonPrivate()
{
delete mpDialog;
}
KIconButton::~KIconButton()
{
delete d;
}
void KIconButton::setStrictIconSize(bool b)
{
d->m_bStrictIconSize=b;
}
bool KIconButton::strictIconSize() const
{
return d->m_bStrictIconSize;
}
void KIconButton::setIconSize( int size )
{
if (d->buttonIconSize == -1) {
QPushButton::setIconSize(QSize(size, size));
}
d->iconSize = size;
}
int KIconButton::iconSize() const
{
return d->iconSize;
}
void KIconButton::setButtonIconSize( int size )
{
QPushButton::setIconSize(QSize(size, size));
d->buttonIconSize = size;
}
int KIconButton::buttonIconSize() const
{
return QPushButton::iconSize().height();
}
void KIconButton::setIconType(KIconLoader::Group group, KIconLoader::Context context, bool user)
{
d->mGroup = group;
d->mContext = context;
d->mbUser = user;
}
void KIconButton::setIcon(const QString& icon)
{
d->mIcon = icon;
setIcon(KIcon(d->mIcon));
if (!d->mpDialog) {
d->mpDialog = new KIconDialog(d->mpLoader, this);
connect(d->mpDialog, SIGNAL(newIconName(const QString&)), this, SLOT(_k_newIconName(const QString&)));
}
if (d->mbUser) {
d->mpDialog->setCustomLocation(QFileInfo(d->mpLoader->iconPath(d->mIcon, d->mGroup, true) ).absolutePath());
}
}
void KIconButton::setIcon(const QIcon& icon)
{
QPushButton::setIcon(icon);
}
void KIconButton::resetIcon()
{
d->mIcon.clear();
setIcon(QIcon());
}
const QString &KIconButton::icon() const
{
return d->mIcon;
}
void KIconButton::KIconButtonPrivate::_k_slotChangeIcon()
{
if (!mpDialog)
{
mpDialog = new KIconDialog(mpLoader, q);
connect(mpDialog, SIGNAL(newIconName(const QString&)), q, SLOT(_k_newIconName(const QString&)));
}
mpDialog->setup(mGroup, mContext, m_bStrictIconSize, iconSize, mbUser);
mpDialog->showDialog();
}
void KIconButton::KIconButtonPrivate::_k_newIconName(const QString& name)
{
if (name.isEmpty())
return;
q->setIcon(KIcon(name));
mIcon = name;
if (mbUser) {
mpDialog->setCustomLocation(QFileInfo(mpLoader->iconPath(mIcon, mGroup, true)).absolutePath());
}
emit q->iconChanged(name);
}
#include "moc_kiconbutton.cpp"
diff --git a/kdeui/jobs/kwidgetjobtracker.cpp b/kdeui/jobs/kwidgetjobtracker.cpp
index c73e3b9c45..1552fab2d9 100644
--- a/kdeui/jobs/kwidgetjobtracker.cpp
+++ b/kdeui/jobs/kwidgetjobtracker.cpp
@@ -1,671 +1,672 @@
/* This file is part of the KDE project
Copyright (C) 2000 Matej Koss <koss@miesto.sk>
Copyright (C) 2007 Kevin Ottens <ervin@kde.org>
Copyright (C) 2007 Rafael Fernández López <ereslibre@kde.org>
Copyright (C) 2009 Shaun Reich <shaun.reich@kdemail.net>
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 "kwidgetjobtracker.h"
#include "kwidgetjobtracker_p.h"
#include <QProcess>
#include <QTimer>
#include <QLabel>
#include <QProgressBar>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QMenu>
#include <QEvent>
+#include <kicon.h>
#include <kurl.h>
#include <kpushbutton.h>
#include <ksqueezedtextlabel.h>
#include <kguiitem.h>
#include <kiconloader.h>
#include <kdialog.h>
#include <kstandarddirs.h>
#include <kdebug.h>
#include <klocale.h>
#include <kwindowsystem.h>
#include <kseparator.h>
void KWidgetJobTracker::Private::_k_showProgressWidget()
{
if (progressWidgetsToBeShown.isEmpty()) {
return;
}
KJob *job = progressWidgetsToBeShown.dequeue();
// If the job has been unregistered before reaching this point, widget will
// return 0.
QWidget *widget = q->widget(job);
if (widget) {
widget->show();
}
}
KWidgetJobTracker::KWidgetJobTracker(QWidget *parent)
: KAbstractWidgetJobTracker(parent), d(new Private(parent, this))
{
}
KWidgetJobTracker::~KWidgetJobTracker()
{
delete d;
}
QWidget *KWidgetJobTracker::widget(KJob *job)
{
return d->progressWidget.value(job, 0);
}
void KWidgetJobTracker::registerJob(KJob *job)
{
Private::ProgressWidget *vi = new Private::ProgressWidget(job, this, d->parent);
vi->jobRegistered = true;
vi->setAttribute(Qt::WA_DeleteOnClose);
d->progressWidget.insert(job, vi);
d->progressWidgetsToBeShown.enqueue(job);
KAbstractWidgetJobTracker::registerJob(job);
QTimer::singleShot(500, this, SLOT(_k_showProgressWidget()));
}
void KWidgetJobTracker::unregisterJob(KJob *job)
{
KAbstractWidgetJobTracker::unregisterJob(job);
d->progressWidgetsToBeShown.removeAll(job);
KWidgetJobTracker::Private::ProgressWidget *pWidget = d->progressWidget.value(job, 0);
if (!pWidget) {
return;
}
pWidget->jobRegistered = false;
pWidget->deref();
}
bool KWidgetJobTracker::keepOpen(KJob *job) const
{
KWidgetJobTracker::Private::ProgressWidget *pWidget = d->progressWidget.value(job, 0);
if (!pWidget) {
return false;
}
return pWidget->keepOpenCheck->isChecked();
}
void KWidgetJobTracker::infoMessage(KJob *job, const QString &plain, const QString &rich)
{
KWidgetJobTracker::Private::ProgressWidget *pWidget = d->progressWidget.value(job, 0);
if (!pWidget) {
return;
}
pWidget->infoMessage(plain, rich);
}
void KWidgetJobTracker::description(KJob *job, const QString &title,
const QPair<QString, QString> &field1,
const QPair<QString, QString> &field2)
{
KWidgetJobTracker::Private::ProgressWidget *pWidget = d->progressWidget.value(job, 0);
if (!pWidget) {
return;
}
pWidget->description(title, field1, field2);
}
void KWidgetJobTracker::totalAmount(KJob *job, KJob::Unit unit, qulonglong amount)
{
KWidgetJobTracker::Private::ProgressWidget *pWidget = d->progressWidget.value(job, 0);
if (!pWidget) {
return;
}
pWidget->totalAmount(unit, amount);
}
void KWidgetJobTracker::processedAmount(KJob *job, KJob::Unit unit, qulonglong amount)
{
KWidgetJobTracker::Private::ProgressWidget *pWidget = d->progressWidget.value(job, 0);
if (!pWidget) {
return;
}
pWidget->processedAmount(unit, amount);
}
void KWidgetJobTracker::percent(KJob *job, unsigned long percent)
{
KWidgetJobTracker::Private::ProgressWidget *pWidget = d->progressWidget.value(job, 0);
if (!pWidget) {
return;
}
pWidget->percent(percent);
}
void KWidgetJobTracker::speed(KJob *job, unsigned long value)
{
KWidgetJobTracker::Private::ProgressWidget *pWidget = d->progressWidget.value(job, 0);
if (!pWidget) {
return;
}
pWidget->speed(value);
}
void KWidgetJobTracker::slotClean(KJob *job)
{
KWidgetJobTracker::Private::ProgressWidget *pWidget = d->progressWidget.value(job, 0);
if (!pWidget) {
return;
}
pWidget->slotClean();
}
void KWidgetJobTracker::suspended(KJob *job)
{
KWidgetJobTracker::Private::ProgressWidget *pWidget = d->progressWidget.value(job, 0);
if (!pWidget) {
return;
}
pWidget->suspended();
}
void KWidgetJobTracker::resumed(KJob *job)
{
KWidgetJobTracker::Private::ProgressWidget *pWidget = d->progressWidget.value(job, 0);
if (!pWidget) {
return;
}
pWidget->resumed();
}
void KWidgetJobTracker::Private::ProgressWidget::ref()
{
++refCount;
}
void KWidgetJobTracker::Private::ProgressWidget::deref()
{
if (refCount) {
--refCount;
}
if (!refCount) {
if (!keepOpenCheck->isChecked()) {
closeNow();
} else {
slotClean();
}
}
}
void KWidgetJobTracker::Private::ProgressWidget::closeNow()
{
close();
// It might happen the next scenario:
// - Start a job which opens a progress widget. Keep it open. Address job is 0xdeadbeef
// - Start a new job, which is given address 0xdeadbeef. A new window is opened.
// This one will take much longer to complete. The key 0xdeadbeef on the widget map now
// stores the new widget address.
// - Close the first progress widget that was opened (and has already finished) while the
// last one is still running. We remove its reference on the map. Wrong.
// For that reason we have to check if the map stores the widget as the current one.
// ereslibre
if (tracker->d->progressWidget[job] == this) {
tracker->d->progressWidget.remove(job);
tracker->d->progressWidgetsToBeShown.removeAll(job);
}
}
bool KWidgetJobTracker::Private::ProgressWidget::eventFilter(QObject *watched, QEvent *event)
{
// Handle context menu events for the source/dest labels here, so that we are ref()ed while the
// menu is exec()ed, to avoid a crash if the job finishes meanwhile. #159621.
if ((watched == sourceEdit || watched == destEdit) && event->type() == QEvent::ContextMenu) {
ref();
watched->event(event);
deref();
return true;
}
return QWidget::eventFilter(watched, event);
}
void KWidgetJobTracker::Private::ProgressWidget::infoMessage(const QString &plain, const QString &/*rich*/)
{
speedLabel->setText(plain);
speedLabel->setAlignment(speedLabel->alignment() & ~Qt::TextWordWrap);
}
void KWidgetJobTracker::Private::ProgressWidget::description(const QString &title,
const QPair<QString, QString> &field1,
const QPair<QString, QString> &field2)
{
setWindowTitle(title);
caption = title;
sourceInvite->setText(i18nc("%1 is the label, we add a ':' to it", "%1:", field1.first));
sourceEdit->setText(field1.second);
if (field2.first.isEmpty()) {
setDestVisible(false);
} else {
setDestVisible(true);
checkDestination(KUrl(field2.second));
destInvite->setText(i18nc("%1 is the label, we add a ':' to it", "%1:", field2.first));
destEdit->setText(field2.second);
}
}
void KWidgetJobTracker::Private::ProgressWidget::totalAmount(KJob::Unit unit, qulonglong amount)
{
switch(unit)
{
case KJob::Bytes:
totalSizeKnown = true;
// size is measured in bytes
if (totalSize == amount)
return;
totalSize = amount;
if (startTime.isNull())
startTime.start();
break;
case KJob::Files:
if (totalFiles == amount)
return;
totalFiles = amount;
showTotals();
break;
case KJob::Directories:
if (totalDirs == amount)
return;
totalDirs = amount;
showTotals();
break;
}
}
void KWidgetJobTracker::Private::ProgressWidget::processedAmount(KJob::Unit unit, qulonglong amount)
{
QString tmp;
switch(unit)
{
case KJob::Bytes:
if (processedSize == amount)
return;
processedSize = amount;
if (totalSizeKnown) {
tmp = i18np( "%2 of %3 complete", "%2 of %3 complete",
amount,
KGlobal::locale()->formatByteSize(amount),
KGlobal::locale()->formatByteSize(totalSize));
} else {
tmp = KGlobal::locale()->formatByteSize(amount);
}
sizeLabel->setText(tmp);
if (!totalSizeKnown) // update jumping progressbar
progressBar->setValue(amount);
break;
case KJob::Directories:
if (processedDirs == amount)
return;
processedDirs = amount;
tmp = i18np("%2 / %1 folder", "%2 / %1 folders", totalDirs, processedDirs);
tmp += " ";
tmp += i18np("%2 / %1 file", "%2 / %1 files", totalFiles, processedFiles);
progressLabel->setText(tmp);
break;
case KJob::Files:
if (processedFiles == amount)
return;
processedFiles = amount;
if (totalDirs > 1) {
tmp = i18np("%2 / %1 folder", "%2 / %1 folders", totalDirs, processedDirs);
tmp += " ";
}
tmp += i18np("%2 / %1 file", "%2 / %1 files", totalFiles, processedFiles);
progressLabel->setText(tmp);
}
}
void KWidgetJobTracker::Private::ProgressWidget::percent(unsigned long percent)
{
QString title = caption + " (";
if (totalSizeKnown) {
title += i18n("%1% of %2", percent,
KGlobal::locale()->formatByteSize(totalSize));
} else if (totalFiles) {
title += i18np("%2% of 1 file", "%2% of %1 files", totalFiles, percent);
} else {
title += i18n("%1%", percent);
}
title += ')';
progressBar->setMaximum(100);
progressBar->setValue(percent);
setWindowTitle(title);
}
void KWidgetJobTracker::Private::ProgressWidget::speed(unsigned long value)
{
if (value == 0) {
speedLabel->setText(i18n("Stalled"));
} else {
const QString speedStr = KGlobal::locale()->formatByteSize(value);
if (totalSizeKnown) {
const int remaining = 1000*(totalSize - processedSize)/value;
speedLabel->setText(i18np("%2/s (%3 remaining)", "%2/s (%3 remaining)", remaining, speedStr,
KGlobal::locale()->prettyFormatDuration(remaining)));
} else { // total size is not known (#24228)
speedLabel->setText(i18nc("speed in bytes per second", "%1/s", speedStr));
}
}
}
void KWidgetJobTracker::Private::ProgressWidget::slotClean()
{
percent(100);
cancelClose->setGuiItem(KStandardGuiItem::close());
openFile->setEnabled(true);
if (!totalSizeKnown || totalSize < processedSize)
totalSize = processedSize;
processedAmount(KJob::Bytes, totalSize);
keepOpenCheck->setEnabled(false);
pauseButton->setEnabled(false);
if (!startTime.isNull()) {
int s = startTime.elapsed();
if (!s)
s = 1;
speedLabel->setText(i18n("%1/s (done)",
KGlobal::locale()->formatByteSize(1000 * totalSize / s)));
}
}
void KWidgetJobTracker::Private::ProgressWidget::suspended()
{
pauseButton->setText(i18n("&Resume"));
suspendedProperty = true;
}
void KWidgetJobTracker::Private::ProgressWidget::resumed()
{
pauseButton->setText(i18n("&Pause"));
suspendedProperty = false;
}
void KWidgetJobTracker::Private::ProgressWidget::closeEvent(QCloseEvent *event)
{
if (jobRegistered && tracker->stopOnClose(job)) {
tracker->slotStop(job);
}
QWidget::closeEvent(event);
}
void KWidgetJobTracker::Private::ProgressWidget::init()
{
// Set a useful icon for this window!
#ifndef KDE_NO_WINDOWSYSTEM
KWindowSystem::setIcons( winId(),
KIconLoader::global()->loadIcon( "document-save", KIconLoader::NoGroup, 32 ),
KIconLoader::global()->loadIcon( "document-save", KIconLoader::NoGroup, 16 ) );
#else
#warning QT5 PORT TO QPA
#endif
QVBoxLayout *topLayout = new QVBoxLayout(this);
QGridLayout *grid = new QGridLayout();
topLayout->addLayout(grid);
grid->addItem(new QSpacerItem(KDialog::spacingHint(),0),0,1);
// filenames or action name
sourceInvite = new QLabel(i18nc("The source url of a job", "Source:"), this);
grid->addWidget(sourceInvite, 0, 0);
sourceEdit = new KSqueezedTextLabel(this);
sourceEdit->setTextInteractionFlags(Qt::TextSelectableByMouse);
sourceEdit->installEventFilter(this);
grid->addWidget(sourceEdit, 0, 2);
destInvite = new QLabel(i18nc("The destination url of a job", "Destination:"), this);
grid->addWidget(destInvite, 1, 0);
destEdit = new KSqueezedTextLabel(this);
destEdit->setTextInteractionFlags(Qt::TextSelectableByMouse);
destEdit->installEventFilter(this);
grid->addWidget(destEdit, 1, 2);
QHBoxLayout *progressHBox = new QHBoxLayout();
topLayout->addLayout(progressHBox);
progressBar = new QProgressBar(this);
progressBar->setMaximum(0); // want a jumping progress bar if percent is not emitted
progressHBox->addWidget(progressBar);
suspendedProperty = false;
// processed info
QHBoxLayout *hBox = new QHBoxLayout();
topLayout->addLayout(hBox);
arrowButton = new KPushButton(this);
arrowButton->setMaximumSize(QSize(32,25));
arrowButton->setIcon(KIcon("arrow-down"));
arrowButton->setToolTip(i18n("Click this to expand the dialog, to show details"));
arrowState = Qt::DownArrow;
connect(arrowButton, SIGNAL(clicked()), this, SLOT(_k_arrowToggled()));
hBox->addWidget(arrowButton);
hBox->addStretch(1);
KSeparator *separator1 = new KSeparator(Qt::Horizontal, this);
topLayout->addWidget(separator1);
sizeLabel = new QLabel(this);
hBox->addWidget(sizeLabel, 0, Qt::AlignLeft);
resumeLabel = new QLabel(this);
hBox->addWidget(resumeLabel);
pauseButton = new KPushButton(i18n("&Pause"), this);
connect(pauseButton, SIGNAL(clicked()), this, SLOT(_k_pauseResumeClicked()));
hBox->addWidget(pauseButton);
hBox = new QHBoxLayout();
topLayout->addLayout(hBox);
speedLabel = new QLabel(this);
hBox->addWidget(speedLabel, 1);
speedLabel->hide();
hBox = new QHBoxLayout();
topLayout->addLayout(hBox);
progressLabel = new QLabel(this);
progressLabel->setAlignment(Qt::AlignLeft);
hBox->addWidget(progressLabel);
progressLabel->hide();
keepOpenCheck = new QCheckBox(i18n("&Keep this window open after transfer is complete"), this);
connect(keepOpenCheck, SIGNAL(toggled(bool)), this, SLOT(_k_keepOpenToggled(bool)));
topLayout->addWidget(keepOpenCheck);
keepOpenCheck->hide();
hBox = new QHBoxLayout();
topLayout->addLayout(hBox);
openFile = new KPushButton(i18n("Open &File"), this);
connect(openFile, SIGNAL(clicked()), this, SLOT(_k_openFile()));
hBox->addWidget(openFile);
openFile->setEnabled(false);
openFile->hide();
openLocation = new KPushButton(i18n("Open &Destination"), this);
connect(openLocation, SIGNAL(clicked()), this, SLOT(_k_openLocation()));
hBox->addWidget(openLocation);
openLocation->hide();
hBox->addStretch(1);
cancelClose = new KPushButton(KStandardGuiItem::cancel(), this);
connect(cancelClose, SIGNAL(clicked()), this, SLOT(_k_stop()));
hBox->addWidget(cancelClose);
resize(sizeHint());
setMaximumHeight(sizeHint().height());
setWindowTitle(i18n("Progress Dialog")); // show something better than kuiserver
}
void KWidgetJobTracker::Private::ProgressWidget::showTotals()
{
// Show the totals in the progress label, if we still haven't
// processed anything. This is useful when the stat'ing phase
// of CopyJob takes a long time (e.g. over networks).
if (processedFiles == 0 && processedDirs == 0)
{
QString tmps;
if (totalDirs > 1)
// that we have a singular to translate looks weired but is only logical
tmps = i18np("%1 folder", "%1 folders", totalDirs) + " ";
tmps += i18np("%1 file", "%1 files", totalFiles);
progressLabel->setText( tmps );
}
}
void KWidgetJobTracker::Private::ProgressWidget::setDestVisible(bool visible)
{
// We can't hide the destInvite/destEdit labels,
// because it screws up the QGridLayout.
if (visible)
{
destInvite->show();
destEdit->show();
}
else
{
destInvite->hide();
destEdit->hide();
destInvite->setText( QString() );
destEdit->setText( QString() );
}
setMaximumHeight(sizeHint().height());
}
void KWidgetJobTracker::Private::ProgressWidget::checkDestination(const KUrl &dest)
{
bool ok = true;
if (dest.isLocalFile()) {
QString path = dest.toLocalFile( KUrl::RemoveTrailingSlash );
const QStringList tmpDirs = KGlobal::dirs()->resourceDirs( "tmp" );
for (QStringList::ConstIterator it = tmpDirs.begin() ; ok && it != tmpDirs.end() ; ++it)
if (path.contains(*it))
ok = false; // it's in the tmp resource
}
if (ok) {
openFile->show();
openLocation->show();
keepOpenCheck->show();
setMaximumHeight(sizeHint().height());
location=dest;
}
}
void KWidgetJobTracker::Private::ProgressWidget::_k_keepOpenToggled(bool keepOpen)
{
if (keepOpen) {
KGlobal::ref();
} else {
KGlobal::deref();
}
}
void KWidgetJobTracker::Private::ProgressWidget::_k_openFile()
{
QProcess::startDetached("kde-open", QStringList() << location.prettyUrl());
}
void KWidgetJobTracker::Private::ProgressWidget::_k_openLocation()
{
KUrl dirLocation(location);
dirLocation.setFileName(QString());
QProcess::startDetached("kde-open", QStringList() << dirLocation.prettyUrl());
}
void KWidgetJobTracker::Private::ProgressWidget::_k_pauseResumeClicked()
{
if (jobRegistered && !suspendedProperty) {
tracker->slotSuspend(job);
} else if (jobRegistered) {
tracker->slotResume(job);
}
}
void KWidgetJobTracker::Private::ProgressWidget::_k_stop()
{
if (jobRegistered) {
tracker->slotStop(job);
}
closeNow();
}
void KWidgetJobTracker::Private::ProgressWidget::_k_arrowToggled()
{
if (arrowState == Qt::DownArrow) {
//The arrow is in the down position, dialog is collapsed, expand it and change icon.
progressLabel->show();
speedLabel->show();
arrowButton->setIcon(KIcon("arrow-up"));
arrowButton->setToolTip(i18n("Click this to collapse the dialog, to hide details"));
arrowState = Qt::UpArrow;
} else {
//Collapse the dialog
progressLabel->hide();
speedLabel->hide();
arrowButton->setIcon(KIcon("arrow-down"));
arrowButton->setToolTip(i18n("Click this to expand the dialog, to show details"));
arrowState = Qt::DownArrow;
}
setMaximumHeight(sizeHint().height());
}
#include "moc_kwidgetjobtracker.cpp"
#include "moc_kwidgetjobtracker_p.cpp"
diff --git a/kdeui/paged/kpagewidgetmodel.cpp b/kdeui/paged/kpagewidgetmodel.cpp
index e065888f8d..c5f6e4164e 100644
--- a/kdeui/paged/kpagewidgetmodel.cpp
+++ b/kdeui/paged/kpagewidgetmodel.cpp
@@ -1,545 +1,545 @@
/*
This file is part of the KDE Libraries
Copyright (C) 2006 Tobias Koenig (tokoe@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 as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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 "kpagewidgetmodel.h"
#include "kpagewidgetmodel_p.h"
#include <QPointer>
#include <QWidget>
-#include <kicon.h>
+#include <QIcon>
class KPageWidgetItem::Private
{
public:
Private()
: checkable(false), checked(false), enabled(true)
{
}
~Private()
{
delete widget;
widget = 0;
}
QString name;
QString header;
- KIcon icon;
+ QIcon icon;
QPointer<QWidget> widget;
bool checkable : 1;
bool checked : 1;
bool enabled : 1;
};
KPageWidgetItem::KPageWidgetItem( QWidget *widget )
: QObject( 0 ), d( new Private )
{
d->widget = widget;
/**
* Hide the widget, otherwise when the widget has this KPageView as
* parent the widget is shown outside the QStackedWidget if the page
* was not selected ( and reparented ) yet.
*/
if ( d->widget )
d->widget->hide();
}
KPageWidgetItem::KPageWidgetItem( QWidget *widget, const QString &name )
: QObject( 0 ), d( new Private )
{
d->widget = widget;
d->name = name;
/**
* Hide the widget, otherwise when the widget has this KPageView as
* parent the widget is shown outside the QStackedWidget if the page
* was not selected ( and reparented ) yet.
*/
if ( d->widget )
d->widget->hide();
}
KPageWidgetItem::~KPageWidgetItem()
{
delete d;
}
void KPageWidgetItem::setEnabled(bool enabled)
{
d->enabled = enabled;
if (d->widget) {
d->widget->setEnabled(enabled);
}
emit changed();
}
bool KPageWidgetItem::isEnabled() const
{
return d->enabled;
}
QWidget* KPageWidgetItem::widget() const
{
return d->widget;
}
void KPageWidgetItem::setName( const QString &name )
{
d->name = name;
emit changed();
}
QString KPageWidgetItem::name() const
{
return d->name;
}
void KPageWidgetItem::setHeader( const QString &header )
{
d->header = header;
emit changed();
}
QString KPageWidgetItem::header() const
{
return d->header;
}
-void KPageWidgetItem::setIcon( const KIcon &icon )
+void KPageWidgetItem::setIcon( const QIcon &icon )
{
d->icon = icon;
emit changed();
}
-KIcon KPageWidgetItem::icon() const
+QIcon KPageWidgetItem::icon() const
{
return d->icon;
}
void KPageWidgetItem::setCheckable( bool checkable )
{
d->checkable = checkable;
emit changed();
}
bool KPageWidgetItem::isCheckable() const
{
return d->checkable;
}
void KPageWidgetItem::setChecked( bool checked )
{
d->checked = checked;
emit toggled( checked );
emit changed();
}
bool KPageWidgetItem::isChecked() const
{
return d->checked;
}
PageItem::PageItem( KPageWidgetItem *pageWidgetItem, PageItem *parent )
: mPageWidgetItem( pageWidgetItem ), mParentItem( parent )
{
}
PageItem::~PageItem()
{
delete mPageWidgetItem;
mPageWidgetItem = 0;
qDeleteAll(mChildItems);
}
void PageItem::appendChild( PageItem *item )
{
mChildItems.append( item );
}
void PageItem::insertChild( int row, PageItem *item )
{
mChildItems.insert( row, item );
}
void PageItem::removeChild( int row )
{
mChildItems.removeAt( row );
}
PageItem *PageItem::child( int row )
{
return mChildItems.value( row );
}
int PageItem::childCount() const
{
return mChildItems.count();
}
int PageItem::columnCount() const
{
return 1;
}
PageItem *PageItem::parent()
{
return mParentItem;
}
int PageItem::row() const
{
if ( mParentItem )
return mParentItem->mChildItems.indexOf( const_cast<PageItem*>(this) );
return 0;
}
KPageWidgetItem* PageItem::pageWidgetItem() const
{
return mPageWidgetItem;
}
PageItem *PageItem::findChild( const KPageWidgetItem *item )
{
if ( mPageWidgetItem == item )
return this;
for ( int i = 0; i < mChildItems.count(); ++i ) {
PageItem *pageItem = mChildItems[ i ]->findChild( item );
if ( pageItem )
return pageItem;
}
return 0;
}
void PageItem::dump( int indent )
{
QString prefix;
for ( int i = 0; i < indent; ++i )
prefix.append( " " );
const QString name = ( mPageWidgetItem ? mPageWidgetItem->name() : "root" );
qDebug( "%s (%p)", qPrintable( QString( "%1%2" ).arg( prefix, name ) ), (void*)this );
for ( int i = 0; i < mChildItems.count(); ++i )
mChildItems[ i ]->dump( indent + 2 );
}
KPageWidgetModel::KPageWidgetModel( QObject *parent )
: KPageModel(*new KPageWidgetModelPrivate, parent)
{
}
KPageWidgetModel::~KPageWidgetModel()
{
}
int KPageWidgetModel::columnCount( const QModelIndex& ) const
{
return 1;
}
QVariant KPageWidgetModel::data( const QModelIndex &index, int role ) const
{
if ( !index.isValid() )
return QVariant();
PageItem *item = static_cast<PageItem*>( index.internalPointer() );
if ( role == Qt::DisplayRole )
return QVariant( item->pageWidgetItem()->name() );
else if ( role == Qt::DecorationRole )
return QVariant( item->pageWidgetItem()->icon() );
else if ( role == HeaderRole )
return QVariant( item->pageWidgetItem()->header() );
else if ( role == WidgetRole )
return QVariant::fromValue( item->pageWidgetItem()->widget() );
else if ( role == Qt::CheckStateRole ) {
if ( item->pageWidgetItem()->isCheckable() ) {
return ( item->pageWidgetItem()->isChecked() ? Qt::Checked : Qt::Unchecked );
} else
return QVariant();
} else
return QVariant();
}
bool KPageWidgetModel::setData( const QModelIndex &index, const QVariant &value, int role )
{
if ( !index.isValid() )
return false;
if ( role != Qt::CheckStateRole )
return false;
PageItem *item = static_cast<PageItem*>( index.internalPointer() );
if ( !item )
return false;
if ( !item->pageWidgetItem()->isCheckable() )
return false;
if ( value.toInt() == Qt::Checked )
item->pageWidgetItem()->setChecked( true );
else
item->pageWidgetItem()->setChecked( false );
return true;
}
Qt::ItemFlags KPageWidgetModel::flags( const QModelIndex &index ) const
{
if ( !index.isValid() )
return 0;
Qt::ItemFlags flags = Qt::ItemIsSelectable;
PageItem *item = static_cast<PageItem*>( index.internalPointer() );
if ( item->pageWidgetItem()->isCheckable() )
flags |= Qt::ItemIsUserCheckable;
if (item->pageWidgetItem()->isEnabled()) {
flags |= Qt::ItemIsEnabled;
}
return flags;
}
QModelIndex KPageWidgetModel::index( int row, int column, const QModelIndex &parent ) const
{
PageItem *parentItem;
if ( parent.isValid() )
parentItem = static_cast<PageItem*>( parent.internalPointer() );
else
parentItem = d_func()->rootItem;
PageItem *childItem = parentItem->child( row );
if ( childItem )
return createIndex( row, column, childItem );
else
return QModelIndex();
}
QModelIndex KPageWidgetModel::parent( const QModelIndex &index ) const
{
if ( !index.isValid() )
return QModelIndex();
PageItem *item = static_cast<PageItem*>( index.internalPointer() );
PageItem *parentItem = item->parent();
if ( parentItem == d_func()->rootItem )
return QModelIndex();
else
return createIndex( parentItem->row(), 0, parentItem );
}
int KPageWidgetModel::rowCount( const QModelIndex &parent ) const
{
PageItem *parentItem;
if ( !parent.isValid() )
parentItem = d_func()->rootItem;
else
parentItem = static_cast<PageItem*>( parent.internalPointer() );
return parentItem->childCount();
}
KPageWidgetItem* KPageWidgetModel::addPage( QWidget *widget, const QString &name )
{
KPageWidgetItem *item = new KPageWidgetItem( widget, name );
addPage( item );
return item;
}
void KPageWidgetModel::addPage( KPageWidgetItem *item )
{
emit layoutAboutToBeChanged();
Q_D(KPageWidgetModel);
connect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged()));
connect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool)));
// The row to be inserted
int row = d->rootItem->childCount();
beginInsertRows(QModelIndex(), row, row);
PageItem *pageItem = new PageItem( item, d->rootItem );
d->rootItem->appendChild( pageItem );
endInsertRows();
emit layoutChanged();
}
KPageWidgetItem* KPageWidgetModel::insertPage( KPageWidgetItem *before, QWidget *widget, const QString &name )
{
KPageWidgetItem *item = new KPageWidgetItem( widget, name );
insertPage( before, item );
return item;
}
void KPageWidgetModel::insertPage( KPageWidgetItem *before, KPageWidgetItem *item )
{
PageItem *beforePageItem = d_func()->rootItem->findChild(before);
if ( !beforePageItem ) {
qDebug( "Invalid KPageWidgetItem passed!" );
return;
}
emit layoutAboutToBeChanged();
connect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged()));
connect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool)));
PageItem *parent = beforePageItem->parent();
// The row to be inserted
int row = beforePageItem->row();
QModelIndex index;
if (parent != d_func()->rootItem) {
index = createIndex( parent->row(), 0, parent );
}
beginInsertRows(index, row, row);
PageItem *newPageItem = new PageItem( item, parent );
parent->insertChild( row, newPageItem );
endInsertRows();
emit layoutChanged();
}
KPageWidgetItem* KPageWidgetModel::addSubPage( KPageWidgetItem *parent, QWidget *widget, const QString &name )
{
KPageWidgetItem *item = new KPageWidgetItem( widget, name );
addSubPage( parent, item );
return item;
}
void KPageWidgetModel::addSubPage( KPageWidgetItem *parent, KPageWidgetItem *item )
{
PageItem *parentPageItem = d_func()->rootItem->findChild(parent);
if ( !parentPageItem ) {
qDebug( "Invalid KPageWidgetItem passed!" );
return;
}
emit layoutAboutToBeChanged();
connect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged()));
connect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool)));
// The row to be inserted
int row = parentPageItem->childCount();
QModelIndex index;
if (parentPageItem != d_func()->rootItem) {
index = createIndex( parentPageItem->row(), 0, parentPageItem );
}
beginInsertRows(index, row, row);
PageItem *newPageItem = new PageItem( item, parentPageItem );
parentPageItem->appendChild( newPageItem );
endInsertRows();
emit layoutChanged();
}
void KPageWidgetModel::removePage( KPageWidgetItem *item )
{
if ( !item )
return;
Q_D(KPageWidgetModel);
PageItem *pageItem = d->rootItem->findChild( item );
if ( !pageItem ) {
qDebug( "Invalid KPageWidgetItem passed!" );
return;
}
emit layoutAboutToBeChanged();
disconnect(item, SIGNAL(changed()), this, SLOT(_k_itemChanged()));
disconnect(item, SIGNAL(toggled(bool)), this, SLOT(_k_itemToggled(bool)));
PageItem *parentPageItem = pageItem->parent();
int row = parentPageItem->row();
QModelIndex index;
if ( parentPageItem != d->rootItem )
index = createIndex( row, 0, parentPageItem );
beginRemoveRows(index, pageItem->row(), pageItem->row());
parentPageItem->removeChild( pageItem->row() );
delete pageItem;
endRemoveRows();
emit layoutChanged();
}
KPageWidgetItem *KPageWidgetModel::item(const QModelIndex &index) const
{
if ( !index.isValid() )
return 0;
PageItem *item = static_cast<PageItem*>( index.internalPointer() );
if ( !item )
return 0;
return item->pageWidgetItem();
}
QModelIndex KPageWidgetModel::index( const KPageWidgetItem *item ) const
{
if ( !item )
return QModelIndex();
const PageItem *pageItem = d_func()->rootItem->findChild(item);
if ( !pageItem ) {
return QModelIndex();
}
return createIndex( pageItem->row(), 0, (void*)pageItem );
}
#include "moc_kpagewidgetmodel.cpp"
diff --git a/kdeui/paged/kpagewidgetmodel.h b/kdeui/paged/kpagewidgetmodel.h
index e0622e72cb..c360f2ccf1 100644
--- a/kdeui/paged/kpagewidgetmodel.h
+++ b/kdeui/paged/kpagewidgetmodel.h
@@ -1,304 +1,304 @@
/*
This file is part of the KDE Libraries
Copyright (C) 2006 Tobias Koenig (tokoe@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 as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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.
*/
#ifndef KPAGEWIDGETMODEL_H
#define KPAGEWIDGETMODEL_H
#include "kpagemodel.h"
class QWidget;
-class KIcon;
+
/**
* KPageWidgetItem is used by @ref KPageWidget and represents
* a page.
*
* <b>Example:</b>\n
*
* \code
* ColorPage *page = new ColorPage;
*
* KPageWidgetItem *item = new KPageWidgetItem( page, i18n( "Colors" ) );
* item->setHeader( i18n( "Colors of Main Window" ) );
* item->setIcon( KIcon( "colors" ) );
*
* KPageWidget *pageWidget = new KPageWidget( this );
* pageWidget->addPage( item );
* \endcode
*
* @author Tobias Koenig (tokoe@kde.org)
*/
class KDEUI_EXPORT KPageWidgetItem : public QObject
{
Q_OBJECT
Q_PROPERTY( QString name READ name WRITE setName )
Q_PROPERTY( QString header READ header WRITE setHeader )
- Q_PROPERTY( KIcon icon READ icon WRITE setIcon )
+ Q_PROPERTY( QIcon icon READ icon WRITE setIcon )
Q_PROPERTY( bool checkable READ isCheckable WRITE setCheckable )
Q_PROPERTY( bool checked READ isChecked WRITE setChecked )
/**
* This property holds whether the item is enabled.
*
* It dis-/enables both the widget and the item in the list-/treeview.
*/
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
public:
/**
* Creates a new page widget item.
*
* @param widget The widget that is shown as page in the KPageWidget.
*/
KPageWidgetItem( QWidget *widget );
/**
* Creates a new page widget item.
*
* @param widget The widget that is shown as page in the KPageWidget.
* @param name The localized string that is show in the navigation view
* of the KPageWidget.
*/
KPageWidgetItem( QWidget *widget, const QString &name );
/**
* Destroys the page widget item.
*/
~KPageWidgetItem();
/**
* Returns the widget of the page widget item.
*/
QWidget* widget() const;
/**
* Sets the name of the item as shown in the navigation view of the page
* widget.
*/
void setName( const QString &name );
/**
* Returns the name of the page widget item.
*/
QString name() const;
/**
* Sets the header of the page widget item.
*
* If setHeader(QString()) is used, what is the default if the header
* does not got set explicit, then the defined name() will also be used
* for the header. If setHeader("") is used, the header will be hidden
* even if the @a KPageView::FaceType is something else then Tabbed.
*
* @param header Header of the page widget item.
*/
void setHeader( const QString &header );
/**
* Returns the header of the page widget item.
*/
QString header() const;
/**
* Sets the icon of the page widget item.
* @param icon Icon of the page widget item.
*/
- void setIcon( const KIcon &icon );
+ void setIcon( const QIcon &icon );
/**
* Returns the icon of the page widget item.
*/
- KIcon icon() const;
+ QIcon icon() const;
/**
* Sets whether the page widget item is checkable in the view.
* @param checkable True if the page widget is checkable,
* otherwise false.
*/
void setCheckable( bool checkable );
/**
* Returns whether the page widget item is checkable.
*/
bool isCheckable() const;
/**
* Returns whether the page widget item is checked.
*/
bool isChecked() const;
/**
* Returns whether the page widget item is enabled.
*/
bool isEnabled() const;
public Q_SLOTS:
/**
* Sets whether the page widget item is enabled.
*/
void setEnabled(bool);
/**
* Sets whether the page widget item is checked.
*/
void setChecked( bool checked );
Q_SIGNALS:
/**
* This signal is emitted whenever the icon or header
* is changed.
*/
void changed();
/**
* This signal is emitted whenever the user checks or
* unchecks the item of @see setChecked() is called.
*/
void toggled( bool checked );
private:
class Private;
Private* const d;
};
class KPageWidgetModelPrivate;
/**
* This page model is used by @see KPageWidget to provide
* a hierarchical layout of pages.
*/
class KDEUI_EXPORT KPageWidgetModel : public KPageModel
{
Q_OBJECT
Q_DECLARE_PRIVATE(KPageWidgetModel)
public:
/**
* Creates a new page widget model.
*
* @param parent The parent object.
*/
explicit KPageWidgetModel( QObject *parent = 0 );
/**
* Destroys the page widget model.
*/
~KPageWidgetModel();
/**
* Adds a new top level page to the model.
*
* @param widget The widget of the page.
* @param name The name which is displayed in the navigation view.
*
* @returns The associated @see KPageWidgetItem.
*/
KPageWidgetItem* addPage( QWidget *widget, const QString &name );
/**
* Adds a new top level page to the model.
*
* @param item The @see KPageWidgetItem which describes the page.
*/
void addPage( KPageWidgetItem *item );
/**
* Inserts a new page in the model.
*
* @param before The new page will be insert before this @see KPageWidgetItem
* on the same level in hierarchy.
* @param widget The widget of the page.
* @param name The name which is displayed in the navigation view.
*
* @returns The associated @see KPageWidgetItem.
*/
KPageWidgetItem* insertPage( KPageWidgetItem *before, QWidget *widget, const QString &name );
/**
* Inserts a new page in the model.
*
* @param before The new page will be insert before this @see KPageWidgetItem
* on the same level in hierarchy.
*
* @param item The @see KPageWidgetItem which describes the page.
*/
void insertPage( KPageWidgetItem *before, KPageWidgetItem *item );
/**
* Inserts a new sub page in the model.
*
* @param parent The new page will be insert as child of this @see KPageWidgetItem.
* @param widget The widget of the page.
* @param name The name which is displayed in the navigation view.
*
* @returns The associated @see KPageWidgetItem.
*/
KPageWidgetItem* addSubPage( KPageWidgetItem *parent, QWidget *widget, const QString &name );
/**
* Inserts a new sub page in the model.
*
* @param parent The new page will be insert as child of this @see KPageWidgetItem.
*
* @param item The @see KPageWidgetItem which describes the page.
*/
void addSubPage( KPageWidgetItem *parent, KPageWidgetItem *item );
/**
* Removes the page associated with the given @see KPageWidgetItem.
*/
void removePage( KPageWidgetItem *item );
/**
* These methods are reimplemented from QAbstractItemModel.
*/
virtual int columnCount( const QModelIndex &parent = QModelIndex() ) const;
virtual QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const;
virtual bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole );
virtual Qt::ItemFlags flags( const QModelIndex &index ) const;
virtual QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const;
virtual QModelIndex parent( const QModelIndex &index ) const;
virtual int rowCount( const QModelIndex &parent = QModelIndex() ) const;
/**
* Returns the @see KPageWidgetItem for a given index or 0 if the index is invalid.
*/
KPageWidgetItem *item(const QModelIndex &index) const;
/**
* Returns the index for a given @see KPageWidgetItem. The index is invalid if the
* item can't be found in the model.
*/
QModelIndex index( const KPageWidgetItem *item ) const;
Q_SIGNALS:
/**
* This signal is emitted whenever a checkable page changes its state. @param checked is true
* when the @param page is checked, or false if the @param page is unchecked.
*/
void toggled( KPageWidgetItem *page, bool checked );
private:
Q_PRIVATE_SLOT(d_func(), void _k_itemChanged())
Q_PRIVATE_SLOT(d_func(), void _k_itemToggled(bool))
};
#endif
diff --git a/kdeui/tests/kdualactiontest.cpp b/kdeui/tests/kdualactiontest.cpp
index e7f214d040..2d0682eb8b 100644
--- a/kdeui/tests/kdualactiontest.cpp
+++ b/kdeui/tests/kdualactiontest.cpp
@@ -1,128 +1,130 @@
/* This file is part of the KDE libraries
*
* Copyright (c) 2010 Aurélien Gâteau <agateau@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include <kdualaction.h>
#include "qtest_kde.h"
+#include "kicon.h"
+
Q_DECLARE_METATYPE(KAction*)
static const QString INACTIVE_TEXT = "Show Foo";
static const QString ACTIVE_TEXT = "Hide Foo";
class KDualActionTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase()
{
qRegisterMetaType<KAction*>("KAction*");
}
void testSetGuiItem()
{
KDualAction action(0);
action.setInactiveGuiItem(KGuiItem(INACTIVE_TEXT));
action.setActiveGuiItem(KGuiItem(ACTIVE_TEXT));
QCOMPARE(action.inactiveText(), INACTIVE_TEXT);
QCOMPARE(action.activeText(), ACTIVE_TEXT);
QCOMPARE(action.text(), INACTIVE_TEXT);
}
void testSetIconForStates()
{
QIcon icon = KIcon("kde");
KDualAction action(0);
QVERIFY(action.inactiveIcon().isNull());
QVERIFY(action.activeIcon().isNull());
action.setIconForStates(icon);
QCOMPARE(action.inactiveIcon(), icon);
QCOMPARE(action.activeIcon(), icon);
}
void testSetActive()
{
KDualAction action(INACTIVE_TEXT, ACTIVE_TEXT, 0);
QVERIFY(!action.isActive());
QCOMPARE(action.text(), INACTIVE_TEXT);
QSignalSpy activeChangedSpy(&action, SIGNAL(activeChanged(bool)));
QSignalSpy activeChangedByUserSpy(&action, SIGNAL(activeChangedByUser(bool)));
action.setActive(true);
QVERIFY(action.isActive());
QCOMPARE(action.text(), ACTIVE_TEXT);
QCOMPARE(activeChangedSpy.count(), 1);
QCOMPARE(activeChangedSpy.takeFirst().at(0).toBool(), true);
QCOMPARE(activeChangedByUserSpy.count(), 0);
action.setActive(false);
QVERIFY(!action.isActive());
QCOMPARE(action.text(), INACTIVE_TEXT);
QCOMPARE(activeChangedSpy.count(), 1);
QCOMPARE(activeChangedSpy.takeFirst().at(0).toBool(), false);
QCOMPARE(activeChangedByUserSpy.count(), 0);
}
void testTrigger()
{
KDualAction action(INACTIVE_TEXT, ACTIVE_TEXT, 0);
QVERIFY(!action.isActive());
QCOMPARE(action.text(), INACTIVE_TEXT);
QSignalSpy activeChangedSpy(&action, SIGNAL(activeChanged(bool)));
QSignalSpy activeChangedByUserSpy(&action, SIGNAL(activeChangedByUser(bool)));
action.trigger();
QVERIFY(action.isActive());
QCOMPARE(action.text(), ACTIVE_TEXT);
QCOMPARE(activeChangedSpy.count(), 1);
QCOMPARE(activeChangedSpy.takeFirst().at(0).toBool(), true);
QCOMPARE(activeChangedByUserSpy.count(), 1);
QCOMPARE(activeChangedByUserSpy.takeFirst().at(0).toBool(), true);
action.trigger();
QVERIFY(!action.isActive());
QCOMPARE(action.text(), INACTIVE_TEXT);
QCOMPARE(activeChangedSpy.count(), 1);
QCOMPARE(activeChangedSpy.takeFirst().at(0).toBool(), false);
QCOMPARE(activeChangedByUserSpy.count(), 1);
QCOMPARE(activeChangedByUserSpy.takeFirst().at(0).toBool(), false);
// Turn off autoToggle, nothing should happen
action.setAutoToggle(false);
action.trigger();
QVERIFY(!action.isActive());
QCOMPARE(action.text(), INACTIVE_TEXT);
QCOMPARE(activeChangedSpy.count(), 0);
QCOMPARE(activeChangedByUserSpy.count(), 0);
// Turn on autoToggle, action should change
action.setAutoToggle(true);
action.trigger();
QCOMPARE(action.text(), ACTIVE_TEXT);
QCOMPARE(activeChangedSpy.count(), 1);
QCOMPARE(activeChangedSpy.takeFirst().at(0).toBool(), true);
QCOMPARE(activeChangedByUserSpy.count(), 1);
QCOMPARE(activeChangedByUserSpy.takeFirst().at(0).toBool(), true);
}
};
QTEST_KDEMAIN(KDualActionTest, GUI)
#include "kdualactiontest.moc"
diff --git a/kdeui/tests/kxmlguiwindowtest.cpp b/kdeui/tests/kxmlguiwindowtest.cpp
index a33d3efee1..487f7aef0f 100644
--- a/kdeui/tests/kxmlguiwindowtest.cpp
+++ b/kdeui/tests/kxmlguiwindowtest.cpp
@@ -1,129 +1,130 @@
/* This file is part of the KDE libraries
Copyright (C) 2008 Rafael Fernández López <ereslibre@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 <QTextEdit>
#include <QTimer>
+#include <kicon.h>
#include <kapplication.h>
#include <kxmlguiwindow.h>
#include <kaboutdata.h>
#include <kcmdlineargs.h>
#include <kactioncollection.h>
#include <kstandarddirs.h>
#include <kmessagebox.h>
#include <kaction.h>
#include <kdebug.h>
#include <kconfiggroup.h>
// BUG: if this symbol is defined the problem consists on:
// - main window is created.
// - settings are saved (and applied), but in this case no toolbars exist yet, so they don't
// apply to any toolbar.
// - after 1 second the GUI is created.
//
// How to reproduce ?
// - Move one toolbar to other place (bottom, left, right, or deattach it).
// - Close the test (so settings are saved).
// - Reopen the test. The toolbar you moved is not keeping the place you specified.
#define REPRODUCE_TOOLBAR_BUG
class MainWindow
: public KXmlGuiWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
public Q_SLOTS:
void slotTest();
void slotCreate();
private:
void setupActions();
};
void MainWindow::slotTest()
{
KMessageBox::information(0, "Test", "Test");
}
void MainWindow::slotCreate()
{
setupGUI(ToolBar);
createGUI(xmlFile());
if (autoSaveConfigGroup().isValid()) {
applyMainWindowSettings(autoSaveConfigGroup());
}
}
void MainWindow::setupActions()
{
KAction *testAction = new KAction(this);
testAction->setText("Test");
testAction->setIcon(KIcon("kde"));
actionCollection()->addAction("test", testAction);
connect(testAction, SIGNAL(triggered(bool)), this, SLOT(slotTest()));
KStandardAction::quit(kapp, SLOT(quit()), actionCollection());
setAutoSaveSettings();
// BUG: if the GUI is created after an amount of time (so settings have been saved), then toolbars
// are shown misplaced. KMainWindow uses a 500 ms timer to save window settings.
#ifdef REPRODUCE_TOOLBAR_BUG
QTimer::singleShot(1000, this, SLOT(slotCreate())); // more than 500 ms so the main window has saved settings.
// We can think of this case on natural applications when they
// load plugins and change parts. It can take 1 second perfectly.
#else
QTimer::singleShot(0, this, SLOT(slotCreate()));
#endif
}
MainWindow::MainWindow(QWidget *parent)
: KXmlGuiWindow(parent)
{
setXMLFile(KDESRCDIR "/kxmlguiwindowtestui.rc", true);
// Because we use a full path in setXMLFile, we need to call setLocalXMLFile too.
// In your apps, just pass a relative filename to setXMLFile instead.
setLocalXMLFile(KStandardDirs::locateLocal("data", "kxmlguiwindowtest/kxmlguiwindowtestui.rc"));
setCentralWidget(new QTextEdit(this));
setupActions();
}
int main(int argc, char **argv)
{
KAboutData aboutData("kxmlguiwindowtest", 0,
qi18n("kxmlguiwindowtest"), "0.1",
qi18n("kxmlguiwindowtest"),
KAboutData::License_LGPL,
qi18n("Copyright (c) 2008 Rafael Fernandez Lopez"));
KCmdLineArgs::init(argc, argv, &aboutData);
KApplication app;
KGlobal::dirs()->addResourceDir("data", KDESRCDIR);
MainWindow *mainWindow = new MainWindow;
mainWindow->show();
return app.exec();
}
#include "kxmlguiwindowtest.moc"
diff --git a/kdeui/util/kguiitem.cpp b/kdeui/util/kguiitem.cpp
index 1dcc3ab9c0..9b7a6ba820 100644
--- a/kdeui/util/kguiitem.cpp
+++ b/kdeui/util/kguiitem.cpp
@@ -1,238 +1,238 @@
/* This file is part of the KDE libraries
Copyright (C) 2001 Holger Freyther (freyher@yahoo.com)
based on ideas from Martijn and Simon
many thanks to Simon
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 "kguiitem.h"
#include <kiconloader.h> // TODO remove
#include <kdebug.h>
#include <kicon.h>
#include <kcomponentdata.h>
#include <assert.h>
class KGuiItem::KGuiItemPrivate
{
public:
KGuiItemPrivate()
{
m_enabled = true;
m_hasIcon = false;
}
KGuiItemPrivate( const KGuiItemPrivate &rhs )
{
( *this ) = rhs;
}
KGuiItemPrivate &operator=( const KGuiItemPrivate &rhs )
{
m_text = rhs.m_text;
m_icon = rhs.m_icon;
m_iconName = rhs.m_iconName;
m_toolTip = rhs.m_toolTip;
m_whatsThis = rhs.m_whatsThis;
m_statusText = rhs.m_statusText;
m_enabled = rhs.m_enabled;
m_hasIcon = rhs.m_hasIcon;
return *this;
}
QString m_text;
QString m_toolTip;
QString m_whatsThis;
QString m_statusText;
QString m_iconName;
- KIcon m_icon;
+ QIcon m_icon;
bool m_hasIcon : 1;
bool m_enabled : 1;
};
KGuiItem::KGuiItem() {
d = new KGuiItemPrivate;
}
KGuiItem::KGuiItem( const QString &text, const QString &iconName,
const QString &toolTip, const QString &whatsThis )
{
d = new KGuiItemPrivate;
d->m_text = text;
d->m_toolTip = toolTip;
d->m_whatsThis = whatsThis;
setIconName( iconName );
}
-KGuiItem::KGuiItem( const QString &text, const KIcon &icon,
+KGuiItem::KGuiItem( const QString &text, const QIcon &icon,
const QString &toolTip, const QString &whatsThis )
{
d = new KGuiItemPrivate;
d->m_text = text;
d->m_toolTip = toolTip;
d->m_whatsThis = whatsThis;
setIcon( icon );
}
KGuiItem::KGuiItem( const KGuiItem &rhs )
: d( 0 )
{
( *this ) = rhs;
}
KGuiItem &KGuiItem::operator=( const KGuiItem &rhs )
{
if ( d == rhs.d )
return *this;
assert( rhs.d );
delete d;
d = new KGuiItemPrivate( *rhs.d );
return *this;
}
KGuiItem::~KGuiItem()
{
delete d;
}
QString KGuiItem::text() const
{
return d->m_text;
}
QString KGuiItem::plainText() const
{
const int len = d->m_text.length();
if (len == 0)
return d->m_text;
//Can assume len >= 1 from now on.
QString stripped;
int resultLength = 0;
stripped.resize(len);
const QChar* data = d->m_text.unicode();
for ( int pos = 0; pos < len; ++pos )
{
if ( data[ pos ] != '&' )
stripped[ resultLength++ ] = data[ pos ];
else if ( pos + 1 < len && data[ pos + 1 ] == '&' )
stripped[ resultLength++ ] = data[ pos++ ];
}
stripped.truncate(resultLength);
return stripped;
}
-KIcon KGuiItem::icon( ) const
+QIcon KGuiItem::icon( ) const
{
if (d->m_hasIcon) {
if (!d->m_iconName.isEmpty()) {
return KIcon(d->m_iconName, KGlobal::mainComponent().isValid() ? KIconLoader::global() : 0);
} else {
return d->m_icon;
}
}
return KIcon();
}
// deprecated
#ifndef KDE_NO_DEPRECATED
QIcon KGuiItem::iconSet( KIconLoader::Group group, int size ) const
{
if (d->m_hasIcon && KGlobal::mainComponent().isValid()) {
if( !d->m_iconName.isEmpty()) {
KIconLoader* iconLoader = KIconLoader::global();
return iconLoader->loadIconSet( d->m_iconName, group, size );
} else {
return d->m_icon;
}
} else
return QIcon();
}
#endif
QString KGuiItem::iconName() const
{
return d->m_iconName;
}
QString KGuiItem::toolTip() const
{
return d->m_toolTip;
}
QString KGuiItem::whatsThis() const
{
return d->m_whatsThis;
}
bool KGuiItem::isEnabled() const
{
return d->m_enabled;
}
bool KGuiItem::hasIcon() const
{
return d->m_hasIcon;
}
void KGuiItem::setText( const QString &text )
{
d->m_text = text;
}
-void KGuiItem::setIcon( const KIcon &icon )
+void KGuiItem::setIcon( const QIcon &icon )
{
d->m_icon = icon;
d->m_iconName.clear();
d->m_hasIcon = !icon.isNull();
}
void KGuiItem::setIconName( const QString &iconName )
{
d->m_iconName = iconName;
d->m_icon = KIcon();
d->m_hasIcon = !iconName.isEmpty();
}
void KGuiItem::setToolTip( const QString &toolTip )
{
d->m_toolTip = toolTip;
}
void KGuiItem::setWhatsThis( const QString &whatsThis )
{
d->m_whatsThis = whatsThis;
}
void KGuiItem::setEnabled( bool enabled )
{
d->m_enabled = enabled;
}
// vim: set et sw=4:
diff --git a/kdeui/util/kguiitem.h b/kdeui/util/kguiitem.h
index 76a9d45f7f..f68ef5d250 100644
--- a/kdeui/util/kguiitem.h
+++ b/kdeui/util/kguiitem.h
@@ -1,94 +1,93 @@
/* This file is part of the KDE libraries
Copyright (C) 2001 Holger Freyther (freyher@yahoo.com)
based on ideas from Martijn and Simon
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.
Many thanks to Simon tronical Hausmann
*/
#ifndef kguiitem_h
#define kguiitem_h
#include <QtCore/QString>
#include <kicontheme.h>
-#include <kicon.h>
/**
* @short An abstract class for GUI data such as ToolTip and Icon.
*
* @author Holger Freyther <freyher@yahoo.com>
* @see KStandardGuiItem
*/
class KDEUI_EXPORT KGuiItem
{
public:
KGuiItem();
// This is explicit because it's easy to get subtle bugs otherwise. The
// icon name, tooltip and whatsthis text get changed behind your back if
// you do 'setButtonFoo( "Bar" );' It gives the wrong impression that you
// just change the text.
explicit KGuiItem( const QString &text,
const QString &iconName = QString(),
const QString &toolTip = QString(),
const QString &whatsThis = QString() );
- KGuiItem( const QString &text, const KIcon &icon,
+ KGuiItem( const QString &text, const QIcon &icon,
const QString &toolTip = QString(),
const QString &whatsThis = QString() );
KGuiItem( const KGuiItem &rhs );
KGuiItem &operator=( const KGuiItem &rhs );
~KGuiItem();
QString text() const;
QString plainText() const;
/// @deprecated use icon() instead
#ifndef KDE_NO_DEPRECATED
KDEUI_DEPRECATED QIcon iconSet( KIconLoader::Group=KIconLoader::Small, int size = 0) const;
#endif
- KIcon icon( ) const;
+ QIcon icon( ) const;
QString iconName() const;
QString toolTip() const;
QString whatsThis() const;
bool isEnabled() const;
bool hasIcon() const;
#if !defined(KDE_NO_COMPAT) && !defined(KDE_NO_DEPRECATED)
KDEUI_DEPRECATED bool hasIconSet() const { return hasIcon(); }
#endif
void setText( const QString &text );
- void setIcon( const KIcon &iconset );
+ void setIcon( const QIcon &iconset );
void setIconName( const QString &iconName );
void setToolTip( const QString &tooltip );
void setWhatsThis( const QString &whatsThis );
void setEnabled( bool enable );
private:
class KGuiItemPrivate;
KGuiItemPrivate *d; //krazy:exclude=dpointer (implicitly shared)
};
/* vim: et sw=4
*/
#endif
diff --git a/kdeui/widgets/kcharselect.cpp b/kdeui/widgets/kcharselect.cpp
index 3da86773ed..adb2d3dcbf 100644
--- a/kdeui/widgets/kcharselect.cpp
+++ b/kdeui/widgets/kcharselect.cpp
@@ -1,899 +1,900 @@
/* This file is part of the KDE libraries
Copyright (C) 1999 Reginald Stadlbauer <reggie@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 as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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 "kcharselect.h"
#include "kcharselect_p.h"
#include <QActionEvent>
#include <QDoubleSpinBox>
#include <QHeaderView>
#include <QBoxLayout>
#include <QShortcut>
#include <QSplitter>
#include <QPushButton>
#include <QToolButton>
+#include <kicon.h>
#include <kcombobox.h>
#include <kdebug.h>
#include <kdialog.h>
#include <klocale.h>
#include <klineedit.h>
#include <ktextbrowser.h>
#include <kfontcombobox.h>
#include <kactioncollection.h>
#include <kstandardaction.h>
K_GLOBAL_STATIC(KCharSelectData, s_data)
class KCharSelectTablePrivate
{
public:
KCharSelectTablePrivate(KCharSelectTable *q): q(q), model(0)
{}
KCharSelectTable *q;
QFont font;
KCharSelectItemModel *model;
QList<QChar> chars;
QChar chr;
void _k_resizeCells();
void _k_doubleClicked(const QModelIndex & index);
void _k_slotSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected);
};
class KCharSelect::KCharSelectPrivate
{
public:
struct HistoryItem
{
QChar c;
bool fromSearch;
QString searchString;
};
enum { MaxHistoryItems = 100 };
KCharSelectPrivate(KCharSelect *q)
: q(q)
,searchLine(0)
,searchMode(false)
,historyEnabled(false)
,inHistory(0)
,actions(NULL)
{
}
KCharSelect *q;
QToolButton *backButton;
QToolButton *forwardButton;
KLineEdit* searchLine;
KFontComboBox *fontCombo;
QSpinBox *fontSizeSpinBox;
QComboBox *sectionCombo;
QComboBox *blockCombo;
KCharSelectTable *charTable;
KTextBrowser *detailBrowser;
bool searchMode; //a search is active
bool historyEnabled;
int inHistory; //index of current char in history
QList<HistoryItem> history;
KActionCollection* actions;
QString createLinks(QString s);
void historyAdd(const QChar &c, bool fromSearch, const QString &searchString);
void showFromHistory(int index);
void updateBackForwardButtons();
void _k_activateSearchLine();
void _k_back();
void _k_forward();
void _k_fontSelected();
void _k_updateCurrentChar(const QChar &c);
void _k_slotUpdateUnicode(const QChar &c);
void _k_sectionSelected(int index);
void _k_blockSelected(int index);
void _k_searchEditChanged();
void _k_search();
void _k_linkClicked(QUrl url);
};
/******************************************************************/
/* Class: KCharSelectTable */
/******************************************************************/
KCharSelectTable::KCharSelectTable(QWidget *parent, const QFont &_font)
: QTableView(parent), d(new KCharSelectTablePrivate(this))
{
d->font = _font;
setTabKeyNavigation(false);
setSelectionMode(QAbstractItemView::SingleSelection);
QPalette _palette;
_palette.setColor(backgroundRole(), palette().color(QPalette::Base));
setPalette(_palette);
verticalHeader()->setVisible(false);
verticalHeader()->setResizeMode(QHeaderView::Custom);
horizontalHeader()->setVisible(false);
horizontalHeader()->setResizeMode(QHeaderView::Custom);
setFocusPolicy(Qt::StrongFocus);
setDragEnabled(true);
setAcceptDrops(true);
setDropIndicatorShown(false);
setDragDropMode(QAbstractItemView::DragDrop);
connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(_k_doubleClicked(QModelIndex)));
d->_k_resizeCells();
}
KCharSelectTable::~KCharSelectTable()
{
delete d;
}
void KCharSelectTable::setFont(const QFont &_font)
{
QTableView::setFont(_font);
d->font = _font;
if (d->model) d->model->setFont(_font);
d->_k_resizeCells();
}
QChar KCharSelectTable::chr()
{
return d->chr;
}
QFont KCharSelectTable::font() const
{
return d->font;
}
QList<QChar> KCharSelectTable::displayedChars() const
{
return d->chars;
}
void KCharSelectTable::setChar(const QChar &c)
{
int pos = d->chars.indexOf(c);
if (pos != -1) {
setCurrentIndex(model()->index(pos / model()->columnCount(), pos % model()->columnCount()));
}
}
void KCharSelectTable::setContents(QList<QChar> chars)
{
d->chars = chars;
KCharSelectItemModel *m = d->model;
d->model = new KCharSelectItemModel(chars, d->font, this);
setModel(d->model);
d->_k_resizeCells();
QItemSelectionModel *selectionModel = new QItemSelectionModel(d->model);
setSelectionModel(selectionModel);
setSelectionBehavior(QAbstractItemView::SelectItems);
setSelectionMode(QAbstractItemView::SingleSelection);
connect(selectionModel, SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this, SLOT(_k_slotSelectionChanged(const QItemSelection &, const QItemSelection &)));
connect(d->model, SIGNAL(showCharRequested(QChar)), this, SIGNAL(showCharRequested(QChar)));
delete m; // this should hopefully delete aold selection models too, since it is the parent of them (didn't track, if there are setParent calls somewhere. Check that (jowenn)
}
void KCharSelectTable::scrollTo(const QModelIndex & index, ScrollHint hint)
{
// this prevents horizontal scrolling when selecting a character in the last column
if (index.isValid() && index.column() != 0) {
QTableView::scrollTo(d->model->index(index.row(), 0), hint);
} else {
QTableView::scrollTo(index, hint);
}
}
void KCharSelectTablePrivate::_k_slotSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected)
{
Q_UNUSED(deselected);
if (!model || selected.indexes().isEmpty())
return;
QVariant temp = model->data(selected.indexes().at(0), KCharSelectItemModel::CharacterRole);
if (temp.type() != QVariant::Char)
return;
QChar c = temp.toChar();
chr = c;
emit q->focusItemChanged(c);
}
void KCharSelectTable::resizeEvent(QResizeEvent * e)
{
QTableView::resizeEvent(e);
if (e->size().width() != e->oldSize().width()) {
d->_k_resizeCells();
}
}
void KCharSelectTablePrivate::_k_resizeCells()
{
if (!q->model()) return;
static_cast<KCharSelectItemModel*>(q->model())->updateColumnCount(q->viewport()->size().width());
QChar oldChar = q->chr();
const int new_w = q->viewport()->size().width() / q->model()->columnCount(QModelIndex());
const int columns = q->model()->columnCount(QModelIndex());
const int rows = q->model()->rowCount(QModelIndex());
q->setUpdatesEnabled(false);
QHeaderView* hv = q->horizontalHeader();
int spaceLeft = q->viewport()->size().width() % new_w + 1;
for (int i = 0;i <= columns;i++) {
if (i < spaceLeft) {
hv->resizeSection(i, new_w + 1);
} else {
hv->resizeSection(i, new_w);
}
}
hv = q->verticalHeader();
#ifdef Q_WS_WIN
int new_h = QFontMetrics(font).lineSpacing() + 1;
#else
int new_h = QFontMetrics(font).xHeight() * 3;
#endif
if (new_h < 5 || new_h < 4 + QFontMetrics(font).height()) {
new_h = qMax(5, 4 + QFontMetrics(font).height());
}
for (int i = 0;i < rows;i++) {
hv->resizeSection(i, new_h);
}
q->setUpdatesEnabled(true);
q->setChar(oldChar);
}
void KCharSelectTablePrivate::_k_doubleClicked(const QModelIndex & index)
{
QChar c = model->data(index, KCharSelectItemModel::CharacterRole).toChar();
if (s_data->isPrint(c)) {
emit q->activated(c);
}
}
void KCharSelectTable::keyPressEvent(QKeyEvent *e)
{
if (d->model)
switch (e->key()) {
case Qt::Key_Space:
emit activated(' ');
return;
break;
case Qt::Key_Enter: case Qt::Key_Return: {
if (!currentIndex().isValid()) return;
QChar c = d->model->data(currentIndex(), KCharSelectItemModel::CharacterRole).toChar();
if (s_data->isPrint(c)) {
emit activated(c);
}
}
return;
break;
}
QTableView::keyPressEvent(e);
}
/******************************************************************/
/* Class: KCharSelect */
/******************************************************************/
#ifndef KDE_NO_DEPRECATED
KCharSelect::KCharSelect(QWidget *parent, const Controls controls)
: QWidget(parent), d(new KCharSelectPrivate(this))
{
init(controls, NULL);
}
#endif
KCharSelect::KCharSelect(
QWidget *parent
,KActionCollection *collection
,const Controls controls)
: QWidget(parent), d(new KCharSelectPrivate(this))
{
init(controls, collection);
}
void KCharSelect::init(const Controls controls, KActionCollection *collection)
{
if (collection==NULL) {
d->actions = new KActionCollection(this);
d->actions->addAssociatedWidget(this);
} else {
d->actions = collection;
}
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->setMargin(0);
if (SearchLine & controls) {
QHBoxLayout *searchLayout = new QHBoxLayout();
mainLayout->addLayout(searchLayout);
d->searchLine = new KLineEdit(this);
searchLayout->addWidget(d->searchLine);
d->searchLine->setClickMessage(i18n("Enter a search term or character here"));
d->searchLine->setClearButtonShown(true);
d->searchLine->setToolTip(i18n("Enter a search term or character here"));
KStandardAction::find(this, SLOT(_k_activateSearchLine()), d->actions);
connect(d->searchLine, SIGNAL(textChanged(QString)), this, SLOT(_k_searchEditChanged()));
connect(d->searchLine, SIGNAL(returnPressed()), this, SLOT(_k_search()));
}
if ((SearchLine & controls) && ((FontCombo & controls) || (FontSize & controls) || (BlockCombos & controls))) {
QFrame* line = new QFrame(this);
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
mainLayout->addWidget(line);
}
QHBoxLayout *comboLayout = new QHBoxLayout();
d->backButton = new QToolButton(this);
comboLayout->addWidget(d->backButton);
d->backButton->setEnabled(false);
d->backButton->setText(i18nc("Goes to previous character", "Previous in History"));
d->backButton->setIcon(KIcon("go-previous"));
d->backButton->setToolTip(i18n("Previous Character in History"));
d->forwardButton = new QToolButton(this);
comboLayout->addWidget(d->forwardButton);
d->forwardButton->setEnabled(false);
d->forwardButton->setText(i18nc("Goes to next character", "Next in History"));
d->forwardButton->setIcon(KIcon("go-next"));
d->forwardButton->setToolTip(i18n("Next Character in History"));
KStandardAction::back(d->backButton, SLOT(animateClick()), d->actions);
KStandardAction::forward(d->forwardButton, SLOT(animateClick()), d->actions);
connect(d->backButton, SIGNAL(clicked()), this, SLOT(_k_back()));
connect(d->forwardButton, SIGNAL(clicked()), this, SLOT(_k_forward()));
d->sectionCombo = new KComboBox(this);
d->sectionCombo->setToolTip(i18n("Select a category"));
comboLayout->addWidget(d->sectionCombo);
d->blockCombo = new KComboBox(this);
d->blockCombo->setToolTip(i18n("Select a block to be displayed"));
d->blockCombo->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
comboLayout->addWidget(d->blockCombo, 1);
d->sectionCombo->addItems(s_data->sectionList());
d->blockCombo->setMinimumWidth(QFontMetrics(QWidget::font()).averageCharWidth() * 25);
connect(d->sectionCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(_k_sectionSelected(int)));
connect(d->blockCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(_k_blockSelected(int)));
d->fontCombo = new KFontComboBox(this);
comboLayout->addWidget(d->fontCombo);
d->fontCombo->setEditable(true);
d->fontCombo->resize(d->fontCombo->sizeHint());
d->fontCombo->setToolTip(i18n("Set font"));
d->fontSizeSpinBox = new QSpinBox(this);
comboLayout->addWidget(d->fontSizeSpinBox);
d->fontSizeSpinBox->setValue(QWidget::font().pointSize());
d->fontSizeSpinBox->setRange(1, 400);
d->fontSizeSpinBox->setSingleStep(1);
d->fontSizeSpinBox->setToolTip(i18n("Set font size"));
connect(d->fontCombo, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(_k_fontSelected()));
connect(d->fontSizeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(_k_fontSelected()));
if ((HistoryButtons & controls) || (FontCombo & controls) || (FontSize & controls) || (BlockCombos & controls)) {
mainLayout->addLayout(comboLayout);
}
if (!(HistoryButtons & controls)) {
d->backButton->hide();
d->forwardButton->hide();
}
if (!(FontCombo & controls)) {
d->fontCombo->hide();
}
if (!(FontSize & controls)) {
d->fontSizeSpinBox->hide();
}
if (!(BlockCombos & controls)) {
d->sectionCombo->hide();
d->blockCombo->hide();
}
QSplitter *splitter = new QSplitter(this);
if ((CharacterTable & controls) || (DetailBrowser & controls)) {
mainLayout->addWidget(splitter);
} else {
splitter->hide();
}
d->charTable = new KCharSelectTable(this, QFont());
if (CharacterTable & controls) {
splitter->addWidget(d->charTable);
d->charTable->setFocus(Qt::OtherFocusReason);
} else {
d->charTable->hide();
}
const QSize sz(200, 200);
d->charTable->resize(sz);
d->charTable->setMinimumSize(sz);
d->charTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setCurrentFont(QFont());
connect(d->charTable, SIGNAL(focusItemChanged(const QChar &)), this, SLOT(_k_updateCurrentChar(const QChar &)));
connect(d->charTable, SIGNAL(activated(const QChar &)), this, SIGNAL(charSelected(const QChar &)));
connect(d->charTable, SIGNAL(focusItemChanged(const QChar &)),
this, SIGNAL(currentCharChanged(const QChar &)));
connect(d->charTable, SIGNAL(showCharRequested(QChar)), this, SLOT(setCurrentChar(QChar)));
d->detailBrowser = new KTextBrowser(this);
if (DetailBrowser & controls) {
splitter->addWidget(d->detailBrowser);
} else {
d->detailBrowser->hide();
}
d->detailBrowser->setOpenLinks(false);
connect(d->detailBrowser, SIGNAL(anchorClicked(QUrl)), this, SLOT(_k_linkClicked(QUrl)));
setFocusPolicy(Qt::StrongFocus);
setFocusProxy(d->charTable);
d->_k_sectionSelected(0);
d->_k_blockSelected(0);
setCurrentChar(0x0);
d->historyEnabled = true;
}
KCharSelect::~KCharSelect()
{
delete d;
}
QSize KCharSelect::sizeHint() const
{
return QWidget::sizeHint();
}
void KCharSelect::setCurrentFont(const QFont &_font)
{
d->fontCombo->setCurrentFont(_font);
d->fontSizeSpinBox->setValue(_font.pointSize());
d->_k_fontSelected();
}
QChar KCharSelect::currentChar() const
{
return d->charTable->chr();
}
QFont KCharSelect::currentFont() const
{
return d->charTable->font();
}
QList<QChar> KCharSelect::displayedChars() const
{
return d->charTable->displayedChars();
}
void KCharSelect::setCurrentChar(const QChar &c)
{
bool oldHistoryEnabled = d->historyEnabled;
d->historyEnabled = false;
int block = s_data->blockIndex(c);
int section = s_data->sectionIndex(block);
d->sectionCombo->setCurrentIndex(section);
int index = d->blockCombo->findData(block);
if (index != -1) {
d->blockCombo->setCurrentIndex(index);
}
d->historyEnabled = oldHistoryEnabled;
d->charTable->setChar(c);
}
void KCharSelect::KCharSelectPrivate::historyAdd(const QChar &c, bool fromSearch, const QString &searchString)
{
//kDebug() << "about to add char" << c << "fromSearch" << fromSearch << "searchString" << searchString;
if (!historyEnabled) {
return;
}
if (!history.isEmpty() && c == history.last().c) {
//avoid duplicates
return;
}
//behave like a web browser, i.e. if user goes back from B to A then clicks C, B is forgotten
while (!history.isEmpty() && inHistory != history.count() - 1) {
history.removeLast();
}
while (history.size() >= MaxHistoryItems) {
history.removeFirst();
}
HistoryItem item;
item.c = c;
item.fromSearch = fromSearch;
item.searchString = searchString;
history.append(item);
inHistory = history.count() - 1;
updateBackForwardButtons();
}
void KCharSelect::KCharSelectPrivate::showFromHistory(int index)
{
Q_ASSERT(index >= 0 && index < history.count());
Q_ASSERT(index != inHistory);
inHistory = index;
updateBackForwardButtons();
const HistoryItem &item = history[index];
//kDebug() << "index" << index << "char" << item.c << "fromSearch" << item.fromSearch
// << "searchString" << item.searchString;
//avoid adding an item from history into history again
bool oldHistoryEnabled = historyEnabled;
historyEnabled = false;
if (item.fromSearch) {
if (searchLine->text() != item.searchString) {
searchLine->setText(item.searchString);
_k_search();
}
charTable->setChar(item.c);
} else {
searchLine->clear();
q->setCurrentChar(item.c);
}
historyEnabled = oldHistoryEnabled;
}
void KCharSelect::KCharSelectPrivate::updateBackForwardButtons()
{
backButton->setEnabled(inHistory > 0);
forwardButton->setEnabled(inHistory < history.count() - 1);
}
void KCharSelect::KCharSelectPrivate::_k_activateSearchLine()
{
searchLine->setFocus();
searchLine->selectAll();
}
void KCharSelect::KCharSelectPrivate::_k_back()
{
Q_ASSERT(inHistory > 0);
showFromHistory(inHistory - 1);
}
void KCharSelect::KCharSelectPrivate::_k_forward()
{
Q_ASSERT(inHistory + 1 < history.count());
showFromHistory(inHistory + 1);
}
void KCharSelect::KCharSelectPrivate::_k_fontSelected()
{
QFont font = fontCombo->currentFont();
font.setPointSize(fontSizeSpinBox->value());
charTable->setFont(font);
emit q->currentFontChanged(font);
}
void KCharSelect::KCharSelectPrivate::_k_updateCurrentChar(const QChar &c)
{
if (searchMode) {
//we are in search mode. make the two comboboxes show the section & block for this character.
//(when we are not in search mode the current character always belongs to the current section & block.)
int block = s_data->blockIndex(c);
int section = s_data->sectionIndex(block);
sectionCombo->setCurrentIndex(section);
int index = blockCombo->findData(block);
if (index != -1) {
blockCombo->setCurrentIndex(index);
}
}
if( searchLine)
historyAdd(c, searchMode, searchLine->text());
_k_slotUpdateUnicode(c);
}
void KCharSelect::KCharSelectPrivate::_k_slotUpdateUnicode(const QChar &c)
{
QString html = "<p>" + i18n("Character:") + ' ' + s_data->display(c, charTable->font()) + ' ' +
s_data->formatCode(c.unicode()) + "<br />";
QString name = s_data->name(c);
if (!name.isEmpty()) {
//is name ever empty? </p> should always be there...
html += i18n("Name: ") + Qt::escape(name) + "</p>";
}
QStringList aliases = s_data->aliases(c);
QStringList notes = s_data->notes(c);
QList<QChar> seeAlso = s_data->seeAlso(c);
QStringList equivalents = s_data->equivalents(c);
QStringList approxEquivalents = s_data->approximateEquivalents(c);
if (!(aliases.isEmpty() && notes.isEmpty() && seeAlso.isEmpty() && equivalents.isEmpty() && approxEquivalents.isEmpty())) {
html += "<p><b>" + i18n("Annotations and Cross References") + "</b></p>";
}
if (!aliases.isEmpty()) {
html += "<p style=\"margin-bottom: 0px;\">" + i18n("Alias names:") + "</p><ul style=\"margin-top: 0px;\">";
foreach(const QString &alias, aliases) {
html += "<li>" + Qt::escape(alias) + "</li>";
}
html += "</ul>";
}
if (!notes.isEmpty()) {
html += "<p style=\"margin-bottom: 0px;\">" + i18n("Notes:") + "</p><ul style=\"margin-top: 0px;\">";
foreach(const QString &note, notes) {
html += "<li>" + createLinks(Qt::escape(note)) + "</li>";
}
html += "</ul>";
}
if (!seeAlso.isEmpty()) {
html += "<p style=\"margin-bottom: 0px;\">" + i18n("See also:") + "</p><ul style=\"margin-top: 0px;\">";
foreach(const QChar &c2, seeAlso) {
html += "<li><a href=\"" + QString::number(c2.unicode(), 16) + "\">";
if (s_data->isPrint(c2)) {
html += "&#" + QString::number(c2.unicode()) + "; ";
}
html += s_data->formatCode(c2.unicode()) + ' ' + Qt::escape(s_data->name(c2)) + "</a></li>";
}
html += "</ul>";
}
if (!equivalents.isEmpty()) {
html += "<p style=\"margin-bottom: 0px;\">" + i18n("Equivalents:") + "</p><ul style=\"margin-top: 0px;\">";
foreach(const QString &equivalent, equivalents) {
html += "<li>" + createLinks(Qt::escape(equivalent)) + "</li>";
}
html += "</ul>";
}
if (!approxEquivalents.isEmpty()) {
html += "<p style=\"margin-bottom: 0px;\">" + i18n("Approximate equivalents:") + "</p><ul style=\"margin-top: 0px;\">";
foreach(const QString &approxEquivalent, approxEquivalents) {
html += "<li>" + createLinks(Qt::escape(approxEquivalent)) + "</li>";
}
html += "</ul>";
}
QStringList unihan = s_data->unihanInfo(c);
if (unihan.count() == 7) {
html += "<p><b>" + i18n("CJK Ideograph Information") + "</b></p><p>";
bool newline = true;
if (!unihan[0].isEmpty()) {
html += i18n("Definition in English: ") + unihan[0];
newline = false;
}
if (!unihan[2].isEmpty()) {
if (!newline) html += "<br>";
html += i18n("Mandarin Pronunciation: ") + unihan[2];
newline = false;
}
if (!unihan[1].isEmpty()) {
if (!newline) html += "<br>";
html += i18n("Cantonese Pronunciation: ") + unihan[1];
newline = false;
}
if (!unihan[6].isEmpty()) {
if (!newline) html += "<br>";
html += i18n("Japanese On Pronunciation: ") + unihan[6];
newline = false;
}
if (!unihan[5].isEmpty()) {
if (!newline) html += "<br>";
html += i18n("Japanese Kun Pronunciation: ") + unihan[5];
newline = false;
}
if (!unihan[3].isEmpty()) {
if (!newline) html += "<br>";
html += i18n("Tang Pronunciation: ") + unihan[3];
newline = false;
}
if (!unihan[4].isEmpty()) {
if (!newline) html += "<br>";
html += i18n("Korean Pronunciation: ") + unihan[4];
newline = false;
}
html += "</p>";
}
html += "<p><b>" + i18n("General Character Properties") + "</b><br>";
html += i18n("Block: ") + s_data->block(c) + "<br>";
html += i18n("Unicode category: ") + s_data->categoryText(s_data->category(c)) + "</p>";
QByteArray utf8 = QString(c).toUtf8();
html += "<p><b>" + i18n("Various Useful Representations") + "</b><br>";
html += i18n("UTF-8:");
foreach(unsigned char c, utf8)
html += ' ' + s_data->formatCode(c, 2, "0x");
html += "<br>" + i18n("UTF-16: ") + s_data->formatCode(c.unicode(), 4, "0x") + "<br>";
html += i18n("C octal escaped UTF-8: ");
foreach(unsigned char c, utf8)
html += s_data->formatCode(c, 3, "\\", 8);
html += "<br>" + i18n("XML decimal entity:") + " &amp;#" + QString::number(c.unicode()) + ";</p>";
detailBrowser->setHtml(html);
}
QString KCharSelect::KCharSelectPrivate::createLinks(QString s)
{
QRegExp rx("\\b([\\dABCDEF]{4})\\b");
QStringList chars;
int pos = 0;
while ((pos = rx.indexIn(s, pos)) != -1) {
chars << rx.cap(1);
pos += rx.matchedLength();
}
QSet<QString> chars2 = QSet<QString>::fromList(chars);
foreach(const QString &c, chars2) {
int unicode = c.toInt(0, 16);
QString link = "<a href=\"" + c + "\">";
if (s_data->isPrint(QChar(unicode))) {
link += "&#" + QString::number(unicode) + ";&nbsp;";
}
link += "U+" + c + ' ';
link += Qt::escape(s_data->name(QChar(unicode))) + "</a>";
s.replace(c, link);
}
return s;
}
void KCharSelect::KCharSelectPrivate::_k_sectionSelected(int index)
{
blockCombo->clear();
QList<int> blocks = s_data->sectionContents(index);
foreach(int block, blocks) {
blockCombo->addItem(s_data->blockName(block), QVariant(block));
}
blockCombo->setCurrentIndex(0);
}
void KCharSelect::KCharSelectPrivate::_k_blockSelected(int index)
{
if (index == -1) {
//the combo box has been cleared and is about to be filled again (because the section has changed)
return;
}
if (searchMode) {
//we are in search mode, so don't fill the table with this block.
return;
}
int block = blockCombo->itemData(index).toInt();
const QList<QChar> contents = s_data->blockContents(block);
if(contents.count() <= index) {
return;
}
charTable->setContents(contents);
emit q->displayedCharsChanged();
charTable->setChar(contents[0]);
}
void KCharSelect::KCharSelectPrivate::_k_searchEditChanged()
{
if (searchLine->text().isEmpty()) {
sectionCombo->setEnabled(true);
blockCombo->setEnabled(true);
//upon leaving search mode, keep the same character selected
searchMode = false;
QChar c = charTable->chr();
bool oldHistoryEnabled = historyEnabled;
historyEnabled = false;
_k_blockSelected(blockCombo->currentIndex());
historyEnabled = oldHistoryEnabled;
q->setCurrentChar(c);
} else {
sectionCombo->setEnabled(false);
blockCombo->setEnabled(false);
int length = searchLine->text().length();
if (length >= 3) {
_k_search();
}
}
}
void KCharSelect::KCharSelectPrivate::_k_search()
{
if (searchLine->text().isEmpty()) {
return;
}
searchMode = true;
const QList<QChar> contents = s_data->find(searchLine->text());
charTable->setContents(contents);
emit q->displayedCharsChanged();
if (!contents.isEmpty()) {
charTable->setChar(contents[0]);
}
}
void KCharSelect::KCharSelectPrivate::_k_linkClicked(QUrl url)
{
QString hex = url.toString();
if (hex.size() > 4) {
return;
}
int unicode = hex.toInt(0, 16);
searchLine->clear();
q->setCurrentChar(QChar(unicode));
}
////
QVariant KCharSelectItemModel::data(const QModelIndex &index, int role) const
{
int pos = m_columns * (index.row()) + index.column();
if (!index.isValid() || pos < 0 || pos >= m_chars.size()
|| index.row() < 0 || index.column() < 0) {
if (role == Qt::BackgroundColorRole) {
return QVariant(qApp->palette().color(QPalette::Button));
}
return QVariant();
}
QChar c = m_chars[pos];
if (role == Qt::ToolTipRole) {
QString result = s_data->display(c, m_font) + "<br />" + Qt::escape(s_data->name(c)) + "<br />" +
i18n("Unicode code point:") + ' ' + s_data->formatCode(c.unicode()) + "<br />" +
i18nc("Character", "In decimal:") + ' ' + QString::number(c.unicode());
return QVariant(result);
} else if (role == Qt::TextAlignmentRole)
return QVariant(Qt::AlignHCenter | Qt::AlignVCenter);
else if (role == Qt::DisplayRole) {
if (s_data->isPrint(c))
return QVariant(c);
return QVariant();
} else if (role == Qt::BackgroundColorRole) {
QFontMetrics fm = QFontMetrics(m_font);
if (fm.inFont(c) && s_data->isPrint(c))
return QVariant(qApp->palette().color(QPalette::Base));
else
return QVariant(qApp->palette().color(QPalette::Button));
} else if (role == Qt::FontRole)
return QVariant(m_font);
else if (role == CharacterRole) {
return QVariant(c);
}
return QVariant();
}
#include "moc_kcharselect.cpp"
#include "moc_kcharselect_p.cpp"
diff --git a/kdeui/widgets/kcombobox.h b/kdeui/widgets/kcombobox.h
index be9f76acc1..2b5f89f8a9 100644
--- a/kdeui/widgets/kcombobox.h
+++ b/kdeui/widgets/kcombobox.h
@@ -1,538 +1,539 @@
/* This file is part of the KDE libraries
Copyright (c) 2000,2001 Dawit Alemayehu <adawit@kde.org>
Copyright (c) 2000,2001 Carsten Pfeiffer <pfeiffer@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License (LGPL) as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser 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.
*/
#ifndef KCOMBOBOX_H
#define KCOMBOBOX_H
#include <QComboBox>
#include <kcompletion.h>
+#include <kicon.h>
class QLineEdit;
class QMenu;
class KCompletionBox;
class KUrl;
/*
* ### KDE 5: On all methods that it is said that a prettyUrl will be used, it
* would be nice to add a flag to the method for forcing the pretty
* url or not. (ereslibre)
*/
/**
* @short An enhanced combo box.
*
* A combined button, line-edit and a popup list widget.
*
* \b Detail \n
*
* This widget inherits from QComboBox and implements the following
* additional functionalities: a completion object that provides both automatic
* and manual text completion as well as text rotation features, configurable
* key-bindings to activate these features, and a popup-menu item that can be
* used to allow the user to change the text completion mode on the fly.
*
* To support these new features KComboBox emits a few additional signals
* such as completion( const QString& ) and textRotation( KeyBindingType ).
* The completion signal can be connected to a slot that will assist the user in
* filling out the remaining text while the rotation signal can be used to traverse
* through all possible matches whenever text completion results in multiple matches.
* Additionally, a returnPressed() and a returnPressed( const QString& )
* signals are emitted when the user presses the Enter/Return key.
*
* KCombobox by default creates a completion object when you invoke the
* completionObject( bool ) member function for the first time or
* explicitly use setCompletionObject( KCompletion*, bool ) to assign your
* own completion object. Additionally, to make this widget more functional,
* KComboBox will by default handle text rotation and completion events
* internally whenever a completion object is created through either one of the
* methods mentioned above. If you do not need this functionality, simply use
* KCompletionBase::setHandleSignals(bool) or alternatively set the boolean
* parameter in the @p setCompletionObject call to false.
*
* Beware: The completion object can be deleted on you, especially if a call
* such as setEditable(false) is made. Store the pointer at your own risk,
* and consider using QGuardedPtr<KCompletion>.
*
* The default key-bindings for completion and rotation is determined from the
* global settings in KStandardShortcut. These values, however, can be overridden
* locally by invoking KCompletionBase::setKeyBinding(). The values can
* easily be reverted back to the default setting, by simply calling
* useGlobalSettings(). An alternate method would be to default individual
* key-bindings by usning setKeyBinding() with the default second argument.
*
* A non-editable combobox only has one completion mode, @p CompletionAuto.
* Unlike an editable combobox the CompletionAuto mode, works by matching
* any typed key with the first letter of entries in the combobox. Please note
* that if you call setEditable( false ) to change an editable combobox to a
* non-editable one, the text completion object associated with the combobox will
* no longer exist unless you created the completion object yourself and assigned
* it to this widget or you called setAutoDeleteCompletionObject( false ). In other
* words do not do the following:
*
* \code
* KComboBox* combo = new KComboBox(true, this);
* KCompletion* comp = combo->completionObject();
* combo->setEditable( false );
* comp->clear(); // CRASH: completion object does not exist anymore.
* \endcode
*
*
* A read-only KComboBox will have the same background color as a
* disabled KComboBox, but its foreground color will be the one used for
* the read-write mode. This differs from QComboBox's implementation
* and is done to give visual distinction between the three different modes:
* disabled, read-only, and read-write.
*
* \b Usage \n
*
* To enable the basic completion feature:
*
* \code
* KComboBox *combo = new KComboBox( true, this );
* KCompletion *comp = combo->completionObject();
* // Connect to the return pressed signal - optional
* connect(combo,SIGNAL(returnPressed(const QString&)),comp,SLOT(addItem(const QString&)));
*
* // Provide the to be completed strings. Note that those are separate from the combo's
* // contents.
* comp->insertItems( someQStringList );
* \endcode
*
* To use your own completion object:
*
* \code
* KComboBox *combo = new KComboBox( this );
* KUrlCompletion *comp = new KUrlCompletion();
* combo->setCompletionObject( comp );
* // Connect to the return pressed signal - optional
* connect(combo,SIGNAL(returnPressed(const QString&)),comp,SLOT(addItem(const QString&)));
* \endcode
*
* Note that you have to either delete the allocated completion object
* when you don't need it anymore, or call
* setAutoDeleteCompletionObject( true );
*
* Miscellaneous function calls:
*
* \code
* // Tell the widget not to handle completion and rotation
* combo->setHandleSignals( false );
* // Set your own completion key for manual completions.
* combo->setKeyBinding( KCompletionBase::TextCompletion, Qt::End );
* \endcode
*
* \image html kcombobox.png "KDE Combo Boxes, one non-editable, one editable with KUrlCompletion"
*
* @author Dawit Alemayehu <adawit@kde.org>
*/
class KDEUI_EXPORT KComboBox : public QComboBox, public KCompletionBase //krazy:exclude=qclasses
{
Q_OBJECT
Q_PROPERTY( bool autoCompletion READ autoCompletion WRITE setAutoCompletion )
Q_PROPERTY( bool urlDropsEnabled READ urlDropsEnabled WRITE setUrlDropsEnabled )
Q_PROPERTY( bool trapReturnKey READ trapReturnKey WRITE setTrapReturnKey )
public:
/**
* Constructs a read-only or rather select-only combo box with a
* parent object and a name.
*
* @param parent The parent object of this widget
*/
explicit KComboBox( QWidget *parent=0 );
/**
* Constructs a "read-write" or "read-only" combo box depending on
* the value of the first argument( @p rw ) with a parent, a
* name.
*
* @param rw When @p true, widget will be editable.
* @param parent The parent object of this widget.
*/
explicit KComboBox( bool rw, QWidget *parent=0 );
/**
* Destructor.
*/
virtual ~KComboBox();
/**
* Deprecated to reflect Qt api changes
* @deprecated
*/
#ifndef KDE_NO_DEPRECATED
KDEUI_DEPRECATED void insertURL( const KUrl& url, int index = -1 )
{ insertUrl( index < 0 ? count() : index, url ); }
KDEUI_DEPRECATED void insertURL( const QPixmap& pixmap, const KUrl& url, int index = -1 )
{ insertUrl( index < 0 ? count() : index, QIcon(pixmap), url ); }
KDEUI_DEPRECATED void changeURL( const KUrl& url, int index )
{ changeUrl( index, url ); }
KDEUI_DEPRECATED void changeURL( const QPixmap& pixmap, const KUrl& url, int index )
{ changeUrl( index, QIcon(pixmap), url ); }
#endif
/**
* Sets @p url into the edit field of the combobox. It uses
* KUrl::prettyUrl() so that the url is properly decoded for
* displaying.
*/
void setEditUrl( const KUrl& url );
/**
* Appends @p url to the combobox.
* KUrl::prettyUrl() is used so that the url is properly decoded
* for displaying.
*/
void addUrl( const KUrl& url );
/**
* Appends @p url with the icon &p icon to the combobox.
* KUrl::prettyUrl() is used so that the url is properly decoded
* for displaying.
*/
void addUrl( const QIcon& icon, const KUrl& url );
/**
* Inserts @p url at position @p index into the combobox.
* KUrl::prettyUrl() is used so that the url is properly decoded
* for displaying.
*/
void insertUrl( int index, const KUrl& url );
/**
* Inserts @p url with the pixmap &p pixmap at position @p index into
* the combobox. KUrl::prettyUrl() is used so that the url is
* properly decoded for displaying.
*/
void insertUrl( int index, const QIcon& icon, const KUrl& url );
/**
* Replaces the item at position @p index with @p url.
* KUrl::prettyUrl() is used so that the url is properly decoded
* for displaying.
*/
void changeUrl( int index, const KUrl& url );
/**
* Replaces the item at position @p index with @p url and icon @p icon.
* KUrl::prettyUrl() is used so that the url is properly decoded
* for displaying.
*/
void changeUrl( int index , const QIcon& icon, const KUrl& url);
/**
* Returns the current cursor position.
*
* This method always returns a -1 if the combo-box is @em not
* editable (read-write).
*
* @return Current cursor position.
*/
int cursorPosition() const;
/**
* Re-implemented from QComboBox.
*
* If @p true, the completion mode will be set to automatic.
* Otherwise, it is defaulted to the global setting. This
* method has been replaced by the more comprehensive
* setCompletionMode().
*
* @param autocomplete Flag to enable/disable automatic completion mode.
*/
virtual void setAutoCompletion( bool autocomplete );
/**
* Re-implemented from QComboBox.
*
* Returns @p true if the current completion mode is set
* to automatic. See its more comprehensive replacement
* completionMode().
*
* @return @p true when completion mode is automatic.
*/
bool autoCompletion() const;
/**
* Enables or disable the popup (context) menu.
*
* This method only works if this widget is editable, i.e. read-write and
* allows you to enable/disable the context menu. It does nothing if invoked
* for a none-editable combo-box.
*
* By default, the context menu is created if this widget is editable.
* Call this function with the argument set to false to disable the popup
* menu.
*
* @param showMenu If @p true, show the context menu.
* @deprecated use setContextMenuPolicy
*/
#ifndef KDE_NO_DEPRECATED
virtual KDEUI_DEPRECATED void setContextMenuEnabled( bool showMenu );
#endif
/**
* Enables/Disables handling of URL drops. If enabled and the user
* drops an URL, the decoded URL will be inserted. Otherwise the default
* behavior of QComboBox is used, which inserts the encoded URL.
*
* @param enable If @p true, insert decoded URLs
*/
void setUrlDropsEnabled( bool enable );
/**
* Returns @p true when decoded URL drops are enabled
*/
bool urlDropsEnabled() const;
/**
* Convenience method which iterates over all items and checks if
* any of them is equal to @p text.
*
* If @p text is an empty string, @p false
* is returned.
*
* @return @p true if an item with the string @p text is in the combobox.
*/
bool contains( const QString& text ) const;
/**
* By default, KComboBox recognizes Key_Return and Key_Enter
* and emits the returnPressed() signals, but it also lets the
* event pass, for example causing a dialog's default-button to
* be called.
*
* Call this method with @p trap equal to true to make KComboBox
* stop these events. The signals will still be emitted of course.
*
* Only affects read-writable comboboxes.
*
* @see setTrapReturnKey()
*/
void setTrapReturnKey( bool trap );
/**
* @return @p true if keyevents of Key_Return or Key_Enter will
* be stopped or if they will be propagated.
*
* @see setTrapReturnKey ()
*/
bool trapReturnKey() const;
/**
* Re-implemented for internal reasons. API not affected.
*/
virtual bool eventFilter( QObject *, QEvent * );
/**
* @returns the completion-box, that is used in completion mode
* KGlobalSettings::CompletionPopup and KGlobalSettings::CompletionPopupAuto.
* This method will create a completion-box by calling
* KLineEdit::completionBox, if none is there, yet.
*
* @param create Set this to false if you don't want the box to be created
* i.e. to test if it is available.
*/
KCompletionBox * completionBox( bool create = true );
/**
* Re-implemented for internal reasons. API remains unaffected.
* Note that QComboBox::setLineEdit is not virtual in Qt4, do not
* use a KComboBox in a QComboBox pointer.
*
* NOTE: Only editable comboboxes can have a line editor. As such
* any attempt to assign a line-edit to a non-editable combobox will
* simply be ignored.
*/
virtual void setLineEdit( QLineEdit * );
/**
* "Re-implemented" so that setEditable(true) creates a KLineEdit
* instead of QLineEdit.
*
* Note that QComboBox::setEditable is not virtual, so do not
* use a KComboBox in a QComboBox pointer.
*/
void setEditable(bool editable);
Q_SIGNALS:
/**
* Emitted when the user presses the Enter key.
*
* Note that this signal is only emitted when the widget is editable.
*/
void returnPressed();
/**
* Emitted when the user presses the Enter key.
*
* The argument is the current text being edited. This signal is just like
* returnPressed() except it contains the current text as its argument.
*
* Note that this signal is only emitted when the
* widget is editable.
*/
void returnPressed( const QString& );
/**
* Emitted when the completion key is pressed.
*
* The argument is the current text being edited.
*
* Note that this signal is @em not available when the widget is non-editable
* or the completion mode is set to @p KGlobalSettings::CompletionNone.
*/
void completion( const QString& );
/**
* Emitted when the shortcut for substring completion is pressed.
*/
void substringCompletion( const QString& );
/**
* Emitted when the text rotation key-bindings are pressed.
*
* The argument indicates which key-binding was pressed. In this case this
* can be either one of four values: @p PrevCompletionMatch,
* @p NextCompletionMatch, @p RotateUp or @p RotateDown. See
* KCompletionBase::setKeyBinding() for details.
*
* Note that this signal is @em NOT emitted if the completion
* mode is set to CompletionNone.
*/
void textRotation( KCompletionBase::KeyBindingType );
/**
* Emitted whenever the completion mode is changed by the user
* through the context menu.
*/
void completionModeChanged( KGlobalSettings::Completion );
/**
* Emitted before the context menu is displayed.
*
* The signal allows you to add your own entries into the context menu.
* Note that you MUST NOT store the pointer to the QPopupMenu since it is
* created and deleted on demand. Otherwise, you can crash your app.
*
* @param p the context menu about to be displayed
*/
void aboutToShowContextMenu( QMenu * p );
public Q_SLOTS:
/**
* Iterates through all possible matches of the completed text
* or the history list.
*
* Depending on the value of the argument, this function either
* iterates through the history list of this widget or the all
* possible matches in whenever multiple matches result from a
* text completion request. Note that the all-possible-match
* iteration will not work if there are no previous matches, i.e.
* no text has been completed and the *nix shell history list
* rotation is only available if the insertion policy for this
* widget is set either @p QComobBox::AtTop or @p QComboBox::AtBottom.
* For other insertion modes whatever has been typed by the user
* when the rotation event was initiated will be lost.
*
* @param type The key-binding invoked.
*/
void rotateText( KCompletionBase::KeyBindingType type );
/**
* Sets the completed text in the line-edit appropriately.
*
* This function is an implementation for
* KCompletionBase::setCompletedText.
*/
virtual void setCompletedText( const QString& );
/**
* Sets @p items into the completion-box if completionMode() is
* CompletionPopup. The popup will be shown immediately.
*/
void setCompletedItems( const QStringList& items, bool autosubject = true );
/**
* Selects the first item that matches @p item. If there is no such item,
* it is inserted at position @p index if @p insert is true. Otherwise,
* no item is selected.
*/
void setCurrentItem( const QString& item, bool insert = false, int index = -1 );
protected Q_SLOTS:
/**
* Completes text according to the completion mode.
*
* Note: this method is @p not invoked if the completion mode is
* set to CompletionNone. Also if the mode is set to @p CompletionShell
* and multiple matches are found, this method will complete the
* text to the first match with a beep to inidicate that there are
* more matches. Then any successive completion key event iterates
* through the remaining matches. This way the rotation functionality
* is left to iterate through the list as usual.
*/
virtual void makeCompletion( const QString& );
protected:
/*
* This function simply sets the lineedit text and
* highlights the text appropriately if the boolean
* value is set to true.
*
* @param
* @param
*/
virtual void setCompletedText( const QString& /* */, bool /*marked*/ );
/**
* Reimplemented for internal reasons, the API is not affected.
*/
virtual void create( WId = 0, bool initializeWindow = true,
bool destroyOldWindow = true );
virtual void wheelEvent( QWheelEvent *ev );
virtual QSize minimumSizeHint() const;
private Q_SLOTS:
void lineEditDeleted();
private:
/**
* Initializes the variables upon construction.
*/
void init();
private:
class KComboBoxPrivate;
KComboBoxPrivate* const d;
};
#endif
diff --git a/kdeui/widgets/keditlistbox.cpp b/kdeui/widgets/keditlistbox.cpp
index fa34d0411b..309c835b67 100644
--- a/kdeui/widgets/keditlistbox.cpp
+++ b/kdeui/widgets/keditlistbox.cpp
@@ -1,686 +1,687 @@
/* This file is part of the KDE libraries
Copyright (C) 2000 David Faure <faure@kde.org>, Alexander Neundorf <neundorf@kde.org>
2000, 2002 Carsten Pfeiffer <pfeiffer@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 as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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 "keditlistbox.h"
#include <QtCore/QStringList>
#include <QKeyEvent>
#include <QLabel>
#include <QLayout>
#include <QListView>
+#include <kicon.h>
#include <kcombobox.h>
#include <kdebug.h>
#include <kdialog.h>
#include <klineedit.h>
#include <klocale.h>
#include <knotification.h>
#include <kpushbutton.h>
#include <assert.h>
class KEditListBoxPrivate
{
public:
KEditListBoxPrivate( KEditListBox* parent )
: lineEdit(0),
editingWidget(0),
q(parent) {
}
QListView *listView;
QPushButton *servUpButton, *servDownButton;
QPushButton *servNewButton, *servRemoveButton;
KLineEdit *lineEdit;
QWidget* editingWidget;
QVBoxLayout* mainLayout;
QVBoxLayout* btnsLayout;
QStringListModel *model;
bool checkAtEntering;
KEditListBox::Buttons buttons;
void init( bool check = false, KEditListBox::Buttons buttons = KEditListBox::All,
QWidget *representationWidget = 0 );
void setEditor( KLineEdit* lineEdit, QWidget* representationWidget = 0 );
void updateButtonState();
QModelIndex selectedIndex();
private:
KEditListBox* q;
};
void KEditListBoxPrivate::init( bool check, KEditListBox::Buttons newButtons,
QWidget *representationWidget )
{
checkAtEntering = check;
servNewButton = servRemoveButton = servUpButton = servDownButton = 0L;
q->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding,
QSizePolicy::Preferred));
mainLayout = new QVBoxLayout(q);
QHBoxLayout* subLayout = new QHBoxLayout;
btnsLayout = new QVBoxLayout;
btnsLayout->addStretch();
model = new QStringListModel();
listView = new QListView(q);
listView->setModel(model);
subLayout->addWidget(listView);
subLayout->addLayout(btnsLayout);
mainLayout->insertLayout(1, subLayout);
setEditor( lineEdit, representationWidget );
buttons = 0;
q->setButtons( newButtons );
q->connect(listView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
SLOT(slotSelectionChanged(const QItemSelection&, const QItemSelection&)));
}
void KEditListBoxPrivate::setEditor( KLineEdit* newLineEdit, QWidget* representationWidget )
{
if (editingWidget != lineEdit &&
editingWidget != representationWidget) {
delete editingWidget;
}
if (lineEdit != newLineEdit) {
delete lineEdit;
}
lineEdit = newLineEdit ? newLineEdit : new KLineEdit(q);
editingWidget = representationWidget ?
representationWidget : lineEdit;
if ( representationWidget )
representationWidget->setParent(q);
mainLayout->insertWidget(0,editingWidget);
lineEdit->setTrapReturnKey(true);
lineEdit->installEventFilter(q);
q->connect(lineEdit,SIGNAL(textChanged(const QString&)),SLOT(typedSomething(const QString&)));
q->connect(lineEdit,SIGNAL(returnPressed()),SLOT(addItem()));
// maybe supplied lineedit has some text already
q->typedSomething( lineEdit->text() );
// fix tab ordering
q->setTabOrder(editingWidget, listView);
QWidget* w = listView;
if (servNewButton) {
q->setTabOrder(w,servNewButton);
w = servNewButton;
}
if (servRemoveButton) {
q->setTabOrder(w,servRemoveButton);
w = servRemoveButton;
}
if (servUpButton) {
q->setTabOrder(w,servUpButton);
w = servUpButton;
}
if (servDownButton) {
q->setTabOrder(w,servDownButton);
w = servDownButton;
}
}
void KEditListBoxPrivate::updateButtonState()
{
QModelIndex index = selectedIndex();
if (servUpButton) {
servUpButton->setEnabled(index.isValid());
}
if (servDownButton) {
servDownButton->setEnabled(index.isValid());
}
if (servRemoveButton) {
servRemoveButton->setEnabled(index.isValid());
}
}
QModelIndex KEditListBoxPrivate::selectedIndex()
{
QItemSelectionModel *selection = listView->selectionModel();
const QModelIndexList selectedIndexes = selection->selectedIndexes();
if ( !selectedIndexes.isEmpty() && selectedIndexes[0].isValid() )
return selectedIndexes[0];
else
return QModelIndex();
}
class KEditListBox::CustomEditorPrivate
{
public:
CustomEditorPrivate(KEditListBox::CustomEditor *q):
q(q),
representationWidget(0),
lineEdit(0) {}
KEditListBox::CustomEditor *q;
QWidget *representationWidget;
KLineEdit *lineEdit;
};
KEditListBox::CustomEditor::CustomEditor()
: d(new CustomEditorPrivate(this))
{
}
KEditListBox::CustomEditor::CustomEditor( QWidget *repWidget, KLineEdit *edit )
: d(new CustomEditorPrivate(this))
{
d->representationWidget = repWidget;
d->lineEdit = edit;
}
KEditListBox::CustomEditor::CustomEditor( KComboBox *combo )
: d(new CustomEditorPrivate(this))
{
d->representationWidget = combo;
d->lineEdit = qobject_cast<KLineEdit*>( combo->lineEdit() );
Q_ASSERT( d->lineEdit );
}
KEditListBox::CustomEditor::~CustomEditor()
{
delete d;
}
void KEditListBox::CustomEditor::setRepresentationWidget( QWidget *repWidget )
{
d->representationWidget = repWidget;
}
void KEditListBox::CustomEditor::setLineEdit( KLineEdit *edit )
{
d->lineEdit = edit;
}
QWidget *KEditListBox::CustomEditor::representationWidget() const
{
return d->representationWidget;
}
KLineEdit *KEditListBox::CustomEditor::lineEdit() const
{
return d->lineEdit;
}
KEditListBox::KEditListBox(QWidget *parent)
: QGroupBox(parent), d(new KEditListBoxPrivate(this))
{
d->init();
}
KEditListBox::KEditListBox(const QString &title, QWidget *parent)
:QGroupBox(title, parent), d(new KEditListBoxPrivate(this))
{
d->init();
}
KEditListBox::KEditListBox(QWidget *parent, const char *name,
bool checkAtEntering, Buttons buttons )
:QGroupBox(parent ), d(new KEditListBoxPrivate(this))
{
setObjectName(name);
d->init( checkAtEntering, buttons );
}
KEditListBox::KEditListBox(const QString& title, QWidget *parent,
const char *name, bool checkAtEntering, Buttons buttons)
:QGroupBox(title, parent ), d(new KEditListBoxPrivate(this))
{
setObjectName(name);
d->init( checkAtEntering, buttons );
}
KEditListBox::KEditListBox(const QString& title, const CustomEditor& custom,
QWidget *parent, const char *name,
bool checkAtEntering, Buttons buttons)
:QGroupBox(title, parent), d(new KEditListBoxPrivate(this))
{
setObjectName(name);
d->lineEdit = custom.lineEdit();
d->init( checkAtEntering, buttons, custom.representationWidget() );
}
KEditListBox::~KEditListBox()
{
delete d;
}
void KEditListBox::setCustomEditor( const CustomEditor& editor )
{
d->setEditor( editor.lineEdit(), editor.representationWidget() );
}
QListView *KEditListBox::listView() const
{
return d->listView;
}
KLineEdit *KEditListBox::lineEdit() const
{
return d->lineEdit;
}
QPushButton *KEditListBox::addButton() const
{
return d->servNewButton;
}
QPushButton *KEditListBox::removeButton() const
{
return d->servRemoveButton;
}
QPushButton *KEditListBox::upButton() const
{
return d->servUpButton;
}
QPushButton *KEditListBox::downButton() const
{
return d->servDownButton;
}
int KEditListBox::count() const
{
return int(d->model->rowCount());
}
void KEditListBox::setButtons( Buttons buttons )
{
if ( d->buttons == buttons )
return;
if ( ( buttons & Add ) && !d->servNewButton ) {
d->servNewButton = new KPushButton(KIcon("list-add"), i18n("&Add"), this);
d->servNewButton->setEnabled(false);
d->servNewButton->show();
connect(d->servNewButton, SIGNAL(clicked()), SLOT(addItem()));
d->btnsLayout->insertWidget(0, d->servNewButton);
} else if ( ( buttons & Add ) == 0 && d->servNewButton ) {
delete d->servNewButton;
d->servNewButton = 0;
}
if ( ( buttons & Remove ) && !d->servRemoveButton ) {
d->servRemoveButton = new KPushButton(KIcon("list-remove"), i18n("&Remove"), this);
d->servRemoveButton->setEnabled(false);
d->servRemoveButton->show();
connect(d->servRemoveButton, SIGNAL(clicked()), SLOT(removeItem()));
d->btnsLayout->insertWidget(1, d->servRemoveButton);
} else if ( ( buttons & Remove ) == 0 && d->servRemoveButton ) {
delete d->servRemoveButton;
d->servRemoveButton = 0;
}
if ( ( buttons & UpDown ) && !d->servUpButton ) {
d->servUpButton = new KPushButton(KIcon("arrow-up"), i18n("Move &Up"), this);
d->servUpButton->setEnabled(false);
d->servUpButton->show();
connect(d->servUpButton, SIGNAL(clicked()), SLOT(moveItemUp()));
d->servDownButton = new KPushButton(KIcon("arrow-down"), i18n("Move &Down"), this);
d->servDownButton->setEnabled(false);
d->servDownButton->show();
connect(d->servDownButton, SIGNAL(clicked()), SLOT(moveItemDown()));
d->btnsLayout->insertWidget(2, d->servUpButton);
d->btnsLayout->insertWidget(3, d->servDownButton);
} else if ( ( buttons & UpDown ) == 0 && d->servUpButton ) {
delete d->servUpButton; d->servUpButton = 0;
delete d->servDownButton; d->servDownButton = 0;
}
d->buttons = buttons;
}
void KEditListBox::setCheckAtEntering(bool check)
{
d->checkAtEntering = check;
}
bool KEditListBox::checkAtEntering()
{
return d->checkAtEntering;
}
void KEditListBox::typedSomething(const QString& text)
{
if(currentItem() >= 0) {
if(currentText() != d->lineEdit->text())
{
// IMHO changeItem() shouldn't do anything with the value
// of currentItem() ... like changing it or emitting signals ...
// but TT disagree with me on this one (it's been that way since ages ... grrr)
bool block = d->listView->signalsBlocked();
d->listView->blockSignals( true );
QModelIndex currentIndex = d->selectedIndex();
if ( currentIndex.isValid() )
d->model->setData(currentIndex,text);
d->listView->blockSignals( block );
emit changed();
}
}
if ( !d->servNewButton )
return;
if ( !d->lineEdit->hasAcceptableInput() ) {
d->servNewButton->setEnabled(false);
return;
}
if (!d->checkAtEntering)
d->servNewButton->setEnabled(!text.isEmpty());
else
{
if (text.isEmpty())
{
d->servNewButton->setEnabled(false);
}
else
{
QStringList list = d->model->stringList();
bool enable = !list.contains( text, Qt::CaseSensitive );
d->servNewButton->setEnabled( enable );
}
}
}
void KEditListBox::moveItemUp()
{
if (!d->listView->isEnabled())
{
KNotification::beep();
return;
}
QModelIndex index = d->selectedIndex();
if ( index.isValid() ) {
if (index.row() == 0) {
KNotification::beep();
return;
}
QModelIndex aboveIndex = d->model->index( index.row() - 1, index.column() );
QString tmp = d->model->data( aboveIndex, Qt::DisplayRole ).toString();
d->model->setData( aboveIndex, d->model->data( index, Qt::DisplayRole ) );
d->model->setData( index, tmp );
d->listView->selectionModel()->select(index, QItemSelectionModel::Deselect);
d->listView->selectionModel()->select(aboveIndex, QItemSelectionModel::Select);
}
emit changed();
}
void KEditListBox::moveItemDown()
{
if (!d->listView->isEnabled())
{
KNotification::beep();
return;
}
QModelIndex index = d->selectedIndex();
if ( index.isValid() ) {
if (index.row() == d->model->rowCount() - 1) {
KNotification::beep();
return;
}
QModelIndex belowIndex = d->model->index( index.row() + 1, index.column() );
QString tmp = d->model->data( belowIndex, Qt::DisplayRole ).toString();
d->model->setData( belowIndex, d->model->data( index, Qt::DisplayRole ) );
d->model->setData( index, tmp );
d->listView->selectionModel()->select(index, QItemSelectionModel::Deselect);
d->listView->selectionModel()->select(belowIndex, QItemSelectionModel::Select);
}
emit changed();
}
void KEditListBox::addItem()
{
// when checkAtEntering is true, the add-button is disabled, but this
// slot can still be called through Key_Return/Key_Enter. So we guard
// against this.
if ( !d->servNewButton || !d->servNewButton->isEnabled() )
return;
QModelIndex currentIndex = d->selectedIndex();
const QString& currentTextLE=d->lineEdit->text();
bool alreadyInList(false);
//if we didn't check for dupes at the inserting we have to do it now
if (!d->checkAtEntering)
{
// first check current item instead of dumb iterating the entire list
if ( currentIndex.isValid() ) {
if ( d->model->data( currentIndex, Qt::DisplayRole ).toString() == currentTextLE )
alreadyInList = true;
}
else
{
alreadyInList = d->model->stringList().contains( currentTextLE, Qt::CaseSensitive );
}
}
if ( d->servNewButton )
d->servNewButton->setEnabled(false);
bool block = d->lineEdit->signalsBlocked();
d->lineEdit->blockSignals(true);
d->lineEdit->clear();
d->lineEdit->blockSignals(block);
d->listView->selectionModel()->setCurrentIndex(currentIndex, QItemSelectionModel::Deselect);
if (!alreadyInList)
{
block = d->listView->signalsBlocked();
if ( currentIndex.isValid() ) {
d->model->setData(currentIndex, currentTextLE );
} else {
QStringList lst;
lst<<currentTextLE;
lst<<d->model->stringList();
d->model->setStringList(lst);
}
emit changed();
emit added( currentTextLE ); // TODO: pass the index too
}
d->updateButtonState();
}
int KEditListBox::currentItem() const
{
QModelIndex selectedIndex = d->selectedIndex();
if ( selectedIndex.isValid() )
return selectedIndex.row();
else
return -1;
}
void KEditListBox::removeItem()
{
QModelIndex currentIndex = d->selectedIndex();
if ( !currentIndex.isValid() )
return;
if ( currentIndex.row() >= 0 )
{
QString removedText = d->model->data( currentIndex, Qt::DisplayRole ).toString();
d->model->removeRows( currentIndex.row(), 1 );
d->listView->selectionModel()->clear();
emit changed();
emit removed( removedText );
}
d->updateButtonState();
}
void KEditListBox::enableMoveButtons(const QModelIndex &newIndex, const QModelIndex&)
{
int index = newIndex.row();
// Update the lineEdit when we select a different line.
if(currentText() != d->lineEdit->text())
d->lineEdit->setText(currentText());
bool moveEnabled = d->servUpButton && d->servDownButton;
if (moveEnabled )
{
if (d->model->rowCount() <= 1)
{
d->servUpButton->setEnabled(false);
d->servDownButton->setEnabled(false);
}
else if (index == (d->model->rowCount() - 1))
{
d->servUpButton->setEnabled(true);
d->servDownButton->setEnabled(false);
}
else if (index == 0)
{
d->servUpButton->setEnabled(false);
d->servDownButton->setEnabled(true);
}
else
{
d->servUpButton->setEnabled(true);
d->servDownButton->setEnabled(true);
}
}
if ( d->servRemoveButton )
d->servRemoveButton->setEnabled(true);
}
void KEditListBox::clear()
{
d->lineEdit->clear();
d->model->setStringList( QStringList() );
emit changed();
}
void KEditListBox::insertStringList(const QStringList& list, int index)
{
QStringList content = d->model->stringList();
if ( index < 0 )
content += list;
else
for ( int i = 0, j = index; i < list.count(); ++i, ++j )
content.insert( j, list[ i ] );
d->model->setStringList( content );
}
void KEditListBox::insertItem(const QString& text, int index)
{
QStringList list = d->model->stringList();
if ( index < 0 )
list.append( text );
else
list.insert( index, text );
d->model->setStringList(list);
}
QString KEditListBox::text(int index) const
{
const QStringList list = d->model->stringList();
return list[ index ];
}
QString KEditListBox::currentText() const
{
QModelIndex index = d->selectedIndex();
if ( !index.isValid() )
return QString();
else
return text( index.row() );
}
QStringList KEditListBox::items() const
{
return d->model->stringList();
}
void KEditListBox::setItems(const QStringList& items)
{
d->model->setStringList(items);
}
KEditListBox::Buttons KEditListBox::buttons() const
{
return d->buttons;
}
void KEditListBox::slotSelectionChanged( const QItemSelection&, const QItemSelection& )
{
d->updateButtonState();
QModelIndex index = d->selectedIndex();
enableMoveButtons(index, QModelIndex());
if (index.isValid()) {
d->lineEdit->setFocus( Qt::OtherFocusReason );
}
}
bool KEditListBox::eventFilter( QObject* o, QEvent* e )
{
if (o == d->lineEdit && e->type() == QEvent::KeyPress ) {
QKeyEvent* keyEvent = (QKeyEvent*)e;
if (keyEvent->key() == Qt::Key_Down ||
keyEvent->key() == Qt::Key_Up) {
return ((QObject*)d->listView)->event(e);
}
}
return false;
}
diff --git a/kdeui/widgets/keditlistwidget.cpp b/kdeui/widgets/keditlistwidget.cpp
index a5bafe925c..cf79dd4062 100644
--- a/kdeui/widgets/keditlistwidget.cpp
+++ b/kdeui/widgets/keditlistwidget.cpp
@@ -1,665 +1,666 @@
/* This file is part of the KDE libraries
Copyright (C) 2000 David Faure <faure@kde.org>, Alexander Neundorf <neundorf@kde.org>
(C) 2000, 2002 Carsten Pfeiffer <pfeiffer@kde.org>
(C) 2010 Sebastian Trueg <trueg@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 as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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 "keditlistwidget.h"
#include <QtCore/QStringList>
#include <QKeyEvent>
#include <QLabel>
#include <QLayout>
#include <QListView>
+#include <kicon.h>
#include <kcombobox.h>
#include <kdebug.h>
#include <kdialog.h>
#include <klineedit.h>
#include <klocale.h>
#include <knotification.h>
#include <kpushbutton.h>
#include <assert.h>
class KEditListWidgetPrivate
{
public:
KEditListWidgetPrivate( KEditListWidget* parent )
: lineEdit(0),
editingWidget(0),
q(parent) {
}
QListView *listView;
QPushButton *servUpButton, *servDownButton;
QPushButton *servNewButton, *servRemoveButton;
KLineEdit *lineEdit;
QWidget* editingWidget;
QVBoxLayout* mainLayout;
QVBoxLayout* btnsLayout;
QStringListModel *model;
bool checkAtEntering;
KEditListWidget::Buttons buttons;
void init( bool check = false, KEditListWidget::Buttons buttons = KEditListWidget::All,
QWidget *representationWidget = 0 );
void setEditor( KLineEdit* lineEdit, QWidget* representationWidget = 0 );
void updateButtonState();
QModelIndex selectedIndex();
private:
KEditListWidget* q;
};
void KEditListWidgetPrivate::init( bool check, KEditListWidget::Buttons newButtons,
QWidget *representationWidget )
{
checkAtEntering = check;
servNewButton = servRemoveButton = servUpButton = servDownButton = 0L;
q->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding,
QSizePolicy::Preferred));
mainLayout = new QVBoxLayout(q);
QHBoxLayout* subLayout = new QHBoxLayout;
btnsLayout = new QVBoxLayout;
btnsLayout->addStretch();
model = new QStringListModel();
listView = new QListView(q);
listView->setModel(model);
subLayout->addWidget(listView);
subLayout->addLayout(btnsLayout);
mainLayout->insertLayout(1, subLayout);
setEditor( lineEdit, representationWidget );
buttons = 0;
q->setButtons( newButtons );
q->connect(listView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
SLOT(slotSelectionChanged(const QItemSelection&, const QItemSelection&)));
}
void KEditListWidgetPrivate::setEditor( KLineEdit* newLineEdit, QWidget* representationWidget )
{
if (editingWidget != lineEdit &&
editingWidget != representationWidget) {
delete editingWidget;
}
if (lineEdit != newLineEdit) {
delete lineEdit;
}
lineEdit = newLineEdit ? newLineEdit : new KLineEdit(q);
editingWidget = representationWidget ?
representationWidget : lineEdit;
if ( representationWidget )
representationWidget->setParent(q);
mainLayout->insertWidget(0,editingWidget);
lineEdit->setTrapReturnKey(true);
lineEdit->installEventFilter(q);
q->connect(lineEdit,SIGNAL(textChanged(const QString&)),SLOT(typedSomething(const QString&)));
q->connect(lineEdit,SIGNAL(returnPressed()),SLOT(addItem()));
// maybe supplied lineedit has some text already
q->typedSomething( lineEdit->text() );
// fix tab ordering
q->setTabOrder(editingWidget, listView);
QWidget* w = listView;
if (servNewButton) {
q->setTabOrder(w,servNewButton);
w = servNewButton;
}
if (servRemoveButton) {
q->setTabOrder(w,servRemoveButton);
w = servRemoveButton;
}
if (servUpButton) {
q->setTabOrder(w,servUpButton);
w = servUpButton;
}
if (servDownButton) {
q->setTabOrder(w,servDownButton);
w = servDownButton;
}
}
void KEditListWidgetPrivate::updateButtonState()
{
QModelIndex index = selectedIndex();
if (servUpButton) {
servUpButton->setEnabled(index.isValid());
}
if (servDownButton) {
servDownButton->setEnabled(index.isValid());
}
if (servRemoveButton) {
servRemoveButton->setEnabled(index.isValid());
}
}
QModelIndex KEditListWidgetPrivate::selectedIndex()
{
QItemSelectionModel *selection = listView->selectionModel();
const QModelIndexList selectedIndexes = selection->selectedIndexes();
if ( !selectedIndexes.isEmpty() && selectedIndexes[0].isValid() )
return selectedIndexes[0];
else
return QModelIndex();
}
class KEditListWidget::CustomEditorPrivate
{
public:
CustomEditorPrivate(KEditListWidget::CustomEditor *q):
q(q),
representationWidget(0),
lineEdit(0) {}
KEditListWidget::CustomEditor *q;
QWidget *representationWidget;
KLineEdit *lineEdit;
};
KEditListWidget::CustomEditor::CustomEditor()
: d(new CustomEditorPrivate(this))
{
}
KEditListWidget::CustomEditor::CustomEditor( QWidget *repWidget, KLineEdit *edit )
: d(new CustomEditorPrivate(this))
{
d->representationWidget = repWidget;
d->lineEdit = edit;
}
KEditListWidget::CustomEditor::CustomEditor( KComboBox *combo )
: d(new CustomEditorPrivate(this))
{
d->representationWidget = combo;
d->lineEdit = qobject_cast<KLineEdit*>( combo->lineEdit() );
Q_ASSERT( d->lineEdit );
}
KEditListWidget::CustomEditor::~CustomEditor()
{
delete d;
}
void KEditListWidget::CustomEditor::setRepresentationWidget( QWidget *repWidget )
{
d->representationWidget = repWidget;
}
void KEditListWidget::CustomEditor::setLineEdit( KLineEdit *edit )
{
d->lineEdit = edit;
}
QWidget *KEditListWidget::CustomEditor::representationWidget() const
{
return d->representationWidget;
}
KLineEdit *KEditListWidget::CustomEditor::lineEdit() const
{
return d->lineEdit;
}
KEditListWidget::KEditListWidget(QWidget *parent)
: QWidget(parent), d(new KEditListWidgetPrivate(this))
{
d->init();
}
KEditListWidget::KEditListWidget(const CustomEditor& custom,
QWidget *parent,
bool checkAtEntering,
Buttons buttons)
:QWidget(parent), d(new KEditListWidgetPrivate(this))
{
d->lineEdit = custom.lineEdit();
d->init( checkAtEntering, buttons, custom.representationWidget() );
}
KEditListWidget::~KEditListWidget()
{
delete d;
}
void KEditListWidget::setCustomEditor( const CustomEditor& editor )
{
d->setEditor( editor.lineEdit(), editor.representationWidget() );
}
QListView *KEditListWidget::listView() const
{
return d->listView;
}
KLineEdit *KEditListWidget::lineEdit() const
{
return d->lineEdit;
}
QPushButton *KEditListWidget::addButton() const
{
return d->servNewButton;
}
QPushButton *KEditListWidget::removeButton() const
{
return d->servRemoveButton;
}
QPushButton *KEditListWidget::upButton() const
{
return d->servUpButton;
}
QPushButton *KEditListWidget::downButton() const
{
return d->servDownButton;
}
int KEditListWidget::count() const
{
return int(d->model->rowCount());
}
void KEditListWidget::setButtons( Buttons buttons )
{
if ( d->buttons == buttons )
return;
if ( ( buttons & Add ) && !d->servNewButton ) {
d->servNewButton = new KPushButton(KIcon("list-add"), i18n("&Add"), this);
d->servNewButton->setEnabled(false);
d->servNewButton->show();
connect(d->servNewButton, SIGNAL(clicked()), SLOT(addItem()));
d->btnsLayout->insertWidget(0, d->servNewButton);
} else if ( ( buttons & Add ) == 0 && d->servNewButton ) {
delete d->servNewButton;
d->servNewButton = 0;
}
if ( ( buttons & Remove ) && !d->servRemoveButton ) {
d->servRemoveButton = new KPushButton(KIcon("list-remove"), i18n("&Remove"), this);
d->servRemoveButton->setEnabled(false);
d->servRemoveButton->show();
connect(d->servRemoveButton, SIGNAL(clicked()), SLOT(removeItem()));
d->btnsLayout->insertWidget(1, d->servRemoveButton);
} else if ( ( buttons & Remove ) == 0 && d->servRemoveButton ) {
delete d->servRemoveButton;
d->servRemoveButton = 0;
}
if ( ( buttons & UpDown ) && !d->servUpButton ) {
d->servUpButton = new KPushButton(KIcon("arrow-up"), i18n("Move &Up"), this);
d->servUpButton->setEnabled(false);
d->servUpButton->show();
connect(d->servUpButton, SIGNAL(clicked()), SLOT(moveItemUp()));
d->servDownButton = new KPushButton(KIcon("arrow-down"), i18n("Move &Down"), this);
d->servDownButton->setEnabled(false);
d->servDownButton->show();
connect(d->servDownButton, SIGNAL(clicked()), SLOT(moveItemDown()));
d->btnsLayout->insertWidget(2, d->servUpButton);
d->btnsLayout->insertWidget(3, d->servDownButton);
} else if ( ( buttons & UpDown ) == 0 && d->servUpButton ) {
delete d->servUpButton; d->servUpButton = 0;
delete d->servDownButton; d->servDownButton = 0;
}
d->buttons = buttons;
}
void KEditListWidget::setCheckAtEntering(bool check)
{
d->checkAtEntering = check;
}
bool KEditListWidget::checkAtEntering()
{
return d->checkAtEntering;
}
void KEditListWidget::typedSomething(const QString& text)
{
if(currentItem() >= 0) {
if(currentText() != d->lineEdit->text())
{
// IMHO changeItem() shouldn't do anything with the value
// of currentItem() ... like changing it or emitting signals ...
// but TT disagree with me on this one (it's been that way since ages ... grrr)
bool block = d->listView->signalsBlocked();
d->listView->blockSignals( true );
QModelIndex currentIndex = d->selectedIndex();
if ( currentIndex.isValid() )
d->model->setData(currentIndex,text);
d->listView->blockSignals( block );
emit changed();
}
}
if ( !d->servNewButton )
return;
if ( !d->lineEdit->hasAcceptableInput() ) {
d->servNewButton->setEnabled(false);
return;
}
if (!d->checkAtEntering)
d->servNewButton->setEnabled(!text.isEmpty());
else
{
if (text.isEmpty())
{
d->servNewButton->setEnabled(false);
}
else
{
QStringList list = d->model->stringList();
bool enable = !list.contains( text, Qt::CaseSensitive );
d->servNewButton->setEnabled( enable );
}
}
}
void KEditListWidget::moveItemUp()
{
if (!d->listView->isEnabled())
{
KNotification::beep();
return;
}
QModelIndex index = d->selectedIndex();
if ( index.isValid() ) {
if (index.row() == 0) {
KNotification::beep();
return;
}
QModelIndex aboveIndex = d->model->index( index.row() - 1, index.column() );
QString tmp = d->model->data( aboveIndex, Qt::DisplayRole ).toString();
d->model->setData( aboveIndex, d->model->data( index, Qt::DisplayRole ) );
d->model->setData( index, tmp );
d->listView->selectionModel()->select(index, QItemSelectionModel::Deselect);
d->listView->selectionModel()->select(aboveIndex, QItemSelectionModel::Select);
}
emit changed();
}
void KEditListWidget::moveItemDown()
{
if (!d->listView->isEnabled())
{
KNotification::beep();
return;
}
QModelIndex index = d->selectedIndex();
if ( index.isValid() ) {
if (index.row() == d->model->rowCount() - 1) {
KNotification::beep();
return;
}
QModelIndex belowIndex = d->model->index( index.row() + 1, index.column() );
QString tmp = d->model->data( belowIndex, Qt::DisplayRole ).toString();
d->model->setData( belowIndex, d->model->data( index, Qt::DisplayRole ) );
d->model->setData( index, tmp );
d->listView->selectionModel()->select(index, QItemSelectionModel::Deselect);
d->listView->selectionModel()->select(belowIndex, QItemSelectionModel::Select);
}
emit changed();
}
void KEditListWidget::addItem()
{
// when checkAtEntering is true, the add-button is disabled, but this
// slot can still be called through Key_Return/Key_Enter. So we guard
// against this.
if ( !d->servNewButton || !d->servNewButton->isEnabled() )
return;
QModelIndex currentIndex = d->selectedIndex();
const QString& currentTextLE=d->lineEdit->text();
bool alreadyInList(false);
//if we didn't check for dupes at the inserting we have to do it now
if (!d->checkAtEntering)
{
// first check current item instead of dumb iterating the entire list
if ( currentIndex.isValid() ) {
if ( d->model->data( currentIndex, Qt::DisplayRole ).toString() == currentTextLE )
alreadyInList = true;
}
else
{
alreadyInList = d->model->stringList().contains( currentTextLE, Qt::CaseSensitive );
}
}
if ( d->servNewButton )
d->servNewButton->setEnabled(false);
bool block = d->lineEdit->signalsBlocked();
d->lineEdit->blockSignals(true);
d->lineEdit->clear();
d->lineEdit->blockSignals(block);
d->listView->selectionModel()->setCurrentIndex(currentIndex, QItemSelectionModel::Deselect);
if (!alreadyInList)
{
block = d->listView->signalsBlocked();
if ( currentIndex.isValid() ) {
d->model->setData(currentIndex, currentTextLE );
} else {
QStringList lst;
lst<<currentTextLE;
lst<<d->model->stringList();
d->model->setStringList(lst);
}
emit changed();
emit added( currentTextLE ); // TODO: pass the index too
}
d->updateButtonState();
}
int KEditListWidget::currentItem() const
{
QModelIndex selectedIndex = d->selectedIndex();
if ( selectedIndex.isValid() )
return selectedIndex.row();
else
return -1;
}
void KEditListWidget::removeItem()
{
QModelIndex currentIndex = d->selectedIndex();
if ( !currentIndex.isValid() )
return;
if ( currentIndex.row() >= 0 )
{
QString removedText = d->model->data( currentIndex, Qt::DisplayRole ).toString();
d->model->removeRows( currentIndex.row(), 1 );
d->listView->selectionModel()->clear();
emit changed();
emit removed( removedText );
}
d->updateButtonState();
}
void KEditListWidget::enableMoveButtons(const QModelIndex &newIndex, const QModelIndex&)
{
int index = newIndex.row();
// Update the lineEdit when we select a different line.
if(currentText() != d->lineEdit->text())
d->lineEdit->setText(currentText());
bool moveEnabled = d->servUpButton && d->servDownButton;
if (moveEnabled )
{
if (d->model->rowCount() <= 1)
{
d->servUpButton->setEnabled(false);
d->servDownButton->setEnabled(false);
}
else if (index == (d->model->rowCount() - 1))
{
d->servUpButton->setEnabled(true);
d->servDownButton->setEnabled(false);
}
else if (index == 0)
{
d->servUpButton->setEnabled(false);
d->servDownButton->setEnabled(true);
}
else
{
d->servUpButton->setEnabled(true);
d->servDownButton->setEnabled(true);
}
}
if ( d->servRemoveButton )
d->servRemoveButton->setEnabled(true);
}
void KEditListWidget::clear()
{
d->lineEdit->clear();
d->model->setStringList( QStringList() );
emit changed();
}
void KEditListWidget::insertStringList(const QStringList& list, int index)
{
QStringList content = d->model->stringList();
if ( index < 0 )
content += list;
else
for ( int i = 0, j = index; i < list.count(); ++i, ++j )
content.insert( j, list[ i ] );
d->model->setStringList( content );
}
void KEditListWidget::insertItem(const QString& text, int index)
{
QStringList list = d->model->stringList();
if ( index < 0 )
list.append( text );
else
list.insert( index, text );
d->model->setStringList(list);
}
QString KEditListWidget::text(int index) const
{
const QStringList list = d->model->stringList();
return list[ index ];
}
QString KEditListWidget::currentText() const
{
QModelIndex index = d->selectedIndex();
if ( !index.isValid() )
return QString();
else
return text( index.row() );
}
QStringList KEditListWidget::items() const
{
return d->model->stringList();
}
void KEditListWidget::setItems(const QStringList& items)
{
d->model->setStringList(items);
}
KEditListWidget::Buttons KEditListWidget::buttons() const
{
return d->buttons;
}
void KEditListWidget::slotSelectionChanged( const QItemSelection&, const QItemSelection& )
{
d->updateButtonState();
QModelIndex index = d->selectedIndex();
enableMoveButtons(index, QModelIndex());
if (index.isValid()) {
d->lineEdit->setFocus( Qt::OtherFocusReason );
}
}
bool KEditListWidget::eventFilter( QObject* o, QEvent* e )
{
if (o == d->lineEdit && e->type() == QEvent::KeyPress ) {
QKeyEvent* keyEvent = (QKeyEvent*)e;
if (keyEvent->key() == Qt::Key_Down ||
keyEvent->key() == Qt::Key_Up) {
return ((QObject*)d->listView)->event(e);
}
}
return false;
}
diff --git a/kdeui/widgets/kmessagewidget.cpp b/kdeui/widgets/kmessagewidget.cpp
index a6c32557a5..dfba25551d 100644
--- a/kdeui/widgets/kmessagewidget.cpp
+++ b/kdeui/widgets/kmessagewidget.cpp
@@ -1,398 +1,398 @@
/* This file is part of the KDE libraries
*
* Copyright (c) 2011 Aurélien Gâteau <agateau@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include "kmessagewidget.h"
#include <kaction.h>
#include <kcolorscheme.h>
#include <kdebug.h>
#include <kglobalsettings.h>
#include <kicon.h>
#include <kiconloader.h>
#include <kstandardaction.h>
#include <QEvent>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QPainter>
#include <QShowEvent>
#include <QTimeLine>
#include <QToolButton>
//---------------------------------------------------------------------
// KMessageWidgetPrivate
//---------------------------------------------------------------------
class KMessageWidgetPrivate
{
public:
void init(KMessageWidget*);
KMessageWidget* q;
QFrame* content;
QLabel* iconLabel;
QLabel* textLabel;
QToolButton* closeButton;
QTimeLine* timeLine;
KMessageWidget::MessageType messageType;
bool wordWrap;
QList<QToolButton*> buttons;
QPixmap contentSnapShot;
void createLayout();
void updateSnapShot();
void updateLayout();
void slotTimeLineChanged(qreal);
void slotTimeLineFinished();
};
void KMessageWidgetPrivate::init(KMessageWidget *q_ptr)
{
q = q_ptr;
q->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
timeLine = new QTimeLine(500, q);
QObject::connect(timeLine, SIGNAL(valueChanged(qreal)), q, SLOT(slotTimeLineChanged(qreal)));
QObject::connect(timeLine, SIGNAL(finished()), q, SLOT(slotTimeLineFinished()));
content = new QFrame(q);
content->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
wordWrap = false;
iconLabel = new QLabel(content);
iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
textLabel = new QLabel(content);
textLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
textLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
KAction* closeAction = KStandardAction::close(q, SLOT(animatedHide()), q);
closeButton = new QToolButton(content);
closeButton->setAutoRaise(true);
closeButton->setDefaultAction(closeAction);
q->setMessageType(KMessageWidget::Information);
}
void KMessageWidgetPrivate::createLayout()
{
delete content->layout();
content->resize(q->size());
qDeleteAll(buttons);
buttons.clear();
Q_FOREACH(QAction* action, q->actions()) {
QToolButton* button = new QToolButton(content);
button->setDefaultAction(action);
button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
buttons.append(button);
}
// Only set autoRaise on if there are no buttons, otherwise the close
// button looks weird
closeButton->setAutoRaise(buttons.isEmpty());
if (wordWrap) {
QGridLayout* layout = new QGridLayout(content);
layout->addWidget(iconLabel, 0, 0);
layout->addWidget(textLabel, 0, 1);
QHBoxLayout* buttonLayout = new QHBoxLayout;
buttonLayout->addStretch();
Q_FOREACH(QToolButton* button, buttons) {
// For some reason, calling show() is necessary here, but not in
// wordwrap mode
button->show();
buttonLayout->addWidget(button);
}
buttonLayout->addWidget(closeButton);
layout->addItem(buttonLayout, 1, 0, 1, 2);
} else {
QHBoxLayout* layout = new QHBoxLayout(content);
layout->addWidget(iconLabel);
layout->addWidget(textLabel);
Q_FOREACH(QToolButton* button, buttons) {
layout->addWidget(button);
}
layout->addWidget(closeButton);
};
if (q->isVisible()) {
q->setFixedHeight(content->sizeHint().height());
}
q->updateGeometry();
}
void KMessageWidgetPrivate::updateLayout()
{
if (content->layout()) {
createLayout();
}
}
void KMessageWidgetPrivate::updateSnapShot()
{
contentSnapShot = QPixmap(content->size());
contentSnapShot.fill(Qt::transparent);
content->render(&contentSnapShot, QPoint(), QRegion(), QWidget::DrawChildren);
}
void KMessageWidgetPrivate::slotTimeLineChanged(qreal value)
{
q->setFixedHeight(qMin(value * 2, qreal(1.0)) * content->height());
q->update();
}
void KMessageWidgetPrivate::slotTimeLineFinished()
{
if (timeLine->direction() == QTimeLine::Forward) {
// Show
content->move(0, 0);
} else {
// Hide
q->hide();
}
}
//---------------------------------------------------------------------
// KMessageWidget
//---------------------------------------------------------------------
KMessageWidget::KMessageWidget(QWidget* parent)
: QFrame(parent)
, d(new KMessageWidgetPrivate)
{
d->init(this);
}
KMessageWidget::KMessageWidget(const QString& text, QWidget* parent)
: QFrame(parent)
, d(new KMessageWidgetPrivate)
{
d->init(this);
setText(text);
}
KMessageWidget::~KMessageWidget()
{
delete d;
}
QString KMessageWidget::text() const
{
return d->textLabel->text();
}
void KMessageWidget::setText(const QString& text)
{
d->textLabel->setText(text);
updateGeometry();
}
KMessageWidget::MessageType KMessageWidget::messageType() const
{
return d->messageType;
}
void KMessageWidget::setMessageType(KMessageWidget::MessageType type)
{
d->messageType = type;
- KIcon icon;
+ QIcon icon;
KColorScheme::BackgroundRole bgRole;
KColorScheme::ForegroundRole fgRole;
KColorScheme::ColorSet colorSet = KColorScheme::Window;
switch (type) {
case Positive:
icon = KIcon("dialog-ok");
bgRole = KColorScheme::PositiveBackground;
fgRole = KColorScheme::PositiveText;
break;
case Information:
icon = KIcon("dialog-information");
bgRole = KColorScheme::NormalBackground;
fgRole = KColorScheme::NormalText;
colorSet = KColorScheme::Tooltip;
break;
case Warning:
icon = KIcon("dialog-warning");
bgRole = KColorScheme::NeutralBackground;
fgRole = KColorScheme::NeutralText;
break;
case Error:
icon = KIcon("dialog-error");
bgRole = KColorScheme::NegativeBackground;
fgRole = KColorScheme::NegativeText;
break;
}
const int size = KIconLoader::global()->currentSize(KIconLoader::MainToolbar);
d->iconLabel->setPixmap(icon.pixmap(size));
KColorScheme scheme(QPalette::Active, colorSet);
QBrush bg = scheme.background(bgRole);
QBrush border = scheme.foreground(fgRole);
QBrush fg = scheme.foreground();
d->content->setStyleSheet(
QString(".QFrame {"
"background-color: %1;"
"border-radius: 5px;"
"border: 1px solid %2;"
"}"
".QLabel { color: %3; }"
)
.arg(bg.color().name())
.arg(border.color().name())
.arg(fg.color().name())
);
}
QSize KMessageWidget::sizeHint() const
{
ensurePolished();
return d->content->sizeHint();
}
QSize KMessageWidget::minimumSizeHint() const
{
ensurePolished();
return d->content->minimumSizeHint();
}
bool KMessageWidget::event(QEvent* event)
{
if (event->type() == QEvent::Polish && !d->content->layout()) {
d->createLayout();
}
return QFrame::event(event);
}
void KMessageWidget::resizeEvent(QResizeEvent* event)
{
QFrame::resizeEvent(event);
if (d->timeLine->state() == QTimeLine::NotRunning) {
d->content->resize(size());
}
}
void KMessageWidget::paintEvent(QPaintEvent* event)
{
QFrame::paintEvent(event);
if (d->timeLine->state() == QTimeLine::Running) {
QPainter painter(this);
painter.setOpacity(d->timeLine->currentValue() * d->timeLine->currentValue());
painter.drawPixmap(0, 0, d->contentSnapShot);
}
}
void KMessageWidget::showEvent(QShowEvent* event)
{
QFrame::showEvent(event);
if (!event->spontaneous()) {
int wantedHeight = d->content->sizeHint().height();
d->content->setGeometry(0, 0, width(), wantedHeight);
setFixedHeight(wantedHeight);
}
}
bool KMessageWidget::wordWrap() const
{
return d->wordWrap;
}
void KMessageWidget::setWordWrap(bool wordWrap)
{
d->wordWrap = wordWrap;
d->textLabel->setWordWrap(wordWrap);
d->updateLayout();
}
bool KMessageWidget::isCloseButtonVisible() const
{
return d->closeButton->isVisible();
}
void KMessageWidget::setCloseButtonVisible(bool show)
{
d->closeButton->setVisible(show);
}
void KMessageWidget::addAction(QAction* action)
{
QFrame::addAction(action);
d->updateLayout();
}
void KMessageWidget::removeAction(QAction* action)
{
QFrame::removeAction(action);
d->updateLayout();
}
void KMessageWidget::animatedShow()
{
if (!(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects)) {
show();
return;
}
if (isVisible()) {
return;
}
QFrame::show();
setFixedHeight(0);
int wantedHeight = d->content->sizeHint().height();
d->content->setGeometry(0, -wantedHeight, width(), wantedHeight);
d->updateSnapShot();
d->timeLine->setDirection(QTimeLine::Forward);
if (d->timeLine->state() == QTimeLine::NotRunning) {
d->timeLine->start();
}
}
void KMessageWidget::animatedHide()
{
if (!(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects)) {
hide();
return;
}
if (!isVisible()) {
return;
}
d->content->move(0, -d->content->height());
d->updateSnapShot();
d->timeLine->setDirection(QTimeLine::Backward);
if (d->timeLine->state() == QTimeLine::NotRunning) {
d->timeLine->start();
}
}
#include "moc_kmessagewidget.cpp"
diff --git a/kdeui/widgets/kpushbutton.cpp b/kdeui/widgets/kpushbutton.cpp
index cc2d685a94..a4770a743e 100644
--- a/kdeui/widgets/kpushbutton.cpp
+++ b/kdeui/widgets/kpushbutton.cpp
@@ -1,385 +1,378 @@
/* This file is part of the KDE libraries
Copyright (C) 2000 Carsten Pfeiffer <pfeiffer@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 as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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 "kpushbutton.h"
#include <QStyleOptionToolButton>
#include <QStylePainter>
#include <QDrag>
#include <QActionEvent>
#include <QMenu>
#include <QtCore/QPointer>
#include <QStyle>
#include <QtCore/QTimer>
#include <config.h>
#include <kconfig.h>
#include <kglobal.h>
#include <kglobalsettings.h>
#include <kguiitem.h>
#include <kicon.h>
#include "kauthaction.h"
#include "kauthactionwatcher.h"
static bool s_useIcons = false;
class KPushButton::KPushButtonPrivate
{
public:
KPushButtonPrivate(KPushButton *_parent) : parent(_parent), m_dragEnabled( false ), authAction(0)
{
}
KPushButton *parent;
KGuiItem item;
KStandardGuiItem::StandardItem itemType;
QPointer<QMenu> delayedMenu;
QTimer * delayedMenuTimer;
bool m_dragEnabled;
QPoint startPos;
KAuth::Action *authAction;
// TODO: Remove whenever QIcon overlays will get fixed
- KIcon oldIcon;
+ QIcon oldIcon;
void slotSettingsChanged( int );
void slotPressedInternal();
void slotClickedInternal();
void authStatusChanged(int status);
void slotDelayedMenuTimeout();
void readSettings();
};
void KPushButton::KPushButtonPrivate::slotSettingsChanged( int /* category */ )
{
readSettings();
parent->setIcon( item.icon() );
}
void KPushButton::KPushButtonPrivate::slotPressedInternal()
{
if (!delayedMenu.isNull()) {
if (delayedMenuTimer==0) {
delayedMenuTimer=new QTimer(parent);
delayedMenuTimer->setSingleShot(true);
connect(delayedMenuTimer,SIGNAL(timeout()),parent,SLOT(slotDelayedMenuTimeout()));
}
const int delay=parent->style()->styleHint(QStyle::SH_ToolButton_PopupDelay, 0, parent);
delayedMenuTimer->start((delay<=0) ? 150:delay);
}
}
void KPushButton::KPushButtonPrivate::slotClickedInternal()
{
if (delayedMenuTimer)
delayedMenuTimer->stop();
if (authAction) {
KAuth::Action::AuthStatus s = authAction->earlyAuthorize();
switch(s) {
case KAuth::Action::Denied:
parent->setEnabled(false);
break;
case KAuth::Action::Authorized:
emit parent->authorized(authAction);
break;
default:
break;
}
}
}
void KPushButton::KPushButtonPrivate::slotDelayedMenuTimeout() {
delayedMenuTimer->stop();
if (!delayedMenu.isNull()) {
parent->setMenu(delayedMenu);
parent->showMenu();
parent->setMenu(0);
}
}
void KPushButton::KPushButtonPrivate::authStatusChanged(int status)
{
KAuth::Action::AuthStatus s = (KAuth::Action::AuthStatus)status;
switch(s) {
case KAuth::Action::Authorized:
parent->setEnabled(true);
if(!oldIcon.isNull()) {
parent->setIcon(oldIcon);
oldIcon = KIcon();
}
break;
case KAuth::Action::AuthRequired:
parent->setEnabled(true);
oldIcon = KIcon(parent->icon());
parent->setIcon(KIcon("dialog-password"));
break;
default:
parent->setEnabled(false);
if(!oldIcon.isNull()) {
parent->setIcon(oldIcon);
oldIcon = KIcon();
}
}
}
void KPushButton::KPushButtonPrivate::readSettings()
{
s_useIcons = KGlobalSettings::showIconsOnPushButtons();
}
KPushButton::KPushButton( QWidget *parent )
: QPushButton( parent ), d( new KPushButtonPrivate(this) )
{
init( KGuiItem( "" ) );
}
KPushButton::KPushButton( const QString &text, QWidget *parent )
: QPushButton( parent ), d( new KPushButtonPrivate(this) )
{
init( KGuiItem( text ) );
}
-KPushButton::KPushButton( const KIcon &icon, const QString &text,
+KPushButton::KPushButton( const QIcon &icon, const QString &text,
QWidget *parent )
: QPushButton( text, parent ), d( new KPushButtonPrivate(this) )
{
init( KGuiItem( text, icon ) );
}
KPushButton::KPushButton( const KGuiItem &item, QWidget *parent )
: QPushButton( parent ), d( new KPushButtonPrivate(this) )
{
init( item );
}
KPushButton::~KPushButton()
{
delete d;
}
void KPushButton::init( const KGuiItem &item )
{
d->item = item;
d->itemType = (KStandardGuiItem::StandardItem) 0;
d->delayedMenuTimer=0;
connect(this,SIGNAL(pressed()), this, SLOT(slotPressedInternal()));
connect(this,SIGNAL(clicked()), this, SLOT(slotClickedInternal()));
// call QPushButton's implementation since we don't need to
// set the GUI items text or check the state of the icon set
QPushButton::setText( d->item.text() );
static bool initialized = false;
if ( !initialized ) {
d->readSettings();
initialized = true;
}
setIcon( d->item.icon() );
setToolTip( item.toolTip() );
setWhatsThis(item.whatsThis());
connect( KGlobalSettings::self(), SIGNAL( settingsChanged(int) ),
SLOT( slotSettingsChanged(int) ) );
}
bool KPushButton::isDragEnabled() const
{
return d->m_dragEnabled;
}
void KPushButton::setGuiItem( const KGuiItem& item )
{
d->item = item;
// call QPushButton's implementation since we don't need to
// set the GUI items text or check the state of the icon set
QPushButton::setText( d->item.text() );
setIcon( d->item.icon() );
setToolTip( d->item.toolTip() );
setEnabled( d->item.isEnabled() );
setWhatsThis( d->item.whatsThis() );
}
void KPushButton::setGuiItem( KStandardGuiItem::StandardItem item )
{
setGuiItem( KStandardGuiItem::guiItem(item) );
d->itemType = item;
}
KStandardGuiItem::StandardItem KPushButton::guiItem() const
{
return d->itemType;
}
void KPushButton::setText( const QString &text )
{
QPushButton::setText(text);
// we need to re-evaluate the icon set when the text
// is removed, or when it is supplied
if (text.isEmpty() != d->item.text().isEmpty())
setIcon(d->item.icon());
d->item.setText(text);
}
-void KPushButton::setIcon( const KIcon &icon )
+void KPushButton::setIcon( const QIcon &icon )
{
d->item.setIcon(icon);
if ( s_useIcons || text().isEmpty() )
QPushButton::setIcon( icon );
else
QPushButton::setIcon( QIcon() );
}
-#ifndef KDE_NO_DEPRECATED
-void KPushButton::setIcon( const QIcon &qicon )
-{
- d->item.setIcon(KIcon(qicon));
-}
-#endif
-
void KPushButton::setDragEnabled( bool enable )
{
d->m_dragEnabled = enable;
}
void KPushButton::mousePressEvent( QMouseEvent *e )
{
if ( d->m_dragEnabled )
d->startPos = e->pos();
QPushButton::mousePressEvent( e );
}
void KPushButton::mouseMoveEvent( QMouseEvent *e )
{
if ( !d->m_dragEnabled )
{
QPushButton::mouseMoveEvent( e );
return;
}
if ( (e->buttons() & Qt::LeftButton) &&
(e->pos() - d->startPos).manhattanLength() >
KGlobalSettings::dndEventDelay() )
{
startDrag();
setDown( false );
}
}
QDrag * KPushButton::dragObject()
{
return 0;
}
void KPushButton::startDrag()
{
QDrag *d = dragObject();
if ( d )
d->start();
}
void KPushButton::setDelayedMenu(QMenu *delayedMenu)
{
d->delayedMenu=delayedMenu;
}
QMenu* KPushButton::delayedMenu()
{
return d->delayedMenu;
}
KAuth::Action *KPushButton::authAction() const
{
return d->authAction;
}
void KPushButton::setAuthAction(const QString &actionName)
{
if (actionName.isEmpty()) {
setAuthAction(0);
} else {
setAuthAction(new KAuth::Action(actionName));
}
}
void KPushButton::setAuthAction(KAuth::Action *action)
{
if (d->authAction == action) {
return;
}
if (d->authAction) {
disconnect(d->authAction->watcher(), SIGNAL(statusChanged(int)),
this, SLOT(authStatusChanged(int)));
//delete d->authAction;
d->authAction = 0;
if (!d->oldIcon.isNull()) {
setIcon(d->oldIcon);
d->oldIcon = KIcon();
}
}
if (action != 0) {
d->authAction = action;
// Set the parent widget
d->authAction->setParentWidget(this);
connect(d->authAction->watcher(), SIGNAL(statusChanged(int)),
this, SLOT(authStatusChanged(int)));
d->authStatusChanged(d->authAction->status());
}
}
QSize KPushButton::sizeHint() const
{
const bool tempSetMenu = !menu() && d->delayedMenu;
if (tempSetMenu)
const_cast<KPushButton *>(this)->setMenu(d->delayedMenu);
const QSize sz = QPushButton::sizeHint();
if (tempSetMenu)
const_cast<KPushButton *>(this)->setMenu(0);
return sz;
}
void KPushButton::paintEvent( QPaintEvent * )
{
QStylePainter p(this);
QStyleOptionButton option;
initStyleOption(&option);
if (d->delayedMenu)
option.features |= QStyleOptionButton::HasMenu;
p.drawControl(QStyle::CE_PushButton, option);
}
#include "moc_kpushbutton.cpp"
diff --git a/kdeui/widgets/kpushbutton.h b/kdeui/widgets/kpushbutton.h
index 0cdde13d99..526e099176 100644
--- a/kdeui/widgets/kpushbutton.h
+++ b/kdeui/widgets/kpushbutton.h
@@ -1,235 +1,226 @@
/* This file is part of the KDE libraries
Copyright (C) 2000 Carsten Pfeiffer <pfeiffer@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 as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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.
*/
#ifndef KPUSHBUTTON_H
#define KPUSHBUTTON_H
#include <QPushButton>
#include <kstandardguiitem.h>
class QDrag;
class QMenu;
-class KIcon;
+
namespace KAuth {
class Action;
}
/**
* @brief A QPushButton with drag-support and KGuiItem support
*
* This is nothing but a QPushButton with drag-support and KGuiItem support.
* You must call #setDragEnabled (true) and override the virtual method
* dragObject() to specify the QDragObject to be used.
*
* \image html kpushbutton.png "KDE Push Button"
*
* @author Carsten Pfeiffer <pfeiffer@kde.org>
*/
class KDEUI_EXPORT KPushButton : public QPushButton
{
Q_OBJECT
Q_PROPERTY(bool isDragEnabled READ isDragEnabled WRITE setDragEnabled)
public:
/**
* Default constructor.
*/
explicit KPushButton( QWidget *parent = 0 );
/**
* Constructor, that sets the button-text to @p text
*/
explicit KPushButton( const QString &text, QWidget *parent = 0 );
/**
* Constructor, that sets an icon and the button-text to @p text
*/
- KPushButton( const KIcon &icon, const QString &text, QWidget *parent = 0 );
+ KPushButton( const QIcon &icon, const QString &text, QWidget *parent = 0 );
/**
* Constructor that takes a KGuiItem for the text, the icon, the tooltip
* and the what's this help
*/
explicit KPushButton( const KGuiItem &item, QWidget *parent = 0 );
/**
* Destructs the button.
*/
~KPushButton();
/**
* Enables/disables drag-support. Default is disabled.
*/
void setDragEnabled( bool enable );
/**
* @returns if drag support is enabled or not.
*/
bool isDragEnabled() const;
/**
* Sets the KGuiItem for this button.
*/
void setGuiItem( const KGuiItem& item );
/**
* Sets the standard KGuiItem for this button.
*/
void setGuiItem( KStandardGuiItem::StandardItem item );
/**
* Reads the standard KGuiItem for this button.
*/
KStandardGuiItem::StandardItem guiItem() const;
/**
* Sets the Icon Set for this button. It also takes into account the
* KGlobalSettings::showIconsOnPushButtons() setting.
*/
- void setIcon( const KIcon &icon );
-
- /**
- * Sets the pixmap for this button. Rarely used. This one exists mostly for usage in Qt designer,
- * with icons embedded into the ui file. But you should rather save them separately, and load them
- * with KIcon("name") so that the icons are themeable.
- */
-#ifndef KDE_NO_DEPRECATED
- KDEUI_DEPRECATED void setIcon( const QIcon &pix );
-#endif
+ void setIcon( const QIcon &icon );
/**
* Sets the text of the button
*/
void setText( const QString &text );
/**
* Sets a delayed popup menu
* for consistency, since menu() isn't virtual
*/
void setDelayedMenu(QMenu *delayed_menu);
/**
* returns a delayed popup menu
* since menu() isn't virtual
*/
QMenu *delayedMenu();
/**
* Reimplemented to add arrow for delayed menu
* @since 4.4
*/
virtual QSize sizeHint() const;
/**
* Returns the action object associated with this button, or 0 if it does not have one
*
* @returns the KAuth::Action associated with this button.
*/
KAuth::Action *authAction() const;
/**
* Sets the action object associated with this button
*
* By setting a KAuth::Action, this button will become associated with it, and
* whenever it gets clicked, it will trigger the authorization and execution process
* for the action. The signal activated will also be emitted whenever the button gets
* clicked and the action gets authorized. Pass 0 to this function to disassociate the button
*
* @param action the KAuth::Action to associate with this button.
*/
void setAuthAction(KAuth::Action *action);
/**
* Sets the action object associated with this button
*
* Overloaded member to allow creating the action by name
*
* @param actionName the name of the action to associate
*/
void setAuthAction(const QString &actionName);
protected:
/**
* Reimplement this and return the QDrag object that should be used
* for the drag. Remember to give it "this" as parent.
*
* Default implementation returns 0, so that no drag is initiated.
*/
virtual QDrag * dragObject();
/**
* Reimplemented to add drag-support
*/
virtual void mousePressEvent( QMouseEvent * );
/**
* Reimplemented to add drag-support
*/
virtual void mouseMoveEvent( QMouseEvent * );
/**
* Reimplemented to add arrow for delayed menu
* @since 4.4
*/
virtual void paintEvent( QPaintEvent * );
/**
* Starts a drag (dragCopy() by default) using dragObject()
*/
virtual void startDrag();
Q_SIGNALS:
/**
* Signal emitted when the button is triggered and authorized
*
* If the button needs authorization, whenever the user triggers it,
* the authorization process automatically begins.
* If it succeeds, this signal is emitted. The KAuth::Action object is provided for convenience
* if you have multiple Action objects, but of course it's always the same set with
* setAuthAction().
*
* WARNING: If your button needs authorization you should connect eventual slots processing
* stuff to this signal, and NOT clicked. Clicked will be emitted even if the user has not
* been authorized
*
* @param action The object set with setAuthAction()
*/
void authorized(KAuth::Action *action);
private:
/**
* Internal.
* Initialize the KPushButton instance
*/
void init( const KGuiItem &item );
private:
class KPushButtonPrivate;
KPushButtonPrivate * const d;
Q_PRIVATE_SLOT(d, void slotSettingsChanged( int ))
Q_PRIVATE_SLOT(d, void slotPressedInternal())
Q_PRIVATE_SLOT(d, void slotClickedInternal())
Q_PRIVATE_SLOT(d, void slotDelayedMenuTimeout())
Q_PRIVATE_SLOT(d, void authStatusChanged(int))
};
#endif // KPUSHBUTTON_H
diff --git a/kdeui/widgets/krichtextwidget.cpp b/kdeui/widgets/krichtextwidget.cpp
index 2d67bc1c0d..dc17dccf23 100644
--- a/kdeui/widgets/krichtextwidget.cpp
+++ b/kdeui/widgets/krichtextwidget.cpp
@@ -1,712 +1,713 @@
/* This file is part of the KDE libraries
Copyright 2008 Stephen Kelly <steveire@gmail.com>
Copyright 2008 Thomas McGuire <thomas.mcguire@gmx.net>
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 "krichtextwidget.h"
// KDE includes
+#include <kicon.h>
#include <kactioncollection.h>
#include <kcolordialog.h>
#include <kcolorscheme.h>
#include <kfontaction.h>
#include <kfontsizeaction.h>
#include <klocale.h>
#include <ktoggleaction.h>
#include <kdebug.h>
// Qt includes
#include <QTextList>
#include "klinkdialog.h"
// TODO: Add i18n context
/**
Private class that helps to provide binary compatibility between releases.
@internal
*/
//@cond PRIVATE
class KRichTextWidget::Private
{
public:
Private(KRichTextWidget *parent)
: q(parent),
painterActive(false),
richTextEnabled(false), // It's only enabled when an action makes text rich.
enableRichText(0),
action_text_foreground_color(0),
action_text_background_color(0),
action_text_bold(0),
action_text_italic(0),
action_text_underline(0),
action_text_strikeout(0),
action_font_family(0),
action_font_size(0),
action_list_style(0),
action_list_indent(0),
action_list_dedent(0),
action_manage_link(0),
action_insert_horizontal_rule(0),
action_format_painter(0),
action_to_plain_text(0),
action_align_left(0),
action_align_right(0),
action_align_center(0),
action_align_justify(0),
action_direction_ltr(0),
action_direction_rtl(0),
action_text_superscript(0),
action_text_subscript(0)
{
}
KRichTextWidget *q;
RichTextSupport richTextSupport;
QTextCharFormat painterFormat;
bool painterActive;
QList<KAction*> richTextActionList;
bool richTextEnabled;
KToggleAction *enableRichText;
KAction *action_text_foreground_color;
KAction *action_text_background_color;
KToggleAction *action_text_bold;
KToggleAction *action_text_italic;
KToggleAction *action_text_underline;
KToggleAction *action_text_strikeout;
KFontAction *action_font_family;
KFontSizeAction *action_font_size;
KSelectAction *action_list_style;
KAction *action_list_indent;
KAction *action_list_dedent;
KAction *action_manage_link;
KAction *action_insert_horizontal_rule;
KAction *action_format_painter;
KAction *action_to_plain_text;
KToggleAction *action_align_left;
KToggleAction *action_align_right;
KToggleAction *action_align_center;
KToggleAction *action_align_justify;
KToggleAction *action_direction_ltr;
KToggleAction *action_direction_rtl;
KToggleAction *action_text_superscript;
KToggleAction *action_text_subscript;
//
// Normal functions
//
void init();
//
// Slots
//
/**
* @brief Opens a dialog to allow the user to select a foreground color.
*/
void _k_setTextForegroundColor();
/**
* @brief Opens a dialog to allow the user to select a background color.
*/
void _k_setTextBackgroundColor();
/**
* Opens a dialog which lets the user turn the currently selected text into
* a link.
* If no text is selected, the word under the cursor will be taken.
* If the cursor is already over a link, the user can edit that link.
*
*/
void _k_manageLink();
/**
* Activates a format painter to allow the user to copy font/text formatting
* to different parts of the document.
*
*/
void _k_formatPainter(bool active);
/**
* @brief Update actions relating to text format (bold, size etc.).
*/
void _k_updateCharFormatActions(const QTextCharFormat &format);
/**
* Update actions not covered by text formatting, such as alignment,
* list style and level.
*/
void _k_updateMiscActions();
/**
* Change the style of the current list or create a new list with the style given by @a index.
*/
void _k_setListStyle(int index);
};
//@endcond
void KRichTextWidget::Private::init()
{
q->setRichTextSupport(KRichTextWidget::FullSupport);
}
KRichTextWidget::KRichTextWidget(QWidget* parent)
: KRichTextEdit(parent),
d(new Private(this))
{
d->init();
}
KRichTextWidget::KRichTextWidget(const QString& text, QWidget *parent)
: KRichTextEdit(text,parent),
d(new Private(this))
{
d->init();
}
KRichTextWidget::~KRichTextWidget()
{
delete d;
}
KRichTextWidget::RichTextSupport KRichTextWidget::richTextSupport() const
{
return d->richTextSupport;
}
void KRichTextWidget::setRichTextSupport(const KRichTextWidget::RichTextSupport &support)
{
d->richTextSupport = support;
}
void KRichTextWidget::createActions(KActionCollection *actionCollection)
{
Q_ASSERT(actionCollection);
// Note to maintainers: If adding new functionality here, make sure to disconnect
// and delete actions which should not be supported.
//
// New Actions need to be added to the following places:
// - possibly the RichTextSupportValues enum
// - the API documentation for createActions()
// - this function
// - the action needs to be added to the private class as a member
// - the constructor of the private class
// - depending on the action, some slot that changes the toggle state when
// appropriate, such as _k_updateCharFormatActions or _k_updateMiscActions.
// The list of actions currently supported is also stored internally.
// This is used to disable all actions at once in setActionsEnabled.
d->richTextActionList.clear();
if (d->richTextSupport & SupportTextForegroundColor) {
//Foreground Color
d->action_text_foreground_color = new KAction(KIcon("format-stroke-color"), i18nc("@action", "Text &Color..."), actionCollection);
d->action_text_foreground_color->setIconText(i18nc("@label stroke color", "Color"));
d->richTextActionList.append((d->action_text_foreground_color));
actionCollection->addAction("format_text_foreground_color", d->action_text_foreground_color);
connect(d->action_text_foreground_color, SIGNAL(triggered()), this, SLOT(_k_setTextForegroundColor()));
} else {
actionCollection->removeAction(d->action_text_foreground_color);
d->action_text_foreground_color = 0;
}
if (d->richTextSupport & SupportTextBackgroundColor) {
//Background Color
d->action_text_background_color = new KAction(KIcon("format-fill-color"), i18nc("@action", "Text &Highlight..."), actionCollection);
d->richTextActionList.append((d->action_text_background_color));
actionCollection->addAction("format_text_background_color", d->action_text_background_color);
connect(d->action_text_background_color, SIGNAL(triggered()), this, SLOT(_k_setTextBackgroundColor()));
} else {
actionCollection->removeAction(d->action_text_background_color);
d->action_text_background_color = 0;
}
if (d->richTextSupport & SupportFontFamily) {
//Font Family
d->action_font_family = new KFontAction(i18nc("@action", "&Font"), actionCollection);
d->richTextActionList.append((d->action_font_family));
actionCollection->addAction("format_font_family", d->action_font_family);
connect(d->action_font_family, SIGNAL(triggered(QString)), this, SLOT(setFontFamily(QString)));
} else {
actionCollection->removeAction(d->action_font_family);
d->action_font_family = 0;
}
if (d->richTextSupport & SupportFontSize) {
//Font Size
d->action_font_size = new KFontSizeAction(i18nc("@action", "Font &Size"), actionCollection);
d->richTextActionList.append((d->action_font_size));
actionCollection->addAction("format_font_size", d->action_font_size);
connect(d->action_font_size, SIGNAL(fontSizeChanged(int)), this, SLOT(setFontSize(int)));
} else {
actionCollection->removeAction(d->action_font_size);
d->action_font_size = 0;
}
if (d->richTextSupport & SupportBold) {
d->action_text_bold = new KToggleAction(KIcon("format-text-bold"), i18nc("@action boldify selected text", "&Bold"), actionCollection);
QFont bold;
bold.setBold(true);
d->action_text_bold->setFont(bold);
d->richTextActionList.append((d->action_text_bold));
actionCollection->addAction("format_text_bold", d->action_text_bold);
d->action_text_bold->setShortcut(KShortcut(Qt::CTRL + Qt::Key_B));
connect(d->action_text_bold, SIGNAL(triggered(bool)), this, SLOT(setTextBold(bool)));
} else {
actionCollection->removeAction(d->action_text_bold);
d->action_text_bold = 0;
}
if (d->richTextSupport & SupportItalic) {
d->action_text_italic = new KToggleAction(KIcon("format-text-italic"), i18nc("@action italicize selected text", "&Italic"), actionCollection);
QFont italic;
italic.setItalic(true);
d->action_text_italic->setFont(italic);
d->richTextActionList.append((d->action_text_italic));
actionCollection->addAction("format_text_italic", d->action_text_italic);
d->action_text_italic->setShortcut(KShortcut(Qt::CTRL + Qt::Key_I));
connect(d->action_text_italic, SIGNAL(triggered(bool)),
this, SLOT(setTextItalic(bool)));
} else {
actionCollection->removeAction(d->action_text_italic);
d->action_text_italic = 0;
}
if (d->richTextSupport & SupportUnderline) {
d->action_text_underline = new KToggleAction(KIcon("format-text-underline"), i18nc("@action underline selected text", "&Underline"), actionCollection);
QFont underline;
underline.setUnderline(true);
d->action_text_underline->setFont(underline);
d->richTextActionList.append((d->action_text_underline));
actionCollection->addAction("format_text_underline", d->action_text_underline);
d->action_text_underline->setShortcut(KShortcut(Qt::CTRL + Qt::Key_U));
connect(d->action_text_underline, SIGNAL(triggered(bool)),
this, SLOT(setTextUnderline(bool)));
} else {
actionCollection->removeAction(d->action_text_underline);
d->action_text_underline = 0;
}
if (d->richTextSupport & SupportStrikeOut) {
d->action_text_strikeout = new KToggleAction(KIcon("format-text-strikethrough"), i18nc("@action", "&Strike Out"), actionCollection);
d->richTextActionList.append((d->action_text_strikeout));
actionCollection->addAction("format_text_strikeout", d->action_text_strikeout);
d->action_text_strikeout->setShortcut(KShortcut(Qt::CTRL + Qt::Key_L));
connect(d->action_text_strikeout, SIGNAL(triggered(bool)),
this, SLOT(setTextStrikeOut(bool)));
} else {
actionCollection->removeAction(d->action_text_strikeout);
d->action_text_strikeout = 0;
}
if (d->richTextSupport & SupportAlignment) {
//Alignment
d->action_align_left = new KToggleAction(KIcon("format-justify-left"), i18nc("@action", "Align &Left"), actionCollection);
d->action_align_left->setIconText(i18nc("@label left justify", "Left"));
d->richTextActionList.append((d->action_align_left));
actionCollection->addAction("format_align_left", d->action_align_left);
connect(d->action_align_left, SIGNAL(triggered()),
this, SLOT(alignLeft()));
d->action_align_center = new KToggleAction(KIcon("format-justify-center"), i18nc("@action", "Align &Center"), actionCollection);
d->action_align_center->setIconText(i18nc("@label center justify", "Center"));
d->richTextActionList.append((d->action_align_center));
actionCollection->addAction("format_align_center", d->action_align_center);
connect(d->action_align_center, SIGNAL(triggered()),
this, SLOT(alignCenter()));
d->action_align_right = new KToggleAction(KIcon("format-justify-right"), i18nc("@action", "Align &Right"), actionCollection);
d->action_align_right->setIconText(i18nc("@label right justify", "Right"));
d->richTextActionList.append((d->action_align_right));
actionCollection->addAction("format_align_right", d->action_align_right);
connect(d->action_align_right, SIGNAL(triggered()),
this, SLOT(alignRight()));
d->action_align_justify = new KToggleAction(KIcon("format-justify-fill"), i18nc("@action", "&Justify"), actionCollection);
d->action_align_justify->setIconText(i18nc("@label justify fill", "Justify"));
d->richTextActionList.append((d->action_align_justify));
actionCollection->addAction("format_align_justify", d->action_align_justify);
connect(d->action_align_justify, SIGNAL(triggered()),
this, SLOT(alignJustify()));
QActionGroup *alignmentGroup = new QActionGroup(this);
alignmentGroup->addAction(d->action_align_left);
alignmentGroup->addAction(d->action_align_center);
alignmentGroup->addAction(d->action_align_right);
alignmentGroup->addAction(d->action_align_justify);
} else {
actionCollection->removeAction(d->action_align_left);
actionCollection->removeAction(d->action_align_center);
actionCollection->removeAction(d->action_align_right);
actionCollection->removeAction(d->action_align_justify);
d->action_align_left = 0;
d->action_align_center = 0;
d->action_align_right = 0;
d->action_align_justify = 0;
}
if (d->richTextSupport & SupportDirection) {
d->action_direction_ltr = new KToggleAction(KIcon("format-text-direction-ltr"), i18nc("@action", "Left-to-Right"), actionCollection);
d->action_direction_ltr->setIconText(i18nc("@label left-to-right", "Left-to-Right"));
d->richTextActionList.append(d->action_direction_ltr);
actionCollection->addAction("direction_ltr", d->action_direction_ltr);
connect(d->action_direction_ltr, SIGNAL(triggered()),
this, SLOT(makeLeftToRight()));
d->action_direction_rtl = new KToggleAction(KIcon("format-text-direction-rtl"), i18nc("@action", "Right-to-Left"), actionCollection);
d->action_direction_rtl->setIconText(i18nc("@label right-to-left", "Right-to-Left"));
d->richTextActionList.append(d->action_direction_rtl);
actionCollection->addAction("direction_rtl", d->action_direction_rtl);
connect(d->action_direction_rtl, SIGNAL(triggered()),
this, SLOT(makeRightToLeft()));
QActionGroup *directionGroup = new QActionGroup(this);
directionGroup->addAction(d->action_direction_ltr);
directionGroup->addAction(d->action_direction_rtl);
} else {
actionCollection->removeAction(d->action_direction_ltr);
actionCollection->removeAction(d->action_direction_rtl);
d->action_direction_ltr = 0;
d->action_direction_rtl = 0;
}
if (d->richTextSupport & SupportChangeListStyle) {
d->action_list_style = new KSelectAction(KIcon("format-list-unordered"), i18nc("@title:menu", "List Style"), actionCollection);
QStringList listStyles;
listStyles << i18nc("@item:inmenu no list style", "None")
<< i18nc("@item:inmenu disc list style", "Disc")
<< i18nc("@item:inmenu circle list style", "Circle")
<< i18nc("@item:inmenu square list style", "Square")
<< i18nc("@item:inmenu numbered lists", "123")
<< i18nc("@item:inmenu lowercase abc lists", "abc")
<< i18nc("@item:inmenu uppercase abc lists", "ABC");
d->action_list_style->setItems(listStyles);
d->action_list_style->setCurrentItem(0);
d->richTextActionList.append((d->action_list_style));
actionCollection->addAction("format_list_style", d->action_list_style);
connect(d->action_list_style, SIGNAL(triggered(int)),
this, SLOT(_k_setListStyle(int)));
connect(d->action_list_style, SIGNAL(triggered()),
this, SLOT(_k_updateMiscActions()));
} else {
actionCollection->removeAction(d->action_list_style);
d->action_list_style = 0;
}
if (d->richTextSupport & SupportIndentLists) {
d->action_list_indent = new KAction(KIcon("format-indent-more"), i18nc("@action", "Increase Indent"), actionCollection);
d->richTextActionList.append((d->action_list_indent));
actionCollection->addAction("format_list_indent_more", d->action_list_indent);
connect(d->action_list_indent, SIGNAL(triggered()),
this, SLOT(indentListMore()));
connect(d->action_list_indent, SIGNAL(triggered()),
this, SLOT(_k_updateMiscActions()));
} else {
actionCollection->removeAction(d->action_list_indent);
d->action_list_indent = 0;
}
if (d->richTextSupport & SupportDedentLists) {
d->action_list_dedent = new KAction(KIcon("format-indent-less"), i18nc("@action", "Decrease Indent"), actionCollection);
d->richTextActionList.append((d->action_list_dedent));
actionCollection->addAction("format_list_indent_less", d->action_list_dedent);
connect(d->action_list_dedent, SIGNAL(triggered()),
this, SLOT(indentListLess()));
connect(d->action_list_dedent, SIGNAL(triggered()),
this, SLOT(_k_updateMiscActions()));
} else {
actionCollection->removeAction(d->action_list_dedent);
d->action_list_dedent = 0;
}
if (d->richTextSupport & SupportRuleLine) {
d->action_insert_horizontal_rule = new KAction(KIcon("insert-horizontal-rule"), i18nc("@action", "Insert Rule Line"), actionCollection);
d->richTextActionList.append((d->action_insert_horizontal_rule));
actionCollection->addAction("insert_horizontal_rule", d->action_insert_horizontal_rule);
connect(d->action_insert_horizontal_rule, SIGNAL(triggered()),
this, SLOT(insertHorizontalRule()));
} else {
actionCollection->removeAction(d->action_insert_horizontal_rule);
d->action_insert_horizontal_rule = 0;
}
if (d->richTextSupport & SupportHyperlinks) {
d->action_manage_link = new KAction(KIcon("insert-link"), i18nc("@action", "Link"), actionCollection);
d->richTextActionList.append((d->action_manage_link));
actionCollection->addAction("manage_link", d->action_manage_link);
connect(d->action_manage_link, SIGNAL(triggered()),
this, SLOT(_k_manageLink()));
} else {
actionCollection->removeAction(d->action_manage_link);
d->action_manage_link = 0;
}
if (d->richTextSupport & SupportFormatPainting) {
d->action_format_painter = new KToggleAction(KIcon("draw-brush"), i18nc("@action", "Format Painter"), actionCollection);
d->richTextActionList.append((d->action_format_painter));
actionCollection->addAction("format_painter", d->action_format_painter);
connect(d->action_format_painter, SIGNAL(toggled(bool)),
this, SLOT(_k_formatPainter(bool)));
} else {
actionCollection->removeAction(d->action_format_painter);
d->action_format_painter = 0;
}
if (d->richTextSupport & SupportToPlainText) {
d->action_to_plain_text = new KToggleAction(i18nc("@action", "To Plain Text"), actionCollection);
d->richTextActionList.append((d->action_to_plain_text));
actionCollection->addAction("action_to_plain_text", d->action_to_plain_text);
connect(d->action_to_plain_text, SIGNAL(triggered()),
this, SLOT(switchToPlainText()));
} else {
actionCollection->removeAction(d->action_to_plain_text);
d->action_to_plain_text = 0;
}
if (d->richTextSupport & SupportSuperScriptAndSubScript) {
d->action_text_subscript = new KToggleAction(KIcon("format-text-subscript"), i18nc("@action", "Subscript"), actionCollection);
d->richTextActionList.append((d->action_text_subscript));
actionCollection->addAction("format_text_subscript", d->action_text_subscript);
connect(d->action_text_subscript, SIGNAL(triggered(bool)),
this, SLOT(setTextSubScript(bool)));
d->action_text_superscript = new KToggleAction(KIcon("format-text-superscript"), i18nc("@action", "Superscript"), actionCollection);
d->richTextActionList.append((d->action_text_superscript));
actionCollection->addAction("format_text_superscript", d->action_text_superscript);
connect(d->action_text_superscript, SIGNAL(triggered(bool)),
this, SLOT(setTextSuperScript(bool)));
} else {
actionCollection->removeAction(d->action_text_subscript);
d->action_text_subscript = 0;
actionCollection->removeAction(d->action_text_superscript);
d->action_text_superscript = 0;
}
disconnect(this, SIGNAL(currentCharFormatChanged(const QTextCharFormat &)),
this, SLOT(_k_updateCharFormatActions(const QTextCharFormat &)));
disconnect(this, SIGNAL(cursorPositionChanged()),
this, SLOT(_k_updateMiscActions()));
connect(this, SIGNAL(currentCharFormatChanged(const QTextCharFormat &)),
this, SLOT(_k_updateCharFormatActions(const QTextCharFormat &)));
connect(this, SIGNAL(cursorPositionChanged()),
this, SLOT(_k_updateMiscActions()));
d->_k_updateMiscActions();
d->_k_updateCharFormatActions(currentCharFormat());
}
void KRichTextWidget::setActionsEnabled(bool enabled)
{
foreach(QAction* action, d->richTextActionList)
{
action->setEnabled(enabled);
}
d->richTextEnabled = enabled;
}
void KRichTextWidget::Private::_k_setListStyle(int index)
{
q->setListStyle(index);
_k_updateMiscActions();
}
void KRichTextWidget::Private::_k_updateCharFormatActions(const QTextCharFormat &format)
{
QFont f = format.font();
if (richTextSupport & SupportFontFamily) {
action_font_family->setFont(f.family());
}
if (richTextSupport & SupportFontSize) {
if (f.pointSize() > 0)
action_font_size->setFontSize((int)f.pointSize());
}
if (richTextSupport & SupportBold) {
action_text_bold->setChecked(f.bold());
}
if (richTextSupport & SupportItalic) {
action_text_italic->setChecked(f.italic());
}
if (richTextSupport & SupportUnderline) {
action_text_underline->setChecked(f.underline());
}
if (richTextSupport & SupportStrikeOut) {
action_text_strikeout->setChecked(f.strikeOut());
}
if (richTextSupport & SupportSuperScriptAndSubScript) {
QTextCharFormat::VerticalAlignment vAlign = format.verticalAlignment();
action_text_superscript->setChecked(vAlign == QTextCharFormat::AlignSuperScript);
action_text_subscript->setChecked(vAlign == QTextCharFormat::AlignSubScript);
}
}
void KRichTextWidget::Private::_k_updateMiscActions()
{
if (richTextSupport & SupportAlignment) {
Qt::Alignment a = q->alignment();
if (a & Qt::AlignLeft) {
action_align_left->setChecked(true);
} else if (a & Qt::AlignHCenter) {
action_align_center->setChecked(true);
} else if (a & Qt::AlignRight) {
action_align_right->setChecked(true);
} else if (a & Qt::AlignJustify) {
action_align_justify->setChecked(true);
}
}
if (richTextSupport & SupportChangeListStyle) {
if (q->textCursor().currentList()) {
action_list_style->setCurrentItem(-q->textCursor().currentList()->format().style());
} else {
action_list_style->setCurrentItem(0);
}
}
if ( richTextSupport & SupportIndentLists ) {
if ( richTextEnabled ) {
action_list_indent->setEnabled( q->canIndentList() );
} else {
action_list_indent->setEnabled( false );
}
}
if ( richTextSupport & SupportDedentLists ) {
if ( richTextEnabled ) {
action_list_dedent->setEnabled( q->canDedentList() );
} else {
action_list_dedent->setEnabled( false );
}
}
if (richTextSupport & SupportDirection) {
const Qt::LayoutDirection direction = q->textCursor().blockFormat().layoutDirection();
action_direction_ltr->setChecked(direction == Qt::LeftToRight);
action_direction_rtl->setChecked(direction == Qt::RightToLeft);
}
}
void KRichTextWidget::Private::_k_setTextForegroundColor()
{
QColor currentTextForegroundColor = q->textColor();
int result = KColorDialog::getColor(currentTextForegroundColor, KColorScheme(QPalette::Active, KColorScheme::View).foreground().color() , q);
if (!currentTextForegroundColor.isValid())
currentTextForegroundColor = KColorScheme(QPalette::Active, KColorScheme::View).foreground().color() ;
if (result != QDialog::Accepted)
return;
q->setTextForegroundColor(currentTextForegroundColor);
}
void KRichTextWidget::Private::_k_setTextBackgroundColor()
{
QTextCharFormat fmt = q->textCursor().charFormat();
QColor currentTextBackgroundColor = fmt.background().color();
int result = KColorDialog::getColor(currentTextBackgroundColor, KColorScheme(QPalette::Active, KColorScheme::View).foreground().color() , q);
if (!currentTextBackgroundColor.isValid())
currentTextBackgroundColor = KColorScheme(QPalette::Active, KColorScheme::View).foreground().color() ;
if (result != QDialog::Accepted)
return;
q->setTextBackgroundColor(currentTextBackgroundColor);
}
void KRichTextWidget::Private::_k_manageLink()
{
q->selectLinkText();
KLinkDialog *linkDialog = new KLinkDialog(q);
linkDialog->setLinkText(q->currentLinkText());
linkDialog->setLinkUrl(q->currentLinkUrl());
if (linkDialog->exec()) {
q->updateLink(linkDialog->linkUrl(), linkDialog->linkText());
}
delete linkDialog;
}
void KRichTextWidget::mouseReleaseEvent(QMouseEvent *event)
{
if (d->painterActive) {
// If the painter is active, paint the selection with the
// correct format.
if (textCursor().hasSelection()) {
textCursor().setCharFormat(d->painterFormat);
}
d->painterActive = false;
d->action_format_painter->setChecked(false);
}
KRichTextEdit::mouseReleaseEvent(event);
}
void KRichTextWidget::Private::_k_formatPainter(bool active)
{
if (active) {
painterFormat = q->currentCharFormat();
painterActive = true;
q->viewport()->setCursor(QCursor(KIcon("draw-brush").pixmap(32, 32), 0, 32));
} else {
painterFormat = QTextCharFormat();
painterActive = false;
q->viewport()->setCursor(Qt::IBeamCursor);
}
}
void KRichTextWidget::updateActionStates()
{
d->_k_updateMiscActions();
d->_k_updateCharFormatActions(currentCharFormat());
}
// kate: space-indent on; indent-width 4; encoding utf-8; replace-tabs on;
#include "moc_krichtextwidget.cpp"
diff --git a/kdeui/xmlgui/kxmlguibuilder.cpp b/kdeui/xmlgui/kxmlguibuilder.cpp
index 6773c313f1..e1f4939482 100644
--- a/kdeui/xmlgui/kxmlguibuilder.cpp
+++ b/kdeui/xmlgui/kxmlguibuilder.cpp
@@ -1,422 +1,423 @@
/* This file is part of the KDE project
Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
David Faure <faure@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 as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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 "kxmlguibuilder.h"
#include "kapplication.h"
#include "kauthorized.h"
#include "kxmlguiclient.h"
#include "kmenubar.h"
#include "kmenu.h"
#include "ktoolbar.h"
#include "kstatusbar.h"
#include "kmainwindow.h"
#include "kxmlguiwindow.h"
#include "kaction.h"
#include "kglobalsettings.h"
#include <klocale.h>
+#include <kicon.h>
#include <kiconloader.h>
#include <kdebug.h>
#include <QtXml/QDomElement>
#include <QtCore/QObject>
#include <QtCore/QMutableStringListIterator>
#include "kmenumenuhandler_p.h"
#include <kcomponentdata.h>
using namespace KDEPrivate;
class KXMLGUIBuilderPrivate
{
public:
KXMLGUIBuilderPrivate() : m_client(0L) {}
~KXMLGUIBuilderPrivate() { }
QWidget *m_widget;
QString tagMainWindow;
QString tagMenuBar;
QString tagMenu;
QString tagToolBar;
QString tagStatusBar;
QString tagSeparator;
QString tagTearOffHandle;
QString tagMenuTitle;
QString attrName;
QString attrLineSeparator;
QString attrText1;
QString attrText2;
QString attrContext;
QString attrIcon;
KComponentData m_componentData;
KXMLGUIClient *m_client;
KMenuMenuHandler *m_menumenuhandler;
};
KXMLGUIBuilder::KXMLGUIBuilder( QWidget *widget )
: d( new KXMLGUIBuilderPrivate )
{
d->m_widget = widget;
d->tagMainWindow = QLatin1String( "mainwindow" );
d->tagMenuBar = QLatin1String( "menubar" );
d->tagMenu = QLatin1String( "menu" );
d->tagToolBar = QLatin1String( "toolbar" );
d->tagStatusBar = QLatin1String( "statusbar" );
d->tagSeparator = QLatin1String( "separator" );
d->tagTearOffHandle = QLatin1String( "tearoffhandle" );
d->tagMenuTitle = QLatin1String( "title" );
d->attrName = QLatin1String( "name" );
d->attrLineSeparator = QLatin1String( "lineseparator" );
d->attrText1 = QLatin1String( "text" );
d->attrText2 = QLatin1String( "Text" );
d->attrContext = QLatin1String( "context" );
d->attrIcon = QLatin1String( "icon" );
d->m_menumenuhandler=new KMenuMenuHandler(this);
}
KXMLGUIBuilder::~KXMLGUIBuilder()
{
delete d->m_menumenuhandler;
delete d;
}
QWidget *KXMLGUIBuilder::widget()
{
return d->m_widget;
}
QStringList KXMLGUIBuilder::containerTags() const
{
QStringList res;
res << d->tagMenu << d->tagToolBar << d->tagMainWindow << d->tagMenuBar << d->tagStatusBar;
return res;
}
QWidget *KXMLGUIBuilder::createContainer( QWidget *parent, int index, const QDomElement &element, QAction*& containerAction )
{
containerAction = 0;
if (element.attribute("deleted").toLower() == "true") {
return 0;
}
const QString tagName = element.tagName().toLower();
if ( tagName == d->tagMainWindow ) {
KMainWindow *mainwindow = qobject_cast<KMainWindow*>( d->m_widget ); // could be 0
return mainwindow;
}
if ( tagName == d->tagMenuBar ) {
KMainWindow *mainWin = qobject_cast<KMainWindow*>( d->m_widget );
KMenuBar *bar = 0;
if (mainWin)
bar = mainWin->menuBar();
if (!bar)
bar = new KMenuBar( d->m_widget );
bar->show();
return bar;
}
if ( tagName == d->tagMenu ) {
// Look up to see if we are inside a mainwindow. If yes, then
// use it as parent widget (to get kaction to plug itself into the
// mainwindow). Don't use a popupmenu as parent widget, otherwise
// the popup won't be hidden if it is used as a standalone menu as well.
// And we don't want to set the parent for a standalone popupmenu,
// otherwise its shortcuts appear.
//
// Note: menus with a parent of 0, coming from child clients, can be
// leaked if the child client is deleted without a proper removeClient call, though.
QWidget* p = parent;
while ( p && !qobject_cast<QMainWindow*>( p ) )
p = p->parentWidget();
QByteArray name = element.attribute( d->attrName ).toUtf8();
if (!KAuthorized::authorizeKAction(name))
return 0;
KMenu *popup = new KMenu(p);
popup->setObjectName(name);
d->m_menumenuhandler->insertKMenu(popup);
QString i18nText;
QDomElement textElem = element.namedItem( d->attrText1 ).toElement();
if ( textElem.isNull() ) // try with capital T
textElem = element.namedItem( d->attrText2 ).toElement();
const QByteArray text = textElem.text().toUtf8();
const QByteArray context = textElem.attribute(d->attrContext).toUtf8();
if ( text.isEmpty() ) // still no luck
i18nText = i18n( "No text" );
else if ( context.isEmpty() )
i18nText = i18n( text );
else
i18nText = i18nc( context, text );
const QString icon = element.attribute( d->attrIcon );
- KIcon pix;
+ QIcon pix;
if (!icon.isEmpty()) {
pix = KIcon( icon );
}
if ( parent ) {
QAction* act = popup->menuAction();
if ( !icon.isEmpty() )
act->setIcon(pix);
act->setText(i18nText);
if (index == -1 || index >= parent->actions().count())
parent->addAction(act);
else
parent->insertAction(parent->actions().value(index), act);
containerAction = act;
containerAction->setObjectName( name );
}
return popup;
}
if ( tagName == d->tagToolBar ) {
QByteArray name = element.attribute( d->attrName ).toUtf8();
KToolBar *bar = static_cast<KToolBar*>(d->m_widget->findChild<KToolBar*>( name ));
if( !bar )
{
bar = new KToolBar(name, d->m_widget, false);
}
if ( qobject_cast<KMainWindow*>( d->m_widget ) )
{
if ( d->m_client && !d->m_client->xmlFile().isEmpty() )
bar->setXMLGUIClient( d->m_client );
}
bar->loadState( element );
return bar;
}
if ( tagName == d->tagStatusBar ) {
KMainWindow *mainWin = qobject_cast<KMainWindow *>(d->m_widget);
if ( mainWin ) {
mainWin->statusBar()->show();
return mainWin->statusBar();
}
KStatusBar *bar = new KStatusBar( d->m_widget );
return bar;
}
return 0L;
}
void KXMLGUIBuilder::removeContainer( QWidget *container, QWidget *parent, QDomElement &element, QAction* containerAction )
{
// Warning parent can be 0L
if ( qobject_cast<QMenu*>( container ) )
{
if ( parent ) {
parent->removeAction( containerAction );
}
delete container;
}
else if ( qobject_cast<KToolBar*>( container ) )
{
KToolBar *tb = static_cast<KToolBar *>( container );
tb->saveState( element );
delete tb;
}
else if ( qobject_cast<KMenuBar*>( container ) )
{
KMenuBar *mb = static_cast<KMenuBar *>( container );
mb->hide();
// Don't delete menubar - it can be reused by createContainer.
// If you decide that you do need to delete the menubar, make
// sure that QMainWindow::d->mb does not point to a deleted
// menubar object.
}
else if ( qobject_cast<KStatusBar*>( container ) )
{
if ( qobject_cast<KMainWindow*>( d->m_widget ) )
container->hide();
else
delete static_cast<KStatusBar *>(container);
}
else
kWarning() << "Unhandled container to remove : " << container->metaObject()->className();
}
QStringList KXMLGUIBuilder::customTags() const
{
QStringList res;
res << d->tagSeparator << d->tagTearOffHandle << d->tagMenuTitle;
return res;
}
QAction* KXMLGUIBuilder::createCustomElement( QWidget *parent, int index, const QDomElement &element )
{
QAction* before = 0L;
if (index > 0 && index < parent->actions().count())
before = parent->actions().at(index);
const QString tagName = element.tagName().toLower();
if (tagName == d->tagSeparator)
{
if ( QMenu *menu = qobject_cast<QMenu*>( parent ) )
{
// QMenu already cares for leading/trailing/repeated separators
// no need to check anything
return menu->insertSeparator( before );
}
else if ( QMenuBar* bar = qobject_cast<QMenuBar*>( parent ) )
{
QAction* separatorAction = new QAction(bar);
separatorAction->setSeparator(true);
bar->insertAction( before, separatorAction );
return separatorAction;
}
else if ( KToolBar *bar = qobject_cast<KToolBar*>( parent ) )
{
/* FIXME KAction port - any need to provide a replacement for lineSeparator/normal separator?
bool isLineSep = true;
QDomNamedNodeMap attributes = element.attributes();
unsigned int i = 0;
for (; i < attributes.length(); i++ )
{
QDomAttr attr = attributes.item( i ).toAttr();
if ( attr.name().toLower() == d->attrLineSeparator &&
attr.value().toLower() == QLatin1String("false") )
{
isLineSep = false;
break;
}
}
if ( isLineSep )
return bar->insertSeparator( index ? bar->actions()[index - 1] : 0L );
else*/
return bar->insertSeparator( before );
}
}
else if (tagName == d->tagTearOffHandle)
{
static_cast<QMenu *>(parent)->setTearOffEnabled(true);
}
else if (tagName == d->tagMenuTitle)
{
if ( KMenu* m = qobject_cast<KMenu*>( parent ) )
{
QString i18nText;
QByteArray text = element.text().toUtf8();
if ( text.isEmpty() )
i18nText = i18n( "No text" );
else
i18nText = i18n( text );
QString icon = element.attribute( d->attrIcon );
- KIcon pix;
+ QIcon pix;
if ( !icon.isEmpty() )
{
pix = KIcon( icon );
}
if ( !icon.isEmpty() ) {
return m->addTitle( pix, i18nText, before );
} else {
return m->addTitle( i18nText, before );
}
}
}
QAction* blank = new QAction(parent);
blank->setVisible(false);
parent->insertAction(before, blank);
return blank;
}
void KXMLGUIBuilder::removeCustomElement( QWidget *parent, QAction* action )
{
parent->removeAction(action);
}
KXMLGUIClient *KXMLGUIBuilder::builderClient() const
{
return d->m_client;
}
void KXMLGUIBuilder::setBuilderClient( KXMLGUIClient *client )
{
d->m_client = client;
if ( client )
setBuilderComponentData( client->componentData() );
}
KComponentData KXMLGUIBuilder::builderComponentData() const
{
return d->m_componentData;
}
void KXMLGUIBuilder::setBuilderComponentData(const KComponentData &componentData)
{
d->m_componentData = componentData;
}
void KXMLGUIBuilder::finalizeGUI( KXMLGUIClient * )
{
KXmlGuiWindow* window = qobject_cast<KXmlGuiWindow*>(d->m_widget);
if (!window)
return;
#if 0
KToolBar *toolbar = 0;
QListIterator<KToolBar> it( ( (KMainWindow*)d->m_widget )->toolBarIterator() );
while ( ( toolbar = it.current() ) ) {
kDebug(260) << "KXMLGUIBuilder::finalizeGUI toolbar=" << (void*)toolbar;
++it;
toolbar->positionYourself();
}
#else
window->finalizeGUI( false );
#endif
}
void KXMLGUIBuilder::virtual_hook( int, void* )
{ /*BASE::virtual_hook( id, data );*/ }
diff --git a/kdeui/xmlgui/kxmlguifactory.cpp b/kdeui/xmlgui/kxmlguifactory.cpp
index 6540f5218d..9bb07e17d2 100644
--- a/kdeui/xmlgui/kxmlguifactory.cpp
+++ b/kdeui/xmlgui/kxmlguifactory.cpp
@@ -1,803 +1,804 @@
/* This file is part of the KDE libraries
Copyright (C) 1999,2000 Simon Hausmann <hausmann@kde.org>
Copyright (C) 2000 Kurt Granroth <granroth@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 as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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 "kxmlguifactory.h"
#include "kxmlguifactory_p.h"
#include "kxmlguiclient.h"
#include "kxmlguibuilder.h"
#include <assert.h>
#include <QtCore/QDir>
#include <QtXml/QDomDocument>
#include <QtCore/QFile>
#include <QtCore/QTextStream>
#include <QWidget>
#include <QtCore/QDate>
#include <QtCore/QVariant>
#include <QTextCodec>
+#include <kicon.h>
#include <kdebug.h>
#include <kcomponentdata.h>
#include <kglobal.h>
#include <kshortcut.h>
#include <kstandarddirs.h>
#include "kaction.h"
#include "kshortcutsdialog.h"
#include "kactioncollection.h"
using namespace KXMLGUI;
class KXMLGUIFactoryPrivate : public BuildState
{
public:
enum ShortcutOption { SetActiveShortcut = 1, SetDefaultShortcut = 2};
KXMLGUIFactoryPrivate()
{
static const QString &defaultMergingName = KGlobal::staticQString( "<default>" );
static const QString &actionList = KGlobal::staticQString( "actionlist" );
static const QString &name = KGlobal::staticQString( "name" );
m_rootNode = new ContainerNode( 0L, QString(), 0L );
m_defaultMergingName = defaultMergingName;
tagActionList = actionList;
attrName = name;
}
~KXMLGUIFactoryPrivate()
{
delete m_rootNode;
}
void pushState()
{
m_stateStack.push( *this );
}
void popState()
{
BuildState::operator=( m_stateStack.pop() );
}
bool emptyState() const { return m_stateStack.isEmpty(); }
QWidget *findRecursive( KXMLGUI::ContainerNode *node, bool tag );
QList<QWidget*> findRecursive( KXMLGUI::ContainerNode *node, const QString &tagName );
void applyActionProperties( const QDomElement &element,
ShortcutOption shortcutOption = KXMLGUIFactoryPrivate::SetActiveShortcut );
void configureAction( QAction *action, const QDomNamedNodeMap &attributes,
ShortcutOption shortcutOption = KXMLGUIFactoryPrivate::SetActiveShortcut );
void configureAction( QAction *action, const QDomAttr &attribute,
ShortcutOption shortcutOption = KXMLGUIFactoryPrivate::SetActiveShortcut );
QDomDocument shortcutSchemeDoc(KXMLGUIClient *client);
void applyShortcutScheme(KXMLGUIClient *client, const QList<QAction*>& actions, const QDomDocument& scheme);
void refreshActionProperties(KXMLGUIClient *client, const QList<QAction*>& actions, const QDomDocument& doc);
void saveDefaultActionProperties(const QList<QAction*>& actions);
ContainerNode *m_rootNode;
QString m_defaultMergingName;
/*
* Contains the container which is searched for in ::container .
*/
QString m_containerName;
/*
* List of all clients
*/
QList<KXMLGUIClient*> m_clients;
QString tagActionList;
QString attrName;
BuildStateStack m_stateStack;
};
QString KXMLGUIFactory::readConfigFile( const QString &filename, const KComponentData &_componentData )
{
QString xml_file;
if (!QDir::isRelativePath(filename))
xml_file = filename;
else
{
KComponentData componentData = _componentData.isValid() ? _componentData : KGlobal::mainComponent();
xml_file = KStandardDirs::locate("data", componentData.componentName() + '/' + filename);
if ( !QFile::exists( xml_file ) )
xml_file = KStandardDirs::locate( "data", filename );
}
QFile file( xml_file );
if ( xml_file.isEmpty() || !file.open( QIODevice::ReadOnly ) )
{
kError(240) << "No such XML file" << filename;
return QString();
}
QByteArray buffer(file.readAll());
return QString::fromUtf8(buffer.constData(), buffer.size());
}
bool KXMLGUIFactory::saveConfigFile( const QDomDocument& doc,
const QString& filename, const KComponentData &_componentData )
{
KComponentData componentData = _componentData.isValid() ? _componentData : KGlobal::mainComponent();
QString xml_file(filename);
if (QDir::isRelativePath(xml_file))
xml_file = KStandardDirs::locateLocal("data", componentData.componentName() + '/' + filename);
QFile file( xml_file );
if ( xml_file.isEmpty() || !file.open( QIODevice::WriteOnly ) )
{
kError(240) << "Could not write to" << filename;
return false;
}
// write out our document
QTextStream ts(&file);
ts.setCodec( QTextCodec::codecForName( "UTF-8" ) );
ts << doc;
file.close();
return true;
}
/**
* Removes all QDomComment objects from the specified node and all its children.
*/
static void removeDOMComments( QDomNode &node )
{
QDomNode n = node.firstChild();
while ( !n.isNull() )
{
if ( n.nodeType() == QDomNode::CommentNode )
{
QDomNode tmp = n;
n = n.nextSibling();
node.removeChild( tmp );
}
else
{
QDomNode tmp = n;
n = n.nextSibling();
removeDOMComments( tmp );
}
}
}
KXMLGUIFactory::KXMLGUIFactory( KXMLGUIBuilder *builder, QObject *parent )
: QObject( parent ),d(new KXMLGUIFactoryPrivate)
{
d->builder = builder;
d->guiClient = 0;
if ( d->builder )
{
d->builderContainerTags = d->builder->containerTags();
d->builderCustomTags = d->builder->customTags();
}
}
KXMLGUIFactory::~KXMLGUIFactory()
{
foreach (KXMLGUIClient *client, d->m_clients) {
client->setFactory ( 0L );
}
delete d;
}
void KXMLGUIFactory::addClient( KXMLGUIClient *client )
{
//kDebug(260) << client;
if ( client->factory() ) {
if ( client->factory() == this )
return;
else
client->factory()->removeClient( client ); //just in case someone does stupid things ;-)
}
if (d->emptyState())
emit makingChanges(true);
d->pushState();
// QTime dt; dt.start();
d->guiClient = client;
// add this client to our client list
if ( !d->m_clients.contains( client ) )
d->m_clients.append( client );
else
kDebug(260) << "XMLGUI client already added " << client;
// Tell the client that plugging in is process and
// let it know what builder widget its mainwindow shortcuts
// should be attached to.
client->beginXMLPlug( d->builder->widget() );
// try to use the build document for building the client's GUI, as the build document
// contains the correct container state information (like toolbar positions, sizes, etc.) .
// if there is non available, then use the "real" document.
QDomDocument doc = client->xmlguiBuildDocument();
if ( doc.documentElement().isNull() )
doc = client->domDocument();
QDomElement docElement = doc.documentElement();
d->m_rootNode->index = -1;
// cache some variables
d->clientName = docElement.attribute( d->attrName );
d->clientBuilder = client->clientBuilder();
if ( d->clientBuilder )
{
d->clientBuilderContainerTags = d->clientBuilder->containerTags();
d->clientBuilderCustomTags = d->clientBuilder->customTags();
}
else
{
d->clientBuilderContainerTags.clear();
d->clientBuilderCustomTags.clear();
}
// load shortcut schemes, user-defined shortcuts and other action properties
d->saveDefaultActionProperties(client->actionCollection()->actions());
if (!doc.isNull())
d->refreshActionProperties(client, client->actionCollection()->actions(), doc);
BuildHelper( *d, d->m_rootNode ).build( docElement );
// let the client know that we built its GUI.
client->setFactory( this );
// call the finalizeGUI method, to fix up the positions of toolbars for example.
// ### FIXME : obey client builder
// --- Well, toolbars have a bool "positioned", so it doesn't really matter,
// if we call positionYourself on all of them each time. (David)
d->builder->finalizeGUI( d->guiClient );
// reset some variables, for safety
d->BuildState::reset();
client->endXMLPlug();
d->popState();
emit clientAdded( client );
// build child clients
foreach (KXMLGUIClient *child, client->childClients())
addClient( child );
if (d->emptyState())
emit makingChanges(false);
/*
QString unaddedActions;
foreach (KActionCollection* ac, KActionCollection::allCollections())
foreach (QAction* action, ac->actions())
if (action->associatedWidgets().isEmpty())
unaddedActions += action->objectName() + ' ';
if (!unaddedActions.isEmpty())
kWarning() << "The following actions are not plugged into the gui (shortcuts will not work): " << unaddedActions;
*/
// kDebug() << "addClient took " << dt.elapsed();
}
void KXMLGUIFactory::refreshActionProperties()
{
foreach (KXMLGUIClient *client, d->m_clients)
{
d->guiClient = client;
QDomDocument doc = client->xmlguiBuildDocument();
if ( doc.documentElement().isNull() )
{
client->reloadXML();
doc = client->domDocument();
}
d->refreshActionProperties(client, client->actionCollection()->actions(), doc);
}
d->guiClient = 0;
}
static QString currentShortcutScheme()
{
const KConfigGroup cg = KGlobal::config()->group("Shortcut Schemes");
return cg.readEntry("Current Scheme", "Default");
}
// Find the right ActionProperties element, otherwise return null element
static QDomElement findActionPropertiesElement(const QDomDocument& doc)
{
const QLatin1String tagActionProp("ActionProperties");
const QString schemeName = currentShortcutScheme();
QDomElement e = doc.documentElement().firstChildElement();
for( ; !e.isNull(); e = e.nextSiblingElement() ) {
if (QString::compare(e.tagName(), tagActionProp, Qt::CaseInsensitive) == 0
&& (e.attribute("scheme", "Default") == schemeName) ) {
return e;
}
}
return QDomElement();
}
void KXMLGUIFactoryPrivate::refreshActionProperties(KXMLGUIClient *client, const QList<QAction*>& actions, const QDomDocument& doc)
{
// try to find and apply shortcuts schemes
QDomDocument scheme = shortcutSchemeDoc(client);
applyShortcutScheme(client, actions, scheme);
// try to find and apply user-defined shortcuts
const QDomElement actionPropElement = findActionPropertiesElement(doc);
if ( !actionPropElement.isNull() )
applyActionProperties( actionPropElement );
}
void KXMLGUIFactoryPrivate::saveDefaultActionProperties(const QList<QAction *>& actions)
{
// This method is called every time the user activated a new
// kxmlguiclient. We only want to execute the following code only once in
// the lifetime of an action.
foreach (QAction *action, actions) {
// Skip NULL actions or those we have seen already.
if (!action || action->property("_k_DefaultShortcut").isValid()) continue;
if (KAction* kaction = qobject_cast<KAction*>(action)) {
// Check if the default shortcut is set
KShortcut defaultShortcut = kaction->shortcut(KAction::DefaultShortcut);
KShortcut activeShortcut = kaction->shortcut(KAction::ActiveShortcut);
//kDebug() << kaction->objectName() << "default=" << defaultShortcut.toString() << "active=" << activeShortcut.toString();
// Check if we have an empty default shortcut and an non empty
// custom shortcut. This should only happen if a developer called
// QAction::setShortcut on an KAction. Print out a warning and
// correct the mistake
if ((!activeShortcut.isEmpty()) && defaultShortcut.isEmpty()) {
kError(240) << "Shortcut for KAction " << kaction->objectName() << kaction->text() << "set with QShortcut::setShortcut()! See KAction documentation.";
kaction->setProperty("_k_DefaultShortcut", activeShortcut);
} else {
kaction->setProperty("_k_DefaultShortcut", defaultShortcut);
}
}
else
{
// A QAction used with KXMLGUI? Set our property and ignore it.
kError(240) << "Attempt to use QAction" << action->objectName() << "with KXMLGUIFactory!";
action->setProperty("_k_DefaultShortcut", KShortcut());
}
}
}
void KXMLGUIFactory::changeShortcutScheme(const QString &scheme)
{
kDebug(260) << "Changing shortcut scheme to" << scheme;
KConfigGroup cg = KGlobal::config()->group( "Shortcut Schemes" );
cg.writeEntry("Current Scheme", scheme);
refreshActionProperties();
}
void KXMLGUIFactory::forgetClient( KXMLGUIClient *client )
{
d->m_clients.removeAll( client );
}
void KXMLGUIFactory::removeClient( KXMLGUIClient *client )
{
//kDebug(260) << client;
// don't try to remove the client's GUI if we didn't build it
if ( !client || client->factory() != this )
return;
if (d->emptyState())
emit makingChanges(true);
// remove this client from our client list
d->m_clients.removeAll( client );
// remove child clients first (create a copy of the list just in case the
// original list is modified directly or indirectly in removeClient())
const QList<KXMLGUIClient*> childClients(client->childClients());
foreach (KXMLGUIClient *child, childClients)
removeClient(child);
//kDebug(260) << "calling removeRecursive";
d->pushState();
// cache some variables
d->guiClient = client;
d->clientName = client->domDocument().documentElement().attribute( d->attrName );
d->clientBuilder = client->clientBuilder();
client->setFactory( 0L );
// if we don't have a build document for that client, yet, then create one by
// cloning the original document, so that saving container information in the
// DOM tree does not touch the original document.
QDomDocument doc = client->xmlguiBuildDocument();
if ( doc.documentElement().isNull() )
{
doc = client->domDocument().cloneNode( true ).toDocument();
client->setXMLGUIBuildDocument( doc );
}
d->m_rootNode->destruct( doc.documentElement(), *d );
// reset some variables
d->BuildState::reset();
// This will destruct the KAccel object built around the given widget.
client->prepareXMLUnplug( d->builder->widget() );
d->popState();
if (d->emptyState())
emit makingChanges(false);
emit clientRemoved( client );
}
QList<KXMLGUIClient*> KXMLGUIFactory::clients() const
{
return d->m_clients;
}
QWidget *KXMLGUIFactory::container( const QString &containerName, KXMLGUIClient *client,
bool useTagName )
{
d->pushState();
d->m_containerName = containerName;
d->guiClient = client;
QWidget *result = d->findRecursive( d->m_rootNode, useTagName );
d->guiClient = 0L;
d->m_containerName.clear();
d->popState();
return result;
}
QList<QWidget*> KXMLGUIFactory::containers( const QString &tagName )
{
return d->findRecursive( d->m_rootNode, tagName );
}
void KXMLGUIFactory::reset()
{
d->m_rootNode->reset();
d->m_rootNode->clearChildren();
}
void KXMLGUIFactory::resetContainer( const QString &containerName, bool useTagName )
{
if ( containerName.isEmpty() )
return;
ContainerNode *container = d->m_rootNode->findContainer( containerName, useTagName );
if ( !container )
return;
ContainerNode *parent = container->parent;
if ( !parent )
return;
// resetInternal( container );
parent->removeChild( container );
}
QWidget *KXMLGUIFactoryPrivate::findRecursive( KXMLGUI::ContainerNode *node, bool tag )
{
if ( ( ( !tag && node->name == m_containerName ) ||
( tag && node->tagName == m_containerName ) ) &&
( !guiClient || node->client == guiClient ) )
return node->container;
foreach (ContainerNode* child, node->children)
{
QWidget *cont = findRecursive( child, tag );
if ( cont )
return cont;
}
return 0L;
}
// Case insensitive equality without calling toLower which allocates a new string
static inline bool equals(const QString& str1, const char* str2)
{
return str1.compare(QLatin1String(str2), Qt::CaseInsensitive) == 0;
}
static inline bool equals(const QString& str1, const QString& str2)
{
return str1.compare(str2, Qt::CaseInsensitive) == 0;
}
QList<QWidget*> KXMLGUIFactoryPrivate::findRecursive( KXMLGUI::ContainerNode *node,
const QString &tagName )
{
QList<QWidget*> res;
if ( equals(node->tagName, tagName) )
res.append( node->container );
foreach (KXMLGUI::ContainerNode* child, node->children)
res << findRecursive( child, tagName );
return res;
}
void KXMLGUIFactory::plugActionList( KXMLGUIClient *client, const QString &name,
const QList<QAction*> &actionList )
{
d->pushState();
d->guiClient = client;
d->actionListName = name;
d->actionList = actionList;
d->clientName = client->domDocument().documentElement().attribute( d->attrName );
d->m_rootNode->plugActionList( *d );
// Load shortcuts for these new actions
d->saveDefaultActionProperties(actionList);
d->refreshActionProperties(client, actionList, client->domDocument());
d->BuildState::reset();
d->popState();
}
void KXMLGUIFactory::unplugActionList( KXMLGUIClient *client, const QString &name )
{
d->pushState();
d->guiClient = client;
d->actionListName = name;
d->clientName = client->domDocument().documentElement().attribute( d->attrName );
d->m_rootNode->unplugActionList( *d );
d->BuildState::reset();
d->popState();
}
void KXMLGUIFactoryPrivate::applyActionProperties( const QDomElement &actionPropElement,
ShortcutOption shortcutOption )
{
for (QDomElement e = actionPropElement.firstChildElement();
!e.isNull(); e = e.nextSiblingElement()) {
if ( !equals(e.tagName(), "action") )
continue;
QAction *action = guiClient->action( e );
if ( !action )
continue;
configureAction( action, e.attributes(), shortcutOption );
}
}
void KXMLGUIFactoryPrivate::configureAction( QAction *action, const QDomNamedNodeMap &attributes,
ShortcutOption shortcutOption )
{
for ( uint i = 0; i < attributes.length(); i++ )
{
QDomAttr attr = attributes.item( i ).toAttr();
if ( attr.isNull() )
continue;
configureAction( action, attr, shortcutOption );
}
}
void KXMLGUIFactoryPrivate::configureAction( QAction *action, const QDomAttr &attribute,
ShortcutOption shortcutOption )
{
static const QString &attrShortcut = KGlobal::staticQString( "shortcut" );
QString attrName = attribute.name();
// If the attribute is a deprecated "accel", change to "shortcut".
if ( equals(attrName, "accel") )
attrName = attrShortcut;
// No need to re-set name, particularly since it's "objectName" in Qt4
if ( equals(attrName, "name") )
return;
if ( equals(attrName, "icon") ) {
action->setIcon( KIcon( attribute.value() ) );
return;
}
QVariant propertyValue;
QVariant::Type propertyType = action->property( attrName.toLatin1() ).type();
if ( propertyType == QVariant::Int ) {
propertyValue = QVariant( attribute.value().toInt() );
} else if ( propertyType == QVariant::UInt ) {
propertyValue = QVariant( attribute.value().toUInt() );
} else if ( propertyType == QVariant::UserType && action->property( attrName.toLatin1() ).userType() == qMetaTypeId<KShortcut>() ) {
// Setting the shortcut by property also sets the default shortcut (which is incorrect), so we have to do it directly
if (KAction* ka = qobject_cast<KAction*>(action)) {
if (attrName=="globalShortcut") {
ka->setGlobalShortcut(KShortcut(attribute.value()), KAction::ActiveShortcut);
} else {
ka->setShortcut(KShortcut(attribute.value()), KAction::ActiveShortcut);
}
if (shortcutOption & KXMLGUIFactoryPrivate::SetDefaultShortcut)
ka->setShortcut(KShortcut(attribute.value()), KAction::DefaultShortcut);
return;
}
propertyValue = KShortcut( attribute.value() );
} else {
propertyValue = QVariant( attribute.value() );
}
if (!action->setProperty( attrName.toLatin1(), propertyValue )) {
kWarning() << "Error: Unknown action property " << attrName << " will be ignored!";
}
}
QDomDocument KXMLGUIFactoryPrivate::shortcutSchemeDoc(KXMLGUIClient *client)
{
// Get the name of the current shorcut scheme
KConfigGroup cg = KGlobal::config()->group( "Shortcut Schemes" );
QString schemeName = cg.readEntry("Current Scheme", "Default");
QDomDocument doc;
if (schemeName != "Default")
{
// Find the document for the shortcut scheme using both current application path
// and current xmlguiclient path but making a preference to app path
QString schemeFileName = KStandardDirs::locateLocal("data",
client->componentData().componentName() + '/' +
client->componentData().componentName() + schemeName.toLower() + "shortcuts.rc" );
QFile schemeFile(schemeFileName);
if (schemeFile.open(QIODevice::ReadOnly))
{
// kDebug(260) << "Found shortcut scheme" << schemeFileName;
doc.setContent(&schemeFile);
schemeFile.close();
}
}
return doc;
}
void KXMLGUIFactoryPrivate::applyShortcutScheme(KXMLGUIClient *client, const QList<QAction*> &actions, const QDomDocument& scheme)
{
static const QString &actionPropElementName = KGlobal::staticQString( "ActionProperties" );
KConfigGroup cg = KGlobal::config()->group( "Shortcut Schemes" );
QString schemeName = cg.readEntry("Current Scheme", "Default");
//First clear all existing shortcuts
if (schemeName != "Default") {
foreach (QAction *action, actions) {
if (KAction *kaction = qobject_cast<KAction*>(action)) {
kaction->setShortcut(KShortcut(), KAction::ActiveShortcut);
// We clear the default shortcut as well because the shortcut scheme will set its own defaults
kaction->setShortcut(KShortcut(), KAction::DefaultShortcut);
continue;
}
if (action) {
action->setProperty("shortcut", KShortcut());
}
}
} else {
// apply saved default shortcuts
foreach (QAction *action, actions) {
if (KAction *kaction = qobject_cast<KAction*>(action)) {
QVariant savedDefaultShortcut = kaction->property("_k_DefaultShortcut");
if (savedDefaultShortcut.isValid()) {
KShortcut shortcut = savedDefaultShortcut.value<KShortcut>();
//kDebug() << "scheme said" << shortcut.toString() << "for action" << kaction->objectName();
kaction->setShortcut(shortcut, KAction::ActiveShortcut);
kaction->setShortcut(shortcut, KAction::DefaultShortcut);
continue;
}
}
if (action) {
action->setProperty("shortcut", KShortcut());
}
}
}
if (scheme.isNull())
return;
QDomElement docElement = scheme.documentElement();
QDomElement actionPropElement = docElement.namedItem( actionPropElementName ).toElement();
//Check if we really have the shortcut configuration here
if (!actionPropElement.isNull()) {
kDebug(260) << "Applying shortcut scheme for XMLGUI client" << client->componentData().componentName();
//Apply all shortcuts we have
applyActionProperties(actionPropElement, KXMLGUIFactoryPrivate::SetDefaultShortcut);
} else {
kDebug(260) << "Invalid shortcut scheme file";
}
}
int KXMLGUIFactory::configureShortcuts(bool letterCutsOk , bool bSaveSettings )
{
KShortcutsDialog dlg(KShortcutsEditor::AllActions,
letterCutsOk ? KShortcutsEditor::LetterShortcutsAllowed : KShortcutsEditor::LetterShortcutsDisallowed,
qobject_cast<QWidget*>(parent()));
foreach (KXMLGUIClient *client, d->m_clients) {
if(client) {
dlg.addCollection(client->actionCollection());
}
}
return dlg.configure(bSaveSettings);
}
// Find or create
QDomElement KXMLGUIFactory::actionPropertiesElement( QDomDocument& doc )
{
// first, lets see if we have existing properties
QDomElement elem = findActionPropertiesElement(doc);
// if there was none, create one
if(elem.isNull()) {
elem = doc.createElement(QLatin1String("ActionProperties"));
elem.setAttribute("scheme", currentShortcutScheme());
doc.documentElement().appendChild( elem );
}
return elem;
}
QDomElement KXMLGUIFactory::findActionByName( QDomElement& elem, const QString& sName, bool create )
{
static const QString& attrName = KGlobal::staticQString( "name" );
static const QString& tagAction = KGlobal::staticQString( "Action" );
for( QDomNode it = elem.firstChild(); !it.isNull(); it = it.nextSibling() ) {
QDomElement e = it.toElement();
if( e.attribute( attrName ) == sName )
return e;
}
if( create ) {
QDomElement act_elem = elem.ownerDocument().createElement( tagAction );
act_elem.setAttribute( attrName, sName );
elem.appendChild( act_elem );
return act_elem;
}
return QDomElement();
}
/* vim: et sw=4
*/
diff --git a/kdewebkit/kwebpage.cpp b/kdewebkit/kwebpage.cpp
index 1c925ccd45..d51d164176 100644
--- a/kdewebkit/kwebpage.cpp
+++ b/kdewebkit/kwebpage.cpp
@@ -1,562 +1,563 @@
/*
* This file is part of the KDE project.
*
* Copyright (C) 2008 Dirk Mueller <mueller@kde.org>
* Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
* Copyright (C) 2008 Michael Howell <mhowell123@gmail.com>
* Copyright (C) 2009,2010 Dawit Alemayehu <adawit@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 as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* 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.
*
*/
// Own
#include "kwebpage.h"
#include "kwebwallet.h"
// Local
#include "kwebpluginfactory.h"
// KDE
+#include <kicon.h>
#include <kaction.h>
#include <kfiledialog.h>
#include <kprotocolmanager.h>
#include <kjobuidelegate.h>
#include <krun.h>
#include <kstandarddirs.h>
#include <kstandardshortcut.h>
#include <kurl.h>
#include <kdebug.h>
#include <kshell.h>
#include <kmimetypetrader.h>
#include <klocalizedstring.h>
#include <kio/accessmanager.h>
#include <kio/job.h>
#include <kio/copyjob.h>
#include <kio/jobuidelegate.h>
#include <kio/renamedialog.h>
#include <kparts/browseropenorsavequestion.h>
// Qt
#include <QtCore/QPointer>
#include <QtCore/QFileInfo>
#include <QtCore/QCoreApplication>
#include <QtWebKit/QWebFrame>
#include <QtNetwork/QNetworkReply>
#include <qtemporaryfile.h>
#define QL1S(x) QLatin1String(x)
#define QL1C(x) QLatin1Char(x)
static void reloadRequestWithoutDisposition (QNetworkReply* reply)
{
QNetworkRequest req (reply->request());
req.setRawHeader("x-kdewebkit-ignore-disposition", "true");
QWebFrame* frame = qobject_cast<QWebFrame*> (req.originatingObject());
if (!frame)
return;
frame->load(req);
}
static bool isMimeTypeAssociatedWithSelf(const KService::Ptr &offer)
{
if (!offer)
return false;
kDebug(800) << offer->desktopEntryName();
const QString& appName = QCoreApplication::applicationName();
if (appName == offer->desktopEntryName() || offer->exec().trimmed().startsWith(appName))
return true;
// konqueror exception since it uses kfmclient to open html content...
if (appName == QL1S("konqueror") && offer->exec().trimmed().startsWith(QL1S("kfmclient")))
return true;
return false;
}
static void extractMimeType(const QNetworkReply* reply, QString& mimeType)
{
mimeType.clear();
const KIO::MetaData& metaData = reply->attribute(static_cast<QNetworkRequest::Attribute>(KIO::AccessManager::MetaData)).toMap();
if (metaData.contains(QL1S("content-type")))
mimeType = metaData.value(QL1S("content-type"));
if (!mimeType.isEmpty())
return;
if (!reply->hasRawHeader("Content-Type"))
return;
const QString value (QL1S(reply->rawHeader("Content-Type").simplified().constData()));
const int index = value.indexOf(QL1C(';'));
mimeType = ((index == -1) ? value : value.left(index));
}
static bool downloadResource (const KUrl& srcUrl, const QString& suggestedName = QString(),
QWidget* parent = 0, const KIO::MetaData& metaData = KIO::MetaData())
{
const QString fileName = suggestedName.isEmpty() ? srcUrl.fileName() : suggestedName;
// convert filename to URL using fromPath to avoid trouble with ':' in filenames (#184202)
KUrl destUrl = KFileDialog::getSaveFileName(KUrl::fromPath(fileName), QString(), parent);
if (!destUrl.isValid())
return false;
// Using KIO::copy rather than file_copy, to benefit from "dest already exists" dialogs.
KIO::Job *job = KIO::copy(srcUrl, destUrl);
if (!metaData.isEmpty())
job->setMetaData(metaData);
job->addMetaData(QL1S("MaxCacheSize"), QL1S("0")); // Don't store in http cache.
job->addMetaData(QL1S("cache"), QL1S("cache")); // Use entry from cache if available.
job->ui()->setWindow((parent ? parent->window() : 0));
job->ui()->setAutoErrorHandlingEnabled(true);
return true;
}
static bool isReplyStatusOk(const QNetworkReply* reply)
{
if (!reply || reply->error() != QNetworkReply::NoError)
return false;
// Check HTTP status code only for http and webdav protocols...
const QString scheme = reply->url().scheme();
if (scheme.startsWith(QLatin1String("http"), Qt::CaseInsensitive) ||
scheme.startsWith(QLatin1String("webdav"), Qt::CaseInsensitive)) {
bool ok = false;
const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(&ok);
if (!ok || statusCode < 200 || statusCode > 299)
return false;
}
return true;
}
class KWebPage::KWebPagePrivate
{
public:
KWebPagePrivate() : inPrivateBrowsingMode(false) {}
void _k_copyResultToTempFile(KJob * job)
{
if ( job->error() ) {
job->uiDelegate()->showErrorMessage();
return;
}
// Same as KRun::foundMimeType but with a different URL
(void)KRun::runUrl(static_cast<KIO::FileCopyJob *>(job)->destUrl(), mimeType, window);
}
QPointer<QWidget> window;
QString mimeType;
QPointer<KWebWallet> wallet;
bool inPrivateBrowsingMode;
};
static void setActionIcon(QAction* action, const QIcon& icon)
{
if (action) {
action->setIcon(icon);
}
}
static void setActionShortcut(QAction* action, const KShortcut& shortcut)
{
if (action) {
action->setShortcuts(shortcut.toList());
}
}
KWebPage::KWebPage(QObject *parent, Integration flags)
:QWebPage(parent), d(new KWebPagePrivate)
{
// KDE KParts integration for <embed> tag...
if (!flags || (flags & KPartsIntegration))
setPluginFactory(new KWebPluginFactory(this));
QWidget *parentWidget = qobject_cast<QWidget*>(parent);
QWidget *window = parentWidget ? parentWidget->window() : 0;
// KDE IO (KIO) integration...
if (!flags || (flags & KIOIntegration)) {
KIO::Integration::AccessManager *manager = new KIO::Integration::AccessManager(this);
// Disable QtWebKit's internal cache to avoid duplication with the one in KIO...
manager->setCache(0);
manager->setWindow(window);
manager->setEmitReadyReadOnMetaDataChange(true);
setNetworkAccessManager(manager);
}
// KWallet integration...
if (!flags || (flags & KWalletIntegration)) {
setWallet(new KWebWallet(0, (window ? window->winId() : 0) ));
}
setActionIcon(action(Back), KIcon("go-previous"));
setActionIcon(action(Forward), KIcon("go-next"));
setActionIcon(action(Reload), KIcon("view-refresh"));
setActionIcon(action(Stop), KIcon("process-stop"));
setActionIcon(action(Cut), KIcon("edit-cut"));
setActionIcon(action(Copy), KIcon("edit-copy"));
setActionIcon(action(Paste), KIcon("edit-paste"));
setActionIcon(action(Undo), KIcon("edit-undo"));
setActionIcon(action(Redo), KIcon("edit-redo"));
setActionIcon(action(InspectElement), KIcon("view-process-all"));
setActionIcon(action(OpenLinkInNewWindow), KIcon("window-new"));
setActionIcon(action(OpenFrameInNewWindow), KIcon("window-new"));
setActionIcon(action(OpenImageInNewWindow), KIcon("window-new"));
setActionIcon(action(CopyLinkToClipboard), KIcon("edit-copy"));
setActionIcon(action(CopyImageToClipboard), KIcon("edit-copy"));
setActionIcon(action(ToggleBold), KIcon("format-text-bold"));
setActionIcon(action(ToggleItalic), KIcon("format-text-italic"));
setActionIcon(action(ToggleUnderline), KIcon("format-text-underline"));
setActionIcon(action(DownloadLinkToDisk), KIcon("document-save"));
setActionIcon(action(DownloadImageToDisk), KIcon("document-save"));
settings()->setWebGraphic(QWebSettings::MissingPluginGraphic, KIcon("preferences-plugin").pixmap(32, 32));
settings()->setWebGraphic(QWebSettings::MissingImageGraphic, KIcon("image-missing").pixmap(32, 32));
settings()->setWebGraphic(QWebSettings::DefaultFrameIconGraphic, KIcon("applications-internet").pixmap(32, 32));
setActionShortcut(action(Back), KStandardShortcut::back());
setActionShortcut(action(Forward), KStandardShortcut::forward());
setActionShortcut(action(Reload), KStandardShortcut::reload());
setActionShortcut(action(Stop), KShortcut(QKeySequence(Qt::Key_Escape)));
setActionShortcut(action(Cut), KStandardShortcut::cut());
setActionShortcut(action(Copy), KStandardShortcut::copy());
setActionShortcut(action(Paste), KStandardShortcut::paste());
setActionShortcut(action(Undo), KStandardShortcut::undo());
setActionShortcut(action(Redo), KStandardShortcut::redo());
setActionShortcut(action(SelectAll), KStandardShortcut::selectAll());
}
KWebPage::~KWebPage()
{
delete d;
}
bool KWebPage::isExternalContentAllowed() const
{
KIO::AccessManager *manager = qobject_cast<KIO::AccessManager*>(networkAccessManager());
if (manager)
return manager->isExternalContentAllowed();
return true;
}
KWebWallet *KWebPage::wallet() const
{
return d->wallet;
}
void KWebPage::setAllowExternalContent(bool allow)
{
KIO::AccessManager *manager = qobject_cast<KIO::AccessManager*>(networkAccessManager());
if (manager)
manager->setExternalContentAllowed(allow);
}
void KWebPage::setWallet(KWebWallet* wallet)
{
// Delete the current wallet if this object is its parent...
if (d->wallet && this == d->wallet->parent())
delete d->wallet;
d->wallet = wallet;
if (d->wallet)
d->wallet->setParent(this);
}
void KWebPage::downloadRequest(const QNetworkRequest &request)
{
downloadResource(request.url(), QString(), view(),
request.attribute(static_cast<QNetworkRequest::Attribute>(KIO::AccessManager::MetaData)).toMap());
}
void KWebPage::downloadUrl(const KUrl &url)
{
downloadResource(url, QString(), view());
}
void KWebPage::downloadResponse(QNetworkReply *reply)
{
Q_ASSERT(reply);
if (!reply)
return;
// Put the job on hold only for the protocols we know about (read: http).
KIO::Integration::AccessManager::putReplyOnHold(reply);
QString mimeType;
KIO::MetaData metaData;
if (handleReply(reply, &mimeType, &metaData)) {
return;
}
const KUrl replyUrl (reply->url());
QWidget* topLevelWindow = view() ? view()->window() : 0;
// Ask KRun to handle the response when mimetype is unknown
if (mimeType.isEmpty()) {
(void)new KRun(replyUrl, topLevelWindow, 0 , replyUrl.isLocalFile());
return;
}
// Ask KRun::runUrl to handle the response when mimetype is inode/*
if (mimeType.startsWith(QL1S("inode/"), Qt::CaseInsensitive) &&
KRun::runUrl(replyUrl, mimeType, topLevelWindow, false, false,
metaData.value(QL1S("content-disposition-filename")))) {
return;
}
}
QString KWebPage::sessionMetaData(const QString &key) const
{
QString value;
KIO::Integration::AccessManager *manager = qobject_cast<KIO::Integration::AccessManager *>(networkAccessManager());
if (manager)
value = manager->sessionMetaData().value(key);
return value;
}
QString KWebPage::requestMetaData(const QString &key) const
{
QString value;
KIO::Integration::AccessManager *manager = qobject_cast<KIO::Integration::AccessManager *>(networkAccessManager());
if (manager)
value = manager->requestMetaData().value(key);
return value;
}
void KWebPage::setSessionMetaData(const QString &key, const QString &value)
{
KIO::Integration::AccessManager *manager = qobject_cast<KIO::Integration::AccessManager *>(networkAccessManager());
if (manager)
manager->sessionMetaData()[key] = value;
}
void KWebPage::setRequestMetaData(const QString &key, const QString &value)
{
KIO::Integration::AccessManager *manager = qobject_cast<KIO::Integration::AccessManager *>(networkAccessManager());
if (manager)
manager->requestMetaData()[key] = value;
}
void KWebPage::removeSessionMetaData(const QString &key)
{
KIO::Integration::AccessManager *manager = qobject_cast<KIO::Integration::AccessManager *>(networkAccessManager());
if (manager)
manager->sessionMetaData().remove(key);
}
void KWebPage::removeRequestMetaData(const QString &key)
{
KIO::Integration::AccessManager *manager = qobject_cast<KIO::Integration::AccessManager *>(networkAccessManager());
if (manager)
manager->requestMetaData().remove(key);
}
QString KWebPage::userAgentForUrl(const QUrl& _url) const
{
const KUrl url(_url);
const QString userAgent = KProtocolManager::userAgentForHost((url.isLocalFile() ? QL1S("localhost") : url.host()));
if (userAgent == KProtocolManager::defaultUserAgent())
return QWebPage::userAgentForUrl(_url);
return userAgent;
}
static void setDisableCookieJarStorage(QNetworkAccessManager* manager, bool status)
{
if (manager) {
KIO::Integration::CookieJar *cookieJar = manager ? qobject_cast<KIO::Integration::CookieJar*>(manager->cookieJar()) : 0;
if (cookieJar) {
//kDebug(800) << "Store cookies ?" << !status;
cookieJar->setDisableCookieStorage(status);
}
}
}
bool KWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type)
{
kDebug(800) << "url:" << request.url() << ", type:" << type << ", frame:" << frame;
if (frame && d->wallet && type == QWebPage::NavigationTypeFormSubmitted)
d->wallet->saveFormData(frame);
// Make sure nothing is cached when private browsing mode is enabled...
if (settings()->testAttribute(QWebSettings::PrivateBrowsingEnabled)) {
if (!d->inPrivateBrowsingMode) {
setDisableCookieJarStorage(networkAccessManager(), true);
setSessionMetaData(QL1S("no-cache"), QL1S("true"));
d->inPrivateBrowsingMode = true;
}
} else {
if (d->inPrivateBrowsingMode) {
setDisableCookieJarStorage(networkAccessManager(), false);
removeSessionMetaData(QL1S("no-cache"));
d->inPrivateBrowsingMode = false;
}
}
/*
If the navigation request is from the main frame, set the cross-domain
meta-data value to the current url for proper integration with KCookieJar...
*/
if (frame == mainFrame() && type != QWebPage::NavigationTypeReload)
setSessionMetaData(QL1S("cross-domain"), request.url().toString());
return QWebPage::acceptNavigationRequest(frame, request, type);
}
bool KWebPage::handleReply(QNetworkReply* reply, QString* contentType, KIO::MetaData* metaData)
{
// Reply url...
const KUrl replyUrl (reply->url());
// Get the top level window...
QWidget* topLevelWindow = view() ? view()->window() : 0;
// Get suggested file name...
const KIO::MetaData& data = reply->attribute(static_cast<QNetworkRequest::Attribute>(KIO::AccessManager::MetaData)).toMap();
const QString suggestedFileName = data.value(QL1S("content-disposition-filename"));
if (metaData) {
*metaData = data;
}
// Get the mime-type...
QString mimeType;
extractMimeType(reply, mimeType);
if (contentType) {
*contentType = mimeType;
}
// Let the calling function deal with handling empty or inode/* mimetypes...
if (mimeType.isEmpty() || mimeType.startsWith(QL1S("inode/"), Qt::CaseInsensitive)) {
return false;
}
// Convert executable text files to plain text...
if (KParts::BrowserRun::isTextExecutable(mimeType))
mimeType = QL1S("text/plain");
//kDebug(800) << "Content-disposition:" << suggestedFileName;
//kDebug(800) << "Got unsupported content of type:" << mimeType << "URL:" << replyUrl;
//kDebug(800) << "Error code:" << reply->error() << reply->errorString();
if (isReplyStatusOk(reply)) {
KParts::BrowserOpenOrSaveQuestion::Result result;
KParts::BrowserOpenOrSaveQuestion dlg(topLevelWindow, replyUrl, mimeType);
dlg.setSuggestedFileName(suggestedFileName);
dlg.setFeatures(KParts::BrowserOpenOrSaveQuestion::ServiceSelection);
result = dlg.askOpenOrSave();
switch (result) {
case KParts::BrowserOpenOrSaveQuestion::Open:
// Handle Post operations that return content...
if (reply->operation() == QNetworkAccessManager::PostOperation) {
d->mimeType = mimeType;
d->window = topLevelWindow;
QFileInfo finfo (suggestedFileName.isEmpty() ? replyUrl.fileName() : suggestedFileName);
QTemporaryFile tempFile(QDir::tempPath() + QLatin1String("/kwebpage_XXXXXX.") + finfo.suffix());
tempFile.setAutoRemove(false);
tempFile.open();
KUrl destUrl;
destUrl.setPath(tempFile.fileName());
KIO::Job *job = KIO::file_copy(replyUrl, destUrl, 0600, KIO::Overwrite);
job->ui()->setWindow(topLevelWindow);
job->ui()->setAutoErrorHandlingEnabled(true);
connect(job, SIGNAL(result(KJob *)),
this, SLOT(_k_copyResultToTempFile(KJob*)));
return true;
}
// Ask before running any executables...
if (KParts::BrowserRun::allowExecution(mimeType, replyUrl)) {
KService::Ptr offer = dlg.selectedService();
// HACK: The check below is necessary to break an infinite
// recursion that occurs whenever this function is called as a result
// of receiving content that can be rendered by the app using this engine.
// For example a text/html header that containing a content-disposition
// header is received by the app using this class.
if (isMimeTypeAssociatedWithSelf(offer)) {
reloadRequestWithoutDisposition(reply);
} else {
KUrl::List list;
list.append(replyUrl);
bool success = false;
// kDebug(800) << "Suggested file name:" << suggestedFileName;
if (offer) {
success = KRun::run(*offer, list, topLevelWindow , false, suggestedFileName);
} else {
success = KRun::displayOpenWithDialog(list, topLevelWindow, false, suggestedFileName);
}
// For non KIO apps and cancelled Open With dialog, remove slave on hold.
if (!success || (offer && !offer->categories().contains(QL1S("KDE")))) {
KIO::SimpleJob::removeOnHold(); // Remove any slave-on-hold...
}
}
return true;
}
// TODO: Instead of silently failing when allowExecution fails, notify
// the user why the requested action cannot be fulfilled...
break;
case KParts::BrowserOpenOrSaveQuestion::Save:
// Do not download local files...
if (!replyUrl.isLocalFile()) {
QString downloadCmd (reply->property("DownloadManagerExe").toString());
if (!downloadCmd.isEmpty()) {
downloadCmd += QLatin1Char(' ');
downloadCmd += KShell::quoteArg(replyUrl.url());
if (!suggestedFileName.isEmpty()) {
downloadCmd += QLatin1Char(' ');
downloadCmd += KShell::quoteArg(suggestedFileName);
}
// kDebug(800) << "download command:" << downloadCmd;
if (KRun::runCommand(downloadCmd, view()))
return true;
}
return downloadResource(replyUrl, suggestedFileName, topLevelWindow);
}
return true;
case KParts::BrowserOpenOrSaveQuestion::Cancel:
default:
return true;
}
} else {
KService::Ptr offer = KMimeTypeTrader::self()->preferredService(mimeType);
if (isMimeTypeAssociatedWithSelf(offer)) {
reloadRequestWithoutDisposition(reply);
return true;
}
}
return false;
}
#include "moc_kwebpage.cpp"
diff --git a/kio/bookmarks/kbookmarkmenu_p.h b/kio/bookmarks/kbookmarkmenu_p.h
index 67e9730006..37ecd12494 100644
--- a/kio/bookmarks/kbookmarkmenu_p.h
+++ b/kio/bookmarks/kbookmarkmenu_p.h
@@ -1,131 +1,131 @@
// -*- c-basic-offset:4; indent-tabs-mode:nil -*-
// vim: set ts=4 sts=4 sw=4 et:
/* This file is part of the KDE project
Copyright (C) 2003 Alexander Kellett <lypanov@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 as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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.
*/
#ifndef __kbookmarkmenu_p_h__
#define __kbookmarkmenu_p_h__
#include <QtCore/QObject>
#include <kdialog.h>
#include <kicon.h>
#include <klocale.h>
#include <kaction.h>
#include <kactionmenu.h>
#include <QBoxLayout>
#include <QTreeWidget>
#include <QLabel>
#include "kbookmark.h"
#include "kbookmarkimporter.h"
#include "kbookmarkmanager.h"
class QString;
class QPushButton;
class KLineEdit;
class KBookmark;
class KBookmarkGroup;
class KAction;
class KActionMenu;
class KActionCollection;
class KBookmarkOwner;
class KBookmarkMenu;
class KImportedBookmarkMenu : public KBookmarkMenu
{
friend class KBookmarkMenuImporter;
Q_OBJECT
public:
//TODO simplfy
KImportedBookmarkMenu( KBookmarkManager* mgr,
KBookmarkOwner * owner, KMenu * parentMenu,
const QString & type, const QString & location );
KImportedBookmarkMenu( KBookmarkManager* mgr,
KBookmarkOwner * owner, KMenu * parentMenu);
~KImportedBookmarkMenu();
virtual void clear();
virtual void refill();
protected Q_SLOTS:
void slotNSLoad();
private:
QString m_type;
QString m_location;
};
class KBookmarkTreeItem : public QTreeWidgetItem
{
public:
KBookmarkTreeItem(QTreeWidget * tree);
KBookmarkTreeItem(QTreeWidgetItem * parent, QTreeWidget * tree, const KBookmarkGroup &bk);
~KBookmarkTreeItem();
QString address();
private:
QString m_address;
};
class KBookmarkSettings
{
public:
bool m_advancedaddbookmark;
bool m_contextmenu;
static KBookmarkSettings *s_self;
static void readSettings();
static KBookmarkSettings *self();
};
/**
* A class connected to KNSBookmarkImporter, to fill KActionMenus.
*/
class KBookmarkMenuImporter : public QObject
{
Q_OBJECT
public:
KBookmarkMenuImporter( KBookmarkManager* mgr, KImportedBookmarkMenu * menu ) :
m_menu(menu), m_pManager(mgr) {}
void openBookmarks( const QString &location, const QString &type );
void connectToImporter( const QObject &importer );
protected Q_SLOTS:
void newBookmark( const QString & text, const QString & url, const QString & );
void newFolder( const QString & text, bool, const QString & );
void newSeparator();
void endFolder();
protected:
QStack<KImportedBookmarkMenu*> mstack;
KImportedBookmarkMenu * m_menu;
KBookmarkManager* m_pManager;
};
class KImportedBookmarkActionMenu : public KActionMenu, public KBookmarkActionInterface
{
public:
- KImportedBookmarkActionMenu(const KIcon &icon, const QString &text, QObject *parent)
+ KImportedBookmarkActionMenu(const QIcon &icon, const QString &text, QObject *parent)
: KActionMenu(icon, text, parent),
KBookmarkActionInterface(KBookmark())
{
}
~KImportedBookmarkActionMenu()
{}
};
#endif
diff --git a/kio/kfile/kurlcombobox.cpp b/kio/kfile/kurlcombobox.cpp
index 4e6cdf48cd..6e0f51b5bf 100644
--- a/kio/kfile/kurlcombobox.cpp
+++ b/kio/kfile/kurlcombobox.cpp
@@ -1,448 +1,448 @@
/* This file is part of the KDE libraries
Copyright (C) 2000,2001 Carsten Pfeiffer <pfeiffer@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 "kurlcombobox.h"
#include <QtCore/QDir>
#include <QMouseEvent>
#include <QDrag>
#include <QMimeData>
#include <kdebug.h>
#include <kglobalsettings.h>
#include <kicon.h>
#include <klocale.h>
#include <kmimetype.h>
#include <kiconloader.h>
class KUrlComboBox::KUrlComboBoxPrivate
{
public:
KUrlComboBoxPrivate(KUrlComboBox *parent)
: m_parent(parent),
dirIcon(QLatin1String("folder"))
{}
~KUrlComboBoxPrivate()
{
qDeleteAll( itemList );
qDeleteAll( defaultList );
}
typedef struct {
QString text;
KUrl url;
QIcon icon;
} KUrlComboItem;
void init( Mode mode );
void insertUrlItem( const KUrlComboItem * );
QIcon getIcon( const KUrl& url ) const;
void updateItem( const KUrlComboItem *item, int index, const QIcon& icon );
void _k_slotActivated( int );
KUrlComboBox *m_parent;
- KIcon dirIcon;
+ QIcon dirIcon;
bool urlAdded;
int myMaximum;
Mode myMode; // can be used as parameter to KUR::path( int ) or url( int )
// to specify if we want a trailing slash or not
QPoint m_dragPoint;
QList<const KUrlComboItem*> itemList;
QList<const KUrlComboItem*> defaultList;
QMap<int,const KUrlComboItem*> itemMapper;
QIcon opendirIcon;
};
KUrlComboBox::KUrlComboBox( Mode mode, QWidget *parent)
: KComboBox( parent),d(new KUrlComboBoxPrivate(this))
{
d->init( mode );
}
KUrlComboBox::KUrlComboBox( Mode mode, bool rw, QWidget *parent)
: KComboBox( rw, parent),d(new KUrlComboBoxPrivate(this))
{
d->init( mode );
}
KUrlComboBox::~KUrlComboBox()
{
delete d;
}
void KUrlComboBox::KUrlComboBoxPrivate::init( Mode mode )
{
myMode = mode;
urlAdded = false;
myMaximum = 10; // default
m_parent->setInsertPolicy( NoInsert );
m_parent->setTrapReturnKey( true );
m_parent->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ));
m_parent->setLayoutDirection( Qt::LeftToRight );
if ( m_parent->completionObject() ) {
m_parent->completionObject()->setOrder( KCompletion::Sorted );
}
opendirIcon = KIcon(QLatin1String("folder-open"));
m_parent->connect( m_parent, SIGNAL( activated( int )), SLOT( _k_slotActivated( int )));
}
QStringList KUrlComboBox::urls() const
{
kDebug(250) << "::urls()";
//static const QString &fileProt = KGlobal::staticQString("file:");
QStringList list;
QString url;
for ( int i = d->defaultList.count(); i < count(); i++ ) {
url = itemText( i );
if ( !url.isEmpty() ) {
//if ( url.at(0) == '/' )
// list.append( url.prepend( fileProt ) );
//else
list.append( url );
}
}
return list;
}
void KUrlComboBox::addDefaultUrl( const KUrl& url, const QString& text )
{
addDefaultUrl( url, d->getIcon( url ), text );
}
void KUrlComboBox::addDefaultUrl( const KUrl& url, const QIcon& icon,
const QString& text )
{
KUrlComboBoxPrivate::KUrlComboItem *item = new KUrlComboBoxPrivate::KUrlComboItem;
item->url = url;
item->icon = icon;
if ( text.isEmpty() )
item->text = url.pathOrUrl(d->myMode == Directories
? KUrl::AddTrailingSlash
: KUrl::RemoveTrailingSlash);
else
item->text = text;
d->defaultList.append( item );
}
void KUrlComboBox::setDefaults()
{
clear();
d->itemMapper.clear();
const KUrlComboBoxPrivate::KUrlComboItem *item;
for ( int id = 0; id < d->defaultList.count(); id++ ) {
item = d->defaultList.at( id );
d->insertUrlItem( item );
}
}
void KUrlComboBox::setUrls( const QStringList &urls )
{
setUrls( urls, RemoveBottom );
}
void KUrlComboBox::setUrls( const QStringList &_urls, OverLoadResolving remove )
{
setDefaults();
qDeleteAll( d->itemList );
d->itemList.clear();
d->urlAdded = false;
if ( _urls.isEmpty() )
return;
QStringList urls;
QStringList::ConstIterator it = _urls.constBegin();
// kill duplicates
while ( it != _urls.constEnd() ) {
if ( !urls.contains( *it ) )
urls += *it;
++it;
}
// limit to myMaximum items
/* Note: overload is an (old) C++ keyword, some compilers (KCC) choke
on that, so call it Overload (capital 'O'). (matz) */
int Overload = urls.count() - d->myMaximum + d->defaultList.count();
while ( Overload > 0) {
if (remove == RemoveBottom) {
if (!urls.isEmpty())
urls.removeLast();
}
else {
if (!urls.isEmpty())
urls.removeFirst();
}
Overload--;
}
it = urls.constBegin();
KUrlComboBoxPrivate::KUrlComboItem *item = 0L;
while ( it != urls.constEnd() ) {
if ( (*it).isEmpty() ) {
++it;
continue;
}
KUrl u = *it;
// Don't restore if file doesn't exist anymore
if (u.isLocalFile() && !QFile::exists(u.toLocalFile())) {
++it;
continue;
}
item = new KUrlComboBoxPrivate::KUrlComboItem;
item->url = u;
item->icon = d->getIcon( u );
item->text = u.pathOrUrl(d->myMode == Directories
? KUrl::AddTrailingSlash
: KUrl::RemoveTrailingSlash);
d->insertUrlItem( item );
d->itemList.append( item );
++it;
}
}
void KUrlComboBox::setUrl( const KUrl& url )
{
if ( url.isEmpty() )
return;
bool blocked = blockSignals( true );
// check for duplicates
QMap<int,const KUrlComboBoxPrivate::KUrlComboItem*>::ConstIterator mit = d->itemMapper.constBegin();
QString urlToInsert = url.url(KUrl::RemoveTrailingSlash);
while ( mit != d->itemMapper.constEnd() ) {
Q_ASSERT( mit.value() );
if ( urlToInsert == mit.value()->url.url(KUrl::RemoveTrailingSlash) ) {
setCurrentIndex( mit.key() );
if (d->myMode == Directories)
d->updateItem( mit.value(), mit.key(), d->opendirIcon );
blockSignals( blocked );
return;
}
++mit;
}
// not in the combo yet -> create a new item and insert it
// first remove the old item
if (d->urlAdded) {
Q_ASSERT(!d->itemList.isEmpty());
d->itemList.removeLast();
d->urlAdded = false;
}
setDefaults();
int offset = qMax (0, d->itemList.count() - d->myMaximum + d->defaultList.count());
for ( int i = offset; i < d->itemList.count(); i++ )
d->insertUrlItem( d->itemList[i] );
KUrlComboBoxPrivate::KUrlComboItem *item = new KUrlComboBoxPrivate::KUrlComboItem;
item->url = url;
item->icon = d->getIcon( url );
item->text = url.pathOrUrl(d->myMode == Directories
? KUrl::AddTrailingSlash
: KUrl::RemoveTrailingSlash);
kDebug(250) << "setURL: text=" << item->text;
int id = count();
QString text = /*isEditable() ? item->url.prettyUrl( (KUrl::AdjustPathOption)myMode ) : */ item->text;
if (d->myMode == Directories)
KComboBox::insertItem( id, d->opendirIcon, text);
else
KComboBox::insertItem( id,item->icon, text);
d->itemMapper.insert( id, item );
d->itemList.append( item );
setCurrentIndex( id );
Q_ASSERT(!d->itemList.isEmpty());
d->urlAdded = true;
blockSignals( blocked );
}
void KUrlComboBox::KUrlComboBoxPrivate::_k_slotActivated( int index )
{
const KUrlComboItem *item = itemMapper.value(index);
if ( item ) {
m_parent->setUrl( item->url );
emit m_parent->urlActivated( item->url );
}
}
void KUrlComboBox::KUrlComboBoxPrivate::insertUrlItem( const KUrlComboBoxPrivate::KUrlComboItem *item )
{
Q_ASSERT( item );
// kDebug(250) << "insertURLItem " << item->text;
int id = m_parent->count();
m_parent->KComboBox::insertItem(id, item->icon, item->text);
itemMapper.insert( id, item );
}
void KUrlComboBox::setMaxItems( int max )
{
d->myMaximum = max;
if (count() > d->myMaximum) {
int oldCurrent = currentIndex();
setDefaults();
int offset = qMax (0, d->itemList.count() - d->myMaximum + d->defaultList.count());
for ( int i = offset; i < d->itemList.count(); i++ )
d->insertUrlItem( d->itemList[i] );
if ( count() > 0 ) { // restore the previous currentItem
if ( oldCurrent >= count() )
oldCurrent = count() -1;
setCurrentIndex( oldCurrent );
}
}
}
int KUrlComboBox::maxItems() const
{
return d->myMaximum;
}
void KUrlComboBox::removeUrl( const KUrl& url, bool checkDefaultURLs )
{
QMap<int,const KUrlComboBoxPrivate::KUrlComboItem*>::ConstIterator mit = d->itemMapper.constBegin();
while ( mit != d->itemMapper.constEnd() ) {
if ( url.url(KUrl::RemoveTrailingSlash) == mit.value()->url.url(KUrl::RemoveTrailingSlash) ) {
if ( !d->itemList.removeAll( mit.value() ) && checkDefaultURLs )
d->defaultList.removeAll( mit.value() );
}
++mit;
}
bool blocked = blockSignals( true );
setDefaults();
QListIterator<const KUrlComboBoxPrivate::KUrlComboItem*> it( d->itemList );
while ( it.hasNext() ) {
d->insertUrlItem( it.next() );
}
blockSignals( blocked );
}
void KUrlComboBox::setCompletionObject(KCompletion* compObj, bool hsig)
{
if ( compObj ) {
// on a url combo box we want completion matches to be sorted. This way, if we are given
// a suggestion, we match the "best" one. For instance, if we have "foo" and "foobar",
// and we write "foo", the match is "foo" and never "foobar". (ereslibre)
compObj->setOrder( KCompletion::Sorted );
}
KComboBox::setCompletionObject( compObj, hsig );
}
void KUrlComboBox::mousePressEvent(QMouseEvent *event)
{
QStyleOptionComboBox comboOpt;
comboOpt.initFrom(this);
const int x0 = QStyle::visualRect(layoutDirection(), rect(),
style()->subControlRect(QStyle::CC_ComboBox, &comboOpt, QStyle::SC_ComboBoxEditField, this)).x();
const int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &comboOpt, this);
if (event->x() < (x0 + KIconLoader::SizeSmall + frameWidth)) {
d->m_dragPoint = event->pos();
} else {
d->m_dragPoint = QPoint();
}
KComboBox::mousePressEvent(event);
}
void KUrlComboBox::mouseMoveEvent(QMouseEvent *event)
{
const int index = currentIndex();
if (!itemIcon(index).isNull() && !d->m_dragPoint.isNull() && event->buttons() & Qt::LeftButton &&
(event->pos() - d->m_dragPoint).manhattanLength() > KGlobalSettings::dndEventDelay()) {
QDrag *drag = new QDrag(this);
QMimeData *mime = new QMimeData();
mime->setUrls(QList<QUrl>() << KUrl(itemText(index)));
mime->setText(itemText(index));
drag->setPixmap(itemIcon(index).pixmap(KIconLoader::SizeMedium));
drag->setMimeData(mime);
drag->exec();
}
KComboBox::mouseMoveEvent(event);
}
QIcon KUrlComboBox::KUrlComboBoxPrivate::getIcon( const KUrl& url ) const
{
if (myMode == Directories)
return dirIcon;
else
return KIcon(KMimeType::iconNameForUrl(url, 0));
}
// updates "item" with icon "icon" and sets the URL instead of text
void KUrlComboBox::KUrlComboBoxPrivate::updateItem( const KUrlComboBoxPrivate::KUrlComboItem *item,
int index, const QIcon& icon)
{
m_parent->setItemIcon(index,icon);
if ( m_parent->isEditable() ) {
m_parent->setItemText(index, item->url.pathOrUrl(myMode == Directories
? KUrl::AddTrailingSlash
: KUrl::RemoveTrailingSlash));
}
else {
m_parent->setItemText(index,item->text);
}
}
#include "moc_kurlcombobox.cpp"
diff --git a/kio/kio/jobuidelegate.cpp b/kio/kio/jobuidelegate.cpp
index 53faef4ac1..033daa6687 100644
--- a/kio/kio/jobuidelegate.cpp
+++ b/kio/kio/jobuidelegate.cpp
@@ -1,193 +1,194 @@
/* This file is part of the KDE libraries
Copyright (C) 2000 Stephan Kulow <coolo@kde.org>
David Faure <faure@kde.org>
Copyright (C) 2006 Kevin Ottens <ervin@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 as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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 "jobuidelegate.h"
+#include <kicon.h>
#include <kdebug.h>
#include <kjob.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <ksharedconfig.h>
#include <QPointer>
#include <QWidget>
#include "kio/scheduler.h"
#if defined Q_WS_X11
#include <QX11Info>
#include <netwm.h>
#endif
class KIO::JobUiDelegate::Private
{
public:
};
KIO::JobUiDelegate::JobUiDelegate()
: d(new Private())
{
}
KIO::JobUiDelegate::~JobUiDelegate()
{
delete d;
}
void KIO::JobUiDelegate::setWindow(QWidget *window)
{
KDialogJobUiDelegate::setWindow(window);
KIO::Scheduler::registerWindow(window);
}
KIO::RenameDialog_Result KIO::JobUiDelegate::askFileRename(KJob * job,
const QString & caption,
const QString& src,
const QString & dest,
KIO::RenameDialog_Mode mode,
QString& newDest,
KIO::filesize_t sizeSrc,
KIO::filesize_t sizeDest,
time_t ctimeSrc,
time_t ctimeDest,
time_t mtimeSrc,
time_t mtimeDest)
{
Q_UNUSED(job);
//kDebug() << "job=" << job;
// We now do it in process, so that opening the rename dialog
// doesn't start uiserver for nothing if progressId=0 (e.g. F2 in konq)
KIO::RenameDialog dlg( window(), caption, src, dest, mode,
sizeSrc, sizeDest,
ctimeSrc, ctimeDest, mtimeSrc,
mtimeDest);
connect(job, SIGNAL(finished(KJob*)), &dlg, SLOT(reject())); // #192976
KIO::RenameDialog_Result res = static_cast<RenameDialog_Result>(dlg.exec());
if (res == R_AUTO_RENAME) {
newDest = dlg.autoDestUrl().path();
}
else {
newDest = dlg.newDestUrl().path();
}
return res;
}
KIO::SkipDialog_Result KIO::JobUiDelegate::askSkip(KJob *job,
bool multi,
const QString & error_text)
{
// We now do it in process. So this method is a useless wrapper around KIO::open_RenameDialog.
KIO::SkipDialog dlg( window(), multi, error_text );
connect(job, SIGNAL(finished(KJob*)), &dlg, SLOT(reject())); // #192976
return static_cast<KIO::SkipDialog_Result>(dlg.exec());
}
bool KIO::JobUiDelegate::askDeleteConfirmation(const KUrl::List& urls,
DeletionType deletionType,
ConfirmationType confirmationType)
{
QString keyName;
bool ask = ( confirmationType == ForceConfirmation );
if (!ask) {
KSharedConfigPtr kioConfig = KSharedConfig::openConfig("kiorc", KConfig::NoGlobals);
switch (deletionType ) {
case Delete:
keyName = "ConfirmDelete" ;
break;
case Trash:
keyName = "ConfirmTrash" ;
break;
case EmptyTrash:
keyName = "ConfirmEmptyTrash" ;
break;
}
// The default value for confirmations is true (for both delete and trash)
// If you change this, update kdebase/apps/konqueror/settings/konq/behaviour.cpp
const bool defaultValue = true;
ask = kioConfig->group("Confirmations").readEntry(keyName, defaultValue);
}
if (ask) {
QStringList prettyList;
Q_FOREACH(const KUrl& url, urls) {
if ( url.scheme() == "trash" ) {
QString path = url.path();
// HACK (#98983): remove "0-foo". Note that it works better than
// displaying KFileItem::name(), for files under a subdir.
path.remove(QRegExp("^/[0-9]*-"));
prettyList.append(path);
} else {
prettyList.append(url.pathOrUrl());
}
}
QWidget* widget = window();
int result;
switch(deletionType) {
case Delete:
result = KMessageBox::warningContinueCancelList(
widget,
i18np("Do you really want to delete this item?", "Do you really want to delete these %1 items?", prettyList.count()),
prettyList,
i18n("Delete Files"),
KStandardGuiItem::del(),
KStandardGuiItem::cancel(),
keyName, KMessageBox::Notify);
break;
case EmptyTrash:
result = KMessageBox::warningContinueCancel(
widget,
i18nc("@info", "Do you want to permanently delete all items from Trash? This action cannot be undone."),
QString(),
KGuiItem(i18nc("@action:button", "Empty Trash"),
KIcon("user-trash")),
KStandardGuiItem::cancel(),
keyName, KMessageBox::Notify);
break;
case Trash:
default:
result = KMessageBox::warningContinueCancelList(
widget,
i18np("Do you really want to move this item to the trash?", "Do you really want to move these %1 items to the trash?", prettyList.count()),
prettyList,
i18n("Move to Trash"),
KGuiItem(i18nc("Verb", "&Trash"), "user-trash"),
KStandardGuiItem::cancel(),
keyName, KMessageBox::Notify);
}
if (!keyName.isEmpty()) {
// Check kmessagebox setting... erase & copy to konquerorrc.
KSharedConfig::Ptr config = KGlobal::config();
KConfigGroup notificationGroup(config, "Notification Messages");
if (!notificationGroup.readEntry(keyName, true)) {
notificationGroup.writeEntry(keyName, true);
notificationGroup.sync();
KSharedConfigPtr kioConfig = KSharedConfig::openConfig("kiorc", KConfig::NoGlobals);
kioConfig->group("Confirmations").writeEntry(keyName, false);
}
}
return (result == KMessageBox::Continue);
}
return true;
}
diff --git a/kio/kio/kfileitemdelegate.cpp b/kio/kio/kfileitemdelegate.cpp
index 7adcff3473..4e7d1f4667 100644
--- a/kio/kio/kfileitemdelegate.cpp
+++ b/kio/kio/kfileitemdelegate.cpp
@@ -1,1691 +1,1691 @@
/*
This file is part of the KDE project
Copyright (C) 2009 Shaun Reich <shaun.reich@kdemail.net>
Copyright © 2006-2007, 2008 Fredrik Höglund <fredrik@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 as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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 "kfileitemdelegate.h"
#include "imagefilter_p.h"
#include <config.h> // for HAVE_XRENDER
#include <QApplication>
#include <QStyle>
#include <QModelIndex>
#include <QPainter>
#include <QCache>
#include <QImage>
#include <QPainterPath>
#include <QTextLayout>
#include <QListView>
#include <QPaintEngine>
#include <qmath.h>
#include <kglobal.h>
#include <klocale.h>
#include <kicon.h>
#include <kiconloader.h>
#include <kiconeffect.h>
#include <kdirmodel.h>
#include <kfileitem.h>
#include <kcolorscheme.h>
#include <kglobalsettings.h>
#include <ktextedit.h>
#include <kstringhandler.h>
#include "delegateanimationhandler_p.h"
#if defined(Q_WS_X11) && defined(HAVE_XRENDER)
# include <X11/Xlib.h>
# include <X11/extensions/Xrender.h>
# include <QX11Info>
# undef KeyPress
# undef FocusOut
#endif
struct Margin
{
int left, right, top, bottom;
};
class KFileItemDelegate::Private
{
public:
enum MarginType { ItemMargin = 0, TextMargin, IconMargin, NMargins };
Private(KFileItemDelegate *parent);
~Private() {}
QSize decorationSizeHint(const QStyleOptionViewItemV4 &option, const QModelIndex &index) const;
QSize displaySizeHint(const QStyleOptionViewItemV4 &option, const QModelIndex &index) const;
QString replaceNewlines(const QString &string) const;
inline KFileItem fileItem(const QModelIndex &index) const;
QString elidedText(QTextLayout &layout, const QStyleOptionViewItemV4 &option, const QSize &maxSize) const;
QSize layoutText(QTextLayout &layout, const QStyleOptionViewItemV4 &option,
const QString &text, const QSize &constraints) const;
QSize layoutText(QTextLayout &layout, const QString &text, int maxWidth) const;
inline void setLayoutOptions(QTextLayout &layout, const QStyleOptionViewItemV4 &options) const;
inline bool verticalLayout(const QStyleOptionViewItemV4 &option) const;
inline QBrush brush(const QVariant &value, const QStyleOptionViewItemV4 &option) const;
QBrush foregroundBrush(const QStyleOptionViewItemV4 &option, const QModelIndex &index) const;
inline void setActiveMargins(Qt::Orientation layout);
void setVerticalMargin(MarginType type, int left, int right, int top, int bottom);
void setHorizontalMargin(MarginType type, int left, int right, int top, int bottom);
inline void setVerticalMargin(MarginType type, int hor, int ver);
inline void setHorizontalMargin(MarginType type, int hor, int ver);
inline QRect addMargin(const QRect &rect, MarginType type) const;
inline QRect subtractMargin(const QRect &rect, MarginType type) const;
inline QSize addMargin(const QSize &size, MarginType type) const;
inline QSize subtractMargin(const QSize &size, MarginType type) const;
QString itemSize(const QModelIndex &index, const KFileItem &item) const;
QString information(const QStyleOptionViewItemV4 &option, const QModelIndex &index, const KFileItem &item) const;
bool isListView(const QStyleOptionViewItemV4 &option) const;
QString display(const QModelIndex &index) const;
QIcon decoration(const QStyleOptionViewItemV4 &option, const QModelIndex &index) const;
QPoint iconPosition(const QStyleOptionViewItemV4 &option) const;
QRect labelRectangle(const QStyleOptionViewItemV4 &option) const;
void layoutTextItems(const QStyleOptionViewItemV4 &option, const QModelIndex &index,
QTextLayout *labelLayout, QTextLayout *infoLayout, QRect *textBoundingRect) const;
void drawTextItems(QPainter *painter, const QTextLayout &labelLayout, const QTextLayout &infoLayout,
const QRect &textBoundingRect) const;
KIO::AnimationState *animationState(const QStyleOptionViewItemV4 &option, const QModelIndex &index,
const QAbstractItemView *view) const;
void restartAnimation(KIO::AnimationState* state);
QPixmap applyHoverEffect(const QPixmap &icon) const;
QPixmap transition(const QPixmap &from, const QPixmap &to, qreal amount) const;
void initStyleOption(QStyleOptionViewItemV4 *option, const QModelIndex &index) const;
void drawFocusRect(QPainter *painter, const QStyleOptionViewItemV4 &option, const QRect &rect) const;
void gotNewIcon(const QModelIndex& index);
void paintJobTransfers(QPainter* painter, const qreal& jobAnimationAngle, const QPoint& iconPos, const QStyleOptionViewItemV4& opt);
public:
KFileItemDelegate::InformationList informationList;
QColor shadowColor;
QPointF shadowOffset;
qreal shadowBlur;
QSize maximumSize;
bool showToolTipWhenElided;
QTextOption::WrapMode wrapMode;
bool jobTransfersVisible;
- KIcon downArrowIcon;
+ QIcon downArrowIcon;
private:
KFileItemDelegate * const q;
KIO::DelegateAnimationHandler *animationHandler;
Margin verticalMargin[NMargins];
Margin horizontalMargin[NMargins];
Margin *activeMargins;
};
KFileItemDelegate::Private::Private(KFileItemDelegate *parent)
: shadowColor(Qt::transparent), shadowOffset(1, 1), shadowBlur(2), maximumSize(0, 0),
showToolTipWhenElided(true), wrapMode( QTextOption::WrapAtWordBoundaryOrAnywhere ), jobTransfersVisible(false),
q(parent), animationHandler(new KIO::DelegateAnimationHandler(parent)), activeMargins(0)
{
}
void KFileItemDelegate::Private::setActiveMargins(Qt::Orientation layout)
{
activeMargins = (layout == Qt::Horizontal ?
horizontalMargin : verticalMargin);
}
void KFileItemDelegate::Private::setVerticalMargin(MarginType type, int left, int top, int right, int bottom)
{
verticalMargin[type].left = left;
verticalMargin[type].right = right;
verticalMargin[type].top = top;
verticalMargin[type].bottom = bottom;
}
void KFileItemDelegate::Private::setHorizontalMargin(MarginType type, int left, int top, int right, int bottom)
{
horizontalMargin[type].left = left;
horizontalMargin[type].right = right;
horizontalMargin[type].top = top;
horizontalMargin[type].bottom = bottom;
}
void KFileItemDelegate::Private::setVerticalMargin(MarginType type, int horizontal, int vertical)
{
setVerticalMargin(type, horizontal, vertical, horizontal, vertical);
}
void KFileItemDelegate::Private::setHorizontalMargin(MarginType type, int horizontal, int vertical)
{
setHorizontalMargin(type, horizontal, vertical, horizontal, vertical);
}
QRect KFileItemDelegate::Private::addMargin(const QRect &rect, MarginType type) const
{
Q_ASSERT(activeMargins != 0);
const Margin &m = activeMargins[type];
return rect.adjusted(-m.left, -m.top, m.right, m.bottom);
}
QRect KFileItemDelegate::Private::subtractMargin(const QRect &rect, MarginType type) const
{
Q_ASSERT(activeMargins != 0);
const Margin &m = activeMargins[type];
return rect.adjusted(m.left, m.top, -m.right, -m.bottom);
}
QSize KFileItemDelegate::Private::addMargin(const QSize &size, MarginType type) const
{
Q_ASSERT(activeMargins != 0);
const Margin &m = activeMargins[type];
return QSize(size.width() + m.left + m.right, size.height() + m.top + m.bottom);
}
QSize KFileItemDelegate::Private::subtractMargin(const QSize &size, MarginType type) const
{
Q_ASSERT(activeMargins != 0);
const Margin &m = activeMargins[type];
return QSize(size.width() - m.left - m.right, size.height() - m.top - m.bottom);
}
// Returns the size of a file, or the number of items in a directory, as a QString
QString KFileItemDelegate::Private::itemSize(const QModelIndex &index, const KFileItem &item) const
{
// Return a formatted string containing the file size, if the item is a file
if (item.isFile())
return KGlobal::locale()->formatByteSize(item.size());
// Return the number of items in the directory
const QVariant value = index.data(KDirModel::ChildCountRole);
const int count = value.type() == QVariant::Int ? value.toInt() : KDirModel::ChildCountUnknown;
if (count == KDirModel::ChildCountUnknown) {
// was: i18nc("Items in a folder", "? items");
// but this just looks useless in a remote directory listing,
// better not show anything.
return QString();
}
return i18ncp("Items in a folder", "1 item", "%1 items", count);
}
// Returns the additional information string, if one should be shown, or an empty string otherwise
QString KFileItemDelegate::Private::information(const QStyleOptionViewItemV4 &option, const QModelIndex &index,
const KFileItem &item) const
{
QString string;
if (informationList.isEmpty() || item.isNull() || !isListView(option))
return string;
foreach (KFileItemDelegate::Information info, informationList)
{
if (info == KFileItemDelegate::NoInformation)
continue;
if (!string.isEmpty())
string += QChar::LineSeparator;
switch (info)
{
case KFileItemDelegate::Size:
string += itemSize(index, item);
break;
case KFileItemDelegate::Permissions:
string += item.permissionsString();
break;
case KFileItemDelegate::OctalPermissions:
string += QString('0') + QString::number(item.permissions(), 8);
break;
case KFileItemDelegate::Owner:
string += item.user();
break;
case KFileItemDelegate::OwnerAndGroup:
string += item.user() + ':' + item.group();
break;
case KFileItemDelegate::CreationTime:
string += item.timeString(KFileItem::CreationTime);
break;
case KFileItemDelegate::ModificationTime:
string += item.timeString(KFileItem::ModificationTime);
break;
case KFileItemDelegate::AccessTime:
string += item.timeString(KFileItem::AccessTime);
break;
case KFileItemDelegate::MimeType:
string += item.isMimeTypeKnown() ? item.mimetype() : i18nc("@info mimetype","Unknown");
break;
case KFileItemDelegate::FriendlyMimeType:
string += item.isMimeTypeKnown() ? item.mimeComment() : i18nc("@info mimetype","Unknown");
break;
case KFileItemDelegate::LinkDest:
string += item.linkDest();
break;
case KFileItemDelegate::LocalPathOrUrl:
if(!item.localPath().isEmpty())
string += item.localPath();
else
string += item.url().pathOrUrl();
break;
case KFileItemDelegate::Comment:
string += item.comment();
break;
default:
break;
} // switch (info)
} // foreach (info, list)
return string;
}
// Returns the KFileItem for the index
KFileItem KFileItemDelegate::Private::fileItem(const QModelIndex &index) const
{
const QVariant value = index.data(KDirModel::FileItemRole);
return qvariant_cast<KFileItem>(value);
}
// Replaces any newline characters in the provided string, with QChar::LineSeparator
QString KFileItemDelegate::Private::replaceNewlines(const QString &text) const
{
QString string = text;
const QChar newline = QLatin1Char('\n');
for (int i = 0; i < string.length(); i++)
if (string[i] == newline)
string[i] = QChar::LineSeparator;
return string;
}
// Lays the text out in a rectangle no larger than constraints, eliding it as necessary
QSize KFileItemDelegate::Private::layoutText(QTextLayout &layout, const QStyleOptionViewItemV4 &option,
const QString &text, const QSize &constraints) const
{
const QSize size = layoutText(layout, text, constraints.width());
if (size.width() > constraints.width() || size.height() > constraints.height())
{
const QString elided = elidedText(layout, option, constraints);
return layoutText(layout, elided, constraints.width());
}
return size;
}
// Lays the text out in a rectangle no wider than maxWidth
QSize KFileItemDelegate::Private::layoutText(QTextLayout &layout, const QString &text, int maxWidth) const
{
QFontMetrics metrics(layout.font());
int leading = metrics.leading();
int height = 0;
qreal widthUsed = 0;
QTextLine line;
layout.setText(text);
layout.beginLayout();
while ((line = layout.createLine()).isValid())
{
line.setLineWidth(maxWidth);
height += leading;
line.setPosition(QPoint(0, height));
height += int(line.height());
widthUsed = qMax(widthUsed, line.naturalTextWidth());
}
layout.endLayout();
return QSize(qCeil(widthUsed), height);
}
// Elides the text in the layout, by iterating over each line in the layout, eliding
// or word breaking the line if it's wider than the max width, and finally adding an
// ellipses at the end of the last line, if there are more lines than will fit within
// the vertical size constraints.
QString KFileItemDelegate::Private::elidedText(QTextLayout &layout, const QStyleOptionViewItemV4 &option,
const QSize &size) const
{
const QString text = layout.text();
int maxWidth = size.width();
int maxHeight = size.height();
qreal height = 0;
bool wrapText = (option.features & QStyleOptionViewItemV2::WrapText);
// If the string contains a single line of text that shouldn't be word wrapped
if (!wrapText && text.indexOf(QChar::LineSeparator) == -1)
return option.fontMetrics.elidedText(text, option.textElideMode, maxWidth);
// Elide each line that has already been laid out in the layout.
QString elided;
elided.reserve(text.length());
for (int i = 0; i < layout.lineCount(); i++)
{
QTextLine line = layout.lineAt(i);
int start = line.textStart();
int length = line.textLength();
height += option.fontMetrics.leading();
if (height + line.height() + option.fontMetrics.lineSpacing() > maxHeight)
{
// Unfortunately, if the line ends because of a line separator, elidedText() will be too
// clever and keep adding lines until it finds one that's too wide.
if (line.naturalTextWidth() < maxWidth && text[start + length - 1] == QChar::LineSeparator)
elided += text.mid(start, length - 1);
else
elided += option.fontMetrics.elidedText(text.mid(start), option.textElideMode, maxWidth);
break;
}
else if (line.naturalTextWidth() > maxWidth)
{
elided += option.fontMetrics.elidedText(text.mid(start, length), option.textElideMode, maxWidth);
if (!elided.endsWith(QChar::LineSeparator))
elided += QChar::LineSeparator;
}
else
elided += text.mid(start, length);
height += line.height();
}
return elided;
}
void KFileItemDelegate::Private::setLayoutOptions(QTextLayout &layout, const QStyleOptionViewItemV4 &option) const
{
QTextOption textoption;
textoption.setTextDirection(option.direction);
textoption.setAlignment(QStyle::visualAlignment(option.direction, option.displayAlignment));
textoption.setWrapMode((option.features & QStyleOptionViewItemV2::WrapText) ? wrapMode : QTextOption::NoWrap);
layout.setFont(option.font);
layout.setTextOption(textoption);
}
QSize KFileItemDelegate::Private::displaySizeHint(const QStyleOptionViewItemV4 &option,
const QModelIndex &index) const
{
QString label = option.text;
int maxWidth = 0;
if (maximumSize.isEmpty()) {
maxWidth = verticalLayout(option) && (option.features & QStyleOptionViewItemV2::WrapText)
? option.decorationSize.width() + 10 : 32757;
}
else {
const Margin &itemMargin = activeMargins[ItemMargin];
const Margin &textMargin = activeMargins[TextMargin];
maxWidth = maximumSize.width() -
(itemMargin.left + itemMargin.right) -
(textMargin.left + textMargin.right);
}
KFileItem item = fileItem(index);
// To compute the nominal size for the label + info, we'll just append
// the information string to the label
const QString info = information(option, index, item);
if (!info.isEmpty())
label += QString(QChar::LineSeparator) + info;
QTextLayout layout;
setLayoutOptions(layout, option);
QSize size = layoutText(layout, label, maxWidth);
if (!info.isEmpty())
{
// As soon as additional information is shown, it might be necessary that
// the label and/or the additional information must get elided. To prevent
// an expensive eliding in the scope of displaySizeHint, the maximum
// width is reserved instead.
size.setWidth(maxWidth);
}
return addMargin(size, TextMargin);
}
QSize KFileItemDelegate::Private::decorationSizeHint(const QStyleOptionViewItemV4 &option,
const QModelIndex &index) const
{
Q_UNUSED(index)
QSize iconSize = option.icon.actualSize(option.decorationSize);
if (!verticalLayout(option))
iconSize.rwidth() = option.decorationSize.width();
else if (iconSize.width() < option.decorationSize.width())
iconSize.rwidth() = qMin(iconSize.width() + 10, option.decorationSize.width());
if (iconSize.height() < option.decorationSize.height())
iconSize.rheight() = option.decorationSize.height();
return addMargin(iconSize, IconMargin);
}
bool KFileItemDelegate::Private::verticalLayout(const QStyleOptionViewItemV4 &option) const
{
return (option.decorationPosition == QStyleOptionViewItem::Top ||
option.decorationPosition == QStyleOptionViewItem::Bottom);
}
// Converts a QVariant of type Brush or Color to a QBrush
QBrush KFileItemDelegate::Private::brush(const QVariant &value, const QStyleOptionViewItemV4 &option) const
{
if (value.userType() == qMetaTypeId<KStatefulBrush>())
return qvariant_cast<KStatefulBrush>(value).brush(option.palette);
switch (value.type())
{
case QVariant::Color:
return QBrush(qvariant_cast<QColor>(value));
case QVariant::Brush:
return qvariant_cast<QBrush>(value);
default:
return QBrush(Qt::NoBrush);
}
}
QBrush KFileItemDelegate::Private::foregroundBrush(const QStyleOptionViewItemV4 &option, const QModelIndex &index) const
{
QPalette::ColorGroup cg = QPalette::Active;
if (!(option.state & QStyle::State_Enabled)) {
cg = QPalette::Disabled;
} else if (!(option.state & QStyle::State_Active)) {
cg = QPalette::Inactive;
}
// Always use the highlight color for selected items
if (option.state & QStyle::State_Selected)
return option.palette.brush(cg, QPalette::HighlightedText);
// If the model provides its own foreground color/brush for this item
const QVariant value = index.data(Qt::ForegroundRole);
if (value.isValid())
return brush(value, option);
return option.palette.brush(cg, QPalette::Text);
}
bool KFileItemDelegate::Private::isListView(const QStyleOptionViewItemV4 &option) const
{
if (qobject_cast<const QListView*>(option.widget) || verticalLayout(option))
return true;
return false;
}
QPixmap KFileItemDelegate::Private::applyHoverEffect(const QPixmap &icon) const
{
KIconEffect *effect = KIconLoader::global()->iconEffect();
// Note that in KIconLoader terminology, active = hover.
// ### We're assuming that the icon group is desktop/filemanager, since this
// is KFileItemDelegate.
if (effect->hasEffect(KIconLoader::Desktop, KIconLoader::ActiveState))
return effect->apply(icon, KIconLoader::Desktop, KIconLoader::ActiveState);
return icon;
}
void KFileItemDelegate::Private::gotNewIcon(const QModelIndex& index)
{
animationHandler->gotNewIcon(index);
}
void KFileItemDelegate::Private::restartAnimation(KIO::AnimationState* state)
{
animationHandler->restartAnimation(state);
}
KIO::AnimationState *KFileItemDelegate::Private::animationState(const QStyleOptionViewItemV4 &option,
const QModelIndex &index,
const QAbstractItemView *view) const
{
if (!(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects)) {
return NULL;
}
if (index.column() == KDirModel::Name)
return animationHandler->animationState(option, index, view);
return NULL;
}
QPixmap KFileItemDelegate::Private::transition(const QPixmap &from, const QPixmap &to, qreal amount) const
{
int value = int(0xff * amount);
if (value == 0 || to.isNull())
return from;
if (value == 0xff || from.isNull())
return to;
QColor color;
color.setAlphaF(amount);
// FIXME: Somehow this doesn't work on Mac OS..
#if defined(Q_OS_MAC)
const bool usePixmap = false;
#else
const bool usePixmap = from.paintEngine()->hasFeature(QPaintEngine::PorterDuff) &&
from.paintEngine()->hasFeature(QPaintEngine::BlendModes);
#endif
// If the native paint engine supports Porter/Duff compositing and CompositionMode_Plus
if (usePixmap)
{
QPixmap under = from;
QPixmap over = to;
QPainter p;
p.begin(&over);
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
p.fillRect(over.rect(), color);
p.end();
p.begin(&under);
p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
p.fillRect(under.rect(), color);
p.setCompositionMode(QPainter::CompositionMode_Plus);
p.drawPixmap(0, 0, over);
p.end();
return under;
}
#if defined(Q_WS_X11) && defined(HAVE_XRENDER)
else if (from.paintEngine()->hasFeature(QPaintEngine::PorterDuff)) // We have Xrender support
{
// QX11PaintEngine doesn't implement CompositionMode_Plus in Qt 4.3,
// which we need to be able to do a transition from one pixmap to
// another.
//
// In order to avoid the overhead of converting the pixmaps to images
// and doing the operation entirely in software, this function has a
// specialized path for X11 that uses Xrender directly to do the
// transition. This operation can be fully accelerated in HW.
//
// This specialization can be removed when QX11PaintEngine supports
// CompositionMode_Plus.
QPixmap source(to), destination(from);
source.detach();
destination.detach();
Display *dpy = QX11Info::display();
XRenderPictFormat *format = XRenderFindStandardFormat(dpy, PictStandardA8);
XRenderPictureAttributes pa;
pa.repeat = 1; // RepeatNormal
// Create a 1x1 8 bit repeating alpha picture
Pixmap pixmap = XCreatePixmap(dpy, destination.handle(), 1, 1, 8);
Picture alpha = XRenderCreatePicture(dpy, pixmap, format, CPRepeat, &pa);
XFreePixmap(dpy, pixmap);
// Fill the alpha picture with the opacity value
XRenderColor xcolor;
xcolor.alpha = quint16(0xffff * amount);
XRenderFillRectangle(dpy, PictOpSrc, alpha, &xcolor, 0, 0, 1, 1);
// Reduce the alpha of the destination with 1 - opacity
XRenderComposite(dpy, PictOpOutReverse, alpha, None, destination.x11PictureHandle(),
0, 0, 0, 0, 0, 0, destination.width(), destination.height());
// Add source * opacity to the destination
XRenderComposite(dpy, PictOpAdd, source.x11PictureHandle(), alpha,
destination.x11PictureHandle(),
0, 0, 0, 0, 0, 0, destination.width(), destination.height());
XRenderFreePicture(dpy, alpha);
return destination;
}
#endif
else
{
// Fall back to using QRasterPaintEngine to do the transition.
QImage under = from.toImage();
QImage over = to.toImage();
QPainter p;
p.begin(&over);
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
p.fillRect(over.rect(), color);
p.end();
p.begin(&under);
p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
p.fillRect(under.rect(), color);
p.setCompositionMode(QPainter::CompositionMode_Plus);
p.drawImage(0, 0, over);
p.end();
return QPixmap::fromImage(under);
}
}
void KFileItemDelegate::Private::layoutTextItems(const QStyleOptionViewItemV4 &option, const QModelIndex &index,
QTextLayout *labelLayout, QTextLayout *infoLayout,
QRect *textBoundingRect) const
{
KFileItem item = fileItem(index);
const QString info = information(option, index, item);
bool showInformation = false;
setLayoutOptions(*labelLayout, option);
const QRect textArea = labelRectangle(option);
QRect textRect = subtractMargin(textArea, Private::TextMargin);
// Sizes and constraints for the different text parts
QSize maxLabelSize = textRect.size();
QSize maxInfoSize = textRect.size();
QSize labelSize;
QSize infoSize;
// If we have additional info text, and there's space for at least two lines of text,
// adjust the max label size to make room for at least one line of the info text
if (!info.isEmpty() && textRect.height() >= option.fontMetrics.lineSpacing() * 2)
{
infoLayout->setFont(labelLayout->font());
infoLayout->setTextOption(labelLayout->textOption());
maxLabelSize.rheight() -= option.fontMetrics.lineSpacing();
showInformation = true;
}
// Lay out the label text, and adjust the max info size based on the label size
labelSize = layoutText(*labelLayout, option, option.text, maxLabelSize);
maxInfoSize.rheight() -= labelSize.height();
// Lay out the info text
if (showInformation)
infoSize = layoutText(*infoLayout, option, info, maxInfoSize);
else
infoSize = QSize(0, 0);
// Compute the bounding rect of the text
const QSize size(qMax(labelSize.width(), infoSize.width()), labelSize.height() + infoSize.height());
*textBoundingRect = QStyle::alignedRect(option.direction, option.displayAlignment, size, textRect);
// Compute the positions where we should draw the layouts
labelLayout->setPosition(QPointF(textRect.x(), textBoundingRect->y()));
infoLayout->setPosition(QPointF(textRect.x(), textBoundingRect->y() + labelSize.height()));
}
void KFileItemDelegate::Private::drawTextItems(QPainter *painter, const QTextLayout &labelLayout,
const QTextLayout &infoLayout, const QRect &boundingRect) const
{
if (shadowColor.alpha() > 0)
{
QPixmap pixmap(boundingRect.size());
pixmap.fill(Qt::transparent);
QPainter p(&pixmap);
p.translate(-boundingRect.topLeft());
p.setPen(painter->pen());
labelLayout.draw(&p, QPoint());
if (!infoLayout.text().isEmpty())
{
QColor color = p.pen().color();
color.setAlphaF(0.6);
p.setPen(color);
infoLayout.draw(&p, QPoint());
}
p.end();
int padding = qCeil(shadowBlur);
int blurFactor = qRound(shadowBlur);
QImage image(boundingRect.size() + QSize(padding * 2, padding * 2), QImage::Format_ARGB32_Premultiplied);
image.fill(0);
p.begin(&image);
p.drawImage(padding, padding, pixmap.toImage());
p.end();
KIO::ImageFilter::shadowBlur(image, blurFactor, shadowColor);
painter->drawImage(boundingRect.topLeft() - QPoint(padding, padding) + shadowOffset.toPoint(), image);
painter->drawPixmap(boundingRect.topLeft(), pixmap);
return;
}
labelLayout.draw(painter, QPoint());
if (!infoLayout.text().isEmpty())
{
// TODO - for apps not doing funny things with the color palette,
// KColorScheme::InactiveText would be a much more correct choice. We
// should provide an API to specify what color to use for information.
QColor color = painter->pen().color();
color.setAlphaF(0.6);
painter->setPen(color);
infoLayout.draw(painter, QPoint());
}
}
void KFileItemDelegate::Private::initStyleOption(QStyleOptionViewItemV4 *option,
const QModelIndex &index) const
{
const KFileItem item = fileItem(index);
bool updateFontMetrics = false;
// Try to get the font from the model
QVariant value = index.data(Qt::FontRole);
if (value.isValid()) {
option->font = qvariant_cast<QFont>(value).resolve(option->font);
updateFontMetrics = true;
}
// Use an italic font for symlinks
if (!item.isNull() && item.isLink()) {
option->font.setItalic(true);
updateFontMetrics = true;
}
if (updateFontMetrics)
option->fontMetrics = QFontMetrics(option->font);
// Try to get the alignment for the item from the model
value = index.data(Qt::TextAlignmentRole);
if (value.isValid())
option->displayAlignment = Qt::Alignment(value.toInt());
value = index.data(Qt::BackgroundRole);
if (value.isValid())
option->backgroundBrush = brush(value, *option);
option->text = display(index);
if (!option->text.isEmpty())
option->features |= QStyleOptionViewItemV2::HasDisplay;
option->icon = decoration(*option, index);
if (!option->icon.isNull())
option->features |= QStyleOptionViewItemV2::HasDecoration;
// ### Make sure this value is always true for now
option->showDecorationSelected = true;
}
void KFileItemDelegate::Private::paintJobTransfers(QPainter *painter, const qreal &jobAnimationAngle, const QPoint &iconPos, const QStyleOptionViewItemV4& opt)
{
painter->save();
QSize iconSize = opt.icon.actualSize(opt.decorationSize);
QPixmap downArrow = downArrowIcon.pixmap(iconSize * 0.30);
//corner (less x and y than bottom-right corner) that we will center the painter around
QPoint bottomRightCorner = QPoint(iconPos.x() + iconSize.width() * 0.75, iconPos.y() + iconSize.height() * 0.60);
QPainter pixmapPainter(&downArrow);
//make the icon transparent and such
pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
pixmapPainter.fillRect(downArrow.rect(), QColor(255, 255, 255, 110));
painter->translate(bottomRightCorner);
painter->drawPixmap(-downArrow.size().width() * .50, -downArrow.size().height() * .50, downArrow);
//animate the circles by rotating the painter around the center point..
painter->rotate(jobAnimationAngle);
painter->setPen(QColor(20, 20, 20, 80));
painter->setBrush(QColor(250, 250, 250, 90));
int radius = iconSize.width() * 0.04;
int spacing = radius * 4.5;
//left
painter->drawEllipse(QPoint(-spacing, 0), radius, radius);
//right
painter->drawEllipse(QPoint(spacing, 0), radius, radius);
//up
painter->drawEllipse(QPoint(0, -spacing), radius, radius);
//down
painter->drawEllipse(QPoint(0, spacing), radius, radius);
painter->restore();
}
// ---------------------------------------------------------------------------
KFileItemDelegate::KFileItemDelegate(QObject *parent)
: QAbstractItemDelegate(parent), d(new Private(this))
{
int focusHMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin);
int focusVMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameVMargin);
// Margins for horizontal mode (list views, tree views, table views)
const int textMargin = focusHMargin * 4;
if (QApplication::isRightToLeft())
d->setHorizontalMargin(Private::TextMargin, textMargin, focusVMargin, focusHMargin, focusVMargin);
else
d->setHorizontalMargin(Private::TextMargin, focusHMargin, focusVMargin, textMargin, focusVMargin);
d->setHorizontalMargin(Private::IconMargin, focusHMargin, focusVMargin);
d->setHorizontalMargin(Private::ItemMargin, 0, 0);
// Margins for vertical mode (icon views)
d->setVerticalMargin(Private::TextMargin, 6, 2);
d->setVerticalMargin(Private::IconMargin, focusHMargin, focusVMargin);
d->setVerticalMargin(Private::ItemMargin, 0, 0);
setShowInformation(NoInformation);
}
KFileItemDelegate::~KFileItemDelegate()
{
delete d;
}
QSize KFileItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
// If the model wants to provide its own size hint for the item
const QVariant value = index.data(Qt::SizeHintRole);
if (value.isValid())
return qvariant_cast<QSize>(value);
QStyleOptionViewItemV4 opt(option);
d->initStyleOption(&opt, index);
d->setActiveMargins(d->verticalLayout(opt) ? Qt::Vertical : Qt::Horizontal);
const QSize displaySize = d->displaySizeHint(opt, index);
const QSize decorationSize = d->decorationSizeHint(opt, index);
QSize size;
if (d->verticalLayout(opt))
{
size.rwidth() = qMax(displaySize.width(), decorationSize.width());
size.rheight() = decorationSize.height() + displaySize.height() + 1;
}
else
{
size.rwidth() = decorationSize.width() + displaySize.width() + 1;
size.rheight() = qMax(decorationSize.height(), displaySize.height());
}
size = d->addMargin(size, Private::ItemMargin);
if (!d->maximumSize.isEmpty())
{
size = size.boundedTo(d->maximumSize);
}
return size;
}
QString KFileItemDelegate::Private::display(const QModelIndex &index) const
{
const QVariant value = index.data(Qt::DisplayRole);
switch (value.type())
{
case QVariant::String:
{
if (index.column() == KDirModel::Size)
return itemSize(index, fileItem(index));
else {
const QString text = replaceNewlines(value.toString());
return KStringHandler::preProcessWrap(text);
}
}
case QVariant::Double:
return KGlobal::locale()->formatNumber(value.toDouble());
case QVariant::Int:
case QVariant::UInt:
return KGlobal::locale()->formatLong(value.toInt());
default:
return QString();
}
}
void KFileItemDelegate::setShowInformation(const InformationList &list)
{
d->informationList = list;
}
void KFileItemDelegate::setShowInformation(Information value)
{
if (value != NoInformation)
d->informationList = InformationList() << value;
else
d->informationList = InformationList();
}
KFileItemDelegate::InformationList KFileItemDelegate::showInformation() const
{
return d->informationList;
}
void KFileItemDelegate::setShadowColor(const QColor &color)
{
d->shadowColor = color;
}
QColor KFileItemDelegate::shadowColor() const
{
return d->shadowColor;
}
void KFileItemDelegate::setShadowOffset(const QPointF &offset)
{
d->shadowOffset = offset;
}
QPointF KFileItemDelegate::shadowOffset() const
{
return d->shadowOffset;
}
void KFileItemDelegate::setShadowBlur(qreal factor)
{
d->shadowBlur = factor;
}
qreal KFileItemDelegate::shadowBlur() const
{
return d->shadowBlur;
}
void KFileItemDelegate::setMaximumSize(const QSize &size)
{
d->maximumSize = size;
}
QSize KFileItemDelegate::maximumSize() const
{
return d->maximumSize;
}
void KFileItemDelegate::setShowToolTipWhenElided(bool showToolTip)
{
d->showToolTipWhenElided = showToolTip;
}
bool KFileItemDelegate::showToolTipWhenElided() const
{
return d->showToolTipWhenElided;
}
void KFileItemDelegate::setWrapMode(QTextOption::WrapMode wrapMode)
{
d->wrapMode = wrapMode;
}
QTextOption::WrapMode KFileItemDelegate::wrapMode() const
{
return d->wrapMode;
}
QRect KFileItemDelegate::iconRect(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItemV4 opt(option);
d->initStyleOption(&opt, index);
return QRect(d->iconPosition(opt), opt.icon.actualSize(opt.decorationSize));
}
void KFileItemDelegate::setJobTransfersVisible(bool jobTransfersVisible)
{
d->downArrowIcon = KIcon("go-down");
d->jobTransfersVisible = jobTransfersVisible;
}
bool KFileItemDelegate::jobTransfersVisible() const
{
return d->jobTransfersVisible;
}
QIcon KFileItemDelegate::Private::decoration(const QStyleOptionViewItemV4 &option, const QModelIndex &index) const
{
const QVariant value = index.data(Qt::DecorationRole);
QIcon icon;
switch (value.type())
{
case QVariant::Icon:
icon = qvariant_cast<QIcon>(value);
break;
case QVariant::Pixmap:
icon.addPixmap(qvariant_cast<QPixmap>(value));
break;
case QVariant::Color: {
QPixmap pixmap(option.decorationSize);
pixmap.fill(qvariant_cast<QColor>(value));
icon.addPixmap(pixmap);
break;
}
default:
break;
}
return icon;
}
QRect KFileItemDelegate::Private::labelRectangle(const QStyleOptionViewItemV4 &option) const
{
if (option.icon.isNull())
return subtractMargin(option.rect, Private::ItemMargin);
const QSize decoSize = addMargin(option.decorationSize, Private::IconMargin);
const QRect itemRect = subtractMargin(option.rect, Private::ItemMargin);
QRect textArea(QPoint(0, 0), itemRect.size());
switch (option.decorationPosition)
{
case QStyleOptionViewItem::Top:
textArea.setTop(decoSize.height() + 1);
break;
case QStyleOptionViewItem::Bottom:
textArea.setBottom(itemRect.height() - decoSize.height() - 1);
break;
case QStyleOptionViewItem::Left:
textArea.setLeft(decoSize.width() + 1);
break;
case QStyleOptionViewItem::Right:
textArea.setRight(itemRect.width() - decoSize.width() - 1);
break;
}
textArea.translate(itemRect.topLeft());
return QStyle::visualRect(option.direction, option.rect, textArea);
}
QPoint KFileItemDelegate::Private::iconPosition(const QStyleOptionViewItemV4 &option) const
{
const QRect itemRect = subtractMargin(option.rect, Private::ItemMargin);
Qt::Alignment alignment;
// Convert decorationPosition to the alignment the decoration will have in option.rect
switch (option.decorationPosition)
{
case QStyleOptionViewItem::Top:
alignment = Qt::AlignHCenter | Qt::AlignTop;
break;
case QStyleOptionViewItem::Bottom:
alignment = Qt::AlignHCenter | Qt::AlignBottom;
break;
case QStyleOptionViewItem::Left:
alignment = Qt::AlignVCenter | Qt::AlignLeft;
break;
case QStyleOptionViewItem::Right:
alignment = Qt::AlignVCenter | Qt::AlignRight;
break;
}
// Compute the nominal decoration rectangle
const QSize size = addMargin(option.decorationSize, Private::IconMargin);
const QRect rect = QStyle::alignedRect(option.direction, alignment, size, itemRect);
// Position the icon in the center of the rectangle
QRect iconRect = QRect(QPoint(), option.icon.actualSize(option.decorationSize));
iconRect.moveCenter(rect.center());
return iconRect.topLeft();
}
void KFileItemDelegate::Private::drawFocusRect(QPainter *painter, const QStyleOptionViewItemV4 &option,
const QRect &rect) const
{
if (!(option.state & QStyle::State_HasFocus))
return;
QStyleOptionFocusRect opt;
opt.direction = option.direction;
opt.fontMetrics = option.fontMetrics;
opt.palette = option.palette;
opt.rect = rect;
opt.state = option.state | QStyle::State_KeyboardFocusChange | QStyle::State_Item;
opt.backgroundColor = option.palette.color(option.state & QStyle::State_Selected ?
QPalette::Highlight : QPalette::Base);
// Apparently some widget styles expect this hint to not be set
painter->setRenderHint(QPainter::Antialiasing, false);
QStyle *style = option.widget ? option.widget->style() : QApplication::style();
style->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, painter, option.widget);
painter->setRenderHint(QPainter::Antialiasing);
}
void KFileItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if (!index.isValid())
return;
QStyleOptionViewItemV4 opt(option);
d->initStyleOption(&opt, index);
d->setActiveMargins(d->verticalLayout(opt) ? Qt::Vertical : Qt::Horizontal);
if (!(option.state & QStyle::State_Enabled))
{
opt.palette.setCurrentColorGroup(QPalette::Disabled);
}
// Unset the mouse over bit if we're not drawing the first column
if (index.column() > 0)
opt.state &= ~QStyle::State_MouseOver;
else
opt.viewItemPosition = QStyleOptionViewItemV4::OnlyOne;
const QAbstractItemView *view = qobject_cast<const QAbstractItemView*>(opt.widget);
// Check if the item is being animated
// ========================================================================
KIO::AnimationState *state = d->animationState(opt, index, view);
KIO::CachedRendering *cache = 0;
qreal progress = ((opt.state & QStyle::State_MouseOver) &&
index.column() == KDirModel::Name) ? 1.0 : 0.0;
const QPoint iconPos = d->iconPosition(opt);
QIcon::Mode iconMode = option.state & QStyle::State_Enabled ? QIcon::Normal : QIcon::Disabled;
QIcon::State iconState = option.state & QStyle::State_Open ? QIcon::On : QIcon::Off;
QPixmap icon = opt.icon.pixmap(opt.decorationSize, iconMode, iconState);
if (state && !state->hasJobAnimation())
{
cache = state->cachedRendering();
progress = state->hoverProgress();
// Clear the mouse over bit temporarily
opt.state &= ~QStyle::State_MouseOver;
// If we have a cached rendering, draw the item from the cache
if (cache)
{
if (cache->checkValidity(opt.state) && cache->regular.size() == opt.rect.size())
{
QPixmap pixmap = d->transition(cache->regular, cache->hover, progress);
if (state->cachedRenderingFadeFrom() && state->fadeProgress() != 1.0)
{
// Apply icon fading animation
KIO::CachedRendering* fadeFromCache = state->cachedRenderingFadeFrom();
const QPixmap fadeFromPixmap = d->transition(fadeFromCache->regular, fadeFromCache->hover, progress);
pixmap = d->transition(fadeFromPixmap, pixmap, state->fadeProgress());
}
painter->drawPixmap(option.rect.topLeft(), pixmap);
if (d->jobTransfersVisible && index.column() == 0) {
if (index.data(KDirModel::HasJobRole).toBool()) {
d->paintJobTransfers(painter, state->jobAnimationAngle(), iconPos, opt);
}
}
return;
}
if (!cache->checkValidity(opt.state))
{
if ((KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects))
{
// Fade over from the old icon to the new one
// Only start a new fade if the previous one is ready
// Else we may start racing when checkValidity() always returns false
if (state->fadeProgress() == 1)
state->setCachedRenderingFadeFrom(state->takeCachedRendering());
}
d->gotNewIcon(index);
}
// If it wasn't valid, delete it
state->setCachedRendering(0);
}
else
{
// The cache may have been discarded, but the animation handler still needs to know about new icons
d->gotNewIcon(index);
}
}
// Compute the metrics, and lay out the text items
// ========================================================================
const QPen pen = QPen(d->foregroundBrush(opt, index), 0);
//### Apply the selection effect to the icon when the item is selected and
// showDecorationSelected is false.
QTextLayout labelLayout, infoLayout;
QRect textBoundingRect;
d->layoutTextItems(opt, index, &labelLayout, &infoLayout, &textBoundingRect);
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
int focusHMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin);
int focusVMargin = style->pixelMetric(QStyle::PM_FocusFrameVMargin);
QRect focusRect = textBoundingRect.adjusted(-focusHMargin, -focusVMargin,
+focusHMargin, +focusVMargin);
// Create a new cached rendering of a hovered and an unhovered item.
// We don't create a new cache for a fully hovered item, since we don't
// know yet if a hover out animation will be run.
// ========================================================================
if (state && (state->hoverProgress() < 1 || state->fadeProgress() < 1))
{
cache = new KIO::CachedRendering(opt.state, option.rect.size(), index);
QPainter p;
p.begin(&cache->regular);
p.translate(-option.rect.topLeft());
p.setRenderHint(QPainter::Antialiasing);
p.setPen(pen);
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, &p, opt.widget);
p.drawPixmap(iconPos, icon);
d->drawTextItems(&p, labelLayout, infoLayout, textBoundingRect);
d->drawFocusRect(&p, opt, focusRect);
p.end();
opt.state |= QStyle::State_MouseOver;
icon = d->applyHoverEffect(icon);
p.begin(&cache->hover);
p.translate(-option.rect.topLeft());
p.setRenderHint(QPainter::Antialiasing);
p.setPen(pen);
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, &p, opt.widget);
p.drawPixmap(iconPos, icon);
d->drawTextItems(&p, labelLayout, infoLayout, textBoundingRect);
d->drawFocusRect(&p, opt, focusRect);
p.end();
state->setCachedRendering(cache);
QPixmap pixmap = d->transition(cache->regular, cache->hover, progress);
if (state->cachedRenderingFadeFrom() && state->fadeProgress() == 0)
{
// Apply icon fading animation
KIO::CachedRendering* fadeFromCache = state->cachedRenderingFadeFrom();
const QPixmap fadeFromPixmap = d->transition(fadeFromCache->regular, fadeFromCache->hover, progress);
pixmap = d->transition(fadeFromPixmap, pixmap, state->fadeProgress());
d->restartAnimation(state);
}
painter->drawPixmap(option.rect.topLeft(), pixmap);
painter->setRenderHint(QPainter::Antialiasing);
if (d->jobTransfersVisible && index.column() == 0) {
if (index.data(KDirModel::HasJobRole).toBool()) {
d->paintJobTransfers(painter, state->jobAnimationAngle(), iconPos, opt);
}
}
return;
}
// Render the item directly if we're not using a cached rendering
// ========================================================================
painter->save();
painter->setRenderHint(QPainter::Antialiasing);
painter->setPen(pen);
if (progress > 0 && !(opt.state & QStyle::State_MouseOver))
{
opt.state |= QStyle::State_MouseOver;
icon = d->applyHoverEffect(icon);
}
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
painter->drawPixmap(iconPos, icon);
d->drawTextItems(painter, labelLayout, infoLayout, textBoundingRect);
d->drawFocusRect(painter, opt, focusRect);
if (d->jobTransfersVisible && index.column() == 0 && state) {
if (index.data(KDirModel::HasJobRole).toBool()) {
d->paintJobTransfers(painter, state->jobAnimationAngle(), iconPos, opt);
}
}
painter->restore();
}
QWidget *KFileItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QStyleOptionViewItemV4 opt(option);
d->initStyleOption(&opt, index);
KTextEdit *edit = new KTextEdit(parent);
edit->setAcceptRichText(false);
edit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
edit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
edit->setAlignment(opt.displayAlignment);
edit->setEnabled(false); //Disable the text-edit to mark it as un-initialized
return edit;
}
bool KFileItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
const QModelIndex &index)
{
Q_UNUSED(event)
Q_UNUSED(model)
Q_UNUSED(option)
Q_UNUSED(index)
return false;
}
void KFileItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
KTextEdit *textedit = qobject_cast<KTextEdit*>(editor);
Q_ASSERT(textedit != 0);
//Do not update existing text that the user may already have edited.
//The models will call setEditorData(..) whenever the icon has changed,
//and this makes the editing work correctly despite that.
if(textedit->isEnabled()) {
return;
}
textedit->setEnabled(true); //Enable the text-edit to mark it as initialized
const QVariant value = index.data(Qt::EditRole);
const QString text = value.toString();
textedit->insertPlainText(text);
textedit->selectAll();
const QString extension = KMimeType::extractKnownExtension(text);
if (!extension.isEmpty()) {
// The filename contains an extension. Assure that only the filename
// gets selected.
const int selectionLength = text.length() - extension.length() - 1;
QTextCursor cursor = textedit->textCursor();
cursor.movePosition(QTextCursor::StartOfBlock);
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, selectionLength);
textedit->setTextCursor(cursor);
}
}
void KFileItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
KTextEdit *textedit = qobject_cast<KTextEdit*>(editor);
Q_ASSERT(textedit != 0);
model->setData(index, textedit->toPlainText(), Qt::EditRole);
}
void KFileItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QStyleOptionViewItemV4 opt(option);
d->initStyleOption(&opt, index);
d->setActiveMargins(d->verticalLayout(opt) ? Qt::Vertical : Qt::Horizontal);
QRect r = d->labelRectangle(opt);
// Use the full available width for the editor when maximumSize is set
if (!d->maximumSize.isEmpty()) {
if (d->verticalLayout(option)) {
int diff = qMax(r.width(), d->maximumSize.width()) - r.width();
if (diff > 1) {
r.adjust(-(diff / 2), 0, diff / 2, 0);
}
}
else {
int diff = qMax(r.width(), d->maximumSize.width() - opt.decorationSize.width()) - r.width();
if (diff > 0) {
if (opt.decorationPosition == QStyleOptionViewItem::Left) {
r.adjust(0, 0, diff, 0);
}
else {
r.adjust(-diff, 0, 0, 0);
}
}
}
}
KTextEdit *textedit = qobject_cast<KTextEdit*>(editor);
Q_ASSERT(textedit != 0);
const int frame = textedit->frameWidth();
r.adjust(-frame, -frame, frame, frame);
editor->setGeometry(r);
}
bool KFileItemDelegate::helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option,
const QModelIndex &index)
{
Q_UNUSED(event)
Q_UNUSED(view)
// if the tooltip information the model keeps is different from the display information,
// show it always
const QVariant toolTip = index.data(Qt::ToolTipRole);
if (!toolTip.isValid()) {
return false;
}
if (index.data() != toolTip) {
return QAbstractItemDelegate::helpEvent(event, view, option, index);
}
if (!d->showToolTipWhenElided) {
return false;
}
// in the case the tooltip information is the same as the display information,
// show it only in the case the display information is elided
QStyleOptionViewItemV4 opt(option);
d->initStyleOption(&opt, index);
d->setActiveMargins(d->verticalLayout(opt) ? Qt::Vertical : Qt::Horizontal);
QTextLayout labelLayout;
QTextLayout infoLayout;
QRect textBoundingRect;
d->layoutTextItems(opt, index, &labelLayout, &infoLayout, &textBoundingRect);
const QString elidedText = d->elidedText(labelLayout, opt, textBoundingRect.size());
if (elidedText != d->display(index)) {
return QAbstractItemDelegate::helpEvent(event, view, option, index);
}
return false;
}
QRegion KFileItemDelegate::shape(const QStyleOptionViewItem &option, const QModelIndex &index)
{
QStyleOptionViewItemV4 opt(option);
d->initStyleOption(&opt, index);
d->setActiveMargins(d->verticalLayout(opt) ? Qt::Vertical : Qt::Horizontal);
QTextLayout labelLayout;
QTextLayout infoLayout;
QRect textBoundingRect;
d->layoutTextItems(opt, index, &labelLayout, &infoLayout, &textBoundingRect);
const QPoint pos = d->iconPosition(opt);
QRect iconRect = QRect(pos, opt.icon.actualSize(opt.decorationSize));
// Extend the icon rect so it touches the text rect
switch (opt.decorationPosition)
{
case QStyleOptionViewItem::Top:
if (iconRect.width() < textBoundingRect.width())
iconRect.setBottom(textBoundingRect.top());
else
textBoundingRect.setTop(iconRect.bottom());
break;
case QStyleOptionViewItem::Bottom:
if (iconRect.width() < textBoundingRect.width())
iconRect.setTop(textBoundingRect.bottom());
else
textBoundingRect.setBottom(iconRect.top());
break;
case QStyleOptionViewItem::Left:
iconRect.setRight(textBoundingRect.left());
break;
case QStyleOptionViewItem::Right:
iconRect.setLeft(textBoundingRect.right());
break;
}
QRegion region;
region += iconRect;
region += textBoundingRect;
return region;
}
bool KFileItemDelegate::eventFilter(QObject *object, QEvent *event)
{
KTextEdit *editor = qobject_cast<KTextEdit*>(object);
if (!editor)
return false;
switch (event->type())
{
case QEvent::KeyPress:
{
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
switch (keyEvent->key())
{
case Qt::Key_Tab:
case Qt::Key_Backtab:
emit commitData(editor);
emit closeEditor(editor, NoHint);
return true;
case Qt::Key_Enter:
case Qt::Key_Return: {
const QString text = editor->toPlainText();
if (text.isEmpty() || (text == QLatin1String(".")) || (text == QLatin1String("..")))
return true; // So a newline doesn't get inserted
emit commitData(editor);
emit closeEditor(editor, SubmitModelCache);
return true;
}
case Qt::Key_Escape:
emit closeEditor(editor, RevertModelCache);
return true;
default:
return false;
} // switch (keyEvent->key())
} // case QEvent::KeyPress
case QEvent::FocusOut:
{
const QWidget *w = QApplication::activePopupWidget();
if (!w || w->parent() != editor)
{
emit commitData(editor);
emit closeEditor(editor, NoHint);
return true;
}
else
return false;
}
default:
return false;
} // switch (event->type())
}
// kate: space-indent on; indent-width 4; replace-tabs on;
diff --git a/kio/kio/kmimetypechooser.cpp b/kio/kio/kmimetypechooser.cpp
index 2e97811e91..0269612576 100644
--- a/kio/kio/kmimetypechooser.cpp
+++ b/kio/kio/kmimetypechooser.cpp
@@ -1,355 +1,356 @@
/* This file is part of the KDE libraries
Copyright (C) 2001 - 2004 Anders Lund <anders@alweb.dk>
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 "kmimetypechooser.h"
+#include <kicon.h>
#include <klocale.h>
#include <kmimetype.h>
#include <kshell.h>
#include <krun.h>
#include <ksycoca.h>
#include <QLabel>
#include <QLayout>
#include <QPushButton>
#include <QTreeWidget>
#include <kconfiggroup.h>
//BEGIN KMimeTypeChooserPrivate
class KMimeTypeChooserPrivate
{
public:
KMimeTypeChooserPrivate( KMimeTypeChooser *parent )
: q(parent),
mimeTypeTree(0),
btnEditMimeType(0)
{
}
void loadMimeTypes( const QStringList &selected = QStringList() );
void _k_editMimeType();
void _k_slotCurrentChanged(QTreeWidgetItem*);
void _k_slotSycocaDatabaseChanged(const QStringList&);
KMimeTypeChooser *q;
QTreeWidget *mimeTypeTree;
QPushButton *btnEditMimeType;
QString defaultgroup;
QStringList groups;
int visuals;
};
//END
//BEGIN KMimeTypeChooser
KMimeTypeChooser::KMimeTypeChooser( const QString &text,
const QStringList &selMimeTypes,
const QString &defaultGroup,
const QStringList &groupsToShow,
int visuals,
QWidget *parent )
: KVBox( parent ),
d(new KMimeTypeChooserPrivate(this))
{
d->defaultgroup = defaultGroup;
d->groups = groupsToShow;
d->visuals = visuals;
setSpacing(-1);
if ( !text.isEmpty() )
{
new QLabel( text, this );
}
d->mimeTypeTree = new QTreeWidget( this );
QStringList headerLabels;
headerLabels.append( i18n("Mime Type") );
// d->mimeTypeTree->setColumnWidthMode( 0, QListView::Manual );
if ( visuals & Comments ) {
headerLabels.append( i18n("Comment") );
//d->mimeTypeTree->setColumnWidthMode( 1, Q3ListView::Manual );
}
if ( visuals & Patterns ) {
headerLabels.append( i18n("Patterns") );
}
// d->mimeTypeTree->setRootIsDecorated( true );
d->mimeTypeTree->setColumnCount(headerLabels.count());
d->mimeTypeTree->setHeaderLabels(headerLabels);
d->loadMimeTypes( selMimeTypes );
if (visuals & EditButton)
{
KHBox *btns = new KHBox( this );
((QBoxLayout*)btns->layout())->addStretch(1);
d->btnEditMimeType = new QPushButton( i18n("&Edit..."), btns );
connect( d->btnEditMimeType, SIGNAL(clicked()), this, SLOT(_k_editMimeType()) );
d->btnEditMimeType->setEnabled( false );
connect( d->mimeTypeTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
this, SLOT(_k_editMimeType()));
connect( d->mimeTypeTree, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
this, SLOT(_k_slotCurrentChanged(QTreeWidgetItem*)) );
d->btnEditMimeType->setWhatsThis(i18n(
"Click this button to display the familiar KDE mime type editor.") );
}
}
KMimeTypeChooser::~KMimeTypeChooser()
{
delete d;
}
void KMimeTypeChooserPrivate::loadMimeTypes( const QStringList &_selectedMimeTypes )
{
QStringList selMimeTypes;
if ( !_selectedMimeTypes.isEmpty() )
selMimeTypes = _selectedMimeTypes;
else
selMimeTypes = q->mimeTypes();
mimeTypeTree->clear();
QMap<QString, QTreeWidgetItem*> groupItems;
const KMimeType::List mimetypes = KMimeType::allMimeTypes();
bool agroupisopen = false;
QTreeWidgetItem *idefault = 0; //open this, if all other fails
QTreeWidgetItem *firstChecked = 0; // make this one visible after the loop
foreach (const KMimeType::Ptr& mt, mimetypes)
{
const QString mimetype = mt->name();
const int index = mimetype.indexOf('/');
const QString maj = mimetype.left(index);
if ( !groups.isEmpty() && !groups.contains( maj ) )
continue;
QTreeWidgetItem *groupItem;
QMap<QString,QTreeWidgetItem*>::Iterator mit = groupItems.find( maj );
if ( mit == groupItems.end() )
{
groupItem = new QTreeWidgetItem( mimeTypeTree, QStringList(maj) );
groupItems.insert( maj, groupItem );
if ( maj == defaultgroup )
idefault = groupItem;
}
else
groupItem = mit.value();
const QString min = mimetype.mid(index+1);
QTreeWidgetItem *item = new QTreeWidgetItem( groupItem, QStringList(min) );
item->setIcon( 0, KIcon( mt->iconName() ) );
int cl = 1;
if ( visuals & KMimeTypeChooser::Comments )
{
item->setText( cl, mt->comment() );
cl++;
}
if ( visuals & KMimeTypeChooser::Patterns )
item->setText( cl, mt->patterns().join("; ") );
if ( selMimeTypes.contains(mimetype) ) {
item->setCheckState( 0, Qt::Checked );
groupItem->setExpanded( true );
agroupisopen = true;
if ( !firstChecked )
firstChecked = item;
} else {
item->setCheckState( 0, Qt::Unchecked );
}
}
if ( firstChecked )
mimeTypeTree->scrollToItem( firstChecked );
if ( !agroupisopen && idefault )
{
idefault->setExpanded( true );
mimeTypeTree->scrollToItem( idefault );
}
}
void KMimeTypeChooserPrivate::_k_editMimeType()
{
QTreeWidgetItem* item = mimeTypeTree->currentItem();
if ( !item || !item->parent() )
return;
QString mt = (item->parent())->text(0) + '/' + item->text(0);
// thanks to libkonq/konq_operations.cc
q->connect( KSycoca::self(), SIGNAL(databaseChanged(QStringList)),
q, SLOT(_k_slotSycocaDatabaseChanged(QStringList)) );
QString keditfiletype = QString::fromLatin1("keditfiletype");
KRun::runCommand( keditfiletype
#ifndef Q_OS_WIN
+ " --parent " + QString::number( (ulong)q->topLevelWidget()->winId())
#endif
+ ' ' + KShell::quoteArg(mt),
keditfiletype, keditfiletype /*unused*/, q->topLevelWidget());
}
void KMimeTypeChooserPrivate::_k_slotCurrentChanged(QTreeWidgetItem* item)
{
if ( btnEditMimeType )
btnEditMimeType->setEnabled( item->parent() );
}
void KMimeTypeChooserPrivate::_k_slotSycocaDatabaseChanged(const QStringList& changedResources)
{
if (changedResources.contains("xdgdata-mime"))
loadMimeTypes();
}
// recursive helper for mimeTypes()
static void getCheckedItems(QList<QTreeWidgetItem *> &lst, QTreeWidgetItem* parent)
{
for (int i = 0; i < parent->childCount(); ++i ) {
QTreeWidgetItem* item = parent->child(i);
if (item->checkState(0) == Qt::Checked)
lst.append(item);
getCheckedItems(lst, item);
}
}
static void getCheckedItems(QList<QTreeWidgetItem *>& lst, QTreeWidget* tree)
{
for (int i = 0; i < tree->topLevelItemCount(); ++i ) {
QTreeWidgetItem* topItem = tree->topLevelItem(i);
//if (topItem->checkState(0) == Qt::Checked)
// lst.append(topItem);
getCheckedItems(lst, topItem);
}
}
QStringList KMimeTypeChooser::mimeTypes() const
{
QStringList mimeList;
QList<QTreeWidgetItem *> checkedItems;
getCheckedItems(checkedItems, d->mimeTypeTree);
foreach(QTreeWidgetItem* item, checkedItems) {
mimeList.append( item->parent()->text(0) + '/' + item->text(0) );
}
return mimeList;
}
QStringList KMimeTypeChooser::patterns() const
{
QStringList patternList;
QList<QTreeWidgetItem *> checkedItems;
getCheckedItems(checkedItems, d->mimeTypeTree);
foreach(QTreeWidgetItem* item, checkedItems) {
KMimeType::Ptr p = KMimeType::mimeType( item->parent()->text(0) + '/' + item->text(0) );
Q_ASSERT(p);
patternList += p->patterns();
}
return patternList;
}
//END
//BEGIN KMimeTypeChooserDialog::Private
class KMimeTypeChooserDialog::Private
{
public:
Private( KMimeTypeChooserDialog *parent )
: q(parent)
{
}
void init();
KMimeTypeChooserDialog *q;
KMimeTypeChooser *m_chooser;
};
//END
//BEGIN KMimeTypeChooserDialog
KMimeTypeChooserDialog::KMimeTypeChooserDialog(
const QString &caption,
const QString& text,
const QStringList &selMimeTypes,
const QString &defaultGroup,
const QStringList &groupsToShow,
int visuals,
QWidget *parent )
: KDialog( parent ), d(new Private(this))
{
setCaption( caption );
d->init();
d->m_chooser = new KMimeTypeChooser( text, selMimeTypes,
defaultGroup, groupsToShow, visuals,
this );
setMainWidget(d->m_chooser);
}
KMimeTypeChooserDialog::KMimeTypeChooserDialog(
const QString &caption,
const QString& text,
const QStringList &selMimeTypes,
const QString &defaultGroup,
QWidget *parent )
: KDialog( parent ), d(new Private(this))
{
setCaption( caption );
d->init();
d->m_chooser = new KMimeTypeChooser( text, selMimeTypes,
defaultGroup, QStringList(),
KMimeTypeChooser::Comments|KMimeTypeChooser::Patterns|KMimeTypeChooser::EditButton,
this );
setMainWidget(d->m_chooser);
}
KMimeTypeChooser* KMimeTypeChooserDialog::chooser()
{
return d->m_chooser;
}
void KMimeTypeChooserDialog::Private::init()
{
q->setButtons( Cancel | Ok );
q->setModal( true );
q->setDefaultButton( Ok );
KConfigGroup group( KGlobal::config(), "KMimeTypeChooserDialog");
q->resize( group.readEntry("size", QSize(500,400)));
}
KMimeTypeChooserDialog::~KMimeTypeChooserDialog()
{
KConfigGroup group( KGlobal::config(), "KMimeTypeChooserDialog");
group.writeEntry("size", size());
delete d;
}
//END KMimeTypeChooserDialog
// kate: space-indent on; indent-width 2; replace-tabs on;
#include "moc_kmimetypechooser.cpp"
diff --git a/kioslave/http/kcookiejar/kcookiewin.cpp b/kioslave/http/kcookiejar/kcookiewin.cpp
index 6d7b4f29e2..82b926e92f 100644
--- a/kioslave/http/kcookiejar/kcookiewin.cpp
+++ b/kioslave/http/kcookiejar/kcookiewin.cpp
@@ -1,313 +1,314 @@
/*
This file is part of KDE
Copyright (C) 2000- Waldo Bastian <bastian@kde.org>
Copyright (C) 2000- Dawit Alemayehu <adawit@kde.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
//----------------------------------------------------------------------------
//
// KDE File Manager -- HTTP Cookie Dialogs
// The purpose of the QT_NO_TOOLTIP and QT_NO_WHATSTHIS ifdefs is because
// this file is also used in Konqueror/Embedded. One of the aims of
// Konqueror/Embedded is to be a small as possible to fit on embedded
// devices. For this it's also useful to strip out unneeded features of
// Qt, like for example QToolTip or QWhatsThis. The availability (or the
// lack thereof) can be determined using these preprocessor defines.
// The same applies to the QT_NO_ACCEL ifdef below. I hope it doesn't make
// too much trouble... (Simon)
#include "kcookiewin.h"
#include "kcookiejar.h"
#include <QLabel>
#include <QLayout>
#include <QGroupBox>
#include <QPushButton>
#include <QRadioButton>
#include <QShortcut>
+#include <kicon.h>
#include <kwindowsystem.h>
#include <klocale.h>
#include <kglobal.h>
#include <klineedit.h>
#include <kiconloader.h>
#include <kapplication.h>
#include <kvbox.h>
#include <kdatetime.h>
KCookieWin::KCookieWin( QWidget *parent, KHttpCookieList cookieList,
int defaultButton, bool showDetails )
:KDialog( parent )
{
setModal(true);
setObjectName("cookiealert");
setButtons(Yes|No|Details);
#ifndef Q_WS_QWS //FIXME(E): Implement for Qt Embedded
setCaption( i18n("Cookie Alert") );
setWindowIcon( KIcon("preferences-web-browser-cookies") );
// all cookies in the list should have the same window at this time, so let's take the first
if( cookieList.first().windowIds().count() > 0 )
{
#ifndef KDE_NO_WINDOWSYSTEM
#ifdef Q_WS_WIN
KWindowSystem::setMainWindow( this, reinterpret_cast<WId>( cookieList.first().windowIds().first() ) );
#else
KWindowSystem::setMainWindow( this, cookieList.first().windowIds().first());
#endif
#else
#warning QT5 PORT TO QPA
#endif
}
else
{
// No window associated... make sure the user notices our dialog.
#ifdef Q_WS_X11
KWindowSystem::setState( winId(), NET::KeepAbove );
#endif
kapp->updateUserTimestamp();
}
#endif
KVBox* vBox1 = new KVBox( this );
vBox1->setSpacing( -1 );
setMainWidget(vBox1);
// Cookie image and message to user
KHBox* hBox = new KHBox( vBox1 );
QLabel* icon = new QLabel( hBox );
icon->setPixmap(KIcon("dialog-warning").pixmap(IconSize(KIconLoader::Desktop)));
icon->setAlignment( Qt::AlignCenter );
icon->setFixedSize( 2*icon->sizeHint() );
int count = cookieList.count();
KVBox* vBox = new KVBox( hBox );
QString txt = i18np("You received a cookie from",
"You received %1 cookies from", count);
QLabel* lbl = new QLabel( txt, vBox );
lbl->setAlignment( Qt::AlignCenter );
const KHttpCookie& cookie = cookieList.first();
QString host (cookie.host());
int pos = host.indexOf(':');
if ( pos > 0 )
{
QString portNum = host.left(pos);
host.remove(0, pos+1);
host += ':';
host += portNum;
}
txt = QString("<b>%1</b>").arg( QUrl::fromAce(host.toLatin1()) );
if (cookie.isCrossDomain())
txt += i18n(" <b>[Cross Domain]</b>");
lbl = new QLabel( txt, vBox );
lbl->setAlignment( Qt::AlignCenter );
lbl = new QLabel( i18n("Do you want to accept or reject?"), vBox );
lbl->setAlignment( Qt::AlignCenter );
// Cookie Details dialog...
m_detailView = new KCookieDetail( cookieList, count, vBox1 );
setDetailsWidget(m_detailView);
// Cookie policy choice...
QGroupBox *m_btnGrp = new QGroupBox(i18n("Apply Choice To"),vBox1);
QVBoxLayout *vbox = new QVBoxLayout;
txt = (count == 1)? i18n("&Only this cookie") : i18n("&Only these cookies");
m_onlyCookies = new QRadioButton( txt, m_btnGrp );
vbox->addWidget(m_onlyCookies);
#ifndef QT_NO_WHATSTHIS
m_onlyCookies->setWhatsThis(i18n("Select this option to accept/reject only this cookie. "
"You will be prompted if another cookie is received. "
"<em>(see WebBrowsing/Cookies in the System Settings)</em>." ) );
#endif
m_allCookiesDomain = new QRadioButton( i18n("All cookies from this do&main"), m_btnGrp );
vbox->addWidget(m_allCookiesDomain);
#ifndef QT_NO_WHATSTHIS
m_allCookiesDomain->setWhatsThis(i18n("Select this option to accept/reject all cookies from "
"this site. Choosing this option will add a new policy for "
"the site this cookie originated from. This policy will be "
"permanent until you manually change it from the System Settings "
"<em>(see WebBrowsing/Cookies in the System Settings)</em>.") );
#endif
m_allCookies = new QRadioButton( i18n("All &cookies"), m_btnGrp);
vbox->addWidget(m_allCookies);
#ifndef QT_NO_WHATSTHIS
m_allCookies->setWhatsThis(i18n("Select this option to accept/reject all cookies from "
"anywhere. Choosing this option will change the global "
"cookie policy set in the System Settings for all cookies "
"<em>(see WebBrowsing/Cookies in the System Settings)</em>.") );
#endif
m_btnGrp->setLayout(vbox);
if (defaultButton == KCookieJar::ApplyToShownCookiesOnly )
m_onlyCookies->setChecked(true);
else if (defaultButton == KCookieJar::ApplyToCookiesFromDomain)
m_allCookiesDomain->setChecked(true);
else if (defaultButton == KCookieJar::ApplyToAllCookies)
m_allCookies->setChecked(true);
else
m_onlyCookies->setChecked(true);
setButtonText(KDialog::Yes, i18n("&Accept"));
setButtonText(KDialog::No, i18n("&Reject"));
//QShortcut( Qt::Key_Escape, btn, SLOT(animateClick()) );
setButtonToolTip(Details, i18n("See or modify the cookie information") );
setDefaultButton(Yes);
setDetailsWidgetVisible(showDetails);
}
KCookieWin::~KCookieWin()
{
}
KCookieAdvice KCookieWin::advice( KCookieJar *cookiejar, const KHttpCookie& cookie )
{
int result = exec();
cookiejar->setShowCookieDetails ( isDetailsWidgetVisible() );
KCookieAdvice advice = (result==KDialog::Yes) ? KCookieAccept : KCookieReject;
KCookieJar::KCookieDefaultPolicy preferredPolicy = KCookieJar::ApplyToShownCookiesOnly;
if (m_allCookiesDomain->isChecked()) {
preferredPolicy = KCookieJar::ApplyToCookiesFromDomain;
cookiejar->setDomainAdvice( cookie, advice );
} else if (m_allCookies->isChecked()) {
preferredPolicy = KCookieJar::ApplyToAllCookies;
cookiejar->setGlobalAdvice( advice );
}
cookiejar->setPreferredDefaultPolicy( preferredPolicy );
return advice;
}
KCookieDetail::KCookieDetail( KHttpCookieList cookieList, int cookieCount,
QWidget* parent )
:QGroupBox( parent )
{
setTitle( i18n("Cookie Details") );
QGridLayout* grid = new QGridLayout( this );
grid->addItem( new QSpacerItem(0, fontMetrics().lineSpacing()), 0, 0 );
grid->setColumnStretch( 1, 3 );
QLabel* label = new QLabel( i18n("Name:"), this );
grid->addWidget( label, 1, 0 );
m_name = new KLineEdit( this );
m_name->setReadOnly( true );
m_name->setMaximumWidth( fontMetrics().maxWidth() * 25 );
grid->addWidget( m_name, 1 ,1 );
//Add the value
label = new QLabel( i18n("Value:"), this );
grid->addWidget( label, 2, 0 );
m_value = new KLineEdit( this );
m_value->setReadOnly( true );
m_value->setMaximumWidth( fontMetrics().maxWidth() * 25 );
grid->addWidget( m_value, 2, 1);
label = new QLabel( i18n("Expires:"), this );
grid->addWidget( label, 3, 0 );
m_expires = new KLineEdit( this );
m_expires->setReadOnly( true );
m_expires->setMaximumWidth(fontMetrics().maxWidth() * 25 );
grid->addWidget( m_expires, 3, 1);
label = new QLabel( i18n("Path:"), this );
grid->addWidget( label, 4, 0 );
m_path = new KLineEdit( this );
m_path->setReadOnly( true );
m_path->setMaximumWidth( fontMetrics().maxWidth() * 25 );
grid->addWidget( m_path, 4, 1);
label = new QLabel( i18n("Domain:"), this );
grid->addWidget( label, 5, 0 );
m_domain = new KLineEdit( this );
m_domain->setReadOnly( true );
m_domain->setMaximumWidth( fontMetrics().maxWidth() * 25 );
grid->addWidget( m_domain, 5, 1);
label = new QLabel( i18n("Exposure:"), this );
grid->addWidget( label, 6, 0 );
m_secure = new KLineEdit( this );
m_secure->setReadOnly( true );
m_secure->setMaximumWidth( fontMetrics().maxWidth() * 25 );
grid->addWidget( m_secure, 6, 1 );
if ( cookieCount > 1 )
{
QPushButton* btnNext = new QPushButton( i18nc("Next cookie","&Next >>"), this );
btnNext->setFixedSize( btnNext->sizeHint() );
grid->addWidget( btnNext, 8, 0, 1, 2 );
connect( btnNext, SIGNAL(clicked()), SLOT(slotNextCookie()) );
#ifndef QT_NO_TOOLTIP
btnNext->setToolTip(i18n("Show details of the next cookie") );
#endif
}
m_cookieList = cookieList;
m_cookieNumber = 0;
slotNextCookie();
}
KCookieDetail::~KCookieDetail()
{
}
void KCookieDetail::slotNextCookie()
{
if (m_cookieNumber == m_cookieList.count() - 1)
m_cookieNumber = 0;
else
++m_cookieNumber;
displayCookieDetails();
}
void KCookieDetail::displayCookieDetails()
{
const KHttpCookie& cookie = m_cookieList.at(m_cookieNumber);
m_name->setText(cookie.name());
m_value->setText((cookie.value()));
if (cookie.domain().isEmpty())
m_domain->setText(i18n("Not specified"));
else
m_domain->setText(cookie.domain());
m_path->setText(cookie.path());
KDateTime cookiedate;
cookiedate.setTime_t(cookie.expireDate());
if (cookie.expireDate())
m_expires->setText(KGlobal::locale()->formatDateTime(cookiedate));
else
m_expires->setText(i18n("End of Session"));
QString sec;
if (cookie.isSecure())
{
if (cookie.isHttpOnly())
sec = i18n("Secure servers only");
else
sec = i18n("Secure servers, page scripts");
}
else
{
if (cookie.isHttpOnly())
sec = i18n("Servers");
else
sec = i18n("Servers, page scripts");
}
m_secure->setText(sec);
}
diff --git a/knewstuff/knewstuff2/ui/itemsviewdelegate.h b/knewstuff/knewstuff2/ui/itemsviewdelegate.h
index 7ed5ad5df3..d07f81091f 100644
--- a/knewstuff/knewstuff2/ui/itemsviewdelegate.h
+++ b/knewstuff/knewstuff2/ui/itemsviewdelegate.h
@@ -1,80 +1,80 @@
/*
This file is part of KNewStuff2.
Copyright (C) 2008 Jeremy Whiting <jpwhiting@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KNEWSTUFF2_UI_ITEMSVIEWDELEGATE_H
#define KNEWSTUFF2_UI_ITEMSVIEWDELEGATE_H
#include <kwidgetitemdelegate.h>
#include <QtCore/QMap>
#include <QtCore/QModelIndex>
#include <QtCore/QObject>
#include <QImage>
#include <QLabel>
#include <QToolButton>
#include <knewstuff2/core/entry.h>
#include <knewstuff2/ui/downloaddialog.h>
#include <kicon.h>
#include <kmenu.h>
namespace KNS
{
class ItemsViewDelegate: public KWidgetItemDelegate
{
Q_OBJECT
public:
explicit ItemsViewDelegate(QAbstractItemView *itemView, QObject * parent = 0);
~ItemsViewDelegate();
// paint the item at index with all its attributes shown
virtual void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
// get the list of widgets
virtual QList<QWidget*> createItemWidgets() const;
// update the widgets
virtual void updateItemWidgets(const QList<QWidget*> widgets,
const QStyleOptionViewItem &option,
const QPersistentModelIndex &index) const;
virtual QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const;
signals:
void performAction(DownloadDialog::EntryAction action, KNS::Entry * entry);
//protected:
//virtual bool eventFilter(QObject *watched, QEvent *event);
private slots:
void slotActionTriggered(QAction *action);
void slotInstallClicked();
void slotLinkClicked(const QString & url);
private:
KMenu * InstallMenu(const QToolButton* button, Entry::Status status) const;
- QList<KIcon> m_statusicons;
+ QList<QIcon> m_statusicons;
QImage m_frameImage;
};
}
#endif
diff --git a/knewstuff/knewstuff2/ui/knewstuffaction.cpp b/knewstuff/knewstuff2/ui/knewstuffaction.cpp
index a34c63a26c..9a1294229d 100644
--- a/knewstuff/knewstuff2/ui/knewstuffaction.cpp
+++ b/knewstuff/knewstuff2/ui/knewstuffaction.cpp
@@ -1,39 +1,40 @@
/*
This file is part of KNewStuff2.
Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "knewstuffaction.h"
#include <kaction.h>
#include <klocale.h>
#include <kactioncollection.h>
+#include <kicon.h>
using namespace KNS;
KAction *KNS::standardAction(const QString &what,
const QObject *receiver,
const char *slot, KActionCollection *parent,
const char *name)
{
KAction *action = new KAction(what, parent);
parent->addAction(QString(name), action);
action->setIcon(KIcon("get-hot-new-stuff"));
QObject::connect(action, SIGNAL(triggered(bool)), receiver, slot);
return action;
}
diff --git a/knewstuff/knewstuff3/knewstuffaction.cpp b/knewstuff/knewstuff3/knewstuffaction.cpp
index c69c2a196f..247c2bc986 100644
--- a/knewstuff/knewstuff3/knewstuffaction.cpp
+++ b/knewstuff/knewstuff3/knewstuffaction.cpp
@@ -1,52 +1,53 @@
/*
This file is part of KNewStuff2.
Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "knewstuffaction.h"
#include <kaction.h>
#include <klocale.h>
+#include <kicon.h>
#include <kactioncollection.h>
using namespace KNS3;
KAction *KNS3::standardAction(const QString &what,
const QObject *receiver,
const char *slot, KActionCollection *parent,
const char *name)
{
KAction *action = new KAction(what, parent);
parent->addAction(QString(name), action);
action->setIcon(KIcon("get-hot-new-stuff"));
QObject::connect(action, SIGNAL(triggered(bool)), receiver, slot);
return action;
}
KAction *KNS3::standardActionUpload(const QString &what,
const QObject *receiver,
const char *slot, KActionCollection *parent,
const char *name)
{
KAction *action = new KAction(what, parent);
parent->addAction(QString(name), action);
// FIXME: Get a specific upload icon!
action->setIcon(KIcon("get-hot-new-stuff"));
QObject::connect(action, SIGNAL(triggered(bool)), receiver, slot);
return action;
}
diff --git a/knewstuff/knewstuff3/ui/itemsgridviewdelegate.cpp b/knewstuff/knewstuff3/ui/itemsgridviewdelegate.cpp
index 2e533c0eb3..f849721e51 100644
--- a/knewstuff/knewstuff3/ui/itemsgridviewdelegate.cpp
+++ b/knewstuff/knewstuff3/ui/itemsgridviewdelegate.cpp
@@ -1,378 +1,378 @@
/*
Copyright (C) 2008 Jeremy Whiting <jpwhiting@kde.org>
Copyright (C) 2010 Reza Fatahilah Shah <rshah0385@kireihana.com>
Copyright (C) 2010 Frederik Gladhorn <gladhorn@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "itemsgridviewdelegate.h"
#include <QPainter>
#include <QSortFilterProxyModel>
#include <QApplication>
#include <QLabel>
#include <QToolButton>
#include <QMenu>
#include <QHBoxLayout>
#include <QAbstractItemView>
#include <kdebug.h>
#include <klocale.h>
#include <kmenu.h>
#include <kratingwidget.h>
#include <ksqueezedtextlabel.h>
#include "itemsmodel.h"
namespace KNS3
{
enum { DelegateTitleLabel, DelegateAuthorLabel, DelegateDownloadCounterLabel,
DelegateGridRatingWidget };
ItemsGridViewDelegate::ItemsGridViewDelegate(QAbstractItemView *itemView, Engine* engine, QObject * parent)
: ItemsViewBaseDelegate(itemView, engine, parent)
,m_elementYPos(0)
{
createOperationBar();
}
ItemsGridViewDelegate::~ItemsGridViewDelegate()
{
}
QList<QWidget*> ItemsGridViewDelegate::createItemWidgets() const
{
QList<QWidget*> m_widgetList;
KSqueezedTextLabel * titleLabel = new KSqueezedTextLabel();
titleLabel->setOpenExternalLinks(true);
titleLabel->setTextElideMode(Qt::ElideRight);
// not so nice - work around constness to install the event filter
ItemsGridViewDelegate* delegate = const_cast<ItemsGridViewDelegate*>(this);
titleLabel->installEventFilter(delegate);
m_widgetList << titleLabel;
KSqueezedTextLabel * authorLabel = new KSqueezedTextLabel();
authorLabel->setTextElideMode(Qt::ElideRight);
m_widgetList << authorLabel;
KSqueezedTextLabel * downloadCounterLabel = new KSqueezedTextLabel();
downloadCounterLabel->setTextElideMode(Qt::ElideRight);
m_widgetList << downloadCounterLabel;
KRatingWidget* rating = new KRatingWidget();
rating->setMaxRating(10);
rating->setHalfStepsEnabled(true);
m_widgetList << rating;
return m_widgetList;
}
void ItemsGridViewDelegate::updateItemWidgets(const QList<QWidget*> widgets,
const QStyleOptionViewItem &option,
const QPersistentModelIndex &index) const
{
const ItemsModel * model = qobject_cast<const ItemsModel*>(index.model());
if (!model) {
kDebug() << "WARNING - INVALID MODEL!";
return;
}
EntryInternal entry = index.data(Qt::UserRole).value<KNS3::EntryInternal>();
int elementXPos = ItemMargin;
int elementYPos = PreviewHeight + ItemMargin + FrameThickness*2;
//setup rating widget
KRatingWidget * rating = qobject_cast<KRatingWidget*>(widgets.at(DelegateGridRatingWidget));
if (rating) {
if (entry.rating() > 0) {
rating->setToolTip(i18n("Rating: %1%", entry.rating()));
// assume all entries come with rating 0..100 but most are in the range 20 - 80, so 20 is 0 stars, 80 is 5 stars
rating->setRating((entry.rating()-20)*10/60);
//make the rating widget smaller than the one at list view
int newWidth = 68;
QSize size(newWidth, 15);
rating->resize(size);
//put rating widget under image rectangle
rating->move((ItemGridWidth-newWidth)/2, elementYPos);
elementYPos += rating->height();
} else {
//is it better to stay visible?
rating->setVisible(false);
}
}
elementYPos += ItemMargin;
//setup title label
QLabel * titleLabel = qobject_cast<QLabel*>(widgets.at(DelegateTitleLabel));
if (titleLabel != NULL) {
titleLabel->setWordWrap(true);
titleLabel->setAlignment(Qt::AlignHCenter);
//titleLabel->setFrameStyle(QFrame::Panel);
titleLabel->resize(QSize(option.rect.width() - (ItemMargin * 2), option.fontMetrics.height() * 2));
titleLabel->move((ItemGridWidth-titleLabel->width())/2, elementYPos);
QString title;
KUrl link = qvariant_cast<KUrl>(entry.homepage());
if (!link.isEmpty()) {
title += "<b><a href=\"" + link.url() + "\">" + entry.name() + "</a></b>\n";
} else {
title += "<b>" + entry.name() + "</b>";
}
titleLabel->setText(title);
elementYPos += titleLabel->height();
}
//setup author label
QLabel * authorLabel = qobject_cast<QLabel*>(widgets.at(DelegateAuthorLabel));
if (authorLabel != NULL) {
authorLabel->setWordWrap(true);
authorLabel->setAlignment(Qt::AlignHCenter);
authorLabel->resize(QSize(option.rect.width() - (ItemMargin * 2), option.fontMetrics.height()));
authorLabel->move((ItemGridWidth-authorLabel->width())/2,elementYPos);
QString text;
QString authorName = entry.author().name();
QString email = entry.author().email();
QString authorPage = entry.author().homepage();
if (!authorName.isEmpty()) {
if (!authorPage.isEmpty()) {
text += "<p>" + i18nc("Show the author of this item in a list", "By <i>%1</i>", " <a href=\"" + authorPage + "\">" + authorName + "</a>") + "</p>\n";
} else if (!email.isEmpty()) {
text += "<p>" + i18nc("Show the author of this item in a list", "By <i>%1</i>", authorName) + " <a href=\"mailto:" + email + "\">" + email + "</a></p>\n";
} else {
text += "<p>" + i18nc("Show the author of this item in a list", "By <i>%1</i>", authorName) + "</p>\n";
}
}
authorLabel->setText(text);
elementYPos += authorLabel->height();
}
elementYPos += ItemMargin;
//setup download label
QLabel * downloadLabel = qobject_cast<QLabel*>(widgets.at(DelegateDownloadCounterLabel));
if (downloadLabel != NULL) {
downloadLabel->setWordWrap(true);
downloadLabel->setAlignment(Qt::AlignHCenter);
downloadLabel->resize(QSize(option.rect.width() - (ItemMargin * 2), option.fontMetrics.height()));
downloadLabel->move((ItemGridWidth-downloadLabel->width())/2,elementYPos);
unsigned int fans = entry.numberFans();
unsigned int downloads = entry.downloadCount();
QString text;
QString fanString;
QString downloadString;
if (fans > 0) {
fanString = i18ncp("fan as in supporter", "1 fan", "%1 fans", fans);
}
if (downloads > 0) {
downloadString = i18np("1 download", "%1 downloads", downloads);
}
if (downloads > 0 || fans > 0) {
text += "<p>" + downloadString;
if (downloads > 0 && fans > 0) {
text += ", ";
}
text += fanString + QLatin1String("</p>");
}
downloadLabel->setText(text);
elementYPos += downloadLabel->height();
}
elementYPos += ItemMargin;
m_elementYPos = elementYPos;
}
void ItemsGridViewDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
{
if (option.state & QStyle::State_MouseOver) {
QModelIndex focIndex = focusedIndex();
if (m_oldIndex != focIndex || !m_operationBar->isVisible()) {
ItemsGridViewDelegate* delegate = const_cast<ItemsGridViewDelegate*>(this);
delegate->displayOperationBar(option.rect,index);
delegate->m_oldIndex = focIndex;
}
} else {
QModelIndex focindex = focusedIndex();
if(!focindex.isValid()){
//kDebug() << "INVALID hide selection";
m_operationBar->hide();
}
}
QStyle *style = QApplication::style();
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, 0);
painter->save();
if (option.state & QStyle::State_Selected) {
painter->setPen(QPen(option.palette.highlightedText().color()));
} else {
painter->setPen(QPen(option.palette.text().color()));
}
const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(index.model());
if (realmodel->hasPreviewImages()) {
int height = option.rect.height();
int width = option.rect.width();
KNS3::EntryInternal entry = index.data(Qt::UserRole).value<KNS3::EntryInternal>();
if (entry.previewUrl(EntryInternal::PreviewSmall1).isEmpty()) {
;
} else {
QPoint centralPoint(option.rect.left() + width/2,option.rect.top() + ItemMargin + FrameThickness + PreviewHeight/2);
QImage image = entry.previewImage(EntryInternal::PreviewSmall1);
if (!image.isNull()) {
QPoint previewPoint(centralPoint.x() - image.width()/2, centralPoint.y() - image.height()/2);
painter->drawImage(previewPoint, image);
QPixmap frameImageScaled = m_frameImage.scaled(image.width() + FrameThickness*2, image.height() + FrameThickness*2);
QPoint framePoint(centralPoint.x() - frameImageScaled.width()/2, centralPoint.y() - frameImageScaled.height()/2);
painter->drawPixmap(framePoint, frameImageScaled);
} else {
QPoint thumbnailPoint(option.rect.left() + ((width - PreviewWidth - FrameThickness*2) / 2), option.rect.top() + ItemMargin);
QRect rect(thumbnailPoint, QSize(PreviewWidth + FrameThickness*2, PreviewHeight + FrameThickness*2));
painter->drawText(rect, Qt::AlignCenter | Qt::TextWordWrap, i18n("Loading Preview"));
}
}
}
painter->restore();
}
QSize ItemsGridViewDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const
{
Q_UNUSED(option);
Q_UNUSED(index);
QSize size;
size.setWidth(ItemGridWidth);
size.setHeight(qMax(option.fontMetrics.height() * 13, ItemGridHeight)); // up to 6 lines of text, and two margins
return size;
}
void ItemsGridViewDelegate::createOperationBar()
{
m_operationBar = new QWidget(this->itemView()->viewport());
m_detailsButton = new QToolButton();
m_detailsButton->setToolButtonStyle(Qt::ToolButtonFollowStyle);
m_detailsButton->setPopupMode(QToolButton::InstantPopup);
m_detailsButton->setToolTip(i18n("Details"));
m_detailsButton->setIcon(KIcon("documentinfo"));
setBlockedEventTypes(m_detailsButton, QList<QEvent::Type>() << QEvent::MouseButtonPress
<< QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick);
connect(m_detailsButton, SIGNAL(clicked()), this, SLOT(slotDetailsClicked()));
m_installButton = new QToolButton();
m_installButton->setToolButtonStyle(Qt::ToolButtonFollowStyle);
m_installButton->setPopupMode(QToolButton::InstantPopup);
setBlockedEventTypes(m_installButton, QList<QEvent::Type>() << QEvent::MouseButtonPress
<< QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick);
connect(m_installButton, SIGNAL(clicked()), this, SLOT(slotInstallClicked()));
connect(m_installButton, SIGNAL(triggered(QAction *)), this, SLOT(slotInstallActionTriggered(QAction *)));
if (m_installButton->menu()) {
QMenu* buttonMenu = m_installButton->menu();
buttonMenu->clear();
m_installButton->setMenu(0);
buttonMenu->deleteLater();
}
QHBoxLayout* layout = new QHBoxLayout(m_operationBar);
layout->setSpacing(1);
layout->addWidget(m_installButton);
layout->addWidget(m_detailsButton);
m_operationBar->adjustSize();
m_operationBar->hide();
}
void ItemsGridViewDelegate::displayOperationBar(const QRect &rect,const QModelIndex & index)
{
KNS3::EntryInternal entry = index.data(Qt::UserRole).value<KNS3::EntryInternal>();
if (m_installButton != 0) {
if (m_installButton->menu() != 0) {
QMenu* buttonMenu = m_installButton->menu();
buttonMenu->clear();
m_installButton->setMenu(0);
buttonMenu->deleteLater();
}
bool installable = false;
bool enabled = true;
QString text;
- KIcon icon;
+ QIcon icon;
switch (entry.status()) {
case Entry::Installed:
text = i18n("Uninstall");
icon = m_iconDelete;
break;
case Entry::Updateable:
text = i18n("Update");
icon = m_iconUpdate;
installable = true;
break;
case Entry::Installing:
text = i18n("Installing");
enabled = false;
icon = m_iconUpdate;
break;
case Entry::Updating:
text = i18n("Updating");
enabled = false;
icon = m_iconUpdate;
break;
case Entry::Downloadable:
text = i18n("Install");
icon = m_iconInstall;
installable = true;
break;
case Entry::Deleted:
text = i18n("Install Again");
icon = m_iconInstall;
installable = true;
break;
default:
text = i18n("Install");
}
m_installButton->setToolTip(text);
m_installButton->setIcon(icon);
m_installButton->setEnabled(enabled);
if (installable && entry.downloadLinkCount() > 1) {
KMenu * installMenu = new KMenu(m_installButton);
foreach (EntryInternal::DownloadLinkInformation info, entry.downloadLinkInformationList()) {
QString text = info.name;
if (!info.distributionType.trimmed().isEmpty()) {
text + " (" + info.distributionType.trimmed() + ")";
}
QAction* installAction = installMenu->addAction(m_iconInstall, text);
installAction->setData(QPoint(index.row(), info.id));
}
m_installButton->setMenu(installMenu);
}
m_operationBar->move(rect.left()+(ItemGridWidth-m_operationBar->width())/2,rect.top() + m_elementYPos);
m_operationBar->show();
}
}
}
diff --git a/knewstuff/knewstuff3/ui/itemsviewbasedelegate.h b/knewstuff/knewstuff3/ui/itemsviewbasedelegate.h
index 4cdf0642ef..a0a8882a51 100644
--- a/knewstuff/knewstuff3/ui/itemsviewbasedelegate.h
+++ b/knewstuff/knewstuff3/ui/itemsviewbasedelegate.h
@@ -1,83 +1,83 @@
/*
Copyright (C) 2008 Jeremy Whiting <jpwhiting@kde.org>
Copyright (C) 2010 Reza Fatahilah Shah <rshah0385@kireihana.com>
Copyright (C) 2010 Frederik Gladhorn <gladhorn@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KNEWSTUFF3_UI_ITEMSVIEWBASEDELEGATE_H
#define KNEWSTUFF3_UI_ITEMSVIEWBASEDELEGATE_H
#include <QList>
#include <QtCore/QMap>
#include <QtCore/QModelIndex>
#include <QtCore/QObject>
#include <QImage>
#include "core/engine.h"
#include "core/entryinternal.h"
#include <kicon.h>
#include <kwidgetitemdelegate.h>
namespace KNS3
{
class ItemsModel;
class Engine;
class ItemsViewBaseDelegate: public KWidgetItemDelegate
{
Q_OBJECT
public:
explicit ItemsViewBaseDelegate(QAbstractItemView* itemView, Engine* engine, QObject* parent = 0);
virtual ~ItemsViewBaseDelegate();
// paint the item at index with all its attributes shown
virtual void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const = 0;
// get the list of widgets
virtual QList<QWidget*> createItemWidgets() const = 0;
// update the widgets
virtual void updateItemWidgets(const QList<QWidget*> widgets,
const QStyleOptionViewItem &option,
const QPersistentModelIndex &index) const =0;
virtual QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const = 0;
Q_SIGNALS:
void signalShowDetails(const KNS3::EntryInternal& entry);
protected slots:
bool eventFilter(QObject *watched, QEvent *event);
void slotInstallClicked();
void slotInstallActionTriggered(QAction* action);
void slotLinkClicked(const QString & url);
void slotDetailsClicked(const QModelIndex& index);
void slotDetailsClicked();
protected:
Engine* m_engine;
QAbstractItemView *m_itemView;
- KIcon m_iconInvalid;
- KIcon m_iconDownloadable;
- KIcon m_iconInstall;
- KIcon m_iconUpdate;
- KIcon m_iconDelete;
+ QIcon m_iconInvalid;
+ QIcon m_iconDownloadable;
+ QIcon m_iconInstall;
+ QIcon m_iconUpdate;
+ QIcon m_iconDelete;
QPixmap m_frameImage;
QPixmap m_noImage;
QSize m_buttonSize;
};
}
#endif
diff --git a/knewstuff/knewstuff3/ui/itemsviewdelegate.cpp b/knewstuff/knewstuff3/ui/itemsviewdelegate.cpp
index 317c21ae59..907b93e1fc 100644
--- a/knewstuff/knewstuff3/ui/itemsviewdelegate.cpp
+++ b/knewstuff/knewstuff3/ui/itemsviewdelegate.cpp
@@ -1,331 +1,331 @@
/*
This file is part of KNewStuff2.
Copyright (C) 2008 Jeremy Whiting <jpwhiting@kde.org>
Copyright (C) 2010 Reza Fatahilah Shah <rshah0385@kireihana.com>
Copyright (C) 2010 Frederik Gladhorn <gladhorn@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "itemsviewdelegate.h"
#include <QPainter>
#include <QSortFilterProxyModel>
#include <QApplication>
#include <QToolButton>
#include <QMenu>
#include <kdebug.h>
#include <kstandarddirs.h>
#include <kicon.h>
#include <klocale.h>
#include <kmenu.h>
#include <kratingwidget.h>
#include "itemsmodel.h"
#include "entrydetailsdialog.h"
namespace KNS3
{
enum { DelegateLabel, DelegateInstallButton, DelegateDetailsButton, DelegateRatingWidget };
ItemsViewDelegate::ItemsViewDelegate(QAbstractItemView *itemView, Engine* engine, QObject * parent)
: ItemsViewBaseDelegate(itemView, engine, parent)
{
}
ItemsViewDelegate::~ItemsViewDelegate()
{
}
QList<QWidget*> ItemsViewDelegate::createItemWidgets() const
{
QList<QWidget*> list;
QLabel * infoLabel = new QLabel();
infoLabel->setOpenExternalLinks(true);
// not so nice - work around constness to install the event filter
ItemsViewDelegate* delegate = const_cast<ItemsViewDelegate*>(this);
infoLabel->installEventFilter(delegate);
list << infoLabel;
QToolButton * installButton = new QToolButton();
installButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
installButton->setPopupMode(QToolButton::InstantPopup);
list << installButton;
setBlockedEventTypes(installButton, QList<QEvent::Type>() << QEvent::MouseButtonPress
<< QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick);
connect(installButton, SIGNAL(clicked()), this, SLOT(slotInstallClicked()));
connect(installButton, SIGNAL(triggered(QAction *)), this, SLOT(slotInstallActionTriggered(QAction *)));
QToolButton* detailsButton = new QToolButton();
detailsButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
list << detailsButton;
setBlockedEventTypes(detailsButton, QList<QEvent::Type>() << QEvent::MouseButtonPress
<< QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick);
connect(detailsButton, SIGNAL(clicked()), this, SLOT(slotDetailsClicked()));
KRatingWidget* rating = new KRatingWidget();
rating->setMaxRating(10);
rating->setHalfStepsEnabled(true);
list << rating;
//connect(rating, SIGNAL(ratingChanged(uint)), this, SLOT());
return list;
}
void ItemsViewDelegate::updateItemWidgets(const QList<QWidget*> widgets,
const QStyleOptionViewItem &option,
const QPersistentModelIndex &index) const
{
const ItemsModel * model = qobject_cast<const ItemsModel*>(index.model());
if (!model) {
kDebug() << "WARNING - INVALID MODEL!";
return;
}
EntryInternal entry = index.data(Qt::UserRole).value<KNS3::EntryInternal>();
// setup the install button
int margin = option.fontMetrics.height() / 2;
int right = option.rect.width();
QToolButton * installButton = qobject_cast<QToolButton*>(widgets.at(DelegateInstallButton));
if (installButton != 0) {
if (installButton->menu()) {
QMenu* buttonMenu = installButton->menu();
buttonMenu->clear();
installButton->setMenu(0);
buttonMenu->deleteLater();
}
bool installable = false;
bool enabled = true;
QString text;
- KIcon icon;
+ QIcon icon;
switch (entry.status()) {
case Entry::Installed:
text = i18n("Uninstall");
icon = m_iconDelete;
break;
case Entry::Updateable:
text = i18n("Update");
icon = m_iconUpdate;
installable = true;
break;
case Entry::Installing:
text = i18n("Installing");
enabled = false;
icon = m_iconUpdate;
break;
case Entry::Updating:
text = i18n("Updating");
enabled = false;
icon = m_iconUpdate;
break;
case Entry::Downloadable:
text = i18n("Install");
icon = m_iconInstall;
installable = true;
break;
case Entry::Deleted:
text = i18n("Install Again");
icon = m_iconInstall;
installable = true;
break;
default:
text = i18n("Install");
}
installButton->setText(text);
installButton->setEnabled(enabled);
installButton->setIcon(icon);
if (installable && entry.downloadLinkCount() > 1) {
KMenu * installMenu = new KMenu(installButton);
foreach (EntryInternal::DownloadLinkInformation info, entry.downloadLinkInformationList()) {
QString text = info.name;
if (!info.distributionType.trimmed().isEmpty()) {
text + " (" + info.distributionType.trimmed() + ")";
}
QAction* installAction = installMenu->addAction(m_iconInstall, text);
installAction->setData(QPoint(index.row(), info.id));
}
installButton->setMenu(installMenu);
}
}
QToolButton* detailsButton = qobject_cast<QToolButton*>(widgets.at(DelegateDetailsButton));
if (detailsButton) {
detailsButton->setText(i18n("Details"));
detailsButton->setIcon(KIcon("documentinfo"));
}
if (installButton && detailsButton) {
if (m_buttonSize.width() < installButton->sizeHint().width()) {
const_cast<QSize&>(m_buttonSize) = QSize(
qMax(option.fontMetrics.height() * 7,
qMax(installButton->sizeHint().width(), detailsButton->sizeHint().width())),
installButton->sizeHint().height());
}
installButton->resize(m_buttonSize);
installButton->move(right - installButton->width() - margin, option.rect.height()/2 - installButton->height()*1.5);
detailsButton->resize(m_buttonSize);
detailsButton->move(right - installButton->width() - margin, option.rect.height()/2 - installButton->height()/2);
}
QLabel * infoLabel = qobject_cast<QLabel*>(widgets.at(DelegateLabel));
infoLabel->setWordWrap(true);
if (infoLabel != NULL) {
if (model->hasPreviewImages()) {
// move the text right by kPreviewWidth + margin pixels to fit the preview
infoLabel->move(PreviewWidth + margin * 2, 0);
infoLabel->resize(QSize(option.rect.width() - PreviewWidth - (margin * 6) - m_buttonSize.width(), option.fontMetrics.height() * 7));
} else {
infoLabel->move(margin, 0);
infoLabel->resize(QSize(option.rect.width() - (margin * 4) - m_buttonSize.width(), option.fontMetrics.height() * 7));
}
QString text = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">p, li { white-space: pre-wrap; margin:0 0 0 0;}\n"
"</style></head><body><p><b>";
KUrl link = qvariant_cast<KUrl>(entry.homepage());
if (!link.isEmpty()) {
text += "<p><a href=\"" + link.url() + "\">" + entry.name() + "</a></p>\n";
} else {
text += entry.name();
}
text += "</b></p>\n";
QString authorName = entry.author().name();
QString email = entry.author().email();
QString authorPage = entry.author().homepage();
if (!authorName.isEmpty()) {
if (!authorPage.isEmpty()) {
text += "<p>" + i18nc("Show the author of this item in a list", "By <i>%1</i>", " <a href=\"" + authorPage + "\">" + authorName + "</a>") + "</p>\n";
} else if (!email.isEmpty()) {
text += "<p>" + i18nc("Show the author of this item in a list", "By <i>%1</i>", authorName) + " <a href=\"mailto:" + email + "\">" + email + "</a></p>\n";
} else {
text += "<p>" + i18nc("Show the author of this item in a list", "By <i>%1</i>", authorName) + "</p>\n";
}
}
QString summary = "<p>" + option.fontMetrics.elidedText(entry.summary(),
Qt::ElideRight, infoLabel->width() * 3) + "</p>\n";
text += summary;
unsigned int fans = entry.numberFans();
unsigned int downloads = entry.downloadCount();
QString fanString;
QString downloadString;
if (fans > 0) {
fanString = i18ncp("fan as in supporter", "1 fan", "%1 fans", fans);
}
if (downloads > 0) {
downloadString = i18np("1 download", "%1 downloads", downloads);
}
if (downloads > 0 || fans > 0) {
text += "<p>" + downloadString;
if (downloads > 0 && fans > 0) {
text += ", ";
}
text += fanString + QLatin1String("</p>\n");
}
text += "</body></html>";
// use simplified to get rid of newlines etc
text = replaceBBCode(text).simplified();
infoLabel->setText(text);
}
KRatingWidget * rating = qobject_cast<KRatingWidget*>(widgets.at(DelegateRatingWidget));
if (rating) {
if (entry.rating() > 0) {
rating->setToolTip(i18n("Rating: %1%", entry.rating()));
// assume all entries come with rating 0..100 but most are in the range 20 - 80, so 20 is 0 stars, 80 is 5 stars
rating->setRating((entry.rating()-20)*10/60);
// put the rating label below the install button
rating->move(right - installButton->width() - margin, option.rect.height()/2 + installButton->height()/2);
rating->resize(m_buttonSize);
} else {
rating->setVisible(false);
}
}
}
// draws the preview
void ItemsViewDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
{
int margin = option.fontMetrics.height() / 2;
QStyle *style = QApplication::style();
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, 0);
painter->save();
if (option.state & QStyle::State_Selected) {
painter->setPen(QPen(option.palette.highlightedText().color()));
} else {
painter->setPen(QPen(option.palette.text().color()));
}
const ItemsModel * realmodel = qobject_cast<const ItemsModel*>(index.model());
if (realmodel->hasPreviewImages()) {
int height = option.rect.height();
QPoint point(option.rect.left() + margin, option.rect.top() + ((height - PreviewHeight) / 2));
KNS3::EntryInternal entry = index.data(Qt::UserRole).value<KNS3::EntryInternal>();
if (entry.previewUrl(EntryInternal::PreviewSmall1).isEmpty()) {
// paint the no preview icon
//point.setX((PreviewWidth - m_noImage.width())/2 + 5);
//point.setY(option.rect.top() + ((height - m_noImage.height()) / 2));
//painter->drawPixmap(point, m_noImage);
} else {
QImage image = entry.previewImage(EntryInternal::PreviewSmall1);
if (!image.isNull()) {
point.setX((PreviewWidth - image.width())/2 + 5);
point.setY(option.rect.top() + ((height - image.height()) / 2));
painter->drawImage(point, image);
QPoint framePoint(point.x() - 5, point.y() - 5);
painter->drawPixmap(framePoint, m_frameImage.scaled(image.width() + 10, image.height() + 10));
} else {
QRect rect(point, QSize(PreviewWidth, PreviewHeight));
painter->drawText(rect, Qt::AlignCenter | Qt::TextWordWrap, i18n("Loading Preview"));
}
}
}
painter->restore();
}
QSize ItemsViewDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const
{
Q_UNUSED(option);
Q_UNUSED(index);
QSize size;
size.setWidth(option.fontMetrics.height() * 4);
size.setHeight(qMax(option.fontMetrics.height() * 7, PreviewHeight)); // up to 6 lines of text, and two margins
return size;
}
} // namespace
diff --git a/knotify/config/knotifyeventlist.cpp b/knotify/config/knotifyeventlist.cpp
index aedd5470d9..ab62236d2c 100644
--- a/knotify/config/knotifyeventlist.cpp
+++ b/knotify/config/knotifyeventlist.cpp
@@ -1,216 +1,216 @@
/* This file is part of the KDE libraries
Copyright (C) 2005 Olivier Goffart <ogoffart at 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 "knotifyeventlist.h"
#include <kdebug.h>
#include <klocale.h>
#include <kicon.h>
#include <kiconloader.h>
#include <kconfig.h>
#include <kconfiggroup.h>
#include <kglobal.h>
#include <kstandarddirs.h>
#include <QStyledItemDelegate>
#include <QPainter>
#include <QHeaderView>
#include <QFontMetrics>
//BEGIN KNotifyEventListDelegate
class KNotifyEventList::KNotifyEventListDelegate : public QStyledItemDelegate
{
public:
KNotifyEventListDelegate(QObject *parent = 0);
virtual void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
private:
};
KNotifyEventList::KNotifyEventListDelegate::KNotifyEventListDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
}
void KNotifyEventList::KNotifyEventListDelegate::paint( QPainter* painter,
const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
if (index.column() != 0)
return QStyledItemDelegate::paint(painter, option, index);
QVariant displayData = index.data(Qt::UserRole);
QString prstring=displayData.toString();
QStyledItemDelegate::paint(painter, option, index);
// kDebug() << prstring;
QRect rect=option.rect;
QStringList optionsList = prstring.split ('|');
- QList<KIcon> iconList;
+ QList<QIcon> iconList;
iconList << ( optionsList.contains("Sound") ? KIcon("media-playback-start") : KIcon() );
iconList << ( optionsList.contains("Popup") ? KIcon("dialog-information") : KIcon() );
iconList << ( optionsList.contains("Logfile") ? KIcon("text-x-generic") : KIcon() );
iconList << ( optionsList.contains("Taskbar") ? KIcon("services") : KIcon() );
iconList << ( optionsList.contains("Execute") ? KIcon("system-run") : KIcon() );
if( KNotifyConfigElement::have_kttsd() )
iconList << ( optionsList.contains("KTTS") ? KIcon("text-speak") : KIcon() );
int mc_x=0;
int iconWidth = option.decorationSize.width();
int iconHeight = option.decorationSize.height();
- foreach(const KIcon &icon, iconList)
+ foreach(const QIcon &icon, iconList)
{
icon.paint(painter, rect.left() + mc_x + 4, rect.top() + (rect.height() - iconHeight) / 2, iconWidth, iconHeight);
mc_x += iconWidth + 4;
}
}
//END KNotifyEventListDelegate
KNotifyEventList::KNotifyEventList(QWidget *parent)
: QTreeWidget(parent) , config(0)
{
QStringList headerLabels;
headerLabels << i18nc( "State of the notified event", "State" ) << i18nc( "Title of the notified event", "Title" ) << i18nc( "Description of the notified event", "Description" );
setHeaderLabels( headerLabels );
setItemDelegate(new KNotifyEventListDelegate(this));
setRootIsDecorated(false);
setAlternatingRowColors(true);
//Extract icon size as the font height (as h=w on icons)
QStyleOptionViewItem iconOption;
iconOption.initFrom( this );
int iconWidth = iconOption.fontMetrics.height() -2 ; //1px margin top & bottom
setIconSize( QSize(iconWidth, iconWidth) );
header()->setResizeMode( 0, QHeaderView::Fixed );
header()->resizeSection( 0, KNotifyConfigElement::have_kttsd() ? (iconWidth+4)*6: (iconWidth+4)*5 );
header()->setResizeMode( 1, QHeaderView::ResizeToContents );
connect(this, SIGNAL(currentItemChanged( QTreeWidgetItem * , QTreeWidgetItem * )) , this , SLOT(slotSelectionChanged( QTreeWidgetItem * , QTreeWidgetItem *)));
}
KNotifyEventList::~KNotifyEventList()
{
delete config;
}
void KNotifyEventList::fill( const QString & appname , const QString & context_name ,const QString & context_value )
{
m_elements.clear();
clear();
delete config;
config = new KConfig(appname + ".notifyrc" , KConfig::NoGlobals);
config->addConfigSources(KGlobal::dirs()->findAllResources("data",
appname + '/' + appname + ".notifyrc"));
QStringList conflist = config->groupList();
QRegExp rx("^Event/([^/]*)$");
conflist=conflist.filter( rx );
foreach (const QString& group , conflist )
{
KConfigGroup cg(config, group);
rx.indexIn(group);
QString id=rx.cap(1);
if(!context_name.isEmpty())
{
QStringList contexts = cg.readEntry("Contexts", QStringList());
if(!contexts.contains(context_name))
continue;
id=id+'/'+context_name+'/'+context_value;
}
QString name = cg.readEntry("Name");
QString description = cg.readEntry("Comment");
m_elements << new KNotifyEventListItem(this, id, name, description, config );
}
resizeColumnToContents(2);
}
void KNotifyEventList::save( )
{
foreach( KNotifyEventListItem *it , m_elements )
{
it->save();
}
}
void KNotifyEventList::slotSelectionChanged( QTreeWidgetItem *current , QTreeWidgetItem *previous)
{
Q_UNUSED( current );
KNotifyEventListItem *it=dynamic_cast<KNotifyEventListItem *>(currentItem());
if(it)
emit eventSelected( it->configElement() );
else
emit eventSelected( 0l );
it=dynamic_cast<KNotifyEventListItem *>(previous);
if(it)
it->update();
}
void KNotifyEventList::updateCurrentItem()
{
KNotifyEventListItem *it=dynamic_cast<KNotifyEventListItem *>(currentItem());
if(it)
it->update();
}
QSize KNotifyEventList::sizeHint() const
{
int fontSize = fontMetrics().height();
return QSize(48 * fontSize, 12 * fontSize);
}
KNotifyEventListItem::KNotifyEventListItem( QTreeWidget * parent, const QString & eventName,
const QString & name, const QString & description , KConfig *config)
: QTreeWidgetItem(parent) ,
m_config(eventName, config )
{
setText( 1, name );
setToolTip( 1, description );
setText( 2, description );
setToolTip( 2, description );
update();
}
KNotifyEventListItem::~KNotifyEventListItem()
{
}
void KNotifyEventListItem::save()
{
m_config.save();
}
void KNotifyEventListItem::update()
{
setData(0 , Qt::UserRole , m_config.readEntry( "Action" ));
}
diff --git a/kparts/browseropenorsavequestion.cpp b/kparts/browseropenorsavequestion.cpp
index 3b7ad0bf52..3435f130c6 100644
--- a/kparts/browseropenorsavequestion.cpp
+++ b/kparts/browseropenorsavequestion.cpp
@@ -1,343 +1,344 @@
/*
Copyright (c) 2009, 2010 David Faure <faure@kde.org>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License or ( at
your option ) version 3 or, at the discretion of KDE e.V. ( which shall
act as a proxy as in section 14 of the GPLv3 ), any later version.
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 Lesser 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 "browseropenorsavequestion.h"
+#include <kicon.h>
#include <kdebug.h>
#include <kaction.h>
#include <kfileitemactions.h>
#include <kpushbutton.h>
#include <kmenu.h>
#include <ksqueezedtextlabel.h>
#include <knotification.h>
#include <kdialog.h>
#include <kmimetypetrader.h>
#include <kstandardguiitem.h>
#include <kguiitem.h>
#include <kmessagebox.h>
#include <kmimetype.h>
#include <QStyle>
#include <QStyleOption>
#include <QVBoxLayout>
#include <QCheckBox>
#include <QLabel>
using namespace KParts;
Q_DECLARE_METATYPE(KService::Ptr)
static KMimeType::Ptr fixupMimeType (const QString& mimeType, const QString& fileName)
{
KMimeType::Ptr mime = KMimeType::mimeType(mimeType, KMimeType::ResolveAliases);
if ((!mime || mime->isDefault()) && !fileName.isEmpty()) {
mime = KMimeType::findByUrl(fileName, 0, false, true);
}
return mime;
}
class KParts::BrowserOpenOrSaveQuestionPrivate : public KDialog
{
Q_OBJECT
public:
// Mapping to KDialog button codes
static const KDialog::ButtonCode Save = KDialog::Yes;
static const KDialog::ButtonCode OpenDefault = KDialog::User2;
static const KDialog::ButtonCode OpenWith = KDialog::User1;
static const KDialog::ButtonCode Cancel = KDialog::Cancel;
-
+
BrowserOpenOrSaveQuestionPrivate(QWidget* parent, const KUrl& url, const QString& mimeType)
: KDialog(parent), url(url), mimeType(mimeType),
features(0)
{
// Use askSave or askEmbedOrSave from filetypesrc
dontAskConfig = KSharedConfig::openConfig("filetypesrc", KConfig::NoGlobals);
setCaption(url.host());
setButtons(Save | OpenDefault | OpenWith | Cancel);
setObjectName("questionYesNoCancel");
setButtonGuiItem(Save, KStandardGuiItem::saveAs());
setButtonGuiItem(Cancel, KStandardGuiItem::cancel());
setDefaultButton(Save);
QVBoxLayout *mainLayout = new QVBoxLayout(mainWidget());
mainLayout->setSpacing(KDialog::spacingHint() * 2); // provide extra spacing
mainLayout->setMargin(0);
QHBoxLayout *hLayout = new QHBoxLayout();
hLayout->setMargin(0);
hLayout->setSpacing(-1); // use default spacing
mainLayout->addLayout(hLayout, 5);
QLabel *iconLabel = new QLabel(mainWidget());
QStyleOption option;
option.initFrom(this);
KIcon icon("dialog-information");
iconLabel->setPixmap(icon.pixmap(style()->pixelMetric(QStyle::PM_MessageBoxIconSize, &option, this)));
hLayout->addWidget(iconLabel, 0, Qt::AlignCenter);
hLayout->addSpacing(KDialog::spacingHint());
QVBoxLayout* textVLayout = new QVBoxLayout;
questionLabel = new KSqueezedTextLabel(mainWidget());
textVLayout->addWidget(questionLabel);
fileNameLabel = new QLabel(mainWidget());
fileNameLabel->hide();
textVLayout->addWidget(fileNameLabel);
mime = fixupMimeType(mimeType, url.fileName());
QString mimeDescription (mimeType);
if (mime) {
// Always prefer the mime-type comment over the raw type for display
mimeDescription = (mime->comment().isEmpty() ? mime->name() : mime->comment());
}
mimeTypeLabel = new QLabel(mainWidget());
mimeTypeLabel->setText(i18nc("@label Type of file", "Type: %1", mimeDescription));
mimeTypeLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
textVLayout->addWidget(mimeTypeLabel);
hLayout->addLayout(textVLayout,5);
mainLayout->addStretch(15);
dontAskAgainCheckBox = new QCheckBox(mainWidget());
dontAskAgainCheckBox->setText(i18nc("@label:checkbox", "Remember action for files of this type"));
mainLayout->addWidget(dontAskAgainCheckBox);
}
bool autoEmbedMimeType(int flags);
int executeDialog(const QString& dontShowAgainName)
{
KConfigGroup cg(dontAskConfig, "Notification Messages"); // group name comes from KMessageBox
const QString dontAsk = cg.readEntry(dontShowAgainName, QString()).toLower();
if (dontAsk == "yes" || dontAsk == "true") {
return Save;
} else if (dontAsk == "no" || dontAsk == "false") {
return OpenDefault;
}
KNotification::event("messageQuestion", // why does KMessageBox uses Information for questionYesNoCancel?
questionLabel->text(), // also include mimetype?
QPixmap(),
window());
const int result = exec();
if (dontAskAgainCheckBox->isChecked()) {
cg.writeEntry(dontShowAgainName, result == Save);
cg.sync();
}
return result;
}
void showService(KService::Ptr selectedService)
{
KGuiItem openItem(i18nc("@label:button", "&Open with %1", selectedService->name()), selectedService->icon());
setButtonGuiItem(OpenWith, openItem);
}
KUrl url;
QString mimeType;
KMimeType::Ptr mime;
KService::Ptr selectedService;
KSqueezedTextLabel* questionLabel;
BrowserOpenOrSaveQuestion::Features features;
QLabel* fileNameLabel;
QLabel* mimeTypeLabel;
protected:
virtual void slotButtonClicked(int buttonId)
{
if (buttonId != OpenDefault)
selectedService = 0;
KPushButton* button = KDialog::button(KDialog::ButtonCode(buttonId));
if (button && !button->menu()) {
done(buttonId);
}
}
private:
QCheckBox* dontAskAgainCheckBox;
KSharedConfig::Ptr dontAskConfig;
public Q_SLOTS:
void slotAppSelected(QAction* action)
{
selectedService = action->data().value<KService::Ptr>();
//showService(selectedService);
done(OpenDefault);
}
};
BrowserOpenOrSaveQuestion::BrowserOpenOrSaveQuestion(QWidget* parent, const KUrl& url, const QString& mimeType)
: d(new BrowserOpenOrSaveQuestionPrivate(parent, url, mimeType))
{
}
BrowserOpenOrSaveQuestion::~BrowserOpenOrSaveQuestion()
{
delete d;
}
static KAction* createAppAction(const KService::Ptr& service, QObject* parent)
{
QString actionName(service->name().replace('&', "&&"));
actionName = i18nc("@action:inmenu", "Open &with %1", actionName);
KAction *act = new KAction(parent);
act->setIcon(KIcon(service->icon()));
act->setText(actionName);
act->setData(QVariant::fromValue(service));
return act;
}
BrowserOpenOrSaveQuestion::Result BrowserOpenOrSaveQuestion::askOpenOrSave()
{
d->questionLabel->setText(i18nc("@info", "Open '%1'?", d->url.pathOrUrl()));
d->questionLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
d->showButton(BrowserOpenOrSaveQuestionPrivate::OpenWith, false);
KGuiItem openWithDialogItem(i18nc("@label:button", "&Open with..."), "document-open");
// I thought about using KFileItemActions, but we don't want a submenu, nor the slots....
// and we want no menu at all if there's only one offer.
// TODO: we probably need a setTraderConstraint(), to exclude the current application?
const KService::List apps = KFileItemActions::associatedApplications(QStringList() << d->mimeType,
QString() /* TODO trader constraint */);
if (apps.isEmpty()) {
d->setButtonGuiItem(BrowserOpenOrSaveQuestionPrivate::OpenDefault, openWithDialogItem);
} else {
KService::Ptr offer = apps.first();
KGuiItem openItem(i18nc("@label:button", "&Open with %1", offer->name()), offer->icon());
d->setButtonGuiItem(BrowserOpenOrSaveQuestionPrivate::OpenDefault, openItem);
if (d->features & ServiceSelection) {
// OpenDefault shall use this service
d->selectedService = apps.first();
d->showButton(BrowserOpenOrSaveQuestionPrivate::OpenWith, true);
KMenu* menu = new KMenu(d);
if (apps.count() > 1) {
// Provide an additional button with a menu of associated apps
KGuiItem openWithItem(i18nc("@label:button", "&Open with"), "document-open");
d->setButtonGuiItem(BrowserOpenOrSaveQuestionPrivate::OpenWith, openWithItem);
d->setButtonMenu(BrowserOpenOrSaveQuestionPrivate::OpenWith, menu, KDialog::InstantPopup);
QObject::connect(menu, SIGNAL(triggered(QAction*)), d, SLOT(slotAppSelected(QAction*)));
for (KService::List::const_iterator it = apps.begin(); it != apps.end(); ++it) {
KAction* act = createAppAction(*it, d);
menu->addAction(act);
}
KAction* openWithDialogAction = new KAction(d);
openWithDialogAction->setIcon(KIcon("document-open"));
openWithDialogAction->setText(openWithDialogItem.text());
menu->addAction(openWithDialogAction);
} else {
// Only one associated app, already offered by the other menu -> add "Open With..." button
d->setButtonGuiItem(BrowserOpenOrSaveQuestionPrivate::OpenWith, openWithDialogItem);
}
} else {
kDebug() << "Not using new feature ServiceSelection; port the caller to BrowserOpenOrSaveQuestion::setFeature(ServiceSelection)";
//kDebug() << kBacktrace();
}
}
// KEEP IN SYNC with kdebase/runtime/keditfiletype/filetypedetails.cpp!!!
const QString dontAskAgain = QLatin1String("askSave") + d->mimeType;
const int choice = d->executeDialog(dontAskAgain);
return choice == BrowserOpenOrSaveQuestionPrivate::Save ? Save
: (choice == BrowserOpenOrSaveQuestionPrivate::Cancel ? Cancel : Open);
}
KService::Ptr BrowserOpenOrSaveQuestion::selectedService() const
{
return d->selectedService;
}
bool BrowserOpenOrSaveQuestionPrivate::autoEmbedMimeType(int flags)
{
// SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC
// NOTE: Keep this function in sync with
// kdebase/runtime/keditfiletype/filetypedetails.cpp
// FileTypeDetails::updateAskSave()
// Don't ask for:
// - html (even new tabs would ask, due to about:blank!)
// - dirs obviously (though not common over HTTP :),
// - images (reasoning: no need to save, most of the time, because fast to see)
// e.g. postscript is different, because takes longer to read, so
// it's more likely that the user might want to save it.
// - multipart/* ("server push", see kmultipart)
// KEEP IN SYNC!!!
if (flags != (int)BrowserRun::AttachmentDisposition && mime && (
mime->is("text/html") ||
mime->is("application/xml") ||
mime->is("inode/directory") ||
mimeType.startsWith(QLatin1String("image")) ||
mime->is("multipart/x-mixed-replace") ||
mime->is("multipart/replace")))
return true;
return false;
}
BrowserOpenOrSaveQuestion::Result BrowserOpenOrSaveQuestion::askEmbedOrSave(int flags)
{
if (d->autoEmbedMimeType(flags))
return Embed;
// don't use KStandardGuiItem::open() here which has trailing ellipsis!
d->setButtonGuiItem(BrowserOpenOrSaveQuestionPrivate::OpenDefault, KGuiItem(i18nc("@label:button", "&Open"), "document-open"));
d->showButton(BrowserOpenOrSaveQuestionPrivate::OpenWith, false);
d->questionLabel->setText(i18nc("@info", "Open '%1'?", d->url.pathOrUrl()));
d->questionLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
const QString dontAskAgain = QLatin1String("askEmbedOrSave")+ d->mimeType; // KEEP IN SYNC!!!
// SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC
const int choice = d->executeDialog(dontAskAgain);
return choice == BrowserOpenOrSaveQuestionPrivate::Save ? Save
: (choice == BrowserOpenOrSaveQuestionPrivate::Cancel ? Cancel : Embed);
}
void BrowserOpenOrSaveQuestion::setFeatures(Features features)
{
d->features = features;
}
void BrowserOpenOrSaveQuestion::setSuggestedFileName(const QString& suggestedFileName)
{
if (suggestedFileName.isEmpty()) {
return;
}
d->fileNameLabel->setText(i18nc("@label File name", "Name: %1", suggestedFileName));
d->fileNameLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
d->fileNameLabel->setWhatsThis(i18nc("@info:whatsthis", "This is the file name suggested by the server"));
d->fileNameLabel->show();
// If the current mime-type is the default mime-type, then attempt to
// determine the "real" mimetype from the file name.
KMimeType::Ptr mimePtr = fixupMimeType(d->mimeType, suggestedFileName);
if (mimePtr && mimePtr->name() != d->mimeType) {
d->mime = mimePtr;
d->mimeType = mimePtr->name();
// Always prefer the mime-type comment over the raw type for display
const QString mimeDescription (mimePtr->comment().isEmpty() ? mimePtr->name() : mimePtr->comment());
d->mimeTypeLabel->setText(i18nc("@label Type of file", "Type: %1", mimeDescription));
}
}
#include "browseropenorsavequestion.moc"
diff --git a/kutils/kpluginselector.cpp b/kutils/kpluginselector.cpp
index 00ae6309dd..ef1726b665 100644
--- a/kutils/kpluginselector.cpp
+++ b/kutils/kpluginselector.cpp
@@ -1,903 +1,904 @@
/**
* This file is part of the KDE project
* Copyright (C) 2007, 2006 Rafael Fernández López <ereslibre@kde.org>
* Copyright (C) 2002-2003 Matthias Kretz <kretz@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 "kpluginselector.h"
#include "kpluginselector_p.h"
#include <QLabel>
#include <QPainter>
#include <QBoxLayout>
#include <QApplication>
#include <QCheckBox>
#include <QStyleOptionViewItemV4>
+#include <kicon.h>
#include <kdebug.h>
#include <klineedit.h>
#include <kdialog.h>
#include <kurllabel.h>
#include <ktabwidget.h>
#include <kcmoduleinfo.h>
#include <kcmoduleproxy.h>
#include <kmessagebox.h>
#include <kpushbutton.h>
#include <kiconloader.h>
#include <kstandarddirs.h>
#include <klocalizedstring.h>
#include <kcategorydrawer.h>
#include <kcategorizedview.h>
#include <kcategorizedsortfilterproxymodel.h>
#include <kaboutapplicationdialog.h>
#define MARGIN 5
KPluginSelector::Private::Private(KPluginSelector *parent)
: QObject(parent)
, parent(parent)
, listView(0)
, categoryDrawer(new KCategoryDrawer)
, showIcons(false)
{
}
KPluginSelector::Private::~Private()
{
delete categoryDrawer;
}
void KPluginSelector::Private::updateDependencies(PluginEntry *pluginEntry, bool added)
{
if (added) {
QStringList dependencyList = pluginEntry->pluginInfo.dependencies();
if (!dependencyList.count()) {
return;
}
for (int i = 0; i < pluginModel->rowCount(); i++) {
const QModelIndex index = pluginModel->index(i, 0);
PluginEntry *pe = static_cast<PluginEntry*>(index.internalPointer());
if ((pe->pluginInfo.pluginName() != pluginEntry->pluginInfo.pluginName()) &&
dependencyList.contains(pe->pluginInfo.pluginName()) && !pe->checked) {
dependenciesWidget->addDependency(pe->pluginInfo.name(), pluginEntry->pluginInfo.name(), added);
const_cast<QAbstractItemModel*>(index.model())->setData(index, added, Qt::CheckStateRole);
updateDependencies(pe, added);
}
}
} else {
for (int i = 0; i < pluginModel->rowCount(); i++) {
const QModelIndex index = pluginModel->index(i, 0);
PluginEntry *pe = static_cast<PluginEntry*>(index.internalPointer());
if ((pe->pluginInfo.pluginName() != pluginEntry->pluginInfo.pluginName()) &&
pe->pluginInfo.dependencies().contains(pluginEntry->pluginInfo.pluginName()) && pe->checked) {
dependenciesWidget->addDependency(pe->pluginInfo.name(), pluginEntry->pluginInfo.name(), added);
const_cast<QAbstractItemModel*>(index.model())->setData(index, added, Qt::CheckStateRole);
updateDependencies(pe, added);
}
}
}
}
int KPluginSelector::Private::dependantLayoutValue(int value, int width, int totalWidth) const
{
if (listView->layoutDirection() == Qt::LeftToRight) {
return value;
}
return totalWidth - width - value;
}
KPluginSelector::Private::DependenciesWidget::DependenciesWidget(QWidget *parent)
: QWidget(parent)
, addedByDependencies(0)
, removedByDependencies(0)
{
setVisible(false);
details = new QLabel();
QHBoxLayout *layout = new QHBoxLayout;
QVBoxLayout *dataLayout = new QVBoxLayout;
dataLayout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
layout->setAlignment(Qt::AlignLeft);
QLabel *label = new QLabel();
label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
label->setPixmap(KIconLoader::global()->loadIcon("dialog-information", KIconLoader::Dialog));
label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
layout->addWidget(label);
KUrlLabel *link = new KUrlLabel();
link->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
link->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
link->setGlowEnabled(false);
link->setUnderline(false);
link->setFloatEnabled(true);
link->setUseCursor(true);
link->setHighlightedColor(palette().color(QPalette::Link));
link->setSelectedColor(palette().color(QPalette::Link));
link->setText(i18n("Automatic changes have been performed due to plugin dependencies. Click here for further information"));
dataLayout->addWidget(link);
dataLayout->addWidget(details);
layout->addLayout(dataLayout);
setLayout(layout);
QObject::connect(link, SIGNAL(leftClickedUrl()), this, SLOT(showDependencyDetails()));
}
KPluginSelector::Private::DependenciesWidget::~DependenciesWidget()
{
}
void KPluginSelector::Private::DependenciesWidget::addDependency(const QString &dependency, const QString &pluginCausant, bool added)
{
if (!isVisible())
setVisible(true);
struct FurtherInfo furtherInfo;
furtherInfo.added = added;
furtherInfo.pluginCausant = pluginCausant;
if (dependencyMap.contains(dependency)) // The dependency moved from added to removed or vice-versa
{
if (added && removedByDependencies)
removedByDependencies--;
else if (addedByDependencies)
addedByDependencies--;
dependencyMap[dependency] = furtherInfo;
}
else
dependencyMap.insert(dependency, furtherInfo);
if (added)
addedByDependencies++;
else
removedByDependencies++;
updateDetails();
}
void KPluginSelector::Private::DependenciesWidget::userOverrideDependency(const QString &dependency)
{
if (dependencyMap.contains(dependency))
{
if (addedByDependencies && dependencyMap[dependency].added)
addedByDependencies--;
else if (removedByDependencies)
removedByDependencies--;
dependencyMap.remove(dependency);
}
updateDetails();
}
void KPluginSelector::Private::DependenciesWidget::clearDependencies()
{
addedByDependencies = 0;
removedByDependencies = 0;
dependencyMap.clear();
updateDetails();
}
void KPluginSelector::Private::DependenciesWidget::showDependencyDetails()
{
QString message = i18n("Automatic changes have been performed in order to satisfy plugin dependencies:\n");
foreach(const QString &dependency, dependencyMap.keys())
{
if (dependencyMap[dependency].added)
message += i18n("\n %1 plugin has been automatically checked because of the dependency of %2 plugin", dependency, dependencyMap[dependency].pluginCausant);
else
message += i18n("\n %1 plugin has been automatically unchecked because of its dependency on %2 plugin", dependency, dependencyMap[dependency].pluginCausant);
}
KMessageBox::information(this, message, i18n("Dependency Check"));
addedByDependencies = 0;
removedByDependencies = 0;
updateDetails();
}
void KPluginSelector::Private::DependenciesWidget::updateDetails()
{
if (!dependencyMap.count())
{
setVisible(false);
return;
}
QString message;
if (addedByDependencies)
message += i18np("%1 plugin automatically added due to plugin dependencies", "%1 plugins automatically added due to plugin dependencies", addedByDependencies);
if (removedByDependencies && !message.isEmpty())
message += i18n(", ");
if (removedByDependencies)
message += i18np("%1 plugin automatically removed due to plugin dependencies", "%1 plugins automatically removed due to plugin dependencies", removedByDependencies);
if (message.isEmpty())
details->setVisible(false);
else
{
details->setVisible(true);
details->setText(message);
}
}
KPluginSelector::KPluginSelector(QWidget *parent)
: QWidget(parent)
, d(new Private(this))
{
QVBoxLayout *layout = new QVBoxLayout;
layout->setMargin(0);
setLayout(layout);
d->lineEdit = new KLineEdit(this);
d->lineEdit->setClearButtonShown(true);
d->lineEdit->setClickMessage(i18n("Search Plugins"));
d->listView = new KCategorizedView(this);
d->listView->setVerticalScrollMode(QListView::ScrollPerPixel);
d->listView->setAlternatingRowColors(true);
d->listView->setCategoryDrawer(d->categoryDrawer);
d->dependenciesWidget = new Private::DependenciesWidget(this);
d->pluginModel = new Private::PluginModel(d, this);
d->proxyModel = new Private::ProxyModel(d, this);
d->proxyModel->setCategorizedModel(true);
d->proxyModel->setSourceModel(d->pluginModel);
d->listView->setModel(d->proxyModel);
d->listView->setAlternatingRowColors(true);
Private::PluginDelegate *pluginDelegate = new Private::PluginDelegate(d, this);
d->listView->setItemDelegate(pluginDelegate);
d->listView->setMouseTracking(true);
d->listView->viewport()->setAttribute(Qt::WA_Hover);
connect(d->lineEdit, SIGNAL(textChanged(QString)), d->proxyModel, SLOT(invalidate()));
connect(pluginDelegate, SIGNAL(changed(bool)), this, SIGNAL(changed(bool)));
connect(pluginDelegate, SIGNAL(configCommitted(QByteArray)), this, SIGNAL(configCommitted(QByteArray)));
layout->addWidget(d->lineEdit);
layout->addWidget(d->listView);
layout->addWidget(d->dependenciesWidget);
}
KPluginSelector::~KPluginSelector()
{
delete d->listView->itemDelegate();
delete d->listView; // depends on some other things in d, make sure this dies first.
delete d;
}
void KPluginSelector::addPlugins(const QString &componentName,
const QString &categoryName,
const QString &categoryKey,
KSharedConfig::Ptr config)
{
QStringList desktopFileNames = KGlobal::dirs()->findAllResources("data",
componentName + "/kpartplugins/*.desktop", KStandardDirs::Recursive);
QList<KPluginInfo> pluginInfoList = KPluginInfo::fromFiles(desktopFileNames);
if (pluginInfoList.isEmpty())
return;
Q_ASSERT(config);
if (!config)
config = KSharedConfig::openConfig(componentName);
KConfigGroup cfgGroup(config, "KParts Plugins");
kDebug( 702 ) << "cfgGroup = " << &cfgGroup;
d->pluginModel->addPlugins(pluginInfoList, categoryName, categoryKey, cfgGroup);
d->proxyModel->sort(0);
}
void KPluginSelector::addPlugins(const KComponentData &instance,
const QString &categoryName,
const QString &categoryKey,
const KSharedConfig::Ptr &config)
{
addPlugins(instance.componentName(), categoryName, categoryKey, config);
}
void KPluginSelector::addPlugins(const QList<KPluginInfo> &pluginInfoList,
PluginLoadMethod pluginLoadMethod,
const QString &categoryName,
const QString &categoryKey,
const KSharedConfig::Ptr &config)
{
if (pluginInfoList.isEmpty())
return;
KConfigGroup cfgGroup(config ? config : KGlobal::config(), "Plugins");
kDebug( 702 ) << "cfgGroup = " << &cfgGroup;
d->pluginModel->addPlugins(pluginInfoList, categoryName, categoryKey, cfgGroup, pluginLoadMethod, true /* manually added */);
d->proxyModel->sort(0);
}
void KPluginSelector::load()
{
for (int i = 0; i < d->pluginModel->rowCount(); i++) {
const QModelIndex index = d->pluginModel->index(i, 0);
PluginEntry *pluginEntry = static_cast<PluginEntry*>(index.internalPointer());
pluginEntry->pluginInfo.load(pluginEntry->cfgGroup);
d->pluginModel->setData(index, pluginEntry->pluginInfo.isPluginEnabled(), Qt::CheckStateRole);
}
emit changed(false);
}
void KPluginSelector::save()
{
for (int i = 0; i < d->pluginModel->rowCount(); i++) {
const QModelIndex index = d->pluginModel->index(i, 0);
PluginEntry *pluginEntry = static_cast<PluginEntry*>(index.internalPointer());
pluginEntry->pluginInfo.setPluginEnabled(pluginEntry->checked);
pluginEntry->pluginInfo.save(pluginEntry->cfgGroup);
pluginEntry->cfgGroup.sync();
}
emit changed(false);
}
void KPluginSelector::defaults()
{
for (int i = 0; i < d->pluginModel->rowCount(); i++) {
const QModelIndex index = d->pluginModel->index(i, 0);
PluginEntry *pluginEntry = static_cast<PluginEntry*>(index.internalPointer());
d->pluginModel->setData(index, pluginEntry->pluginInfo.isPluginEnabledByDefault(), Qt::CheckStateRole);
}
emit changed(true);
}
bool KPluginSelector::isDefault() const
{
for (int i = 0; i < d->pluginModel->rowCount(); i++) {
const QModelIndex index = d->pluginModel->index(i, 0);
PluginEntry *pluginEntry = static_cast<PluginEntry*>(index.internalPointer());
if (d->pluginModel->data(index, Qt::CheckStateRole).toBool() != pluginEntry->pluginInfo.isPluginEnabledByDefault()) {
return false;
}
}
return true;
}
void KPluginSelector::updatePluginsState()
{
for (int i = 0; i < d->pluginModel->rowCount(); i++) {
const QModelIndex index = d->pluginModel->index(i, 0);
PluginEntry *pluginEntry = static_cast<PluginEntry*>(index.internalPointer());
if (pluginEntry->manuallyAdded) {
pluginEntry->pluginInfo.setPluginEnabled(pluginEntry->checked);
}
}
}
KPluginSelector::Private::PluginModel::PluginModel(KPluginSelector::Private *pluginSelector_d, QObject *parent)
: QAbstractListModel(parent)
, pluginSelector_d(pluginSelector_d)
{
}
KPluginSelector::Private::PluginModel::~PluginModel()
{
}
void KPluginSelector::Private::PluginModel::addPlugins(const QList<KPluginInfo> &pluginList, const QString &categoryName, const QString &categoryKey, const KConfigGroup &cfgGroup, PluginLoadMethod pluginLoadMethod, bool manuallyAdded)
{
QList<PluginEntry> listToAdd;
foreach (const KPluginInfo &pluginInfo, pluginList) {
PluginEntry pluginEntry;
pluginEntry.category = categoryName;
pluginEntry.pluginInfo = pluginInfo;
if (pluginLoadMethod == ReadConfigFile) {
pluginEntry.pluginInfo.load(cfgGroup);
}
pluginEntry.checked = pluginInfo.isPluginEnabled();
pluginEntry.manuallyAdded = manuallyAdded;
if (cfgGroup.isValid()) {
pluginEntry.cfgGroup = cfgGroup;
} else {
pluginEntry.cfgGroup = pluginInfo.config();
}
// this is where kiosk will set if a plugin is checkable or not (pluginName + "Enabled")
pluginEntry.isCheckable = !pluginInfo.isValid() || !pluginEntry.cfgGroup.isEntryImmutable(pluginInfo.pluginName() + QLatin1String("Enabled"));
if (!pluginEntryList.contains(pluginEntry) && !listToAdd.contains(pluginEntry) &&
(!pluginInfo.property("X-KDE-PluginInfo-Category").isValid() ||
!pluginInfo.property("X-KDE-PluginInfo-Category").toString().compare(categoryKey, Qt::CaseInsensitive)) &&
(pluginInfo.service().isNull() || !pluginInfo.service()->noDisplay())) {
listToAdd << pluginEntry;
if (!pluginSelector_d->showIcons && !pluginInfo.icon().isEmpty()) {
pluginSelector_d->showIcons = true;
}
}
}
if (listToAdd.count()) {
beginInsertRows(QModelIndex(), pluginEntryList.count(), pluginEntryList.count() + listToAdd.count() - 1);
pluginEntryList << listToAdd;
endInsertRows();
}
}
QList<KService::Ptr> KPluginSelector::Private::PluginModel::pluginServices(const QModelIndex &index) const
{
return static_cast<PluginEntry*>(index.internalPointer())->pluginInfo.kcmServices();
}
QModelIndex KPluginSelector::Private::PluginModel::index(int row, int column, const QModelIndex &parent) const
{
Q_UNUSED(parent)
return createIndex(row, column, (row < pluginEntryList.count()) ? (void*) &pluginEntryList.at(row)
: 0);
}
QVariant KPluginSelector::Private::PluginModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || !index.internalPointer()) {
return QVariant();
}
PluginEntry *pluginEntry = static_cast<PluginEntry*>(index.internalPointer());
switch (role) {
case Qt::DisplayRole:
return pluginEntry->pluginInfo.name();
case PluginEntryRole:
return QVariant::fromValue(pluginEntry);
case ServicesCountRole:
return pluginEntry->pluginInfo.kcmServices().count();
case NameRole:
return pluginEntry->pluginInfo.name();
case CommentRole:
return pluginEntry->pluginInfo.comment();
case AuthorRole:
return pluginEntry->pluginInfo.author();
case EmailRole:
return pluginEntry->pluginInfo.email();
case WebsiteRole:
return pluginEntry->pluginInfo.website();
case VersionRole:
return pluginEntry->pluginInfo.version();
case LicenseRole:
return pluginEntry->pluginInfo.license();
case DependenciesRole:
return pluginEntry->pluginInfo.dependencies();
case IsCheckableRole:
return pluginEntry->isCheckable;
case Qt::DecorationRole:
return pluginEntry->pluginInfo.icon();
case Qt::CheckStateRole:
return pluginEntry->checked;
case KCategorizedSortFilterProxyModel::CategoryDisplayRole: // fall through
case KCategorizedSortFilterProxyModel::CategorySortRole:
return pluginEntry->category;
default:
return QVariant();
}
}
bool KPluginSelector::Private::PluginModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid()) {
return false;
}
bool ret = false;
if (role == Qt::CheckStateRole) {
static_cast<PluginEntry*>(index.internalPointer())->checked = value.toBool();
ret = true;
}
if (ret) {
emit dataChanged(index, index);
}
return ret;
}
int KPluginSelector::Private::PluginModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid()) {
return 0;
}
return pluginEntryList.count();
}
KPluginSelector::Private::ProxyModel::ProxyModel(KPluginSelector::Private *pluginSelector_d, QObject *parent)
: KCategorizedSortFilterProxyModel(parent)
, pluginSelector_d(pluginSelector_d)
{
sort(0);
}
KPluginSelector::Private::ProxyModel::~ProxyModel()
{
}
bool KPluginSelector::Private::ProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
Q_UNUSED(sourceParent)
if (!pluginSelector_d->lineEdit->text().isEmpty()) {
const QModelIndex index = sourceModel()->index(sourceRow, 0);
const KPluginInfo pluginInfo = static_cast<PluginEntry*>(index.internalPointer())->pluginInfo;
return pluginInfo.name().contains(pluginSelector_d->lineEdit->text(), Qt::CaseInsensitive) ||
pluginInfo.comment().contains(pluginSelector_d->lineEdit->text(), Qt::CaseInsensitive);
}
return true;
}
bool KPluginSelector::Private::ProxyModel::subSortLessThan(const QModelIndex &left, const QModelIndex &right) const
{
return static_cast<PluginEntry*>(left.internalPointer())->pluginInfo.name().compare(static_cast<PluginEntry*>(right.internalPointer())->pluginInfo.name(), Qt::CaseInsensitive) < 0;
}
KPluginSelector::Private::PluginDelegate::PluginDelegate(KPluginSelector::Private *pluginSelector_d, QObject *parent)
: KWidgetItemDelegate(pluginSelector_d->listView, parent)
, checkBox(new QCheckBox)
, pushButton(new KPushButton)
, pluginSelector_d(pluginSelector_d)
{
pushButton->setIcon(KIcon("configure")); // only for getting size matters
}
KPluginSelector::Private::PluginDelegate::~PluginDelegate()
{
delete checkBox;
delete pushButton;
}
void KPluginSelector::Private::PluginDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (!index.isValid()) {
return;
}
int xOffset = checkBox->sizeHint().width();
bool disabled = !index.model()->data(index, IsCheckableRole).toBool();
painter->save();
QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, 0);
int iconSize = option.rect.height() - MARGIN * 2;
if (pluginSelector_d->showIcons) {
QPixmap pixmap = KIconLoader::global()->loadIcon(index.model()->data(index, Qt::DecorationRole).toString(),
KIconLoader::Desktop, iconSize, disabled ? KIconLoader::DisabledState : KIconLoader::DefaultState);
painter->drawPixmap(QRect(pluginSelector_d->dependantLayoutValue(MARGIN + option.rect.left() + xOffset, iconSize, option.rect.width()), MARGIN + option.rect.top(), iconSize, iconSize), pixmap, QRect(0, 0, iconSize, iconSize));
} else {
iconSize = -MARGIN;
}
QRect contentsRect(pluginSelector_d->dependantLayoutValue(MARGIN * 2 + iconSize + option.rect.left() + xOffset, option.rect.width() - MARGIN * 3 - iconSize - xOffset, option.rect.width()), MARGIN + option.rect.top(), option.rect.width() - MARGIN * 3 - iconSize - xOffset, option.rect.height() - MARGIN * 2);
int lessHorizontalSpace = MARGIN * 2 + pushButton->sizeHint().width();
if (index.model()->data(index, ServicesCountRole).toBool()) {
lessHorizontalSpace += MARGIN + pushButton->sizeHint().width();
}
contentsRect.setWidth(contentsRect.width() - lessHorizontalSpace);
if (option.state & QStyle::State_Selected) {
painter->setPen(option.palette.highlightedText().color());
}
if (pluginSelector_d->listView->layoutDirection() == Qt::RightToLeft) {
contentsRect.translate(lessHorizontalSpace, 0);
}
painter->save();
if (disabled) {
QPalette pal(option.palette);
pal.setCurrentColorGroup(QPalette::Disabled);
painter->setPen(pal.text().color());
}
painter->save();
QFont font = titleFont(option.font);
QFontMetrics fmTitle(font);
painter->setFont(font);
painter->drawText(contentsRect, Qt::AlignLeft | Qt::AlignTop, fmTitle.elidedText(index.model()->data(index, Qt::DisplayRole).toString(), Qt::ElideRight, contentsRect.width()));
painter->restore();
painter->drawText(contentsRect, Qt::AlignLeft | Qt::AlignBottom, option.fontMetrics.elidedText(index.model()->data(index, CommentRole).toString(), Qt::ElideRight, contentsRect.width()));
painter->restore();
painter->restore();
}
QSize KPluginSelector::Private::PluginDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
int i = 5;
int j = 1;
if (index.model()->data(index, ServicesCountRole).toBool()) {
i = 6;
j = 2;
}
if (!pluginSelector_d->showIcons) {
i--;
}
QFont font = titleFont(option.font);
QFontMetrics fmTitle(font);
return QSize(qMax(fmTitle.width(index.model()->data(index, Qt::DisplayRole).toString()),
option.fontMetrics.width(index.model()->data(index, CommentRole).toString())) +
(pluginSelector_d->showIcons ? KIconLoader::SizeMedium : 0) + MARGIN * i + pushButton->sizeHint().width() * j,
qMax(KIconLoader::SizeMedium + MARGIN * 2, fmTitle.height() + option.fontMetrics.height() + MARGIN * 2));
}
QList<QWidget*> KPluginSelector::Private::PluginDelegate::createItemWidgets() const
{
QList<QWidget*> widgetList;
QCheckBox *enabledCheckBox = new QCheckBox;
connect(enabledCheckBox, SIGNAL(clicked(bool)), this, SLOT(slotStateChanged(bool)));
connect(enabledCheckBox, SIGNAL(clicked(bool)), this, SLOT(emitChanged()));
KPushButton *aboutPushButton = new KPushButton;
aboutPushButton->setIcon(KIcon("dialog-information"));
connect(aboutPushButton, SIGNAL(clicked(bool)), this, SLOT(slotAboutClicked()));
KPushButton *configurePushButton = new KPushButton;
configurePushButton->setIcon(KIcon("configure"));
connect(configurePushButton, SIGNAL(clicked(bool)), this, SLOT(slotConfigureClicked()));
setBlockedEventTypes(enabledCheckBox, QList<QEvent::Type>() << QEvent::MouseButtonPress
<< QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick
<< QEvent::KeyPress << QEvent::KeyRelease);
setBlockedEventTypes(aboutPushButton, QList<QEvent::Type>() << QEvent::MouseButtonPress
<< QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick
<< QEvent::KeyPress << QEvent::KeyRelease);
setBlockedEventTypes(configurePushButton, QList<QEvent::Type>() << QEvent::MouseButtonPress
<< QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick
<< QEvent::KeyPress << QEvent::KeyRelease);
widgetList << enabledCheckBox << configurePushButton << aboutPushButton;
return widgetList;
}
void KPluginSelector::Private::PluginDelegate::updateItemWidgets(const QList<QWidget*> widgets,
const QStyleOptionViewItem &option,
const QPersistentModelIndex &index) const
{
QCheckBox *checkBox = static_cast<QCheckBox*>(widgets[0]);
checkBox->resize(checkBox->sizeHint());
checkBox->move(pluginSelector_d->dependantLayoutValue(MARGIN, checkBox->sizeHint().width(), option.rect.width()), option.rect.height() / 2 - checkBox->sizeHint().height() / 2);
KPushButton *aboutPushButton = static_cast<KPushButton*>(widgets[2]);
QSize aboutPushButtonSizeHint = aboutPushButton->sizeHint();
aboutPushButton->resize(aboutPushButtonSizeHint);
aboutPushButton->move(pluginSelector_d->dependantLayoutValue(option.rect.width() - MARGIN - aboutPushButtonSizeHint.width(), aboutPushButtonSizeHint.width(), option.rect.width()), option.rect.height() / 2 - aboutPushButtonSizeHint.height() / 2);
KPushButton *configurePushButton = static_cast<KPushButton*>(widgets[1]);
QSize configurePushButtonSizeHint = configurePushButton->sizeHint();
configurePushButton->resize(configurePushButtonSizeHint);
configurePushButton->move(pluginSelector_d->dependantLayoutValue(option.rect.width() - MARGIN * 2 - configurePushButtonSizeHint.width() - aboutPushButtonSizeHint.width(), configurePushButtonSizeHint.width(), option.rect.width()), option.rect.height() / 2 - configurePushButtonSizeHint.height() / 2);
if (!index.isValid() || !index.internalPointer()) {
checkBox->setVisible(false);
aboutPushButton->setVisible(false);
configurePushButton->setVisible(false);
} else {
checkBox->setChecked(index.model()->data(index, Qt::CheckStateRole).toBool());
checkBox->setEnabled(index.model()->data(index, IsCheckableRole).toBool());
configurePushButton->setVisible(index.model()->data(index, ServicesCountRole).toBool());
configurePushButton->setEnabled(index.model()->data(index, Qt::CheckStateRole).toBool());
}
}
void KPluginSelector::Private::PluginDelegate::slotStateChanged(bool state)
{
if (!focusedIndex().isValid())
return;
const QModelIndex index = focusedIndex();
pluginSelector_d->dependenciesWidget->clearDependencies();
PluginEntry *pluginEntry = index.model()->data(index, PluginEntryRole).value<PluginEntry*>();
pluginSelector_d->updateDependencies(pluginEntry, state);
const_cast<QAbstractItemModel*>(index.model())->setData(index, state, Qt::CheckStateRole);
}
void KPluginSelector::Private::PluginDelegate::emitChanged()
{
emit changed(true);
}
void KPluginSelector::Private::PluginDelegate::slotAboutClicked()
{
const QModelIndex index = focusedIndex();
const QAbstractItemModel *model = index.model();
// Try to retrieve the plugin information from the KComponentData object of the plugin.
// If there is no valid information, go and fetch it from the service itself (the .desktop
// file).
PluginEntry *entry = index.model()->data(index, PluginEntryRole).value<PluginEntry*>();
KService::Ptr entryService = entry->pluginInfo.service();
if (entryService) {
KPluginLoader loader(*entryService);
KPluginFactory *factory = loader.factory();
if (factory) {
const KAboutData *aboutData = factory->componentData().aboutData();
if (!aboutData->programName().isEmpty()) { // Be sure the about data is not completely empty
KAboutApplicationDialog aboutPlugin(aboutData, itemView());
aboutPlugin.setPlainCaption(i18nc("Used only for plugins", "About %1", aboutData->programName()));
aboutPlugin.exec();
return;
}
}
}
const QString name = model->data(index, NameRole).toString();
const QString comment = model->data(index, CommentRole).toString();
const QString author = model->data(index, AuthorRole).toString();
const QString email = model->data(index, EmailRole).toString();
const QString website = model->data(index, WebsiteRole).toString();
const QString version = model->data(index, VersionRole).toString();
const QString license = model->data(index, LicenseRole).toString();
KAboutData aboutData(name.toUtf8(), name.toUtf8(), qi18n(name.toUtf8()), version.toUtf8(), qi18n(comment.toUtf8()), KAboutLicense::byKeyword(license).key(), qi18n(QByteArray()), qi18n(QByteArray()), website.toLatin1());
aboutData.setProgramIconName(index.model()->data(index, Qt::DecorationRole).toString());
const QStringList authors = author.split(',');
const QStringList emails = email.split(',');
if (authors.count() == emails.count()) {
int i = 0;
foreach (const QString &author, authors) {
if (!author.isEmpty()) {
aboutData.addAuthor(qi18n(author.toUtf8()), qi18n(QByteArray()), emails[i].toUtf8(), 0);
}
i++;
}
}
KAboutApplicationDialog aboutPlugin(&aboutData, itemView());
aboutPlugin.setPlainCaption(i18nc("Used only for plugins", "About %1", aboutData.programName()));
aboutPlugin.exec();
}
void KPluginSelector::Private::PluginDelegate::slotConfigureClicked()
{
const QModelIndex index = focusedIndex();
const QAbstractItemModel *model = index.model();
PluginEntry *pluginEntry = model->data(index, PluginEntryRole).value<PluginEntry*>();
KPluginInfo pluginInfo = pluginEntry->pluginInfo;
KDialog configDialog(itemView());
configDialog.setWindowTitle(model->data(index, NameRole).toString());
// The number of KCModuleProxies in use determines whether to use a tabwidget
KTabWidget *newTabWidget = 0;
// Widget to use for the setting dialog's main widget,
// either a KTabWidget or a KCModuleProxy
QWidget * mainWidget = 0;
// Widget to use as the KCModuleProxy's parent.
// The first proxy is owned by the dialog itself
QWidget *moduleProxyParentWidget = &configDialog;
foreach (const KService::Ptr &servicePtr, pluginInfo.kcmServices()) {
if(!servicePtr->noDisplay()) {
KCModuleInfo moduleInfo(servicePtr);
KCModuleProxy *currentModuleProxy = new KCModuleProxy(moduleInfo, moduleProxyParentWidget);
if (currentModuleProxy->realModule()) {
moduleProxyList << currentModuleProxy;
if (mainWidget && !newTabWidget) {
// we already created one KCModuleProxy, so we need a tab widget.
// Move the first proxy into the tab widget and ensure this and subsequent
// proxies are in the tab widget
newTabWidget = new KTabWidget(&configDialog);
moduleProxyParentWidget = newTabWidget;
mainWidget->setParent( newTabWidget );
KCModuleProxy *moduleProxy = qobject_cast<KCModuleProxy*>(mainWidget);
if (moduleProxy) {
newTabWidget->addTab(mainWidget, moduleProxy->moduleInfo().moduleName());
mainWidget = newTabWidget;
} else {
delete newTabWidget;
newTabWidget = 0;
moduleProxyParentWidget = &configDialog;
mainWidget->setParent(0);
}
}
if (newTabWidget) {
newTabWidget->addTab(currentModuleProxy, servicePtr->name());
} else {
mainWidget = currentModuleProxy;
}
} else {
delete currentModuleProxy;
}
}
}
// it could happen that we had services to show, but none of them were real modules.
if (moduleProxyList.count()) {
configDialog.setButtons(KDialog::Ok | KDialog::Cancel | KDialog::Default);
QWidget *showWidget = new QWidget(&configDialog);
QVBoxLayout *layout = new QVBoxLayout;
showWidget->setLayout(layout);
layout->addWidget(mainWidget);
layout->insertSpacing(-1, KDialog::marginHint());
configDialog.setMainWidget(showWidget);
connect(&configDialog, SIGNAL(defaultClicked()), this, SLOT(slotDefaultClicked()));
if (configDialog.exec() == QDialog::Accepted) {
foreach (KCModuleProxy *moduleProxy, moduleProxyList) {
QStringList parentComponents = moduleProxy->moduleInfo().service()->property("X-KDE-ParentComponents").toStringList();
moduleProxy->save();
foreach (const QString &parentComponent, parentComponents) {
emit configCommitted(parentComponent.toLatin1());
}
}
} else {
foreach (KCModuleProxy *moduleProxy, moduleProxyList) {
moduleProxy->load();
}
}
qDeleteAll(moduleProxyList);
moduleProxyList.clear();
}
}
void KPluginSelector::Private::PluginDelegate::slotDefaultClicked()
{
foreach (KCModuleProxy *moduleProxy, moduleProxyList) {
moduleProxy->defaults();
}
}
QFont KPluginSelector::Private::PluginDelegate::titleFont(const QFont &baseFont) const
{
QFont retFont(baseFont);
retFont.setBold(true);
return retFont;
}
#include "moc_kpluginselector_p.cpp"
#include "moc_kpluginselector.cpp"
diff --git a/kutils/ksettings/dialog.cpp b/kutils/ksettings/dialog.cpp
index cda9246c71..3bf89092a4 100644
--- a/kutils/ksettings/dialog.cpp
+++ b/kutils/ksettings/dialog.cpp
@@ -1,563 +1,564 @@
/* This file is part of the KDE project
Copyright (C) 2003 Matthias Kretz <kretz@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 "dialog.h"
#include "dialog_p.h"
#include "dispatcher.h"
//#include "componentsdialog_p.h"
+#include <kicon.h>
#include <klocale.h>
#include <kservicegroup.h>
#include <kdebug.h>
#include <kservicetypetrader.h>
#include <kconfig.h>
#include <kstandarddirs.h>
#include <kcomponentdata.h>
#include <kiconloader.h>
#include <QtCore/QFile>
#include <QCheckBox>
#include <QtCore/QStack>
uint qHash(const KCModuleInfo &info)
{
return qHash(info.fileName());
}
namespace KSettings
{
Dialog::Dialog(QWidget *parent)
: KCMultiDialog(*new DialogPrivate, new KPageWidget, parent)
{
}
Dialog::Dialog(const QStringList &components, QWidget *parent)
: KCMultiDialog(*new DialogPrivate, new KPageWidget, parent)
{
Q_D(Dialog);
d->components = components;
}
Dialog::~Dialog()
{
}
void Dialog::setAllowComponentSelection(bool selection)
{
d_func()->staticlistview = !selection;
}
bool Dialog::allowComponentSelection() const
{
return !d_func()->staticlistview;
}
void Dialog::setKCMArguments(const QStringList& arguments)
{
Q_D(Dialog);
d->arguments = arguments;
}
void Dialog::setComponentBlacklist(const QStringList& blacklist)
{
Q_D(Dialog);
d->componentBlacklist = blacklist;
}
void Dialog::addPluginInfos(const KPluginInfo::List &plugininfos)
{
Q_D(Dialog);
for (KPluginInfo::List::ConstIterator it = plugininfos.begin();
it != plugininfos.end(); ++it ) {
d->registeredComponents.append(it->pluginName());
if (it->kcmServices().isEmpty()) {
// this plugin has no kcm services, still we want to show the disable/enable stuff
// so add a dummy kcm
KService::Ptr service = it->service();
d->kcmInfos << KCModuleInfo(service);
continue;
}
foreach (const KService::Ptr &service, it->kcmServices()) {
d->kcmInfos << KCModuleInfo(service);
}
}
// The plugin, when disabled, disables all the KCMs described by kcmServices().
// - Normally they are grouped using a .setdlg file so that the group parent can get a
// checkbox to enable/disable the plugin.
// - If the plugin does not belong to a group and has only one KCM the checkbox can be
// used with this KCM.
// - If the plugin belongs to a group but there are other modules in the group that do not
// belong to this plugin we give a kError and show no checkbox
// - If the plugin belongs to multiple groups we give a kError and show no checkbox
d->plugininfos = plugininfos;
}
KPluginInfo::List Dialog::pluginInfos() const
{
return d_func()->plugininfos;
}
void Dialog::showEvent(QShowEvent *)
{
Q_D(Dialog);
if (d->firstshow) {
setUpdatesEnabled(false);
d->kcmInfos += d->instanceServices();
if (!d->components.isEmpty()) {
d->kcmInfos += d->parentComponentsServices(d->components);
}
d->createDialogFromServices();
d->firstshow = false;
setUpdatesEnabled(true);
}
Dispatcher::syncConfiguration();
}
DialogPrivate::DialogPrivate()
: staticlistview(true), firstshow(true), pluginStateDirty(0)
{
}
QSet<KCModuleInfo> DialogPrivate::instanceServices()
{
//kDebug(700) ;
QString componentName = KGlobal::mainComponent().componentName();
registeredComponents.append(componentName);
//kDebug(700) << "calling KServiceGroup::childGroup( " << componentName << " )";
KServiceGroup::Ptr service = KServiceGroup::childGroup( componentName );
QSet<KCModuleInfo> ret;
if( service && service->isValid() )
{
//kDebug(700) << "call was successful";
const KServiceGroup::List list = service->entries();
for( KServiceGroup::List::ConstIterator it = list.begin();
it != list.end(); ++it )
{
KSycocaEntry::Ptr p = (*it);
if( p->isType( KST_KService ) )
{
//kDebug( 700 ) << "found service";
ret << KCModuleInfo(KService::Ptr::staticCast(p));
}
else
kWarning( 700 ) << "KServiceGroup::childGroup returned"
" something else than a KService" << endl;
}
}
return ret;
}
QSet<KCModuleInfo> DialogPrivate::parentComponentsServices(const QStringList &kcdparents)
{
registeredComponents += kcdparents;
QString constraint = kcdparents.join("' in [X-KDE-ParentComponents]) or ('");
constraint = "('" + constraint + "' in [X-KDE-ParentComponents])";
//kDebug(700) << "constraint = " << constraint;
const QList<KService::Ptr> services = KServiceTypeTrader::self()->query("KCModule", constraint);
QSet<KCModuleInfo> ret;
foreach (const KService::Ptr &service, services) {
ret << KCModuleInfo(service);
}
return ret;
}
bool DialogPrivate::isPluginForKCMEnabled(const KCModuleInfo *moduleinfo, KPluginInfo &pinfo) const
{
// if the user of this class requested to hide disabled modules
// we check whether it should be enabled or not
bool enabled = true;
//kDebug(700) << "check whether the '" << moduleinfo->moduleName() << "' KCM should be shown";
// for all parent components
const QStringList parentComponents = moduleinfo->service()->property(
"X-KDE-ParentComponents" ).toStringList();
for( QStringList::ConstIterator pcit = parentComponents.begin();
pcit != parentComponents.end(); ++pcit )
{
// if the parentComponent is not registered ignore it
if (!registeredComponents.contains(*pcit)) {
continue;
}
// we check if the parent component is a plugin
// if not the KCModule must be enabled
enabled = true;
if (pinfo.pluginName() == *pcit) {
// it is a plugin: we check whether the plugin is enabled
pinfo.load();
enabled = pinfo.isPluginEnabled();
//kDebug(700) << "parent " << *pcit << " is " << (enabled ? "enabled" : "disabled");
}
// if it is enabled we're done for this KCModuleInfo
if (enabled) {
return true;
}
}
return enabled;
}
bool DialogPrivate::isPluginImmutable(const KPluginInfo &pinfo) const
{
return pinfo.property("X-KDE-PluginInfo-Immutable").toBool();
}
KPageWidgetItem *DialogPrivate::createPageItem(KPageWidgetItem *parentItem,
const QString &name, const QString &comment,
const QString &iconName, int weight)
{
Q_Q(Dialog);
QWidget * page = new QWidget( q );
QCheckBox *checkBox = new QCheckBox(i18n("Enable component"), page);
QLabel *iconLabel = new QLabel(page);
QLabel *commentLabel = new QLabel(comment, page);
commentLabel->setTextFormat(Qt::RichText);
QVBoxLayout * layout = new QVBoxLayout(page);
layout->addWidget(checkBox);
layout->addWidget(iconLabel);
layout->addWidget(commentLabel);
layout->addStretch();
page->setLayout(layout);
KPageWidgetItem *item = new KPageWidgetItem(page, name);
item->setIcon(KIcon(iconName));
iconLabel->setPixmap(item->icon().pixmap(128, 128));
item->setProperty("_k_weight", weight);
checkBoxForItem.insert(item, checkBox);
const KPageWidgetModel *model = qobject_cast<const KPageWidgetModel *>(q->pageWidget()->model());
Q_ASSERT(model);
if (parentItem) {
const QModelIndex parentIndex = model->index(parentItem);
const int siblingCount = model->rowCount(parentIndex);
int row = 0;
for (; row < siblingCount; ++row) {
KPageWidgetItem *siblingItem = model->item(parentIndex.child(row, 0));
if (siblingItem->property("_k_weight").toInt() > weight) {
// the item we found is heavier than the new module
q->insertPage(siblingItem, item);
break;
}
}
if (row == siblingCount) {
// the new module is either the first or the heaviest item
q->addSubPage(parentItem, item);
}
} else {
const int siblingCount = model->rowCount();
int row = 0;
for (; row < siblingCount; ++row) {
KPageWidgetItem *siblingItem = model->item(model->index(row, 0));
if (siblingItem->property("_k_weight").toInt() > weight) {
// the item we found is heavier than the new module
q->insertPage(siblingItem, item);
break;
}
}
if (row == siblingCount) {
// the new module is either the first or the heaviest item
q->addPage(item);
}
}
return (item);
}
void DialogPrivate::parseGroupFile( const QString & filename )
{
KConfig file( filename, KConfig::SimpleConfig );
const QStringList groups = file.groupList();
foreach (const QString &group, groups) {
if (group.isEmpty()) {
continue;
}
KConfigGroup conf(&file, group);
const QString parentId = conf.readEntry("Parent");
KPageWidgetItem *parentItem = pageItemForGroupId.value(parentId);
KPageWidgetItem *item = createPageItem(parentItem, conf.readEntry("Name"), conf.readEntry("Comment"),
conf.readEntry("Icon"), conf.readEntry("Weight", 100));
pageItemForGroupId.insert(group, item);
}
}
void DialogPrivate::createDialogFromServices()
{
Q_Q(Dialog);
// read .setdlg files
QString setdlgpath = KStandardDirs::locate( "appdata",
KGlobal::mainComponent().componentName() + ".setdlg" );
const QStringList setdlgaddon = KGlobal::dirs()->findAllResources( "appdata",
"ksettingsdialog/*.setdlg" );
if (!setdlgpath.isNull()) {
parseGroupFile(setdlgpath);
}
if (setdlgaddon.size() > 0) {
for (QStringList::ConstIterator it = setdlgaddon.begin(); it != setdlgaddon.end(); ++it) {
parseGroupFile(*it);
}
}
//kDebug(700) << kcmInfos.count();
foreach (const KCModuleInfo &info, kcmInfos) {
const QStringList parentComponents = info.service()->property("X-KDE-ParentComponents").toStringList();
bool blacklisted = false;
foreach (const QString &parentComponent, parentComponents) {
if (componentBlacklist.contains(parentComponent)) {
blacklisted = true;
break;
}
}
if (blacklisted) {
continue;
}
const QString parentId = info.service()->property("X-KDE-CfgDlgHierarchy", QVariant::String).toString();
KPageWidgetItem *parent = pageItemForGroupId.value(parentId);
if (!parent) {
// dummy kcm
bool foundPlugin = false;
foreach (const KPluginInfo &pinfo, plugininfos) {
if (pinfo.service() == info.service()) {
if (!pinfo.kcmServices().count()) {
const KService::Ptr service = info.service();
// FIXME get weight from service or plugin info
const int weight = 1000;
KPageWidgetItem *item = createPageItem(0, service->name(), service->comment(), service->icon(), weight);
connectItemCheckBox(item, pinfo, pinfo.isPluginEnabled());
foundPlugin = true;
break;
}
}
}
if (foundPlugin) {
continue;
}
}
KPageWidgetItem *item = q->addModule(info, parent, arguments);
kDebug(700) << "added KCM '" << info.moduleName() << "'";
foreach (KPluginInfo pinfo, plugininfos) {
kDebug(700) << pinfo.pluginName();
if (pinfo.kcmServices().contains(info.service())) {
const bool isEnabled = isPluginForKCMEnabled(&info, pinfo);
kDebug(700) << "correct KPluginInfo for this KCM";
// this KCM belongs to a plugin
if (parent && pinfo.kcmServices().count() >= 1) {
item->setEnabled(isEnabled);
const KPluginInfo &plugin = pluginForItem.value(parent);
if (plugin.isValid()) {
if (plugin != pinfo) {
kError(700) << "A group contains more than one plugin: '"
<< plugin.pluginName() << "' and '" << pinfo.pluginName()
<< "'. Now it won't be possible to enable/disable the plugin."
<< endl;
parent->setCheckable(false);
q->disconnect(parent, SIGNAL(toggled(bool)), q, SLOT(_k_updateEnabledState(bool)));
}
// else everything is fine
} else {
connectItemCheckBox(parent, pinfo, isEnabled);
}
} else {
pluginForItem.insert(item, pinfo);
item->setCheckable(!isPluginImmutable(pinfo));
item->setChecked(isEnabled);
q->connect(item, SIGNAL(toggled(bool)), q, SLOT(_k_updateEnabledState(bool)));
}
break;
}
}
}
// now that the KCMs are in, check for empty groups and remove them again
{
const KPageWidgetModel *model = qobject_cast<const KPageWidgetModel *>(q->pageWidget()->model());
const QHash<QString, KPageWidgetItem *>::ConstIterator end = pageItemForGroupId.constEnd();
QHash<QString, KPageWidgetItem *>::ConstIterator it = pageItemForGroupId.constBegin();
for (; it != end; ++it) {
const QModelIndex index = model->index(it.value());
KPluginInfo pinfo;
foreach (const KPluginInfo &p, plugininfos) {
if (p.name()==it.key()) {
pinfo = p;
break;
}
}
bool allowEmpty = false;
if (pinfo.isValid()) {
allowEmpty = pinfo.property("X-KDE-PluginInfo-AllowEmptySettings").toBool();
}
if (!index.child(0, 0).isValid()) {
// no children, and it's not allowed => remove this item
if (!allowEmpty) {
q->removePage(it.value());
} else {
connectItemCheckBox(it.value(), pinfo, pinfo.isPluginEnabled());
}
}
}
}
// TODO: Don't show the reset button until the issue with the
// KPluginSelector::load() method is solved.
// Problem:
// KCMultiDialog::show() call KCModule::load() to reset all KCMs
// (KPluginSelector::load() resets all plugin selections and all plugin
// KCMs).
// The reset button calls KCModule::load(), too but in this case we want the
// KPluginSelector to only reset the current visible plugin KCM and not
// touch the plugin selections.
// I have no idea how to check that in KPluginSelector::load()...
//q->showButton(KDialog::User1, true);
QObject::connect(q, SIGNAL(okClicked()), q, SLOT(_k_syncConfiguration()));
QObject::connect(q, SIGNAL(applyClicked()), q, SLOT(_k_syncConfiguration()));
QObject::connect(q, SIGNAL(configCommitted(const QByteArray &)), q,
SLOT(_k_reparseConfiguration(const QByteArray &)));
}
void DialogPrivate::connectItemCheckBox(KPageWidgetItem *item, const KPluginInfo &pinfo, bool isEnabled)
{
Q_Q(Dialog);
QCheckBox *checkBox = checkBoxForItem.value(item);
Q_ASSERT(checkBox);
pluginForItem.insert(item, pinfo);
item->setCheckable(!isPluginImmutable(pinfo));
item->setChecked(isEnabled);
checkBox->setVisible(!isPluginImmutable(pinfo));
checkBox->setChecked(isEnabled);
q->connect(item, SIGNAL(toggled(bool)), q, SLOT(_k_updateEnabledState(bool)));
q->connect(item, SIGNAL(toggled(bool)), checkBox, SLOT(setChecked(bool)));
q->connect(checkBox, SIGNAL(clicked(bool)), item, SLOT(setChecked(bool)));
}
void DialogPrivate::_k_syncConfiguration()
{
Q_Q(Dialog);
const QHash<KPageWidgetItem *, KPluginInfo>::Iterator endIt = pluginForItem.end();
QHash<KPageWidgetItem *, KPluginInfo>::Iterator it = pluginForItem.begin();
for (; it != endIt; ++it) {
KPageWidgetItem *item = it.key();
KPluginInfo pinfo = it.value();
pinfo.setPluginEnabled(item->isChecked());
pinfo.save();
}
if (pluginStateDirty > 0) {
emit q->pluginSelectionChanged();
pluginStateDirty = 0;
}
Dispatcher::syncConfiguration();
}
void DialogPrivate::_k_reparseConfiguration(const QByteArray &a)
{
Dispatcher::reparseConfiguration(a);
}
/*
void DialogPrivate::_k_configureTree()
{
kDebug( 700 ) ;
QObject::connect(subdlg, SIGNAL(okClicked()), q, SLOT(_k_updateTreeList()));
QObject::connect(subdlg, SIGNAL(applyClicked()), q, SLOT(_k_updateTreeList()));
QObject::connect(subdlg, SIGNAL(okClicked()), q, SIGNAL(pluginSelectionChanged()));
QObject::connect(subdlg, SIGNAL(applyClicked()), q, SIGNAL(pluginSelectionChanged()));
}
*/
void DialogPrivate::_k_clientChanged()
{
if (pluginStateDirty > 0) {
Q_Q(Dialog);
q->enableButton(KDialog::Apply, true);
} else {
KCMultiDialogPrivate::_k_clientChanged();
}
}
void DialogPrivate::_k_updateEnabledState(bool enabled)
{
Q_Q(Dialog);
KPageWidgetItem *item = qobject_cast<KPageWidgetItem *>(q->sender());
if (!item) {
kWarning(700) << "invalid sender";
return;
}
// iterate over all child KPageWidgetItem objects and check whether they need to be enabled/disabled
const KPageWidgetModel *model = qobject_cast<const KPageWidgetModel *>(q->pageWidget()->model());
Q_ASSERT(model);
QModelIndex index = model->index(item);
if (!index.isValid()) {
kWarning(700) << "could not find item in model";
return;
}
const KPluginInfo &pinfo = pluginForItem.value(item);
if (!pinfo.isValid()) {
kWarning(700) << "could not find KPluginInfo in item";
return;
}
if (pinfo.isPluginEnabled() != enabled) {
++pluginStateDirty;
} else {
--pluginStateDirty;
}
if (pluginStateDirty < 2) {
_k_clientChanged();
}
//kDebug(700) ;
QModelIndex firstborn = index.child(0, 0);
if (firstborn.isValid()) {
//kDebug(700) << "iterating over children";
// change all children
index = firstborn;
QStack<QModelIndex> stack;
while (index.isValid()) {
//kDebug(700) << index;
KPageWidgetItem *item = model->item(index);
//kDebug(700) << "item->setEnabled(" << enabled << ')';
item->setEnabled(enabled);
firstborn = index.child(0, 0);
if (firstborn.isValid()) {
stack.push(index);
index = firstborn;
} else {
index = index.sibling(index.row() + 1, 0);
while (!index.isValid() && !stack.isEmpty()) {
index = stack.pop();
index = index.sibling(index.row() + 1, 0);
}
}
}
}
}
} //namespace
#include "moc_dialog.cpp"
// vim: ts=4
diff --git a/plasma/widgets/pushbutton.cpp b/plasma/widgets/pushbutton.cpp
index 0609428114..ef2f09b6ce 100644
--- a/plasma/widgets/pushbutton.cpp
+++ b/plasma/widgets/pushbutton.cpp
@@ -1,542 +1,542 @@
/*
* Copyright 2008 Aaron Seigo <aseigo@kde.org>
* Copyright 2008 Marco Martin <notmart@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "pushbutton.h"
#include <QDir>
#include <QPainter>
#include <QStyleOptionGraphicsItem>
#include <QWeakPointer>
#include <kicon.h>
#include <kiconeffect.h>
#include <kmimetype.h>
#include <kpushbutton.h>
#include "animator.h"
#include "animations/animation.h"
#include "framesvg.h"
#include "paintutils.h"
#include "private/actionwidgetinterface_p.h"
#include "private/focusindicator_p.h"
#include "private/themedwidgetinterface_p.h"
#include "theme.h"
namespace Plasma
{
class PushButtonPrivate : public ActionWidgetInterface<PushButton>
{
public:
PushButtonPrivate(PushButton *pushButton)
: ActionWidgetInterface<PushButton>(pushButton),
background(0),
fadeIn(false),
svg(0)
{
}
~PushButtonPrivate()
{
delete svg;
}
void setPixmap()
{
if (imagePath.isEmpty()) {
delete svg;
svg = 0;
return;
}
KMimeType::Ptr mime = KMimeType::findByPath(absImagePath);
QPixmap pm;
if (mime->is("image/svg+xml") || mime->is("image/svg+xml-compressed")) {
if (!svg || svg->imagePath() != absImagePath) {
delete svg;
svg = new Svg();
svg->setImagePath(imagePath);
QObject::connect(svg, SIGNAL(repaintNeeded()), q, SLOT(setPixmap()));
if (!svgElement.isNull()) {
svg->setContainsMultipleImages(true);
}
}
//QPainter p(&pm);
if (!svgElement.isEmpty() && svg->hasElement(svgElement)) {
svg->resize();
QSizeF elementSize = svg->elementSize(svgElement);
float scale = q->nativeWidget()->iconSize().width() / qMax(elementSize.width(), elementSize.height());
svg->resize(elementSize * scale);
pm = svg->pixmap(svgElement);
} else {
svg->resize(q->nativeWidget()->iconSize());
pm = svg->pixmap();
}
} else {
delete svg;
svg = 0;
pm = QPixmap(absImagePath);
}
static_cast<KPushButton*>(q->widget())->setIcon(KIcon(pm));
}
void pressedChanged()
{
if (q->nativeWidget()->isDown() || q->nativeWidget()->isChecked()) {
focusIndicator->animateVisibility(false);
} else {
focusIndicator->animateVisibility(true);
}
}
void syncFrame()
{
if (background) {
//resize all panels
background->setElementPrefix("pressed");
background->resizeFrame(q->size());
syncActiveRect();
background->setElementPrefix("normal");
background->resizeFrame(q->size());
hoverAnimation->setProperty("startPixmap", background->framePixmap());
background->setElementPrefix("active");
background->resizeFrame(activeRect.size());
hoverAnimation->setProperty("targetPixmap", background->framePixmap());
}
}
void syncActiveRect();
void syncBorders();
FrameSvg *background;
bool fadeIn;
qreal opacity;
QRectF activeRect;
Animation *hoverAnimation;
FocusIndicator *focusIndicator;
QString imagePath;
QString absImagePath;
Svg *svg;
QString svgElement;
};
void PushButtonPrivate::syncActiveRect()
{
background->setElementPrefix("normal");
qreal left, top, right, bottom;
background->getMargins(left, top, right, bottom);
background->setElementPrefix("active");
qreal activeLeft, activeTop, activeRight, activeBottom;
background->getMargins(activeLeft, activeTop, activeRight, activeBottom);
activeRect = QRectF(QPointF(0, 0), q->size());
activeRect.adjust(left - activeLeft, top - activeTop,
-(right - activeRight), -(bottom - activeBottom));
background->setElementPrefix("normal");
}
void PushButtonPrivate::syncBorders()
{
//set margins from the normal element
qreal left, top, right, bottom;
background->setElementPrefix("normal");
background->getMargins(left, top, right, bottom);
q->setContentsMargins(left, top, right, bottom);
//calc the rect for the over effect
syncActiveRect();
}
PushButton::PushButton(QGraphicsWidget *parent)
: QGraphicsProxyWidget(parent),
d(new PushButtonPrivate(this))
{
d->background = new FrameSvg(this);
d->background->setImagePath("widgets/button");
d->background->setCacheAllRenderedFrames(true);
d->background->setElementPrefix("normal");
d->hoverAnimation = Animator::create(Animator::PixmapTransitionAnimation);
d->hoverAnimation->setTargetWidget(this);
KPushButton *native = new KPushButton;
connect(native, SIGNAL(pressed()), this, SIGNAL(pressed()));
connect(native, SIGNAL(pressed()), this, SLOT(pressedChanged()));
connect(native, SIGNAL(released()), this, SIGNAL(released()));
connect(native, SIGNAL(released()), this, SLOT(pressedChanged()));
connect(native, SIGNAL(clicked()), this, SIGNAL(clicked()));
connect(native, SIGNAL(toggled(bool)), this, SIGNAL(toggled(bool)));
setWidget(native);
native->setAttribute(Qt::WA_NoSystemBackground);
native->setWindowIcon(QIcon());
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
d->focusIndicator = new FocusIndicator(this, d->background);
d->syncBorders();
setAcceptHoverEvents(true);
connect(d->background, SIGNAL(repaintNeeded()), SLOT(syncBorders()));
d->initTheming();
d->syncFrame();
}
PushButton::~PushButton()
{
delete d;
}
void PushButton::setText(const QString &text)
{
static_cast<KPushButton*>(widget())->setText(text);
updateGeometry();
}
QString PushButton::text() const
{
return static_cast<KPushButton*>(widget())->text();
}
void PushButton::setImage(const QString &path)
{
if (d->imagePath == path) {
return;
}
delete d->svg;
d->svg = 0;
d->imagePath = path;
bool absolutePath = !path.isEmpty() &&
#ifdef Q_WS_WIN
!QDir::isRelativePath(path)
#else
(path[0] == '/' || path.startsWith(QLatin1String(":/")))
#endif
;
if (absolutePath) {
d->absImagePath = path;
} else {
//TODO: package support
d->absImagePath = Theme::defaultTheme()->imagePath(path);
}
d->setPixmap();
}
void PushButton::setImage(const QString &path, const QString &elementid)
{
d->svgElement = elementid;
setImage(path);
}
QString PushButton::image() const
{
return d->imagePath;
}
void PushButton::setStyleSheet(const QString &stylesheet)
{
d->focusIndicator->setVisible(stylesheet.isEmpty());
widget()->setStyleSheet(stylesheet);
}
QString PushButton::styleSheet()
{
return widget()->styleSheet();
}
void PushButton::setAction(QAction *action)
{
d->setAction(action);
}
QAction *PushButton::action() const
{
return d->action;
}
-void PushButton::setIcon(const KIcon &icon)
+void PushButton::setIcon(const QIcon &icon)
{
nativeWidget()->setIcon(icon);
}
void PushButton::setIcon(const QIcon &icon)
{
setIcon(KIcon(icon));
}
QIcon PushButton::icon() const
{
return nativeWidget()->icon();
}
void PushButton::setCheckable(bool checkable)
{
nativeWidget()->setCheckable(checkable);
}
bool PushButton::isCheckable() const
{
return nativeWidget()->isCheckable();
}
void PushButton::setChecked(bool checked)
{
nativeWidget()->setChecked(checked);
}
void PushButton::click()
{
nativeWidget()->animateClick();
}
bool PushButton::isChecked() const
{
return nativeWidget()->isChecked();
}
bool PushButton::isDown() const
{
return nativeWidget()->isDown();
}
KPushButton *PushButton::nativeWidget() const
{
return static_cast<KPushButton*>(widget());
}
void PushButton::resizeEvent(QGraphicsSceneResizeEvent *event)
{
d->setPixmap();
d->syncFrame();
QGraphicsProxyWidget::resizeEvent(event);
}
void PushButton::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
if (!styleSheet().isNull() || Theme::defaultTheme()->useNativeWidgetStyle()) {
QGraphicsProxyWidget::paint(painter, option, widget);
return;
}
QPixmap bufferPixmap;
//Normal button, pressed or not
if (isEnabled()) {
if (nativeWidget()->isDown() || nativeWidget()->isChecked()) {
d->background->setElementPrefix("pressed");
} else {
d->background->setElementPrefix("normal");
}
//flat or disabled
} else if (!isEnabled() || nativeWidget()->isFlat()) {
bufferPixmap = QPixmap(rect().size().toSize());
bufferPixmap.fill(Qt::transparent);
QPainter buffPainter(&bufferPixmap);
d->background->paintFrame(&buffPainter);
buffPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
buffPainter.fillRect(bufferPixmap.rect(), QColor(0, 0, 0, 128));
painter->drawPixmap(0, 0, bufferPixmap);
}
//if is under mouse draw the animated glow overlay
if (!nativeWidget()->isDown() && !nativeWidget()->isChecked() && isEnabled() && acceptHoverEvents() && d->background->hasElementPrefix("active")) {
if (d->hoverAnimation->state() == QAbstractAnimation::Running && !isUnderMouse() && !nativeWidget()->isDefault()) {
d->background->setElementPrefix("active");
d->background->paintFrame(painter, d->activeRect.topLeft());
} else {
painter->drawPixmap(
d->activeRect.topLeft(),
d->hoverAnimation->property("currentPixmap").value<QPixmap>());
}
} else if (isEnabled()) {
d->background->paintFrame(painter);
}
painter->setPen(Plasma::Theme::defaultTheme()->color(Theme::ButtonTextColor));
if (nativeWidget()->isDown()) {
painter->translate(QPoint(1, 1));
}
QRectF rect = contentsRect();
if (!nativeWidget()->icon().isNull()) {
const qreal iconSize = qMin(rect.width(), rect.height());
QPixmap iconPix = nativeWidget()->icon().pixmap(iconSize);
if (!isEnabled()) {
KIconEffect *effect = KIconLoader::global()->iconEffect();
iconPix = effect->apply(iconPix, KIconLoader::Toolbar, KIconLoader::DisabledState);
}
QRect pixmapRect;
if (nativeWidget()->text().isEmpty()) {
pixmapRect = nativeWidget()->style()->alignedRect(option->direction, Qt::AlignCenter, iconPix.size(), rect.toRect());
} else {
pixmapRect = nativeWidget()->style()->alignedRect(option->direction, Qt::AlignLeft|Qt::AlignVCenter, iconPix.size(), rect.toRect());
}
painter->drawPixmap(pixmapRect.topLeft(), iconPix);
if (option->direction == Qt::LeftToRight) {
rect.adjust(rect.height(), 0, 0, 0);
} else {
rect.adjust(0, 0, -rect.height(), 0);
}
}
QFontMetricsF fm(font());
// If the height is too small increase the Height of the button to shall the whole text #192988
if (rect.height() < fm.height()) {
rect.setHeight(fm.height());
rect.moveTop(boundingRect().center().y() - rect.height() / 2);
}
// If there is not enough room for the text make it to fade out
if (rect.width() < fm.width(nativeWidget()->text())) {
if (bufferPixmap.isNull()) {
bufferPixmap = QPixmap(rect.size().toSize());
}
bufferPixmap.fill(Qt::transparent);
QPainter p(&bufferPixmap);
p.setPen(painter->pen());
p.setFont(font());
// Create the alpha gradient for the fade out effect
QLinearGradient alphaGradient(0, 0, 1, 0);
alphaGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
if (option->direction == Qt::LeftToRight) {
alphaGradient.setColorAt(0, QColor(0, 0, 0, 255));
alphaGradient.setColorAt(1, QColor(0, 0, 0, 0));
p.drawText(bufferPixmap.rect(), Qt::AlignLeft|Qt::AlignVCenter|Qt::TextShowMnemonic,
nativeWidget()->text());
} else {
alphaGradient.setColorAt(0, QColor(0, 0, 0, 0));
alphaGradient.setColorAt(1, QColor(0, 0, 0, 255));
p.drawText(bufferPixmap.rect(), Qt::AlignRight|Qt::AlignVCenter|Qt::TextShowMnemonic,
nativeWidget()->text());
}
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
p.fillRect(bufferPixmap.rect(), alphaGradient);
painter->drawPixmap(rect.topLeft(), bufferPixmap);
} else {
painter->setFont(font());
painter->drawText(rect, Qt::AlignCenter|Qt::TextShowMnemonic, nativeWidget()->text());
}
}
void PushButton::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
if (nativeWidget()->isDown() || d->background->hasElementPrefix("hover")) {
return;
}
d->hoverAnimation->setProperty("duration", 75);
d->background->setElementPrefix("normal");
d->hoverAnimation->setProperty("startPixmap", d->background->framePixmap());
d->background->setElementPrefix("active");
d->hoverAnimation->setProperty("targetPixmap", d->background->framePixmap());
d->hoverAnimation->start();
QGraphicsProxyWidget::hoverEnterEvent(event);
}
void PushButton::changeEvent(QEvent *event)
{
d->changeEvent(event);
QGraphicsProxyWidget::changeEvent(event);
}
void PushButton::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
if (nativeWidget()->isDown() || d->background->hasElementPrefix("hover")) {
return;
}
d->hoverAnimation->setProperty("duration", 150);
d->background->setElementPrefix("active");
d->hoverAnimation->setProperty("startPixmap", d->background->framePixmap());
d->background->setElementPrefix("normal");
d->hoverAnimation->setProperty("targetPixmap", d->background->framePixmap());
d->hoverAnimation->start();
QGraphicsProxyWidget::hoverLeaveEvent(event);
}
QSizeF PushButton::sizeHint(Qt::SizeHint which, const QSizeF & constraint) const
{
QSizeF hint = QGraphicsProxyWidget::sizeHint(which, constraint);
if (hint.isEmpty()) {
return hint;
}
//replace the native margin with the Svg one
QStyleOption option;
option.initFrom(nativeWidget());
int nativeMargin = nativeWidget()->style()->pixelMetric(QStyle::PM_ButtonMargin, &option, nativeWidget());
qreal left, top, right, bottom;
d->background->getMargins(left, top, right, bottom);
hint = hint - QSize(nativeMargin, nativeMargin) + QSize(left+right, top+bottom);
return hint;
}
} // namespace Plasma
#include "moc_pushbutton.cpp"
diff --git a/plasma/widgets/pushbutton.h b/plasma/widgets/pushbutton.h
index b1fb36e534..6c280a9ee0 100644
--- a/plasma/widgets/pushbutton.h
+++ b/plasma/widgets/pushbutton.h
@@ -1,243 +1,243 @@
/*
* Copyright 2008 Aaron Seigo <aseigo@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef PLASMA_PUSHBUTTON_H
#define PLASMA_PUSHBUTTON_H
#include <QGraphicsProxyWidget>
#include <kicon.h>
class KPushButton;
#include <plasma/plasma_export.h>
namespace Plasma
{
class PushButtonPrivate;
/**
* @class PushButton plasma/widgets/pushbutton.h <Plasma/Widgets/PushButton>
*
* @short Provides a plasma-themed KPushButton.
*/
class PLASMA_EXPORT PushButton : public QGraphicsProxyWidget
{
Q_OBJECT
Q_PROPERTY(QGraphicsWidget *parentWidget READ parentWidget)
Q_PROPERTY(QString text READ text WRITE setText)
Q_PROPERTY(QString image READ image WRITE setImage)
Q_PROPERTY(QString styleSheet READ styleSheet WRITE setStyleSheet)
Q_PROPERTY(KPushButton *nativeWidget READ nativeWidget)
Q_PROPERTY(QAction *action READ action WRITE setAction)
Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable)
Q_PROPERTY(bool checked READ isChecked WRITE setChecked)
Q_PROPERTY(bool down READ isDown)
public:
explicit PushButton(QGraphicsWidget *parent = 0);
~PushButton();
/**
* Sets the display text for this PushButton
*
* @param text the text to display; should be translated.
*/
void setText(const QString &text);
/**
* @return the display text
*/
QString text() const;
/**
* Sets the path to an image to display.
*
* @param path the path to the image; if a relative path, then a themed image will be loaded.
*/
void setImage(const QString &path);
/**
* Sets the path to an svg image to display and the id of the used svg element, if necessary.
*
* @param path the path to the image; if a relative path, then a themed image will be loaded.
* @param elementid the id of a svg element.
*
* @since 4.4
*/
void setImage(const QString &path, const QString &elementid);
/**
* @return the image path being displayed currently, or an empty string if none.
*/
QString image() const;
/**
* Sets the stylesheet used to control the visual display of this PushButton
*
* @param stylesheet a CSS string
*/
void setStyleSheet(const QString &stylesheet);
/**
* @return the stylesheet currently used with this widget
*/
QString styleSheet();
/**
* Associate an action with this IconWidget
* this makes the button follow the state of the action, using its icon, text, etc.
* when the button is clicked, it will also trigger the action.
*
* @since 4.3
*/
void setAction(QAction *action);
/**
* @return the currently associated action, if any.
*
* @since 4.3
*/
QAction *action() const;
/**
* sets the icon for this push button
*
* @param icon the icon to use
*
* @since 4.3
*/
void setIcon(const QIcon &icon);
/**
* sets the icon for this push button using a KIcon
*
* @param icon the icon to use
*
* @since 4.4
*/
- void setIcon(const KIcon &icon);
+ void setIcon(const QIcon &icon);
/**
* @return the icon of this button
*
* @since 4.3
*/
QIcon icon() const;
/**
* Sets whether or not this button can be toggled on/off
*
* @since 4.3
*/
void setCheckable(bool checkable);
/**
* @return true if the button is checkable
* @see setCheckable
* @since 4.4
*/
bool isCheckable() const;
/**
* @return true if the button is checked; requires setIsCheckable(true) to
* be called
*
* @since 4.3
*/
bool isChecked() const;
/**
* @return true if the button is pressed down
* @since 4.4
*/
bool isDown() const;
/**
* @return the native widget wrapped by this PushButton
*/
KPushButton *nativeWidget() const;
Q_SIGNALS:
/**
* Emitted when the button is pressed down; usually the clicked() signal
* will suffice, however.
* @since 4.4
*/
void pressed();
/**
* Emitted when the button is released; usually the clicked() signal
* will suffice, however.
* @since 4.4
*/
void released();
/**
* Emitted when the button is pressed then released, completing a click
*/
void clicked();
/**
* Emitted when the button changes state from up to down
*/
void toggled(bool);
public Q_SLOTS:
/**
* Performs a visual click and emits the associated signals
* @since 4.6
*/
void click();
/**
* Sets whether or not this button is checked. Implies setIsCheckable(true).
*
* @since 4.3
*/
void setChecked(bool checked);
protected:
void paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget = 0);
void resizeEvent(QGraphicsSceneResizeEvent *event);
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
void changeEvent(QEvent *event);
QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint) const;
private:
Q_PRIVATE_SLOT(d, void syncBorders())
Q_PRIVATE_SLOT(d, void setPixmap())
Q_PRIVATE_SLOT(d, void pressedChanged())
Q_PRIVATE_SLOT(d, void syncToAction())
Q_PRIVATE_SLOT(d, void clearAction())
Q_PRIVATE_SLOT(d, void setPalette())
friend class PushButtonPrivate;
PushButtonPrivate *const d;
};
} // namespace Plasma
#endif // multiple inclusion guard

File Metadata

Mime Type
text/x-diff
Expires
Fri, Nov 1, 9:09 AM (1 d, 12 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
10075569
Default Alt Text
(880 KB)

Event Timeline