From f8529970a4018ee95b52a9c3bede75f3098186b4 Mon Sep 17 00:00:00 2001
From: Moritz Strohm <strohm@data-quest.de>
Date: Wed, 11 May 2022 08:42:11 +0000
Subject: [PATCH] TIC #608

Merge request studip/studip!421
---
 app/views/admin/course_wizard_steps/index.php |  2 +-
 app/views/admin/ilias_interface/index.php     |  6 +--
 app/views/admin/plugin/index.php              |  2 +-
 app/views/admin/semester/index.php            |  2 +-
 app/views/admin/statusgroups/_group.php       |  2 +-
 app/views/admin/statusgroups/_members.php     |  2 +-
 app/views/admin/user/_course_files.php        |  4 +-
 app/views/admin/user/_institute_files.php     |  2 +-
 app/views/admin/user/_results.php             |  2 +-
 app/views/admin/user/list_files.php           |  2 +-
 app/views/consultation/admin/index.php        |  4 +-
 app/views/consultation/admin/ungrouped.php    |  4 +-
 app/views/contact/index.php                   |  2 +-
 app/views/course/dates/_date_row-exdate.php   |  2 +-
 app/views/course/dates/_date_row.php          |  2 +-
 app/views/course/feedback/index.php           |  2 +-
 .../course/ilias_interface/add_object.php     |  2 +-
 app/views/course/ilias_interface/index.php    |  4 +-
 app/views/course/members/accepted_list.php    |  2 +-
 app/views/course/members/autor_list.php       |  2 +-
 app/views/course/members/awaiting_list.php    |  2 +-
 app/views/course/members/dozent_list.php      |  2 +-
 app/views/course/members/tutor_list.php       |  2 +-
 app/views/course/members/user_list.php        |  2 +-
 app/views/course/plus/index.php               |  4 +-
 app/views/course/room_requests/index.php      |  2 +-
 app/views/course/statusgroups/_group.php      |  2 +-
 app/views/course/statusgroups/_member.php     |  2 +-
 app/views/course/timesrooms/_cycleRow.php     |  2 +-
 .../course/timesrooms/_irregularEvents.php    |  2 +-
 .../course/timesrooms/_regularEvents.php      |  2 +-
 app/views/files/_folder_tr.php                |  2 +-
 app/views/institute/members/_table_body.php   |  1 +
 app/views/lvgruppen/lvgruppen/index.php       |  8 ++--
 app/views/materialien/files/index.php         |  2 +-
 app/views/materialien/files/range.php         |  2 +-
 app/views/module/module/details.php           |  2 +-
 app/views/module/module/module.php            |  2 +-
 app/views/module/module/modulteil_lvg.php     |  2 +-
 app/views/my_ilias_accounts/index.php         |  4 +-
 app/views/news/admin_news.php                 |  2 +-
 app/views/online/user-row.php                 |  2 +-
 .../questionnaire/_overview_questionnaire.php |  2 +-
 app/views/resources/_common/_request_tr.php   |  3 +-
 app/views/resources/_common/_resource_tr.php  |  2 +-
 .../resources/_common/_room_search_result.php |  2 +-
 app/views/resources/admin/categories.php      |  1 +
 app/views/resources/admin/global_locks.php    | 11 +++++-
 app/views/shared/contacts/details.php         |  2 +-
 app/views/shared/contacts/index.php           |  2 +-
 app/views/shared/contacts/range.php           |  2 +-
 .../informationen/showdegree.php              |  3 +-
 .../informationen/showstudycourse.php         |  2 +-
 .../studiengaenge/studiengaenge.php           |  2 +-
 .../studiengangteile/details_grouped.php      |  2 +-
 .../studiengaenge/studiengangteile/index.php  |  2 +-
 .../studiengaenge/versionen/abschnitte.php    |  2 +-
 .../studiengaenge/versionen/versionen.php     |  4 +-
 app/views/tour/admin_details.php              |  2 +-
 app/views/tour/admin_overview.php             |  4 +-
 lib/classes/ActionMenu.php                    | 39 +++++++++++++++++++
 lib/classes/Range.interface.php               |  6 +++
 lib/classes/StudipItem.interface.php          |  8 ++++
 lib/filesystem/FilesystemVueDataManager.php   |  4 +-
 lib/filesystem/StandardFile.php               |  2 +-
 lib/models/ConsultationBlock.php              | 15 +++++++
 lib/models/ConsultationSlot.php               | 15 +++++++
 lib/models/Course.class.php                   |  9 +++++
 lib/models/CourseDate.class.php               | 15 +++++++
 lib/models/CourseExDate.class.php             | 15 +++++++
 lib/models/Institute.class.php                |  9 +++++
 lib/models/User.class.php                     |  9 +++++
 lib/models/resources/Building.class.php       |  3 ++
 lib/models/resources/Location.class.php       |  3 ++
 lib/models/resources/Resource.class.php       |  4 ++
 lib/models/resources/Room.class.php           |  3 ++
 lib/wiki.inc.php                              |  4 +-
 .../javascripts/bootstrap/actionmenu.js       | 14 +++++++
 .../assets/javascripts/lib/actionmenu.js      | 36 +++++++++++++++++
 .../assets/stylesheets/scss/actionmenu.scss   |  6 ++-
 resources/vue/components/StudipActionMenu.vue | 10 ++---
 .../courseware/CoursewareBlockActions.vue     |  3 +-
 .../CoursewareStructuralElement.vue           |  1 +
 templates/shared/action-menu.php              | 10 ++---
 templates/sidebar/room-clipboard-item.php     |  2 +-
 85 files changed, 310 insertions(+), 90 deletions(-)

diff --git a/app/views/admin/course_wizard_steps/index.php b/app/views/admin/course_wizard_steps/index.php
index 963d5da9ca2..bed64e5ad45 100644
--- a/app/views/admin/course_wizard_steps/index.php
+++ b/app/views/admin/course_wizard_steps/index.php
@@ -42,7 +42,7 @@
                     </a>
                 </td>
                 <td class="actions">
-                    <? $actionMenu = ActionMenu::get() ?>
+                    <? $actionMenu = ActionMenu::get()->setContext($step->name) ?>
                     <? $actionMenu->addLink(
                         $controller->url_for("admin/coursewizardsteps/edit/{$step->id}"),
                         _('Schritt bearbeiten'),
diff --git a/app/views/admin/ilias_interface/index.php b/app/views/admin/ilias_interface/index.php
index b9e1ff79870..6c103ac3405 100755
--- a/app/views/admin/ilias_interface/index.php
+++ b/app/views/admin/ilias_interface/index.php
@@ -35,7 +35,7 @@
                         $text = _('Diese ILIAS-Installation ist inaktiv. Klicken Sie hier, um sie zu aktivieren.');
                         $img  = 'checkbox-unchecked';
                         $cmd  = 'activate';
-                    } 
+                    }
                     ?>
                     <a href="<?= $controller->url_for('admin/ilias_interface/'.$cmd.'/'.$ilias_index) ?>">
                         <?= Icon::create($img, 'clickable', ['title' => $text])->asImg() ?>
@@ -45,7 +45,7 @@
                 <td><?= htmlReady($ilias_index) ?></td>
                 <td><?= htmlReady($ilias_config['version']) ?></td>
                 <td class="actions">
-                    <? $actionMenu = ActionMenu::get() ?>
+                    <? $actionMenu = ActionMenu::get()->setContext($ilias_config['name']) ?>
                     <? $actionMenu->addLink(
                         $controller->url_for("admin/ilias_interface/edit_server/$ilias_index"),
                         _('Servereinstellungen bearbeiten'),
@@ -91,4 +91,4 @@
         <? endif ?>
         </tbody>
     </table>
-</form>
\ No newline at end of file
+</form>
diff --git a/app/views/admin/plugin/index.php b/app/views/admin/plugin/index.php
index 3266c778ac8..5f38b363dfb 100644
--- a/app/views/admin/plugin/index.php
+++ b/app/views/admin/plugin/index.php
@@ -89,7 +89,7 @@ use Studip\Button, Studip\LinkButton;
                                    value="<?= $plugin['position'] ?>" <? if (!$plugin['enabled']) echo 'disabled'; ?>>
                         </td>
                         <td class="actions">
-                            <? $actionMenu = ActionMenu::get() ?>
+                            <? $actionMenu = ActionMenu::get()->setContext($plugin['name']) ?>
                             <? $actionMenu->addLink(
                                 $controller->url_for('admin/role/assign_plugin_role/' . $pluginid),
                                 _('Zugriffsrechte bearbeiten'),
diff --git a/app/views/admin/semester/index.php b/app/views/admin/semester/index.php
index bae47376310..c6aeb815ce9 100644
--- a/app/views/admin/semester/index.php
+++ b/app/views/admin/semester/index.php
@@ -79,7 +79,7 @@
             <td class="actions" nowrap>
 
             <?
-                $actionMenu = ActionMenu::get();
+                $actionMenu = ActionMenu::get()->setContext($semester->name);
 
                 $actionMenu->addLink(
                     $controller->url_for("admin/semester/edit/{$semester->id}"),
diff --git a/app/views/admin/statusgroups/_group.php b/app/views/admin/statusgroups/_group.php
index 237254ef86d..0b29329f50a 100644
--- a/app/views/admin/statusgroups/_group.php
+++ b/app/views/admin/statusgroups/_group.php
@@ -11,7 +11,7 @@
         <?= htmlReady($group->name) ?>
         <? if ($tutor): ?>
         <span class="actions">
-            <? $menu = ActionMenu::get() ?>
+            <? $menu = ActionMenu::get()->setContext($group->name) ?>
             <? $menu->addLink($controller->url_for("admin/statusgroups/editGroup/{$group->id}"),
                     _('Gruppe bearbeiten'), Icon::create('edit'), ['data-dialog' => 'size=auto']) ?>
             <? $menu->addMultiPersonSearch(
diff --git a/app/views/admin/statusgroups/_members.php b/app/views/admin/statusgroups/_members.php
index a4e8bf747dd..956679e501c 100644
--- a/app/views/admin/statusgroups/_members.php
+++ b/app/views/admin/statusgroups/_members.php
@@ -5,7 +5,7 @@
         <td><?= $user->avatar() ?></td>
         <td><?= htmlReady($user->name()) ?></td>
         <td class="actions">
-            <? $actionMenu = ActionMenu::get() ?>
+            <? $actionMenu = ActionMenu::get()->setContext($user->user) ?>
             <? $actionMenu->addLink($controller->url_for('settings/statusgruppen/', ['open' => $group->id, 'type' => 'role', 'username' => $user->user->username]),
                     _('Benutzer in dieser Rolle bearbeiten'),
                     Icon::create('edit', 'clickable')) ?>
diff --git a/app/views/admin/user/_course_files.php b/app/views/admin/user/_course_files.php
index c4276195c21..6da1662d52c 100644
--- a/app/views/admin/user/_course_files.php
+++ b/app/views/admin/user/_course_files.php
@@ -51,7 +51,7 @@
                                 <td class="actions">
                                     <? if ($data['files']) : ?>
                                         <?
-                                        $actionMenu = ActionMenu::get();
+                                        $actionMenu = ActionMenu::get()->setContext($data['course']->name);
                                         $actionMenu->addLink($controller->url_for('admin/user/list_files/' . $user['user_id'] . '/' . $data['course']->id, $params),
                                                 _('Dateien auflisten'),
                                                 Icon::create('folder-full', 'clickable'),
@@ -73,4 +73,4 @@
             </section>
         </article>
     <? endforeach; ?>
-</section>
\ No newline at end of file
+</section>
diff --git a/app/views/admin/user/_institute_files.php b/app/views/admin/user/_institute_files.php
index 9f17a08a48e..6aeb05d28bf 100644
--- a/app/views/admin/user/_institute_files.php
+++ b/app/views/admin/user/_institute_files.php
@@ -36,7 +36,7 @@
                         <td class="actions">
                             <? if ($institute['files']) : ?>
                                 <?
-                                $actionMenu = ActionMenu::get();
+                                $actionMenu = ActionMenu::get()->setContext($institute['name']);
                                 $actionMenu->addLink($controller->url_for('admin/user/list_files/' . $user['user_id'] . '/' . $institute['Institut_id'] , $params),
                                     _('Dateien auflisten'),
                                     Icon::create('folder-full', 'clickable'),
diff --git a/app/views/admin/user/_results.php b/app/views/admin/user/_results.php
index 1d02f193123..73b266d46df 100644
--- a/app/views/admin/user/_results.php
+++ b/app/views/admin/user/_results.php
@@ -114,7 +114,7 @@
                     <td><?= htmlReady($user['auth_plugin'] === null ? _('vorläufig') : $user->auth_plugin) ?></td>
                     <td class="actions" nowrap>
                     <?
-                        $actionMenu = ActionMenu::get();
+                        $actionMenu = ActionMenu::get()->setContext($user);
                         $actionMenu->addLink(
                             $controller->url_for("admin/user/edit/{$user->id}"),
                             _('Nutzer bearbeiten'),
diff --git a/app/views/admin/user/list_files.php b/app/views/admin/user/list_files.php
index 3707d87f53d..2d7ce9b3c8d 100644
--- a/app/views/admin/user/list_files.php
+++ b/app/views/admin/user/list_files.php
@@ -13,7 +13,7 @@
                         </a>
                     </h1>
                 <? if ($folder->isFileDownloadable($file->id, $user->id)): ?>
-                    <?= ActionMenu::get()->addLink(
+                    <?= ActionMenu::get()->setContext($file->name)->addLink(
                         $file->getDownloadURL(),
                         _('Datei herunterladen'),
                         Icon::create('download', 'clickable')
diff --git a/app/views/consultation/admin/index.php b/app/views/consultation/admin/index.php
index 6ee75508c5e..cf8d6c0ae11 100644
--- a/app/views/consultation/admin/index.php
+++ b/app/views/consultation/admin/index.php
@@ -44,7 +44,7 @@
                 <?= $this->render_partial('consultation/block-description.php', ['block' => $block['block']]) ?>
             </th>
             <th class="actions">
-                <?= ActionMenu::get()->addLink(
+                <?= ActionMenu::get()->setContext(strval($block['block']))->addLink(
                     $controller->editURL($block['block'], 0, $page),
                     _('Bearbeiten'),
                     Icon::create('edit'),
@@ -119,7 +119,7 @@
             <? endif; ?>
             </td>
             <td class="actions">
-                <?= ActionMenu::get()->addLink(
+                <?= ActionMenu::get()->setContext(strval($slot))->addLink(
                     $controller->noteURL($block['block'], $slot, $page),
                     _('Information bearbeiten'),
                     Icon::create('edit'),
diff --git a/app/views/consultation/admin/ungrouped.php b/app/views/consultation/admin/ungrouped.php
index 81b82751467..e64efea67f0 100644
--- a/app/views/consultation/admin/ungrouped.php
+++ b/app/views/consultation/admin/ungrouped.php
@@ -70,7 +70,7 @@
                 <?= formatLinks($block->room) ?>
             </td>
             <td class="actions">
-                <?= ActionMenu::get()->addLink(
+                <?= ActionMenu::get()->setContext(strval($block))->addLink(
                     $controller->editURL($block, 0, $page),
                     _('Information bearbeiten'),
                     Icon::create('edit'),
@@ -206,7 +206,7 @@
             <? endif; ?>
             </td>
             <td class="actions">
-                <?= ActionMenu::get()->addLink(
+                <?= ActionMenu::get()->setContext(strval($slot))->addLink(
                     $controller->noteURL($slot->block, $slot, $page),
                     _('Information bearbeiten'),
                     Icon::create('edit'),
diff --git a/app/views/contact/index.php b/app/views/contact/index.php
index 6b417df07b8..503c65a2463 100644
--- a/app/views/contact/index.php
+++ b/app/views/contact/index.php
@@ -68,7 +68,7 @@
                                 </a>
                             </td>
                             <td class="actions">
-                                <? $actionMenu = ActionMenu::get() ?>
+                                <? $actionMenu = ActionMenu::get()->setContext($contact) ?>
                                 <? if (Config::get()->BLUBBER_GLOBAL_MESSENGER_ACTIVATE) : ?>
                                     <? $actionMenu->addLink(
                                         URLHelper::getURL('dispatch.php/blubber/write_to/' . $contact->user_id),
diff --git a/app/views/course/dates/_date_row-exdate.php b/app/views/course/dates/_date_row-exdate.php
index b905663bd52..c9b95f5d725 100644
--- a/app/views/course/dates/_date_row-exdate.php
+++ b/app/views/course/dates/_date_row-exdate.php
@@ -19,7 +19,7 @@
     <td class="actions">
     <? if ($has_access && !$cancelled_dates_locked): ?>
         <form action="<?= $controller->url_for("course/timesrooms/undeleteSingle/{$date->id}/1") ?>" method="post">
-            <? $actionMenu = ActionMenu::get() ?>
+            <? $actionMenu = ActionMenu::get()->setContext($date) ?>
             <? $actionMenu->addButton('restore_date', _('Termin wiederherstellen'), Icon::create('trash+decline'),
                                       ['data-confirm' => _('Diesen Termin wiederherstellen?')]) ?>
             <?= $actionMenu->render() ?>
diff --git a/app/views/course/dates/_date_row.php b/app/views/course/dates/_date_row.php
index 152b6fc90b5..fe045ed73ca 100644
--- a/app/views/course/dates/_date_row.php
+++ b/app/views/course/dates/_date_row.php
@@ -49,7 +49,7 @@ $dialog_url = $show_raumzeit
         <? endif ?>
     </td>
     <td class="actions">
-        <? $actionMenu = ActionMenu::get() ?>
+        <? $actionMenu = ActionMenu::get()->setContext($date) ?>
         <? $filecount = count($date->getAccessibleFolderFiles($GLOBALS['user']->id)['files']); ?>
         <? if ($has_access): ?>
             <? $actionMenu->addLink($dialog_url, _('Termin bearbeiten'), Icon::create('edit'), ['data-dialog' => '']) ?>
diff --git a/app/views/course/feedback/index.php b/app/views/course/feedback/index.php
index 28d04f3ab5a..fe4c83fffa6 100644
--- a/app/views/course/feedback/index.php
+++ b/app/views/course/feedback/index.php
@@ -93,7 +93,7 @@
                 </td>
                 <td class="actions">
                     <?php
-                        $actionMenu = ActionMenu::get();
+                        $actionMenu = ActionMenu::get()->setContext($feedback->question);
                         $actionMenu->addLink(
                             $controller->link_for('course/feedback/edit_form/' . $feedback->id),
                             _('Feedback-Element bearbeiten'),
diff --git a/app/views/course/ilias_interface/add_object.php b/app/views/course/ilias_interface/add_object.php
index 429ee584151..b2b5e022a9e 100755
--- a/app/views/course/ilias_interface/add_object.php
+++ b/app/views/course/ilias_interface/add_object.php
@@ -96,7 +96,7 @@
                 </td>
                 <td><?= $module->getModuleTypeName() ?></td>
                 <td class="actions">
-                    <?= ActionMenu::get()->addButton(
+                    <?= ActionMenu::get()->setContext($module->getTitle())->addButton(
                         'view',
                         _('Info'),
                         Icon::create('info-circle'),
diff --git a/app/views/course/ilias_interface/index.php b/app/views/course/ilias_interface/index.php
index 9deab9f22f3..c45d058b7e0 100755
--- a/app/views/course/ilias_interface/index.php
+++ b/app/views/course/ilias_interface/index.php
@@ -35,7 +35,7 @@
             <? endif ?>
             <td><?=$module->getModuleTypeName()?></td>
                 <td class="actions">
-                    <? $actionMenu = ActionMenu::get() ?>
+                    <? $actionMenu = ActionMenu::get()->setContext($module->getTitle()) ?>
                     <? if (! $module->is_offline) $actionMenu->addButton(
                             'view',
                             _('Info'),
@@ -97,7 +97,7 @@
             </td>
             <td><?=_('ILIAS-Kurs')?></td>
                 <td class="actions">
-                    <? $actionMenu = ActionMenu::get() ?>
+                    <? $actionMenu = ActionMenu::get()->setContext(sprintf(_('Kurs in %s'), $ilias->getName())) ?>
                     <? $actionMenu->addButton(
                             'start',
                             _('In ILIAS anzeigen'),
diff --git a/app/views/course/members/accepted_list.php b/app/views/course/members/accepted_list.php
index e789a10c668..53e69181355 100644
--- a/app/views/course/members/accepted_list.php
+++ b/app/views/course/members/accepted_list.php
@@ -111,7 +111,7 @@
                     ]) ?>
                 </td>
                 <td class="actions">
-                    <? $actionMenu = ActionMenu::get() ?>
+                    <? $actionMenu = ActionMenu::get()->setContext($fullname) ?>
                     <? $actionMenu->addLink(
                         $controller->url_for('course/members/add_comment/' . $accept['user_id']),
                         _('Bemerkung hinzufügen'),
diff --git a/app/views/course/members/autor_list.php b/app/views/course/members/autor_list.php
index ed031a43cef..e40a4547e46 100644
--- a/app/views/course/members/autor_list.php
+++ b/app/views/course/members/autor_list.php
@@ -128,7 +128,7 @@
             <? endif ?>
 
                 <td class="actions">
-                    <? $actionMenu = ActionMenu::get() ?>
+                    <? $actionMenu = ActionMenu::get()->setContext($fullname) ?>
                     <? if ($is_tutor) : ?>
                         <? $actionMenu->addLink(
                             $controller->url_for('course/members/add_comment/' . $autor['user_id']),
diff --git a/app/views/course/members/awaiting_list.php b/app/views/course/members/awaiting_list.php
index 6ac535cd0b8..cb44dea5688 100644
--- a/app/views/course/members/awaiting_list.php
+++ b/app/views/course/members/awaiting_list.php
@@ -98,7 +98,7 @@
                     ]) ?>
                 </td>
                 <td class="actions">
-                    <? $actionMenu = ActionMenu::get() ?>
+                    <? $actionMenu = ActionMenu::get()->setContext($fullname) ?>
                     <? if ($user_id !== $waiting['user_id']) : ?>
                         <? $actionMenu->addLink(
                             URLHelper::getURL('dispatch.php/messages/write', [
diff --git a/app/views/course/members/dozent_list.php b/app/views/course/members/dozent_list.php
index e955b569c12..d839b7e4f9b 100644
--- a/app/views/course/members/dozent_list.php
+++ b/app/views/course/members/dozent_list.php
@@ -66,7 +66,7 @@
             <? endif ?>
             </td>
             <td class="actions">
-                <? $actionMenu = ActionMenu::get() ?>
+                <? $actionMenu = ActionMenu::get()->setContext($fullname) ?>
                 <? if ($is_tutor) : ?>
                     <? $actionMenu->addLink(
                         $controller->url_for('course/members/add_comment/' . $dozent['user_id']),
diff --git a/app/views/course/members/tutor_list.php b/app/views/course/members/tutor_list.php
index e07b4302a70..bb77d3a5e80 100644
--- a/app/views/course/members/tutor_list.php
+++ b/app/views/course/members/tutor_list.php
@@ -116,7 +116,7 @@
                 </td>
             <? endif ?>
                 <td class="actions">
-                    <? $actionMenu = ActionMenu::get() ?>
+                    <? $actionMenu = ActionMenu::get()->setContext($fullname) ?>
                     <? if ($is_tutor) : ?>
                         <? $actionMenu->addLink(
                             $controller->url_for('course/members/add_comment/' . $tutor['user_id']),
diff --git a/app/views/course/members/user_list.php b/app/views/course/members/user_list.php
index 6ebd3b01f03..c3102ea3a36 100644
--- a/app/views/course/members/user_list.php
+++ b/app/views/course/members/user_list.php
@@ -109,7 +109,7 @@
                 </td>
             <? endif ?>
                 <td style="text-align: right">
-                    <? $actionMenu = ActionMenu::get() ?>
+                    <? $actionMenu = ActionMenu::get()->setContext($fullname) ?>
                     <? if ($user_id !== $leser['user_id']) : ?>
                         <? $actionMenu->addLink(
                             URLHelper::getURL('dispatch.php/messages/write', [
diff --git a/app/views/course/plus/index.php b/app/views/course/plus/index.php
index 9daa3dee638..b50bd535522 100644
--- a/app/views/course/plus/index.php
+++ b/app/views/course/plus/index.php
@@ -55,8 +55,8 @@ use Studip\Button;
                     <tr id="<?= htmlReady($anchor); ?>"
                         class="<?= $visibility; ?> <?= $pre_check != null ? ' quiet' : '' ?>">
                         <td class="element" colspan=3>
-                            <div class="plus_basic">
 
+                            <div class="plus_basic">
                                 <input type="checkbox"
                                        id="<?= $key ?>"
                                        name="<?= $key ?>"
@@ -111,7 +111,7 @@ use Studip\Button;
                                 </div>
                                 <? if ($plugin_activated) : ?>
                                     <?
-                                    $actionMenu = ActionMenu::get();
+                                    $actionMenu = ActionMenu::get()->setContext($pluginname);
                                     $actionMenu->addLink(
                                         $controller->url_for('/edittool/' . $key),
                                         _('Optionen bearbeiten'),
diff --git a/app/views/course/room_requests/index.php b/app/views/course/room_requests/index.php
index e8b94dc7f2b..3f13b05a7dc 100644
--- a/app/views/course/room_requests/index.php
+++ b/app/views/course/room_requests/index.php
@@ -51,7 +51,7 @@ echo $flash['message'];
                         <? $dialog['data-dialog'] = 'size=big' ?>
                     <? endif ?>
 
-                    <? $actionMenu = ActionMenu::get() ?>
+                    <? $actionMenu = ActionMenu::get()->setContext($rr->getTypeString()) ?>
                     <? $actionMenu->addLink(
                         $controller->url_for('course/room_requests/request_summary/' . $rr->id, ['clear_cache' => 1]),
                         _('Diese Anfrage bearbeiten'),
diff --git a/app/views/course/statusgroups/_group.php b/app/views/course/statusgroups/_group.php
index ebd99728102..1110e7caabf 100644
--- a/app/views/course/statusgroups/_group.php
+++ b/app/views/course/statusgroups/_group.php
@@ -64,7 +64,7 @@
             <?php endif ?>
             <?php if ($is_tutor) : ?>
                 <?php if ($group->id != 'nogroup') : ?>
-                    <?= ActionMenu::get()
+                    <?= ActionMenu::get()->setContext($group->name)
                           ->addLink(
                               $controller->url_for('messages/write', [
                                   'group_id' => $group->id,
diff --git a/app/views/course/statusgroups/_member.php b/app/views/course/statusgroups/_member.php
index a874e6b37ad..ce3507b312e 100644
--- a/app/views/course/statusgroups/_member.php
+++ b/app/views/course/statusgroups/_member.php
@@ -34,7 +34,7 @@
     </td>
 <? endif ?>
     <td class="memberactions">
-        <? $actions = ActionMenu::get();
+        <? $actions = ActionMenu::get()->setContext($user_fullname);
            if ($is_tutor || $m->user_id !== $GLOBALS['user']->id) {
                $actions->addLink(
             $controller->url_for('messages/write', [
diff --git a/app/views/course/timesrooms/_cycleRow.php b/app/views/course/timesrooms/_cycleRow.php
index c58990b1b26..cfb291ad3bf 100644
--- a/app/views/course/timesrooms/_cycleRow.php
+++ b/app/views/course/timesrooms/_cycleRow.php
@@ -77,7 +77,7 @@ $is_exTermin = $termin instanceof CourseExDate;
     <? endif ?>
     </td>
     <td class="actions">
-        <? $actionMenu = ActionMenu::get() ?>
+        <? $actionMenu = ActionMenu::get()->setContext($termin) ?>
     <? if ($is_exTermin): ?>
         <? $actionMenu->addLink(
             $controller->url_for(
diff --git a/app/views/course/timesrooms/_irregularEvents.php b/app/views/course/timesrooms/_irregularEvents.php
index 0181ec5123f..f85b18ba124 100644
--- a/app/views/course/timesrooms/_irregularEvents.php
+++ b/app/views/course/timesrooms/_irregularEvents.php
@@ -14,7 +14,7 @@ $room_request_filter = function ($date) {
         </h1>
     <? if(!$locked) : ?>
         <nav>
-            <? $actionMenu = ActionMenu::get()?>
+            <? $actionMenu = ActionMenu::get()->setContext(_('Unregelmäßige Termine / Blocktermine')) ?>
             <? $actionMenu->addLink(
                 $controller->url_for('course/timesrooms/createSingleDate/' . $course->id, $linkAttributes),
                 _('Einzeltermin hinzufügen'),
diff --git a/app/views/course/timesrooms/_regularEvents.php b/app/views/course/timesrooms/_regularEvents.php
index 69e4d7e6ee9..d813254d697 100644
--- a/app/views/course/timesrooms/_regularEvents.php
+++ b/app/views/course/timesrooms/_regularEvents.php
@@ -75,7 +75,7 @@
                     </section>
                     <? if (!$locked) : ?>
                     <nav>
-                        <? $actionMenu = ActionMenu::get()?>
+                        <? $actionMenu = ActionMenu::get()->setContext($cycle['cycle']->toString('long')) ?>
                         <? $actionMenu->addLink(
                             $controller->url_for('course/timesrooms/createCycle/' . $metadate_id, $linkAttributes),
                             _('Diesen Zeitraum bearbeiten'),
diff --git a/app/views/files/_folder_tr.php b/app/views/files/_folder_tr.php
index 6d7dc8accee..ca89fc9bbda 100644
--- a/app/views/files/_folder_tr.php
+++ b/app/views/files/_folder_tr.php
@@ -67,7 +67,7 @@ if ($folder->isReadable($GLOBALS['user']->id)) {
     <? endforeach ?>
     <td class="actions">
     <?php
-        $actionMenu = ActionMenu::get();
+        $actionMenu = ActionMenu::get()->setContext($folder->name);
         $actionMenu->addLink(
             $controller->url_for('file/details/' . $folder->getId()),
             _('Info'),
diff --git a/app/views/institute/members/_table_body.php b/app/views/institute/members/_table_body.php
index 90d7c02637e..d9772433955 100644
--- a/app/views/institute/members/_table_body.php
+++ b/app/views/institute/members/_table_body.php
@@ -89,6 +89,7 @@
     <? if ($structure['actions']): ?>
         <td class="actions">
         <?= ActionMenu::get()
+            ->setContext($member->user)
             ->addLink(
                 $controller->url_for("messages/write?rec_uname={$member->username}"),
                 _('Nachricht an Benutzer verschicken'),
diff --git a/app/views/lvgruppen/lvgruppen/index.php b/app/views/lvgruppen/lvgruppen/index.php
index aae9d8049de..e4800828688 100644
--- a/app/views/lvgruppen/lvgruppen/index.php
+++ b/app/views/lvgruppen/lvgruppen/index.php
@@ -27,7 +27,7 @@
                     <td style="text-align: center;" class="dont-hide"><?= $lvgruppe->count_archiv ?> </td>
                     <td style="text-align: center;" class="dont-hide"><?= $lvgruppe->count_modulteile ?> </td>
                     <td class="dont-hide actions" style="white-space: nowrap;">
-                        <? $actionMenu = ActionMenu::get() ?>
+                        <? $actionMenu = ActionMenu::get()->setContext($lvgruppe->getDisplayName()) ?>
                         <? if (MvvPerm::get($lvgruppe)->havePermWrite()) : ?>
                             <? $actionMenu->addLink(
                                 $controller->url_for('/lvgruppe/' . $lvgruppe->id),
@@ -35,7 +35,7 @@
                                 Icon::create('edit', Icon::ROLE_CLICKABLE, tooltip2(_('Lehrveranstaltungsgruppe bearbeiten'))),
                                 ['data-dialog' => 'size=']
                             ) ?>
-                            
+
                             <? $actionMenu->addLink(
                                 $controller->url_for('shared/log_event/show/Lvgruppe/' . $lvgruppe->id),
                                 _('Log-Einträge dieser Lehrveranstaltungsgruppe'),
@@ -78,7 +78,7 @@
                 </tr>
             </tbody>
         <? endif ?>
-        
+
         <? if ($count > MVVController::$items_per_page) : ?>
         <tfoot>
             <tr>
@@ -98,4 +98,4 @@
         <tfoot>
             <? endif; ?>
     </table>
-</form>
\ No newline at end of file
+</form>
diff --git a/app/views/materialien/files/index.php b/app/views/materialien/files/index.php
index af3d8cd0612..5e0117d86b2 100644
--- a/app/views/materialien/files/index.php
+++ b/app/views/materialien/files/index.php
@@ -57,7 +57,7 @@
             <td class="dont-hide" style="text-align: center;"><?= htmlReady($mvv_file->count_relations) ?></td>
             <td class="dont-hide actions">
             <?
-                $actions = ActionMenu::get();
+                $actions = ActionMenu::get()->setContext($mvv_file->getFilenames()[0]);
                 $actions->addLink(
                     $controller->url_for('materialien/files/add_dokument', 'index', $mvv_file->getRangeType()?:0, 0, $mvv_file->mvvfile_id),
                     _('Dokument bearbeiten'),
diff --git a/app/views/materialien/files/range.php b/app/views/materialien/files/range.php
index b00ac1403a0..86c36f4200a 100644
--- a/app/views/materialien/files/range.php
+++ b/app/views/materialien/files/range.php
@@ -73,7 +73,7 @@
             <td style="text-align: center;"><?= htmlReady($mvv_file->count_relations); ?></td>
             <td class="actions">
             <?
-                $actions = ActionMenu::get();
+                $actions = ActionMenu::get()->setContext($mvv_file->getDisplayName());
                 $actions->addLink(
                     $controller->url_for('materialien/files/details',$mvv_file->mvvfile_id),
                     _('Details'),
diff --git a/app/views/module/module/details.php b/app/views/module/module/details.php
index b8f813e495f..e5ab93c4e49 100644
--- a/app/views/module/module/details.php
+++ b/app/views/module/module/details.php
@@ -32,7 +32,7 @@
                     <td class="dont-hide actions" style="white-space: nowrap;">
                         <form method="post">
                             <?= CSRFProtection::tokenTag(); ?>
-                            <? $actionMenu = ActionMenu::get() ?>
+                            <? $actionMenu = ActionMenu::get()->setContext($modulteil->getDisplayName()) ?>
                             <? if (MvvPerm::havePermCreate('Lvgruppe') && $perm->haveFieldPermLvgruppen(MvvPerm::PERM_CREATE)) : ?>
                                 <? $actionMenu->addLink(
                                     $controller->url_for('/lvgruppe/' . $modulteil->id),
diff --git a/app/views/module/module/module.php b/app/views/module/module/module.php
index 75d30719153..a89fbd50d92 100644
--- a/app/views/module/module/module.php
+++ b/app/views/module/module/module.php
@@ -56,7 +56,7 @@
             <td class="dont-hide actions" style="white-space: nowrap;">
                 <form method="post">
                     <?= CSRFProtection::tokenTag(); ?>
-                    <? $actionMenu = ActionMenu::get() ?>
+                    <? $actionMenu = ActionMenu::get()->setContext($modul->getDisplayName()) ?>
                     <? if ($modul->stat === 'planung' && $perm->haveFieldPerm('stat')) : ?>
                         <? $actionMenu->addLink(
                             $controller->url_for('/approve/' . $modul->id),
diff --git a/app/views/module/module/modulteil_lvg.php b/app/views/module/module/modulteil_lvg.php
index c2e5c3913dc..238009c87f1 100644
--- a/app/views/module/module/modulteil_lvg.php
+++ b/app/views/module/module/modulteil_lvg.php
@@ -12,7 +12,7 @@
                     <td class="actions">
                         <form method="post">
                             <?= CSRFProtection::tokenTag(); ?>
-                            <? $actionMenu = ActionMenu::get() ?>
+                            <? $actionMenu = ActionMenu::get()->setContext($lvgruppe->getDisplayName()) ?>
                             <? if (MvvPerm::haveFieldPermLvgruppen($modulteil, MvvPerm::PERM_WRITE)) : ?>
                                 <? $actionMenu->addLink(
                                     $controller->url_for('/lvgruppe/' . $modulteil->id . '/' . $lvgruppe->id),
diff --git a/app/views/my_ilias_accounts/index.php b/app/views/my_ilias_accounts/index.php
index a8d1a802f13..6b29d5d408f 100755
--- a/app/views/my_ilias_accounts/index.php
+++ b/app/views/my_ilias_accounts/index.php
@@ -32,7 +32,7 @@
             <td><a href="<?= $controller->url_for($module->getRoute('view_tools'))?>" data-dialog=""><?=$module->getTitle()?></a></td>
             <td><?=$module->getModuleTypeName()?></td>
                 <td class="actions">
-                    <? $actionMenu = ActionMenu::get() ?>
+                    <? $actionMenu = ActionMenu::get()->setContext($module->getTitle()) ?>
                     <? $actionMenu->addButton(
                             'view',
                             _('Info'),
@@ -107,7 +107,7 @@
                 <td><?=$ilias->user->getUserName()?></td>
                 <td><?=$ilias->getName()?></td>
                 <td class="actions">
-                    <? $actionMenu = ActionMenu::get() ?>
+                    <? $actionMenu = ActionMenu::get()->setContext($ilias->getName()) ?>
                     <? if ($ilias->ilias_config['allow_change_account'] && ($ilias->user->getUserType() === IliasUser::USER_TYPE_CREATED)) $actionMenu->addButton(
                             'new_account',
                             _('Account neu zuordnen'),
diff --git a/app/views/news/admin_news.php b/app/views/news/admin_news.php
index 0909b1d085f..17e28286154 100644
--- a/app/views/news/admin_news.php
+++ b/app/views/news/admin_news.php
@@ -120,7 +120,7 @@
                         <td><?= strftime("%d.%m.%y", $news['object']->date + $news['object']->expire) ?></td>
                         <td class="actions">
                             <?
-                            $menu = ActionMenu::get();
+                            $menu = ActionMenu::get()->setContext($news['object']->topic);
                             $menu->addLink(
                                 $controller->url_for('news/edit_news/' . $news['object']->news_id),
                                 _('Ankündigung bearbeiten'),
diff --git a/app/views/online/user-row.php b/app/views/online/user-row.php
index 9bc417d1c27..cc4b12f2083 100644
--- a/app/views/online/user-row.php
+++ b/app/views/online/user-row.php
@@ -18,7 +18,7 @@
         <?= ucfirst(reltime(time() - $user['last_action'])) ?>
     </td>
     <td class="actions" nowrap="nowrap">
-        <? $actionMenu = ActionMenu::get() ?>
+        <? $actionMenu = ActionMenu::get()->setContext($user['name']) ?>
         <? if (Config::get()->BLUBBER_GLOBAL_MESSENGER_ACTIVATE) : ?>
             <? $actionMenu->addLink(
                 URLHelper::getURL('dispatch.php/blubber/write_to/'.$user['user_id']),
diff --git a/app/views/questionnaire/_overview_questionnaire.php b/app/views/questionnaire/_overview_questionnaire.php
index dc166a0d417..4bf2897ca76 100644
--- a/app/views/questionnaire/_overview_questionnaire.php
+++ b/app/views/questionnaire/_overview_questionnaire.php
@@ -93,7 +93,7 @@
         </a>
 
         <?
-        $menu = ActionMenu::get();
+        $menu = ActionMenu::get()->setContext($questionnaire['title']);
         if ($questionnaire->isRunning()) {
             $menu->addLink(
                 $controller->url_for('questionnaire/stop/' . $questionnaire->id, in_array($range_type, ['course', 'institute']) ? ['redirect' => 'questionnaire/courseoverview'] : []),
diff --git a/app/views/resources/_common/_request_tr.php b/app/views/resources/_common/_request_tr.php
index 3deefe86c5a..777931bb543 100644
--- a/app/views/resources/_common/_request_tr.php
+++ b/app/views/resources/_common/_request_tr.php
@@ -95,6 +95,7 @@
     </td>
     <td class="actions">
         <? $action_menu = ActionMenu::get()
+            ->setContext($request->getTypeString())
             ->addLink(
                 $controller->link_for('resources/room_request/resolve/' . $request->id),
                 _('Anfrage auflösen'),
@@ -158,4 +159,4 @@
         ?>
         <?= $action_menu->render() ?>
     </td>
-</tr>
\ No newline at end of file
+</tr>
diff --git a/app/views/resources/_common/_resource_tr.php b/app/views/resources/_common/_resource_tr.php
index d459013382c..66203c986f5 100644
--- a/app/views/resources/_common/_resource_tr.php
+++ b/app/views/resources/_common/_resource_tr.php
@@ -157,7 +157,7 @@
             //Build the actions as array. Ordering is done by array indexes.
 
             $actions = [];
-            $action_menu = ActionMenu::get();
+            $action_menu = ActionMenu::get()->setContext($resource);
             if ($show_user_actions) {
                 $actions['0010'] = [
                     $resource->getActionLink('show'),
diff --git a/app/views/resources/_common/_room_search_result.php b/app/views/resources/_common/_room_search_result.php
index 7c82fcfd3e1..7cd5900b315 100644
--- a/app/views/resources/_common/_room_search_result.php
+++ b/app/views/resources/_common/_room_search_result.php
@@ -10,7 +10,7 @@
             ]
         ) ?><?= htmlReady($room->name) ?></h1>
         <?
-        $actions = ActionMenu::get();
+        $actions = ActionMenu::get()->setContext($room);
         $actions->addLink(
             $room->getActionLink('show'),
             _('Raumdetails anzeigen'),
diff --git a/app/views/resources/admin/categories.php b/app/views/resources/admin/categories.php
index 0b69231632d..7f04d7961f1 100644
--- a/app/views/resources/admin/categories.php
+++ b/app/views/resources/admin/categories.php
@@ -33,6 +33,7 @@
                 <td class="actions">
                     <?php
                     $actions = ActionMenu::get()
+                        ->setContext($category->name)
                         ->conditionAll($category->hasResources())
                         ->addLink(
                             $controller->url_for(
diff --git a/app/views/resources/admin/global_locks.php b/app/views/resources/admin/global_locks.php
index e4c55dfd9bb..88dde52208f 100644
--- a/app/views/resources/admin/global_locks.php
+++ b/app/views/resources/admin/global_locks.php
@@ -24,8 +24,15 @@
                     <td><?= date('d.m.Y H:i', $lock->end) ?></td>
                     <td><?= $lock->getTypeString() ?></td>
                     <td class="actions">
-                        <?= ActionMenu::get()
-                            ->addLink(
+                        <?= ActionMenu::get()->setContext(
+                            sprintf(
+                                _('Sperre vom %1$s %2$s Uhr bis %3$s %4$s Uhr'),
+                                strftime('%x', $lock->begin),
+                                date('H:i', $lock->begin),
+                                strftime('%x', $lock->end),
+                                date('H:i', $lock->end)
+                            )
+                        )->addLink(
                                 $controller->url_for('resources/global_locks/edit/' . $lock->id),
                                 _('Sperrung bearbeiten'),
                                 Icon::create('edit'),
diff --git a/app/views/shared/contacts/details.php b/app/views/shared/contacts/details.php
index 7a7347774ba..680ccee3f53 100644
--- a/app/views/shared/contacts/details.php
+++ b/app/views/shared/contacts/details.php
@@ -53,7 +53,7 @@
                                     </td>
                                     <td class="actions">
                                     <?
-                                        $actions = ActionMenu::get();
+                                        $actions = ActionMenu::get()->setContext($object_name);
                                         $actions->addLink(
                                             $controller->url_for('shared/contacts/edit_ansprechpartner', $rel['contact_range_id'], $origin),
                                             _('Ansprechpartner bearbeiten'),
diff --git a/app/views/shared/contacts/index.php b/app/views/shared/contacts/index.php
index 0377a9de6c8..f52a315c63f 100644
--- a/app/views/shared/contacts/index.php
+++ b/app/views/shared/contacts/index.php
@@ -32,7 +32,7 @@
             <td class="dont-hide"><?= htmlReady($mvv_contact->count_relations); ?></td>
             <td class="dont-hide actions">
             <?
-                $actions = ActionMenu::get();
+                $actions = ActionMenu::get()->setContext($mvv_contact->getContactName());
                 if ($perm->haveFieldPerm('ranges', MvvPerm::PERM_CREATE)) {
                     $actions->addLink(
                         $controller->url_for('shared/contacts/add_ranges_to_contact', $mvv_contact->contact_id),
diff --git a/app/views/shared/contacts/range.php b/app/views/shared/contacts/range.php
index a036c1073aa..78d9a14f1c9 100644
--- a/app/views/shared/contacts/range.php
+++ b/app/views/shared/contacts/range.php
@@ -46,7 +46,7 @@
             <td ><?= htmlReady($mvv_contact->count_relations); ?></td>
             <td class="actions">
             <?
-                $actions = ActionMenu::get();
+                $actions = ActionMenu::get()->setContext($mvv_contact->name);
                 if ($perm_contacts >= MvvPerm::PERM_WRITE) {
                     $actions->addLink(
                         $controller->url_for('shared/contacts/edit_ansprechpartner', $mvv_contact->id, 'range'),
diff --git a/app/views/studiengaenge/informationen/showdegree.php b/app/views/studiengaenge/informationen/showdegree.php
index dc2c0437b4f..25badec476d 100644
--- a/app/views/studiengaenge/informationen/showdegree.php
+++ b/app/views/studiengaenge/informationen/showdegree.php
@@ -15,6 +15,7 @@
                     </td>
                 <td class="actions">
                     <? $action =ActionMenu::get()
+                        ->setContext($deg->name)
                         ->addLink($controller->url_for('/messagehelper',
                             ['fach_id' => $studycourse->fach_id, 'abschluss_id' => $deg->abschluss_id]),
                             _('Nachricht an Studierende schreiben'),
@@ -28,4 +29,4 @@
         </tbody>
     <? endforeach; ?>
     </table>
-</td>
\ No newline at end of file
+</td>
diff --git a/app/views/studiengaenge/informationen/showstudycourse.php b/app/views/studiengaenge/informationen/showstudycourse.php
index c1c57bf475f..ae4f745aa45 100644
--- a/app/views/studiengaenge/informationen/showstudycourse.php
+++ b/app/views/studiengaenge/informationen/showstudycourse.php
@@ -15,7 +15,7 @@
                     <?= $count ?>
                 </td>
                 <td class="actions">
-                    <? $action =ActionMenu::get()
+                    <? $action =ActionMenu::get()->setContext($course->name)
                         ->addLink($controller->url_for('/messagehelper',
                             ['fach_id' => $course->fach_id, 'abschluss_id' => $degree->abschluss_id]),
                             _('Nachricht an Studierende schreiben'),
diff --git a/app/views/studiengaenge/studiengaenge/studiengaenge.php b/app/views/studiengaenge/studiengaenge/studiengaenge.php
index 54f27662c20..78a1eab4a74 100644
--- a/app/views/studiengaenge/studiengaenge/studiengaenge.php
+++ b/app/views/studiengaenge/studiengaenge/studiengaenge.php
@@ -38,7 +38,7 @@
             <td class="actions dont-hide">
                 <form method="post">
                     <?= CSRFProtection::tokenTag(); ?>
-                    <? $actionMenu = ActionMenu::get() ?>
+                    <? $actionMenu = ActionMenu::get()->setContext($studiengang->name) ?>
                     <? if ($studiengang->stat === 'planung' && MvvPerm::haveFieldPermStat($studiengang)) : ?>
                         <? $actionMenu->addLink(
                             $controller->url_for('/approve/' . $studiengang->id),
diff --git a/app/views/studiengaenge/studiengangteile/details_grouped.php b/app/views/studiengaenge/studiengangteile/details_grouped.php
index 965962459e2..ab4cd519b89 100644
--- a/app/views/studiengaenge/studiengangteile/details_grouped.php
+++ b/app/views/studiengaenge/studiengangteile/details_grouped.php
@@ -10,7 +10,7 @@
                         <?= htmlReady($stgteil->getDisplayName()) ?>
                     </td>
                     <td class="actions" style="white-space: nowrap; width: 1%;">
-                        <? $actionMenu = ActionMenu::get() ?>
+                        <? $actionMenu = ActionMenu::get()->setContext($stgteil->fach_name) ?>
                         <? if (MvvPerm::havePermWrite($stgteil)) : ?>
                             <? $actionMenu->addLink(
                                 $controller->url_for('/stgteil/' . $stgteil->id),
diff --git a/app/views/studiengaenge/studiengangteile/index.php b/app/views/studiengaenge/studiengangteile/index.php
index bbffeadef6e..5b0a1f5edf0 100644
--- a/app/views/studiengaenge/studiengangteile/index.php
+++ b/app/views/studiengaenge/studiengangteile/index.php
@@ -39,7 +39,7 @@
                         <td class="dont-hide" style="text-align: center;"><?= htmlReady($stgteil->kp) ?> </td>
                         <td class="dont-hide" style="text-align: center;"><?= $stgteil->count_versionen ?> </td>
                         <td class="dont-hide actions" style="white-space: nowrap;">
-                            <? $actionMenu = ActionMenu::get() ?>
+                            <? $actionMenu = ActionMenu::get()->setContext($stgteil->fach_name) ?>
                             <? if (MvvPerm::havePermCreate('StgteilVersion')) : ?>
                                 <? $actionMenu->addLink(
                                     $controller->url_for('/version/' . $stgteil->getId()),
diff --git a/app/views/studiengaenge/versionen/abschnitte.php b/app/views/studiengaenge/versionen/abschnitte.php
index 7a710671f93..dfa5ba4a36c 100644
--- a/app/views/studiengaenge/versionen/abschnitte.php
+++ b/app/views/studiengaenge/versionen/abschnitte.php
@@ -17,7 +17,7 @@
                     <td class="dont-hide actions" style="white-space: nowrap;">
                         <form method="post">
                             <?= CSRFProtection::tokenTag(); ?>
-                            <? $actionMenu = ActionMenu::get() ?>
+                            <? $actionMenu = ActionMenu::get()->setContext($abschnitt->name) ?>
                             <? if (MvvPerm::havePermWrite($version)) : ?>
                                 <? $actionMenu->addLink(
                                     $controller->url_for('/abschnitt/' . $abschnitt->id),
diff --git a/app/views/studiengaenge/versionen/versionen.php b/app/views/studiengaenge/versionen/versionen.php
index f73790c0fdd..2f052bda541 100644
--- a/app/views/studiengaenge/versionen/versionen.php
+++ b/app/views/studiengaenge/versionen/versionen.php
@@ -24,7 +24,7 @@
             <td class="dont-hide" style="white-space: nowrap; text-align: right;">
                 <form method="post">
                     <?= CSRFProtection::tokenTag(); ?>
-                    <? $actionMenu = ActionMenu::get() ?>
+                    <? $actionMenu = ActionMenu::get()->setContext($version->getDisplayName()) ?>
                     <? if ($version->stat === 'planung' && MvvPerm::haveFieldPermStat($version)) : ?>
                         <? $actionMenu->addLink(
                             $controller->url_for('/approve/' . $version->id),
@@ -88,4 +88,4 @@
             </tr>
         <? endif; ?>
     </tbody>
-<? endforeach; ?>
\ No newline at end of file
+<? endforeach; ?>
diff --git a/app/views/tour/admin_details.php b/app/views/tour/admin_details.php
index cf018b0cf3a..8e89524abfd 100644
--- a/app/views/tour/admin_details.php
+++ b/app/views/tour/admin_details.php
@@ -143,7 +143,7 @@
                         <td><?= htmlReady($step->tip) ?></td>
                         <td><?= htmlReady($step->route) ?></td>
                         <td class="actions">
-                        <? $actionMenu = ActionMenu::get() ?>
+                        <? $actionMenu = ActionMenu::get()->setContext($step->title) ?>
                         <? $actionMenu->addLink(
                             $controller->url_for('tour/edit_step/' . $tour->tour_id . '/' . $step->step),
                             _('Schritt bearbeiten'),
diff --git a/app/views/tour/admin_overview.php b/app/views/tour/admin_overview.php
index a6710fcaf00..6a892711310 100644
--- a/app/views/tour/admin_overview.php
+++ b/app/views/tour/admin_overview.php
@@ -67,7 +67,9 @@
                 </td>
                 <td><?= count($tour->steps) ?></td>
                 <td class="actions">
-                    <?= ActionMenu::get()->addLink(
+                    <?= ActionMenu::get()->setContext(
+                        $tour->name
+                    )->addLink(
                         $controller->url_for('tour/admin_details/' . $tour_id),
                         _('Tour bearbeiten'),
                         Icon::create('edit')
diff --git a/lib/classes/ActionMenu.php b/lib/classes/ActionMenu.php
index ed6b36a157a..92eac8dbcf8 100644
--- a/lib/classes/ActionMenu.php
+++ b/lib/classes/ActionMenu.php
@@ -27,6 +27,11 @@ class ActionMenu
     private $condition_all = null;
     private $condition     = true;
 
+    /**
+     * @var string $context The context for the action menu.
+     */
+    protected $context = '';
+
 
     /**
      * Private constructur.
@@ -254,6 +259,7 @@ class ActionMenu
             }
             return $action;
         }, $this->actions);
+        $template->action_menu_title = $this->generateTitle();
         $template->attributes = $this->attributes;
         return $template->render();
     }
@@ -278,4 +284,37 @@ class ActionMenu
         }
         return null;
     }
+
+
+    /**
+     * Sets the context for the menu.
+     *
+     * @param string $context The context to be set.
+     *
+     * @return ActionMenu The action menu instance (to allow chaining).
+     */
+    public function setContext(string $context)
+    {
+        $this->context = $context;
+
+        return $this;
+    }
+
+
+    /**
+     * Generates the title of the action menu, including its context, if the context has been set.
+     *
+     * @return string The title of the action menu.
+     */
+    public function generateTitle() : string
+    {
+        if ($this->context) {
+            return sprintf(
+                _('Aktionsmenü für %s'),
+                $this->context
+            );
+        } else {
+            return _('Aktionsmenü');
+        }
+    }
 }
diff --git a/lib/classes/Range.interface.php b/lib/classes/Range.interface.php
index aa4c9cf1f51..41cc1001edf 100644
--- a/lib/classes/Range.interface.php
+++ b/lib/classes/Range.interface.php
@@ -57,4 +57,10 @@ interface Range
      * @return bool
      */
     public function isEditableByUser($user_id = null);
+
+
+    /**
+     * @return string A string representation of the Range instance.
+     */
+    public function __toString() : string;
 }
diff --git a/lib/classes/StudipItem.interface.php b/lib/classes/StudipItem.interface.php
index 51352303329..b575bdc5c06 100644
--- a/lib/classes/StudipItem.interface.php
+++ b/lib/classes/StudipItem.interface.php
@@ -61,4 +61,12 @@ interface StudipItem
      *     of the StudipItem object.
      */
     public function getLink() : StudipLink;
+
+
+    /**
+     * @return string A string representation of the item.
+     *     For backward compatibility with existing plugins that have classes
+     *     derived of StudipItem, the return type is not specified.
+     */
+    public function __toString();
 }
diff --git a/lib/filesystem/FilesystemVueDataManager.php b/lib/filesystem/FilesystemVueDataManager.php
index 87769e80071..28440a92114 100644
--- a/lib/filesystem/FilesystemVueDataManager.php
+++ b/lib/filesystem/FilesystemVueDataManager.php
@@ -25,7 +25,7 @@ class FilesystemVueDataManager
                 'order' => $file->getAdditionalColumnOrderWeigh($index)
             ];
         }
-        $actionMenu = $file->getActionMenu();
+        $actionMenu = $file->getActionMenu()->setContext($file->getFilename());
         return [
             'id' => $file->getId(),
             'name' => $file->getFilename(),
@@ -57,7 +57,7 @@ class FilesystemVueDataManager
      */
     public static function getFolderVueData(FolderType $folder, FolderType $topFolder)
     {
-        $actionMenu = ActionMenu::get();
+        $actionMenu = ActionMenu::get()->setContext($folder->name);
         $actionMenu->addLink(
             URLHelper::getURL('dispatch.php/file/details/' . $folder->getId()),
             _('Info'),
diff --git a/lib/filesystem/StandardFile.php b/lib/filesystem/StandardFile.php
index 74e538ae86f..3f9ae39d982 100644
--- a/lib/filesystem/StandardFile.php
+++ b/lib/filesystem/StandardFile.php
@@ -229,7 +229,7 @@ class StandardFile implements FileType, ArrayAccess
 
     public function getActionmenu()
     {
-        $actionMenu = ActionMenu::get();
+        $actionMenu = ActionMenu::get()->setContext($this->fileref->name);
         $actionMenu->addLink(
             URLHelper::getURL("dispatch.php/file/details/{$this->fileref->id}/1"),
             _('Info'),
diff --git a/lib/models/ConsultationBlock.php b/lib/models/ConsultationBlock.php
index 6020ebe7ddd..01b688a3da2 100644
--- a/lib/models/ConsultationBlock.php
+++ b/lib/models/ConsultationBlock.php
@@ -394,4 +394,19 @@ class ConsultationBlock extends SimpleORMap implements PrivacyObject
             [$range->getRangeId(), $range->getRangeType()]
         );
     }
+
+
+    /**
+     * @return string A string representation of the consultation block instance.
+     */
+    public function __toString() : string
+    {
+        return sprintf(
+            _('Terminblock am %1$s, %2$s von %3$s bis %4$s Uhr'),
+            strftime('%A', $this->start),
+            strftime('%x', $this->start),
+            date('H:i', $this->start),
+            date('H:i', $this->end)
+        );
+    }
 }
diff --git a/lib/models/ConsultationSlot.php b/lib/models/ConsultationSlot.php
index a902f0631b5..51d28d270f4 100644
--- a/lib/models/ConsultationSlot.php
+++ b/lib/models/ConsultationSlot.php
@@ -273,4 +273,19 @@ class ConsultationSlot extends SimpleORMap
 
         }
     }
+
+
+    /**
+     * @return string A string representation of the consultation slot.
+     */
+    public function __toString() : string
+    {
+        return sprintf(
+            _('Termin am %1$s, %2$s von %3$s bis %4$s'),
+            strftime('%A', $this->start_time),
+            strftime('%x', $this->start_time),
+            date('H:i', $this->start_time),
+            date('H:i', $this->end_time)
+        );
+    }
 }
diff --git a/lib/models/Course.class.php b/lib/models/Course.class.php
index 971d92f82ef..878c12edbf4 100644
--- a/lib/models/Course.class.php
+++ b/lib/models/Course.class.php
@@ -1005,4 +1005,13 @@ class Course extends SimpleORMap implements Range, PrivacyObject, StudipItem, Fe
     {
         return array_filter($this->tools->getStudipModule());
     }
+
+
+    /**
+     * @see Range::__toString()
+     */
+    public function __toString() : string
+    {
+        return $this->getFullName();
+    }
 }
diff --git a/lib/models/CourseDate.class.php b/lib/models/CourseDate.class.php
index 3780fc872ad..9060797f8c3 100644
--- a/lib/models/CourseDate.class.php
+++ b/lib/models/CourseDate.class.php
@@ -462,4 +462,19 @@ class CourseDate extends SimpleORMap implements PrivacyObject
             }
         }
     }
+
+
+    /**
+     * @return string A string representation of the course date.
+     */
+    public function __toString() : string
+    {
+        return sprintf(
+            _('Termin am %1$s, %2$s von %3$s bis %4$s Uhr'),
+            strftime('%A', $this->date),
+            strftime('%x', $this->date),
+            date('H:i', $this->date),
+            date('H:i', $this->end_time)
+        );
+    }
 }
diff --git a/lib/models/CourseExDate.class.php b/lib/models/CourseExDate.class.php
index d77a8ca02d5..625653e4139 100644
--- a/lib/models/CourseExDate.class.php
+++ b/lib/models/CourseExDate.class.php
@@ -232,4 +232,19 @@ class CourseExDate extends SimpleORMap implements PrivacyObject
             }
         }
     }
+
+
+    /**
+     * @return string A string representation of the course date.
+     */
+    public function __toString() : string
+    {
+        return sprintf(
+            _('Ausgefallener Termin am %1$s, %2$s von %3$s bis %4$s Uhr'),
+            strftime('%A', $this->date),
+            strftime('%x', $this->date),
+            date('H:i', $this->date),
+            date('H:i', $this->end_time)
+        );
+    }
 }
diff --git a/lib/models/Institute.class.php b/lib/models/Institute.class.php
index 743931c8a14..435fd988103 100644
--- a/lib/models/Institute.class.php
+++ b/lib/models/Institute.class.php
@@ -345,4 +345,13 @@ class Institute extends SimpleORMap implements Range
     {
         return array_filter($this->tools->getStudipModule());
     }
+
+
+    /**
+     * @see Range::__toString()
+     */
+    public function __toString() : string
+    {
+        return $this->getFullName();
+    }
 }
diff --git a/lib/models/User.class.php b/lib/models/User.class.php
index 23756c2dcd1..8760e0cce14 100644
--- a/lib/models/User.class.php
+++ b/lib/models/User.class.php
@@ -1458,4 +1458,13 @@ class User extends AuthUserMd5 implements Range, PrivacyObject
             RolePersistence::expireUserCache($this->user_id);
         }
     }
+
+
+    /**
+     * @see Range::__toString()
+     */
+    public function __toString() : string
+    {
+        return $this->getFullName();
+    }
 }
diff --git a/lib/models/resources/Building.class.php b/lib/models/resources/Building.class.php
index ceda058f212..09c7786bf8d 100644
--- a/lib/models/resources/Building.class.php
+++ b/lib/models/resources/Building.class.php
@@ -203,6 +203,9 @@ class Building extends Resource
         return self::$required_properties;
     }
     
+    /**
+     * @see StudipItem::__toString
+     */
     public function __toString()
     {
         return $this->getFullName();
diff --git a/lib/models/resources/Location.class.php b/lib/models/resources/Location.class.php
index 9191053d955..f380859e0da 100644
--- a/lib/models/resources/Location.class.php
+++ b/lib/models/resources/Location.class.php
@@ -156,6 +156,9 @@ class Location extends Resource
         return self::$required_properties;
     }
     
+    /**
+     * @see StudipItem::__toString
+     */
     public function __toString()
     {
         return $this->getFullName();
diff --git a/lib/models/resources/Resource.class.php b/lib/models/resources/Resource.class.php
index 660b3e87b83..d07d068564d 100644
--- a/lib/models/resources/Resource.class.php
+++ b/lib/models/resources/Resource.class.php
@@ -347,6 +347,10 @@ class Resource extends SimpleORMap implements StudipItem
         return true;
     }
 
+
+    /**
+     * @see StudipItem::__toString
+     */
     public function __toString()
     {
         return $this->getFullName();
diff --git a/lib/models/resources/Room.class.php b/lib/models/resources/Room.class.php
index e5960dbe63b..f0a54b0628c 100644
--- a/lib/models/resources/Room.class.php
+++ b/lib/models/resources/Room.class.php
@@ -519,6 +519,9 @@ class Room extends Resource
     }
 
 
+    /**
+     * @see StudipItem::__toString
+     */
     public function __toString()
     {
         return $this->getFullName();
diff --git a/lib/wiki.inc.php b/lib/wiki.inc.php
index f813d059ea2..9f11672ab5c 100644
--- a/lib/wiki.inc.php
+++ b/lib/wiki.inc.php
@@ -1006,7 +1006,7 @@ function wikiEdit($keyword, $wikiData, $user_id, $backpage=NULL, $ancestor=NULL)
 
     // Action menu for content bar.
     if ($page && $page->isLatestVersion()) {
-        $actionMenu = ActionMenu::get();
+        $actionMenu = ActionMenu::get()->setContext($page->keyword);
         if ($page->isEditableBy($GLOBALS['user'])) {
             if (!$page->isNew()) {
                 $actionMenu->addLink(
@@ -1558,7 +1558,7 @@ function showWikiPage($keyword, $version, $special="", $show_comments="icon", $h
 
     // Action menu for content bar.
     if ($page && $page->isLatestVersion()) {
-        $actionMenu = ActionMenu::get();
+        $actionMenu = ActionMenu::get()->setContext($page->keyword);
         if ($page->isEditableBy($GLOBALS['user'])) {
             if (!$page->isNew()) {
                 $actionMenu->addLink(
diff --git a/resources/assets/javascripts/bootstrap/actionmenu.js b/resources/assets/javascripts/bootstrap/actionmenu.js
index 0c025eeeea9..8c6db2e2c1b 100644
--- a/resources/assets/javascripts/bootstrap/actionmenu.js
+++ b/resources/assets/javascripts/bootstrap/actionmenu.js
@@ -35,4 +35,18 @@
         }
     });
 
+    // Close all action menus when the escape key is pressed and rotate through all its items
+    // when TAB or SHIFT + TAB is pressed.
+    $(document).on('keydown', function(event) {
+        if (event.key === 'Escape') {
+            STUDIP.ActionMenu.closeAll();
+        } else if (event.key === 'Tab') {
+            //Check if the focus is inside an action menu:
+            let menu = $(event.target).closest('nav.action-menu');
+            if (menu.hasClass('is-open') && STUDIP.ActionMenu.tabThroughItems(menu, event.shiftKey)) {
+                event.preventDefault();
+            }
+        }
+    });
+
 }(jQuery));
diff --git a/resources/assets/javascripts/lib/actionmenu.js b/resources/assets/javascripts/lib/actionmenu.js
index 5bfef934e41..bcbdf046eae 100644
--- a/resources/assets/javascripts/lib/actionmenu.js
+++ b/resources/assets/javascripts/lib/actionmenu.js
@@ -224,6 +224,42 @@ class ActionMenu {
             jQuery(element).parent().removeClass('js-action-confirm-animation');
         });
     }
+
+    /**
+     * Handles the rotation through the action menu items when the first
+     * or last element of the menu has been reached.
+     *
+     * @param menu The menu whose items shall be rotated through.
+     *
+     * @param reverse Whether to rotate in reverse (true) or not (false).
+     *     Defaults to false.
+     */
+    static tabThroughItems(menu, reverse = false) {
+        if (reverse) {
+            //Put the focus on the last link in the menu, if the first link has the focus:
+            if (jQuery(menu).find('a:first:focus').length > 0) {
+                //Put the focus on the action menu button:
+                jQuery(menu).find('button.action-menu-icon').focus();
+                return true;
+            } else if (jQuery(menu).find('button.action-menu-icon:focus').length > 0) {
+                //Put the focus on the last action menu item:
+                jQuery(menu).find('a:last').focus();
+                return true;
+            }
+        } else {
+            //Put the focus on the first link in the menu, if the last link has the focus:
+            if (jQuery(menu).find('a:last:focus').length > 0) {
+                //Put the focus on the action menu button:
+                jQuery(menu).find('button.action-menu-icon').focus();
+                return true;
+            }  else if (jQuery(menu).find('button.action-menu-icon:focus').length > 0) {
+                //Put the focus on the first action menu item:
+                jQuery(menu).find('a:first').focus();
+                return true;
+            }
+        }
+        return false;
+    }
 }
 
 export default ActionMenu;
diff --git a/resources/assets/stylesheets/scss/actionmenu.scss b/resources/assets/stylesheets/scss/actionmenu.scss
index f62a515c9fb..9414b6a80ca 100644
--- a/resources/assets/stylesheets/scss/actionmenu.scss
+++ b/resources/assets/stylesheets/scss/actionmenu.scss
@@ -42,6 +42,8 @@ $action-menu-shadow: 1px 1px 1px $dark-gray-color-60;
     .action-menu-icon {
         z-index: 1;
 
+        background: transparent;
+        border: 0;
         position: relative;
         cursor: pointer;
         display: inline-block;
@@ -50,7 +52,7 @@ $action-menu-shadow: 1px 1px 1px $dark-gray-color-60;
         height: 20px;
 
         // Create animated icon that changes to close icon on activation/hover
-        div {
+        span {
             width: ($action-menu-icon-size / 4);
             height: ($action-menu-icon-size / 4);
             transform: translate((-($action-menu-icon-size / 8)), 0);
@@ -144,7 +146,7 @@ $action-menu-shadow: 1px 1px 1px $dark-gray-color-60;
     &.is-open {
         z-index: 3;
         .action-menu-icon {
-            div {
+            span {
                 border-radius: 0;
 
                 &:nth-child(1) {
diff --git a/resources/vue/components/StudipActionMenu.vue b/resources/vue/components/StudipActionMenu.vue
index 14e5517516e..7d8e63434e3 100644
--- a/resources/vue/components/StudipActionMenu.vue
+++ b/resources/vue/components/StudipActionMenu.vue
@@ -1,10 +1,10 @@
 <template>
     <nav v-if="shouldCollapse" class="action-menu">
-        <a class="action-menu-icon" :title="$gettext('Aktionen')" aria-expanded="false" :aria-label="$gettext('Aktionsmenü')" href="#">
-            <div></div>
-            <div></div>
-            <div></div>
-        </a>
+        <button class="action-menu-icon" :title="$gettext('Aktionsmenü')" aria-expanded="false" :aria-label="$gettext('Aktionsmenü')">
+            <span></span>
+            <span></span>
+            <span></span>
+        </button>
         <div class="action-menu-content">
             <div class="action-menu-title">
                 {{ $gettext('Aktionen') }}
diff --git a/resources/vue/components/courseware/CoursewareBlockActions.vue b/resources/vue/components/courseware/CoursewareBlockActions.vue
index e5af4249507..3019e40196d 100755
--- a/resources/vue/components/courseware/CoursewareBlockActions.vue
+++ b/resources/vue/components/courseware/CoursewareBlockActions.vue
@@ -1,8 +1,9 @@
 <template>
     <div class="cw-block-actions">
-        <studip-action-menu 
+        <studip-action-menu
             :items="menuItems"
             collapseAt="2"
+            :context="block.attributes.title"
             @editBlock="editBlock"
             @setVisibility="setVisibility"
             @showInfo="showInfo"
diff --git a/resources/vue/components/courseware/CoursewareStructuralElement.vue b/resources/vue/components/courseware/CoursewareStructuralElement.vue
index 71caff47fcc..137c84fbd17 100755
--- a/resources/vue/components/courseware/CoursewareStructuralElement.vue
+++ b/resources/vue/components/courseware/CoursewareStructuralElement.vue
@@ -49,6 +49,7 @@
                                 v-if="!consumeMode"
                                 :items="menuItems"
                                 class="cw-ribbon-action-menu"
+                                :context="structuralElement.attributes.title"
                                 @editCurrentElement="menuAction('editCurrentElement')"
                                 @addElement="menuAction('addElement')"
                                 @deleteCurrentElement="menuAction('deleteCurrentElement')"
diff --git a/templates/shared/action-menu.php b/templates/shared/action-menu.php
index 9c3bf1ddf67..1b3fb066fa5 100644
--- a/templates/shared/action-menu.php
+++ b/templates/shared/action-menu.php
@@ -1,10 +1,10 @@
 <? // class "action-menu" will be set from API ?>
 <nav <?= arrayToHtmlAttributes($attributes) ?> aria-role="presentation">
-    <a class="action-menu-icon" aria-role="button" aria-expanded="false" title="<?= _('Aktionsmenü') ?>" href="#">
-        <div></div>
-        <div></div>
-        <div></div>
-    </a>
+    <button class="action-menu-icon" aria-role="button" aria-expanded="false" title="<?= htmlReady($action_menu_title) ?>">
+        <span></span>
+        <span></span>
+        <span></span>
+    </button>
     <div class="action-menu-content">
         <div class="action-menu-title" aria-hidden="true">
             <?= _('Aktionen') ?>
diff --git a/templates/sidebar/room-clipboard-item.php b/templates/sidebar/room-clipboard-item.php
index c7d5734d262..994713c6cdd 100644
--- a/templates/sidebar/room-clipboard-item.php
+++ b/templates/sidebar/room-clipboard-item.php
@@ -48,7 +48,7 @@ if (!$item) {
     </td>
     <td class="item-actions">
         <?
-        $actions = ActionMenu::get();
+        $actions = ActionMenu::get()->setContext($item['name'] ?: '');
         $actions->addLink(
             Room::getLinkForAction(
                 'show',
-- 
GitLab