mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Log statistics for usage and interactions of bookmarks and favorites
GitOrigin-RevId: e7ea46fbf93da339464dbdf93e086e7120c5c055
This commit is contained in:
committed by
intellij-monorepo-bot
parent
07453d0303
commit
0eac6d25ad
@@ -0,0 +1,32 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ide
|
||||
|
||||
import com.intellij.pom.Navigatable
|
||||
import com.intellij.pom.NavigatableWithText
|
||||
import com.intellij.util.containers.map2Array
|
||||
|
||||
class NavigatableInterceptor(val baseNavigatable: Navigatable, val callback: (Navigatable, Boolean) -> Unit) : NavigatableWithText {
|
||||
override fun navigate(requestFocus: Boolean) {
|
||||
callback(baseNavigatable, requestFocus)
|
||||
baseNavigatable.navigate(requestFocus)
|
||||
}
|
||||
|
||||
override fun canNavigate(): Boolean {
|
||||
return baseNavigatable.canNavigate()
|
||||
}
|
||||
|
||||
override fun canNavigateToSource(): Boolean {
|
||||
return baseNavigatable.canNavigateToSource()
|
||||
}
|
||||
|
||||
override fun getNavigateActionText(focusEditor: Boolean): String? {
|
||||
return (baseNavigatable as? NavigatableWithText)?.getNavigateActionText(focusEditor)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun wrap(navigatables: Array<Navigatable>, callback: (Navigatable, Boolean) -> Unit): Array<NavigatableInterceptor> {
|
||||
return navigatables.map2Array { NavigatableInterceptor(it, callback) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,6 +213,10 @@ public final class BookmarkManager implements PersistentStateComponent<Element>
|
||||
return answer;
|
||||
}
|
||||
|
||||
public Collection<Bookmark> getAllBookmarks() {
|
||||
return myBookmarks.values();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Bookmark findEditorBookmark(@NotNull Document document, int line) {
|
||||
VirtualFile file = FileDocumentManager.getInstance().getFile(document);
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.intellij.ide.bookmarks.Bookmark;
|
||||
import com.intellij.ide.bookmarks.BookmarkItem;
|
||||
import com.intellij.ide.bookmarks.BookmarkManager;
|
||||
import com.intellij.ide.bookmarks.BookmarksListener;
|
||||
import com.intellij.internal.statistic.BookmarkCounterCollector;
|
||||
import com.intellij.lang.LangBundle;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
@@ -161,10 +162,11 @@ public class BookmarksAction extends AnAction implements DumbAware, MasterDetail
|
||||
|
||||
@Override
|
||||
public void handleMnemonic(KeyEvent e, Project project, JBPopup popup) {
|
||||
char mnemonic = e.getKeyChar();
|
||||
char mnemonic = Character.toUpperCase(e.getKeyChar());
|
||||
final Bookmark bookmark = BookmarkManager.getInstance(project).findBookmarkForMnemonic(mnemonic);
|
||||
if (bookmark != null) {
|
||||
popup.cancel();
|
||||
BookmarkCounterCollector.bookmarkNavigate.log(mnemonic >= '0' && mnemonic <= '9', mnemonic >= 'A' && mnemonic <= 'Z', bookmark.getLine() >= 0);
|
||||
IdeFocusManager.getInstance(project).doWhenFocusSettlesDown(() -> bookmark.navigate(true));
|
||||
}
|
||||
}
|
||||
@@ -205,6 +207,7 @@ public class BookmarksAction extends AnAction implements DumbAware, MasterDetail
|
||||
if (item instanceof BookmarkItem && withEnterOrDoubleClick) {
|
||||
Bookmark bookmark = ((BookmarkItem)item).getBookmark();
|
||||
popup.cancel();
|
||||
BookmarkCounterCollector.bookmarkNavigate.log(false, false, bookmark.getLine() >= 0);
|
||||
bookmark.navigate(true);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-16
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.ide.favoritesTreeView;
|
||||
|
||||
@@ -48,7 +34,7 @@ public class AbstractUrlFavoriteAdapter extends AbstractUrl {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
FavoriteNodeProvider getNodeProvider() {
|
||||
public FavoriteNodeProvider getNodeProvider() {
|
||||
return myNodeProvider;
|
||||
}
|
||||
}
|
||||
|
||||
+10
-2
@@ -4,6 +4,7 @@ package com.intellij.ide.favoritesTreeView;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.CopyPasteDelegator;
|
||||
import com.intellij.ide.IdeView;
|
||||
import com.intellij.ide.NavigatableInterceptor;
|
||||
import com.intellij.ide.bookmarks.Bookmark;
|
||||
import com.intellij.ide.dnd.aware.DnDAwareTree;
|
||||
import com.intellij.ide.favoritesTreeView.actions.*;
|
||||
@@ -17,6 +18,7 @@ import com.intellij.ide.util.DirectoryChooserUtil;
|
||||
import com.intellij.ide.util.EditorHelper;
|
||||
import com.intellij.ide.util.treeView.AbstractTreeNode;
|
||||
import com.intellij.ide.util.treeView.NodeRenderer;
|
||||
import com.intellij.internal.statistic.BookmarkCounterCollector;
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -43,6 +45,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.JBIterable;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.tree.TreeUtil;
|
||||
import kotlin.Unit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -282,7 +285,7 @@ public final class FavoritesTreeViewPanel extends JPanel implements DataProvider
|
||||
}
|
||||
if (CommonDataKeys.NAVIGATABLE.is(dataId)) {
|
||||
final FavoriteTreeNodeDescriptor[] selectedNodeDescriptors = FavoritesTreeUtil.getSelectedNodeDescriptors(myTree);
|
||||
return selectedNodeDescriptors.length == 1 ? selectedNodeDescriptors[0].getElement() : null;
|
||||
return selectedNodeDescriptors.length == 1 ? new NavigatableInterceptor(selectedNodeDescriptors[0].getElement(), this::logNavigation) : null;
|
||||
}
|
||||
FavoritesManager favoriteManager = FavoritesManager.getInstance(myProject);
|
||||
if (CommonDataKeys.NAVIGATABLE_ARRAY.is(dataId)) {
|
||||
@@ -292,7 +295,7 @@ public final class FavoritesTreeViewPanel extends JPanel implements DataProvider
|
||||
selectedElements.addAll(ContainerUtil.map(favoriteManager.getVirtualFiles(listname, false), file -> new OpenFileDescriptor(myProject, file)));
|
||||
}
|
||||
selectedElements.addAll(getSelectedElements(Navigatable.class));
|
||||
return selectedElements.isEmpty() ? null : selectedElements.toArray(new Navigatable[0]);
|
||||
return selectedElements.isEmpty() ? null : NavigatableInterceptor.wrap(selectedElements.toArray(new Navigatable[0]), this::logNavigation);
|
||||
}
|
||||
|
||||
if (PlatformDataKeys.CUT_PROVIDER.is(dataId)) {
|
||||
@@ -401,6 +404,11 @@ public final class FavoritesTreeViewPanel extends JPanel implements DataProvider
|
||||
return null;
|
||||
}
|
||||
|
||||
private Unit logNavigation(Navigatable navigatable, Boolean focusEditor) {
|
||||
BookmarkCounterCollector.favoritesNavigate.log(myProject, navigatable.getClass());
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
|
||||
private <T> List<T> getSelectedElements(Class<T> klass) {
|
||||
final Object[] elements = getSelectedNodeElements();
|
||||
ArrayList<T> result = new ArrayList<>();
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.internal.statistic
|
||||
|
||||
import com.intellij.ide.bookmarks.BookmarkManager
|
||||
import com.intellij.ide.favoritesTreeView.AbstractUrlFavoriteAdapter
|
||||
import com.intellij.ide.favoritesTreeView.FavoriteNodeProvider
|
||||
import com.intellij.ide.favoritesTreeView.FavoritesManager
|
||||
import com.intellij.ide.projectView.impl.DirectoryUrl
|
||||
import com.intellij.ide.projectView.impl.PsiFileUrl
|
||||
import com.intellij.internal.statistic.beans.MetricEvent
|
||||
import com.intellij.internal.statistic.eventLog.EventLogGroup
|
||||
import com.intellij.internal.statistic.eventLog.events.EventFields
|
||||
import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesCollector
|
||||
import com.intellij.internal.statistic.service.fus.collectors.ProjectUsagesCollector
|
||||
import com.intellij.openapi.project.Project
|
||||
|
||||
class BookmarkUsagesCollector : ProjectUsagesCollector() {
|
||||
private val group: EventLogGroup = EventLogGroup("bookmarks", 1)
|
||||
|
||||
private val bookmarksTotal = group.registerEvent("bookmarks.total", EventFields.Count)
|
||||
private val bookmarksWithLine = group.registerEvent("bookmarks.with.line", EventFields.Count)
|
||||
private val bookmarksWithNumber = group.registerEvent("bookmarks.with.number.mnemonic", EventFields.Count)
|
||||
private val bookmarksWithLetter = group.registerEvent("bookmarks.with.letter.mnemonic", EventFields.Count)
|
||||
|
||||
private val favoritesLists = group.registerEvent("favorites.lists", EventFields.Count)
|
||||
private val favoritesTotal = group.registerEvent("favorites.total", EventFields.Count)
|
||||
private val favoriteFiles = group.registerEvent("favorites.files", EventFields.Count)
|
||||
private val favoriteDirectories = group.registerEvent("favorites.directories", EventFields.Count)
|
||||
private val favoriteCustom = group.registerEvent("favorites.custom", EventFields.Count,
|
||||
EventFields.StringValidatedByCustomRule("type", "favorite_type"),
|
||||
EventFields.PluginInfoFromInstance)
|
||||
|
||||
override fun getGroup(): EventLogGroup {
|
||||
return group
|
||||
}
|
||||
|
||||
override fun getMetrics(project: Project): MutableSet<MetricEvent> {
|
||||
val result = mutableSetOf<MetricEvent>()
|
||||
|
||||
val bookmarkManager = BookmarkManager.getInstance(project)
|
||||
val bookmarks = bookmarkManager.allBookmarks
|
||||
|
||||
result += bookmarksTotal.metric(bookmarks.size)
|
||||
result += bookmarksWithLine.metric(bookmarks.filter { it.line >= 0 }.size)
|
||||
result += bookmarksWithNumber.metric(bookmarks.filter { it.mnemonic in '0'..'9' }.size)
|
||||
result += bookmarksWithLetter.metric(bookmarks.filter { it.mnemonic in 'A'..'Z' }.size)
|
||||
|
||||
val favoritesManager = FavoritesManager.getInstance(project)
|
||||
val listNames = favoritesManager.availableFavoritesListNames
|
||||
result += favoritesLists.metric(listNames.size)
|
||||
|
||||
var favTotal = 0
|
||||
var favFiles = 0
|
||||
var favDirectories = 0
|
||||
val favCustom = mutableMapOf<String, Int>()
|
||||
val favCustomProviders = mutableMapOf<String, FavoriteNodeProvider>()
|
||||
for (listName in listNames) {
|
||||
val urls = favoritesManager.getFavoritesListRootUrls(listName)
|
||||
favTotal += urls.size
|
||||
for (url in urls) {
|
||||
when (val abstractUrl = url.data.first) {
|
||||
is PsiFileUrl -> favFiles++
|
||||
is DirectoryUrl -> favDirectories++
|
||||
is AbstractUrlFavoriteAdapter -> {
|
||||
val type = abstractUrl.nodeProvider.favoriteTypeId
|
||||
val count = favCustom.getOrPut(type) { 0 }
|
||||
favCustom[type] = count + 1
|
||||
favCustomProviders[type] = abstractUrl.nodeProvider
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result += favoritesTotal.metric(favTotal)
|
||||
result += favoriteFiles.metric(favFiles)
|
||||
result += favoriteDirectories.metric(favDirectories)
|
||||
for ((type, count) in favCustom) {
|
||||
result += favoriteCustom.metric(count, type, favCustomProviders[type]!!)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
class BookmarkCounterCollector : CounterUsagesCollector() {
|
||||
companion object {
|
||||
private val group: EventLogGroup = EventLogGroup("bookmarks.counters", 1)
|
||||
|
||||
@JvmField
|
||||
val favoritesNavigate = group.registerEvent("favorites.navigate", EventFields.Class("navigatable"))
|
||||
@JvmField
|
||||
val bookmarkNavigate = group.registerEvent("bookmark.navigate",
|
||||
EventFields.Boolean("numberMnemonicUsed"),
|
||||
EventFields.Boolean("letterMnemonicUsed"),
|
||||
EventFields.Boolean("withLine"));
|
||||
}
|
||||
|
||||
override fun getGroup(): EventLogGroup = Companion.group
|
||||
}
|
||||
@@ -1007,6 +1007,8 @@
|
||||
<statistics.projectUsagesCollector implementation="com.intellij.codeInsight.hints.InlayProviderUsageCollector"/>
|
||||
<statistics.projectUsagesCollector implementation="com.intellij.codeInsight.daemon.impl.analysis.HighlightingSettingsPerFileCollector"/>
|
||||
<statistics.projectUsagesCollector implementation="com.intellij.ui.tabs.FileColorsUsagesCollector"/>
|
||||
<statistics.projectUsagesCollector implementation="com.intellij.internal.statistic.BookmarkUsagesCollector"/>
|
||||
<statistics.counterUsagesCollector implementationClass="com.intellij.internal.statistic.BookmarkCounterCollector"/>
|
||||
|
||||
<statistics.counterUsagesCollector groupId="searchEverywhere" version="4"/>
|
||||
<statistics.counterUsagesCollector groupId="actions.runAnything" version="1"/>
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.internal.statistic.collectors.fus
|
||||
|
||||
import com.intellij.internal.statistic.eventLog.validator.ValidationResultType
|
||||
@@ -13,6 +13,6 @@ class PluginInfoValidationRule : CustomValidationRule() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val acceptedRules = hashSetOf("plugin_info", "project_type", "framework", "gutter_icon", "editor_notification_panel_key", "plugin_version")
|
||||
private val acceptedRules = hashSetOf("plugin_info", "project_type", "framework", "gutter_icon", "editor_notification_panel_key", "plugin_version", "favorite_type")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user