summaryrefslogtreecommitdiffstats
path: root/python/pykde/extra/kde353/kaccelbase.h
blob: 0becbe0a75f952c5574c2e545ba4418fb15367e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
/* This file is part of the KDE libraries
    Copyright (C) 2001 Ellis Whitehead <ellis@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 _KACCELBASE_H
#define _KACCELBASE_H

#include <qmap.h>
#include <qptrvector.h>
#include <qstring.h>
#include <qvaluevector.h>
#include <qvaluelist.h>

#include "kaccelaction.h"
#include "kkeyserver.h"

class QPopupMenu;
class QWidget;

//----------------------------------------------------

/**
 * @internal
 * Handle keyboard accelerators.
 *
 * Allow an user to configure
 * key bindings through application configuration files or through the
 * KKeyChooser GUI.
 *
 * A KAccel contains a list of accelerator items. Each accelerator item
 * consists of an action name and a keyboard code combined with modifiers
 * (Shift, Ctrl and Alt.)
 *
 * For example, "Ctrl+P" could be a shortcut for printing a document. The key
 * codes are listed in ckey.h. "Print" could be the action name for printing.
 * The action name identifies the key binding in configuration files and the
 * KKeyChooser GUI.
 *
 * When pressed, an accelerator key calls the slot to which it has been
 * connected. Accelerator items can be connected so that a key will activate
 * two different slots.
 *
 * A KAccel object handles key events sent to its parent widget and to all
 * children of this parent widget.
 *
 * Key binding reconfiguration during run time can be prevented by specifying
 * that an accelerator item is not configurable when it is inserted. A special
 * group of non-configurable key bindings are known as the
 * standard accelerators.
 *
 * The standard accelerators appear repeatedly in applications for
 * standard document actions such as printing and saving. Convenience methods are
 * available to insert and connect these accelerators which are configurable on
 * a desktop-wide basis.
 *
 * It is possible for a user to choose to have no key associated with
 * an action.
 *
 * The translated first argument for insertItem() is used only
 * in the configuration dialog.
 *\code
 * KAccel *a = new KAccel( myWindow );
 * // Insert an action "Scroll Up" which is associated with the "Up" key:
 * a->insertItem( i18n("Scroll Up"), "Scroll Up", "Up" );
 * // Insert an action "Scroll Down" which is not associated with any key:
 * a->insertItem( i18n("Scroll Down"), "Scroll Down", 0);
 * a->connectItem( "Scroll up", myWindow, SLOT( scrollUp() ) );
 * // a->insertStdItem( KStdAccel::Print ); //not necessary, since it
 *	// is done automatially with the
 *	// connect below!
 * a->connectItem(KStdAccel::Print, myWindow, SLOT( printDoc() ) );
 *
 * a->readSettings();
 *\endcode
 *
 * If a shortcut has a menu entry as well, you could insert them like
 * this. The example is again the KStdAccel::Print from above.
 *
 * \code
 * int id;
 * id = popup->insertItem("&Print",this, SLOT(printDoc()));
 * a->changeMenuAccel(popup, id, KStdAccel::Print );
 * \endcode
 *
 * If you want a somewhat "exotic" name for your standard print action, like
 *   id = popup->insertItem(i18n("Print &Document"),this, SLOT(printDoc()));
 * it might be a good idea to insert the standard action before as
 *          a->insertStdItem( KStdAccel::Print, i18n("Print Document") )
 * as well, so that the user can easily find the corresponding function.
 *
 * This technique works for other actions as well.  Your "scroll up" function
 * in a menu could be done with
 *
 * \code
 *    id = popup->insertItem(i18n"Scroll &up",this, SLOT(scrollUp()));
 *    a->changeMenuAccel(popup, id, "Scroll Up" );
 * \endcode
 *
 * Please keep the order right:  First insert all functions in the
 * acceleratior, then call a -> readSettings() and @em then build your
 * menu structure.
 *
 * @short Configurable key binding support.
 */

class KDECORE_EXPORT KAccelBase
{
 public:
	/** Initialization mode of the KAccelBase, used in constructor. */
	enum Init { QT_KEYS = 0x00, NATIVE_KEYS = 0x01 };

	/** Enum for kinds of signals which may be emitted. */
	enum Signal { KEYCODE_CHANGED };

	/** Constructor. @p fInitCode should be a bitwise OR of
	*   values from the Init enum.
	*/
	KAccelBase( int fInitCode );
	virtual ~KAccelBase();

	/** Returns number of actions in this handler. */
	uint actionCount() const;
	/** Returns a list of all the actions in this handler. */
	KAccelActions& actions();
	/** Returns whether this accelerator handler is enabled or not. */
	bool isEnabled() const;

	/** Returns a pointer to the KAccelAction named @p sAction. */
	KAccelAction* actionPtr( const QString& sAction );
	/** Const version of the above. */
	const KAccelAction* actionPtr( const QString& sAction ) const;
	/** Returns a pointer to the KAccelAction associated with
	*   the key @p key. This function takes into account the
	*   key mapping defined in the constructor.
	*
	*   May return 0 if no (or more than one)
	*   action is associated with the key.
	*/
	KAccelAction* actionPtr( const KKey& key );
	/** Basically the same as above, except a KKeyServer::Key
	*   already has a key mapping defined (either NATIVE_KEYS or not).
	*/
	KAccelAction* actionPtr( const KKeyServer::Key& key );

	/** Returns the name of the configuration group these
	*   accelerators are stored in. The default is "Shortcuts".
	*/
	const QString& configGroup() const { return m_sConfigGroup; }
	/** Set the group (in the configuration file) for storing
	*   accelerators.
	*/
	void setConfigGroup( const QString& group );
	void setConfigGlobal( bool global );
	virtual void setEnabled( bool bEnabled ) = 0;
	/** Returns whether autoupdate is enabled for these accelerators. */
	bool getAutoUpdate() { return m_bAutoUpdate; }
	/** Enables (or disables) autoupdate for these accelerators.
	*   @return the value of autoupdate before the call.
	*/
	bool setAutoUpdate( bool bAuto );

// Procedures for manipulating Actions.
	//void clearActions();

	KAccelAction* insert( const QString& sName, const QString& sDesc );
	KAccelAction* insert(
	                 const QString& sAction, const QString& sDesc, const QString& sHelp,
	                 const KShortcut& rgCutDefaults3, const KShortcut& rgCutDefaults4,
	                 const QObject* pObjSlot, const char* psMethodSlot,
			 bool bConfigurable = true, bool bEnabled = true );
	bool remove( const QString& sAction );
	bool setActionSlot( const QString& sAction, const QObject* pObjSlot, const char* psMethodSlot );

	bool updateConnections();

	bool setShortcut( const QString& sAction, const KShortcut& cut );

// Modify individual Action sub-items
	bool setActionEnabled( const QString& sAction, bool bEnable );

	/**
	 * Read all key associations from @p config, or (if @p config
	 * is zero) from the application's configuration file
	 * KGlobal::config().
	 *
	 * The group in which the configuration is stored can be
	 * set with setConfigGroup().
	 */
	void readSettings( KConfigBase* pConfig = 0 );

	/**
	 * Write the current configurable associations to @p config,
         * or (if @p config is zero) to the application's
	 * configuration file.
	 */
	void writeSettings( KConfigBase* pConfig = 0 ) const;

	QPopupMenu* createPopupMenu( QWidget* pParent, const KKeySequence& );

 // Protected methods
 protected:
	void slotRemoveAction( KAccelAction* );

	struct X;
	void createKeyList( QValueVector<struct X>& rgKeys );
	bool insertConnection( KAccelAction* );
	bool removeConnection( KAccelAction* );

	virtual bool emitSignal( Signal ) = 0;
	virtual bool connectKey( KAccelAction&, const KKeyServer::Key& ) = 0;
	virtual bool connectKey( const KKeyServer::Key& ) = 0;
	virtual bool disconnectKey( KAccelAction&, const KKeyServer::Key& ) = 0;
	virtual bool disconnectKey( const KKeyServer::Key& ) = 0;

 protected:
        virtual bool isEnabledInternal() const;
	struct ActionInfo
	{
		KAccelAction* pAction;
		uint iSeq, iVariation;
		//ActionInfo* pInfoNext; // nil if only one action uses this key.

		ActionInfo() { pAction = 0; iSeq = 0xffff; iVariation = 0xffff; }
		ActionInfo( KAccelAction* _pAction, uint _iSeq, uint _iVariation )
			{ pAction = _pAction; iSeq = _iSeq; iVariation = _iVariation; }
	};
	typedef QMap<KKeyServer::Key, ActionInfo> KKeyToActionMap;

	KAccelActions m_rgActions;
	KKeyToActionMap m_mapKeyToAction;
	QValueList<KAccelAction*> m_rgActionsNonUnique;
	bool m_bNativeKeys; // Use native key codes instead of Qt codes
	bool m_bEnabled;
	bool m_bConfigIsGlobal;
	QString m_sConfigGroup;
	bool m_bAutoUpdate;
	KAccelAction* mtemp_pActionRemoving;

 private:
	KAccelBase& operator =( const KAccelBase& );

	friend class KAccelActions;
};

#endif // _KACCELBASE_H