Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Utilities
Kate
Commits
a592691c
Commit
a592691c
authored
Aug 02, 2022
by
Pablo Rauzy
Committed by
Christoph Cullmann
Aug 14, 2022
Browse files
added support for persistent named keyboard macros
parent
c41bfcb6
Changes
4
Hide whitespace changes
Inline
Side-by-side
addons/keyboardmacros/keyboardmacrosplugin.cpp
View file @
a592691c
...
...
@@ -8,14 +8,26 @@
#include
<QAction>
#include
<QApplication>
#include
<QCoreApplication>
#include
<QFile>
#include
<QIODevice>
#include
<QJsonDocument>
#include
<QJsonObject>
#include
<QJsonParseError>
#include
<QKeyEvent>
#include
<QKeySequence>
#include
<QList>
#include
<QRegExp>
#include
<QStandardPaths>
#include
<QString>
#include
<Q
tAlgorithms
>
#include
<Q
StringList
>
#include
<KTextEditor/Application>
#include
<KTextEditor/Command>
#include
<KTextEditor/Editor>
#include
<KTextEditor/MainWindow>
#include
<KTextEditor/Message>
#include
<KTextEditor/Plugin>
#include
<KTextEditor/View>
#include
<KActionCollection>
#include
<KLocalizedString>
...
...
@@ -27,10 +39,15 @@ K_PLUGIN_FACTORY_WITH_JSON(KeyboardMacrosPluginFactory, "keyboardmacrosplugin.js
KeyboardMacrosPlugin
::
KeyboardMacrosPlugin
(
QObject
*
parent
,
const
QList
<
QVariant
>
&
)
:
KTextEditor
::
Plugin
(
parent
)
{
m_commands
=
new
KeyboardMacrosPluginCommands
(
this
);
m_storage
=
QStandardPaths
::
writableLocation
(
QStandardPaths
::
GenericDataLocation
)
+
QStringLiteral
(
"/kate/keyboardmacros.json"
);
loadNamedMacros
();
}
KeyboardMacrosPlugin
::~
KeyboardMacrosPlugin
()
{
saveNamedMacros
();
delete
m_commands
;
}
QObject
*
KeyboardMacrosPlugin
::
createView
(
KTextEditor
::
MainWindow
*
mainWindow
)
...
...
@@ -151,6 +168,81 @@ bool KeyboardMacrosPlugin::play()
return
true
;
}
bool
KeyboardMacrosPlugin
::
save
(
QString
name
)
{
// we don't need to save macros that do nothing
if
(
m_macro
.
isEmpty
())
{
return
false
;
}
qDebug
()
<<
"[KeyboardMacrosPlugin] saving macro:"
<<
name
;
m_namedMacros
.
insert
(
name
,
m_macro
);
return
true
;
}
bool
KeyboardMacrosPlugin
::
load
(
QString
name
)
{
if
(
!
m_namedMacros
.
contains
(
name
))
{
return
false
;
}
qDebug
()
<<
"[KeyboardMacrosPlugin] loading macro:"
<<
name
;
// clear current macro
m_macro
.
clear
();
// load named macro
m_macro
=
m_namedMacros
.
value
(
name
);
// update GUI
m_playAction
->
setEnabled
(
true
);
return
true
;
}
bool
KeyboardMacrosPlugin
::
remove
(
QString
name
)
{
if
(
!
m_namedMacros
.
contains
(
name
))
{
return
false
;
}
qDebug
()
<<
"[KeyboardMacrosPlugin] removing macro:"
<<
name
;
m_namedMacros
.
remove
(
name
);
return
true
;
}
void
KeyboardMacrosPlugin
::
loadNamedMacros
()
{
QFile
storage
(
m_storage
);
if
(
!
storage
.
open
(
QIODevice
::
ReadOnly
|
QIODevice
::
Text
))
{
sendMessage
(
i18n
(
"Could not open file '%1'."
,
m_storage
),
false
);
return
;
}
QJsonParseError
parseError
;
QJsonDocument
jsonDoc
=
QJsonDocument
::
fromJson
(
storage
.
readAll
(),
&
parseError
);
if
(
parseError
.
error
!=
QJsonParseError
::
NoError
)
{
sendMessage
(
i18n
(
"Malformed JSON file '%1': %2"
,
m_storage
,
parseError
.
errorString
()),
true
);
}
QJsonObject
json
=
jsonDoc
.
object
();
QJsonObject
::
ConstIterator
it
;
for
(
it
=
json
.
constBegin
();
it
!=
json
.
constEnd
();
++
it
)
{
m_namedMacros
.
insert
(
it
.
key
(),
Macro
(
it
.
value
()));
}
storage
.
close
();
}
void
KeyboardMacrosPlugin
::
saveNamedMacros
()
{
if
(
m_namedMacros
.
isEmpty
())
{
return
;
}
QFile
storage
(
m_storage
);
if
(
!
storage
.
open
(
QIODevice
::
WriteOnly
|
QIODevice
::
Text
))
{
sendMessage
(
i18n
(
"Could not open file '%1'."
,
m_storage
),
false
);
return
;
}
QJsonObject
json
;
QMap
<
QString
,
Macro
>::
ConstIterator
it
;
for
(
it
=
m_namedMacros
.
constBegin
();
it
!=
m_namedMacros
.
constEnd
();
++
it
)
{
json
.
insert
(
it
.
key
(),
it
.
value
().
toJson
());
}
storage
.
write
(
QJsonDocument
(
json
).
toJson
(
QJsonDocument
::
Compact
));
storage
.
close
();
}
void
KeyboardMacrosPlugin
::
focusObjectChanged
(
QObject
*
focusObject
)
{
qDebug
()
<<
"[KeyboardMacrosPlugin] focusObjectChanged:"
<<
focusObject
;
...
...
@@ -256,5 +348,61 @@ KeyboardMacrosPluginView::~KeyboardMacrosPluginView()
// END
// BEGIN Plugin commands to manage named keyboard macros
KeyboardMacrosPluginCommands
::
KeyboardMacrosPluginCommands
(
KeyboardMacrosPlugin
*
plugin
)
:
KTextEditor
::
Command
(
QStringList
()
<<
QStringLiteral
(
"kmsave"
)
<<
QStringLiteral
(
"kmload"
)
<<
QStringLiteral
(
"kmremove"
),
plugin
)
,
m_plugin
(
plugin
)
{
}
bool
KeyboardMacrosPluginCommands
::
exec
(
KTextEditor
::
View
*
,
const
QString
&
cmd
,
QString
&
msg
,
const
KTextEditor
::
Range
&
)
{
QStringList
actionAndName
=
cmd
.
split
(
QRegExp
(
QStringLiteral
(
"
\\
s+"
)));
if
(
actionAndName
.
length
()
!=
2
)
{
msg
=
i18n
(
"Usage: %1 <name>."
,
actionAndName
.
at
(
0
));
return
false
;
}
QString
action
=
actionAndName
.
at
(
0
);
QString
name
=
actionAndName
.
at
(
1
);
if
(
action
==
QStringLiteral
(
"kmsave"
))
{
if
(
!
m_plugin
->
save
(
name
))
{
msg
=
i18n
(
"Cannot save empty keyboard macro."
);
return
false
;
}
return
true
;
}
else
if
(
action
==
QStringLiteral
(
"kmload"
))
{
if
(
!
m_plugin
->
load
(
name
))
{
msg
=
i18n
(
"No keyboard macro named '%1' found."
,
name
);
return
false
;
}
return
true
;
}
else
if
(
action
==
QStringLiteral
(
"kmremove"
))
{
if
(
!
m_plugin
->
remove
(
name
))
{
msg
=
i18n
(
"No keyboard macro named '%1' found."
,
name
);
return
false
;
}
return
true
;
}
return
false
;
}
bool
KeyboardMacrosPluginCommands
::
help
(
KTextEditor
::
View
*
,
const
QString
&
cmd
,
QString
&
msg
)
{
if
(
cmd
==
QStringLiteral
(
"kmsave"
))
{
msg
=
i18n
(
"<qt><p>Usage: <code>kmsave <name></code></p><p>Save current keyboard macro as <code><name></code>.</p></qt>"
);
return
true
;
}
else
if
(
cmd
==
QStringLiteral
(
"kmload"
))
{
msg
=
i18n
(
"<qt><p>Usage: <code>kmload <name></code></p><p>Load saved keyboard macro <code><name></code> as current macro.</p></qt>"
);
return
true
;
}
else
if
(
cmd
==
QStringLiteral
(
"kmremove"
))
{
msg
=
i18n
(
"<qt><p>Usage: <code>kmremove <name></code></p><p>Remove saved keyboard macro <code><name></code>.</p></qt>"
);
return
true
;
}
return
false
;
}
// END
// required for KeyboardMacrosPluginFactory vtable
#include
"keyboardmacrosplugin.moc"
addons/keyboardmacros/keyboardmacrosplugin.h
View file @
a592691c
...
...
@@ -3,11 +3,16 @@
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef
PLUGIN_KATE
KEYBOARDMACRO_H
#define
PLUGIN_KATE
KEYBOARDMACRO_H
#ifndef KEYBOARDMACRO
SPLUGIN
_H
#define KEYBOARDMACRO
SPLUGIN
_H
#include
<Q
Key
Event>
#include
<QEvent>
#include
<QList>
#include
<QMap>
#include
<QObject>
#include
<QString>
#include
<QVariant>
#include
<QVariantMap>
#include
<KTextEditor/Application>
#include
<KTextEditor/Command>
...
...
@@ -15,39 +20,17 @@
#include
<KTextEditor/Plugin>
#include
<KTextEditor/View>
class
KeyCombination
{
private:
int
key
;
Qt
::
KeyboardModifiers
modifiers
;
QString
text
;
#include
"macro.h"
public:
explicit
KeyCombination
(
const
QKeyEvent
*
keyEvent
)
:
key
(
keyEvent
->
key
())
,
modifiers
(
keyEvent
->
modifiers
())
,
text
(
keyEvent
->
text
()){};
QKeyEvent
*
keyPress
()
{
return
new
QKeyEvent
(
QEvent
::
KeyPress
,
key
,
modifiers
,
text
);
};
QKeyEvent
*
keyRelease
()
{
return
new
QKeyEvent
(
QEvent
::
KeyRelease
,
key
,
modifiers
,
text
);
};
friend
QDebug
operator
<<
(
QDebug
dbg
,
const
KeyCombination
&
kc
)
{
return
dbg
<<
QKeySequence
(
kc
.
key
|
kc
.
modifiers
).
toString
();
};
};
typedef
QList
<
KeyCombination
>
Macro
;
class
KeyboardMacrosPluginView
;
class
KeyboardMacrosPluginCommands
;
class
KeyboardMacrosPlugin
:
public
KTextEditor
::
Plugin
{
Q_OBJECT
friend
class
KeyboardMacrosPluginView
;
friend
KeyboardMacrosPluginView
;
friend
KeyboardMacrosPluginCommands
;
public:
explicit
KeyboardMacrosPlugin
(
QObject
*
parent
=
nullptr
,
const
QList
<
QVariant
>
&
=
QList
<
QVariant
>
());
...
...
@@ -68,19 +51,30 @@ private:
KTextEditor
::
MainWindow
*
m_mainWindow
=
nullptr
;
QWidget
*
m_focusWidget
=
nullptr
;
KeyboardMacrosPluginCommands
*
m_commands
;
QAction
*
m_recordAction
=
nullptr
;
QAction
*
m_cancelAction
=
nullptr
;
QAction
*
m_playAction
=
nullptr
;
bool
m_recording
=
false
;
Macro
m_tape
;
Macro
m_macro
;
void
record
();
void
stop
(
bool
save
);
void
cancel
();
bool
play
();
bool
save
(
QString
name
);
bool
load
(
QString
name
);
bool
remove
(
QString
name
);
bool
m_recording
=
false
;
Macro
m_tape
;
Macro
m_macro
;
QMap
<
QString
,
Macro
>
m_namedMacros
;
QString
m_storage
;
void
loadNamedMacros
();
void
saveNamedMacros
();
void
focusObjectChanged
(
QObject
*
focusObject
);
void
applicationStateChanged
(
Qt
::
ApplicationState
state
);
...
...
@@ -91,7 +85,7 @@ public Q_SLOTS:
};
/**
* Plugin view to add
our
actions to the
gui
* Plugin view to add
keyboard macros
actions to the
GUI
*/
class
KeyboardMacrosPluginView
:
public
QObject
,
public
KXMLGUIClient
{
...
...
@@ -105,4 +99,20 @@ private:
KTextEditor
::
MainWindow
*
m_mainWindow
;
};
/**
* Plugin commands to manage named keyboard macros
*/
class
KeyboardMacrosPluginCommands
:
public
KTextEditor
::
Command
{
Q_OBJECT
public:
KeyboardMacrosPluginCommands
(
KeyboardMacrosPlugin
*
plugin
);
bool
exec
(
KTextEditor
::
View
*
,
const
QString
&
cmd
,
QString
&
msg
,
const
KTextEditor
::
Range
&
=
KTextEditor
::
Range
::
invalid
())
override
;
bool
help
(
KTextEditor
::
View
*
,
const
QString
&
cmd
,
QString
&
msg
)
override
;
private:
KeyboardMacrosPlugin
*
m_plugin
;
};
#endif
addons/keyboardmacros/keycombination.h
0 → 100644
View file @
a592691c
/*
* SPDX-FileCopyrightText: 2022 Pablo Rauzy <r .at. uzy .dot. me>
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef KEYBOARDMACROSPLUGIN_KEYCOMBINATION_H
#define KEYBOARDMACROSPLUGIN_KEYCOMBINATION_H
#include
<QDebug>
#include
<QJsonArray>
#include
<QJsonValue>
#include
<QKeyEvent>
#include
<QKeySequence>
#include
<QList>
#include
<QString>
#include
<QtGlobal>
class
KeyCombination
{
private:
int
key
;
Qt
::
KeyboardModifiers
modifiers
;
QString
text
;
public:
explicit
KeyCombination
(
const
QKeyEvent
*
keyEvent
)
:
key
(
keyEvent
->
key
())
,
modifiers
(
keyEvent
->
modifiers
())
,
text
(
keyEvent
->
text
()){};
explicit
KeyCombination
(
const
QJsonArray
json
)
{
Q_ASSERT
(
json
.
size
()
==
3
);
Q_ASSERT
(
json
.
at
(
0
).
type
()
==
QJsonValue
::
Double
);
Q_ASSERT
(
json
.
at
(
1
).
type
()
==
QJsonValue
::
Double
);
Q_ASSERT
(
json
.
at
(
2
).
type
()
==
QJsonValue
::
String
);
key
=
json
.
at
(
0
).
toInt
(
0
);
modifiers
=
static_cast
<
Qt
::
KeyboardModifiers
>
(
json
.
at
(
1
).
toInt
(
0
));
text
=
json
.
at
(
2
).
toString
();
};
QKeyEvent
*
keyPress
()
{
return
new
QKeyEvent
(
QEvent
::
KeyPress
,
key
,
modifiers
,
text
);
};
QKeyEvent
*
keyRelease
()
{
return
new
QKeyEvent
(
QEvent
::
KeyRelease
,
key
,
modifiers
,
text
);
};
QJsonArray
toJson
()
const
{
QJsonArray
json
;
json
.
append
(
QJsonValue
(
key
));
json
.
append
(
QJsonValue
(
static_cast
<
int
>
(
modifiers
)));
json
.
append
(
QJsonValue
(
text
));
return
json
;
};
friend
QDebug
operator
<<
(
QDebug
dbg
,
const
KeyCombination
&
kc
)
{
return
dbg
<<
QKeySequence
(
kc
.
key
|
kc
.
modifiers
).
toString
();
};
};
#endif
addons/keyboardmacros/macro.h
0 → 100644
View file @
a592691c
/*
* SPDX-FileCopyrightText: 2022 Pablo Rauzy <r .at. uzy .dot. me>
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef KEYBOARDMACROSPLUGIN_MACRO_H
#define KEYBOARDMACROSPLUGIN_MACRO_H
#include
<QDebug>
#include
<QJsonArray>
#include
<QJsonValue>
#include
<QList>
#include
<QtGlobal>
#include
"keycombination.h"
class
Macro
:
public
QList
<
KeyCombination
>
{
public:
explicit
Macro
()
:
QList
<
KeyCombination
>
(){};
explicit
Macro
(
const
QJsonValue
json
)
{
Q_ASSERT
(
json
.
type
()
==
QJsonValue
::
Array
);
QJsonArray
::
ConstIterator
it
;
for
(
it
=
json
.
toArray
().
constBegin
();
it
!=
json
.
toArray
().
constEnd
();
++
it
)
{
Q_ASSERT
(
it
->
type
()
==
QJsonValue
::
Array
);
this
->
append
(
KeyCombination
(
it
->
toArray
()));
}
};
QJsonArray
toJson
()
const
{
QJsonArray
json
;
Macro
::
ConstIterator
it
;
for
(
it
=
this
->
constBegin
();
it
!=
this
->
constEnd
();
++
it
)
{
json
.
append
(
it
->
toJson
());
}
return
json
;
};
};
#endif
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment