inial commit
This commit is contained in:
37
CMakeLists.txt
Normal file
37
CMakeLists.txt
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
|
||||||
|
|
||||||
|
project(kateai VERSION 0.1)
|
||||||
|
|
||||||
|
set(KF5_DEP_VERSION "5.111.0")
|
||||||
|
|
||||||
|
find_package(ECM ${KF5_DEP_VERSION} QUIET REQUIRED NO_MODULE)
|
||||||
|
list(APPEND CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
|
||||||
|
|
||||||
|
include(KDECompilerSettings NO_POLICY_SCOPE)
|
||||||
|
include(KDEInstallDirs)
|
||||||
|
include(KDECMakeSettings)
|
||||||
|
include(KDEClangFormat)
|
||||||
|
include(KDEGitCommitHooks)
|
||||||
|
|
||||||
|
include(ECMOptionalAddSubdirectory)
|
||||||
|
include(ECMAddAppIcon)
|
||||||
|
include(ECMInstallIcons)
|
||||||
|
include(ECMDeprecationSettings)
|
||||||
|
|
||||||
|
find_package(Qt5Widgets CONFIG REQUIRED)
|
||||||
|
find_package(KF5
|
||||||
|
REQUIRED COMPONENTS
|
||||||
|
CoreAddons
|
||||||
|
GuiAddons
|
||||||
|
TextEditor
|
||||||
|
)
|
||||||
|
|
||||||
|
kcoreaddons_add_plugin(${PROJECT_NAME} INSTALL_NAMESPACE "kf5/ktexteditor")
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE KF5::TextEditor)
|
||||||
|
target_sources(
|
||||||
|
${PROJECT_NAME}
|
||||||
|
PRIVATE
|
||||||
|
katecolorpickerplugin.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
|
302
katecolorpickerplugin.cpp
Normal file
302
katecolorpickerplugin.cpp
Normal file
@ -0,0 +1,302 @@
|
|||||||
|
/*
|
||||||
|
SPDX-FileCopyrightText: 2018 Sven Brauch <mail@svenbrauch.de>
|
||||||
|
SPDX-FileCopyrightText: 2018 Michal Srb <michalsrb@gmail.com>
|
||||||
|
SPDX-FileCopyrightText: 2020 Jan Paul Batrina <jpmbatrina01@gmail.com>
|
||||||
|
SPDX-FileCopyrightText: 2021 Dominik Haumann <dhaumann@kde.org>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "katecolorpickerplugin.h"
|
||||||
|
|
||||||
|
#include <KConfigGroup>
|
||||||
|
#include <KLocalizedString>
|
||||||
|
#include <KPluginFactory>
|
||||||
|
#include <KSharedConfig>
|
||||||
|
#include <KTextEditor/Document>
|
||||||
|
#include <KTextEditor/View>
|
||||||
|
#include <KTextEditor/InlineNoteInterface>
|
||||||
|
|
||||||
|
#include <QColor>
|
||||||
|
#include <QColorDialog>
|
||||||
|
#include <QFontMetricsF>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
|
ColorPickerInlineNoteProvider::ColorPickerInlineNoteProvider(KTextEditor::Document *doc)
|
||||||
|
: m_doc(doc)
|
||||||
|
{
|
||||||
|
// initialize the color regex
|
||||||
|
m_colorRegex.setPatternOptions(QRegularExpression::DontCaptureOption | QRegularExpression::CaseInsensitiveOption);
|
||||||
|
updateColorMatchingCriteria();
|
||||||
|
|
||||||
|
const auto views = m_doc->views();
|
||||||
|
for (auto view : views) {
|
||||||
|
qobject_cast<KTextEditor::InlineNoteInterface *>(view)->registerInlineNoteProvider(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(m_doc, &KTextEditor::Document::viewCreated, this, [this](KTextEditor::Document *, KTextEditor::View *view) {
|
||||||
|
qobject_cast<KTextEditor::InlineNoteInterface *>(view)->registerInlineNoteProvider(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
auto lineChanged = [this](const int line) {
|
||||||
|
if (m_startChangedLines == -1 || m_endChangedLines == -1) {
|
||||||
|
m_startChangedLines = line;
|
||||||
|
// changed line is directly above/below the previous changed line, so we just update them
|
||||||
|
} else if (line == m_endChangedLines) { // handled below. Condition added here to avoid fallthrough
|
||||||
|
} else if (line == m_startChangedLines - 1) {
|
||||||
|
m_startChangedLines = line;
|
||||||
|
} else if (line < m_startChangedLines || line > m_endChangedLines) {
|
||||||
|
// changed line is outside the range of previous changes. Change proably skipped lines
|
||||||
|
updateNotes(m_startChangedLines, m_endChangedLines);
|
||||||
|
m_startChangedLines = line;
|
||||||
|
m_endChangedLines = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_endChangedLines = line >= m_endChangedLines ? line + 1 : m_endChangedLines;
|
||||||
|
};
|
||||||
|
|
||||||
|
// textInserted and textRemoved are emitted per line, then the last line is followed by a textChanged signal
|
||||||
|
connect(m_doc, &KTextEditor::Document::textInserted, this, [lineChanged](KTextEditor::Document *, const KTextEditor::Cursor &cur, const QString &) {
|
||||||
|
lineChanged(cur.line());
|
||||||
|
});
|
||||||
|
connect(m_doc, &KTextEditor::Document::textRemoved, this, [lineChanged](KTextEditor::Document *, const KTextEditor::Range &range, const QString &) {
|
||||||
|
lineChanged(range.start().line());
|
||||||
|
});
|
||||||
|
connect(m_doc, &KTextEditor::Document::textChanged, this, [this](KTextEditor::Document *) {
|
||||||
|
int newNumLines = m_doc->lines();
|
||||||
|
if (m_startChangedLines == -1) {
|
||||||
|
// textChanged not preceded by textInserted or textRemoved. This probably means that either:
|
||||||
|
// *empty line(s) were inserted/removed (TODO: Update only the lines directly below the removed/inserted empty line(s))
|
||||||
|
// *the document is newly opened so we update all lines
|
||||||
|
updateNotes();
|
||||||
|
} else {
|
||||||
|
if (m_previousNumLines != newNumLines) {
|
||||||
|
// either whole line(s) were removed or inserted. We update all lines (even those that are now non-existent) below m_startChangedLines
|
||||||
|
m_endChangedLines = newNumLines > m_previousNumLines ? newNumLines : m_previousNumLines;
|
||||||
|
}
|
||||||
|
updateNotes(m_startChangedLines, m_endChangedLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_startChangedLines = -1;
|
||||||
|
m_endChangedLines = -1;
|
||||||
|
m_previousNumLines = newNumLines;
|
||||||
|
});
|
||||||
|
|
||||||
|
updateNotes();
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorPickerInlineNoteProvider::~ColorPickerInlineNoteProvider()
|
||||||
|
{
|
||||||
|
QPointer<KTextEditor::Document> doc = m_doc;
|
||||||
|
if (doc) {
|
||||||
|
const auto views = m_doc->views();
|
||||||
|
for (auto view : views) {
|
||||||
|
qobject_cast<KTextEditor::InlineNoteInterface *>(view)->unregisterInlineNoteProvider(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorPickerInlineNoteProvider::updateColorMatchingCriteria()
|
||||||
|
{
|
||||||
|
KConfigGroup config(KSharedConfig::openConfig(), "ColorPicker");
|
||||||
|
m_matchHexLengths = config.readEntry("HexLengths", QList<int>{12, 9, 6, 3}).toVector();
|
||||||
|
m_putPreviewAfterColor = config.readEntry("PreviewAfterColor", true);
|
||||||
|
m_matchNamedColors = config.readEntry("NamedColors", false);
|
||||||
|
|
||||||
|
QString colorRegex;
|
||||||
|
if (m_matchHexLengths.size() > 0) {
|
||||||
|
colorRegex += QLatin1String("(#[[:xdigit:]]{3,12})");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_matchNamedColors) {
|
||||||
|
if (!colorRegex.isEmpty()) {
|
||||||
|
colorRegex += QLatin1Char('|');
|
||||||
|
}
|
||||||
|
// shortest and longest colors have 3 (e.g. red) and 20 (lightgoldenrodyellow) characters respectively
|
||||||
|
colorRegex += QLatin1String("((?<![\\w])[a-z]{3,20})");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!colorRegex.isEmpty()) {
|
||||||
|
colorRegex = QStringLiteral("(?<![-])(%1)(?![-\\w])").arg(colorRegex);
|
||||||
|
} else {
|
||||||
|
// No matching criteria enabled. Set regex to negative lookahead to match nothing.
|
||||||
|
colorRegex = QLatin1String("(?!)");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_colorRegex.setPattern(colorRegex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorPickerInlineNoteProvider::updateNotes(int startLine, int endLine)
|
||||||
|
{
|
||||||
|
if (m_colorNoteIndices.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
startLine = startLine < -1 ? -1 : startLine;
|
||||||
|
if (startLine == -1) {
|
||||||
|
startLine = 0;
|
||||||
|
// we use whichever of newNumLines and m_previousNumLines are longer so that note indices for non-existent lines are also removed
|
||||||
|
const int lastLine = m_doc->lines();
|
||||||
|
endLine = lastLine > m_previousNumLines ? lastLine : m_previousNumLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endLine == -1) {
|
||||||
|
endLine = startLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int line = startLine; line < endLine; ++line) {
|
||||||
|
int removed = m_colorNoteIndices.remove(line);
|
||||||
|
if (removed != 0) {
|
||||||
|
Q_EMIT inlineNotesChanged(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<int> ColorPickerInlineNoteProvider::inlineNotes(int line) const
|
||||||
|
{
|
||||||
|
if (!m_colorNoteIndices.contains(line)) {
|
||||||
|
const QString lineText = m_doc->line(line);
|
||||||
|
auto matchIter = m_colorRegex.globalMatch(lineText);
|
||||||
|
while (matchIter.hasNext()) {
|
||||||
|
const auto match = matchIter.next();
|
||||||
|
if (!QColor(match.captured()).isValid()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lineText.at(match.capturedStart()) == QLatin1Char('#') && !m_matchHexLengths.contains(match.capturedLength() - 1)) {
|
||||||
|
// matching for this hex color format is disabled
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int start = match.capturedStart();
|
||||||
|
int end = start + match.capturedLength();
|
||||||
|
if (m_putPreviewAfterColor) {
|
||||||
|
start = end;
|
||||||
|
end = match.capturedStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &colorIndices = m_colorNoteIndices[line];
|
||||||
|
colorIndices.colorNoteIndices.append(start);
|
||||||
|
colorIndices.otherColorIndices.append(end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_colorNoteIndices[line].colorNoteIndices;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize ColorPickerInlineNoteProvider::inlineNoteSize(const KTextEditor::InlineNote ¬e) const
|
||||||
|
{
|
||||||
|
return QSize(note.lineHeight() - 1, note.lineHeight() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorPickerInlineNoteProvider::paintInlineNote(const KTextEditor::InlineNote ¬e, QPainter &painter) const
|
||||||
|
{
|
||||||
|
const auto line = note.position().line();
|
||||||
|
auto colorEnd = note.position().column();
|
||||||
|
|
||||||
|
const QVector<int> &colorNoteIndices = m_colorNoteIndices[line].colorNoteIndices;
|
||||||
|
// Since the colorNoteIndices are inserted in left-to-right (increasing) order in inlineNotes(), we can use binary search to find the index (or color note
|
||||||
|
// number) for the line
|
||||||
|
const int colorNoteNumber = std::lower_bound(colorNoteIndices.cbegin(), colorNoteIndices.cend(), colorEnd) - colorNoteIndices.cbegin();
|
||||||
|
auto colorStart = m_colorNoteIndices[line].otherColorIndices[colorNoteNumber];
|
||||||
|
|
||||||
|
if (colorStart > colorEnd) {
|
||||||
|
colorEnd = colorStart;
|
||||||
|
colorStart = note.position().column();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto color = QColor(m_doc->text({line, colorStart, line, colorEnd}));
|
||||||
|
// ensure that the border color is always visible
|
||||||
|
QColor penColor = color;
|
||||||
|
penColor.setAlpha(255);
|
||||||
|
painter.setPen(penColor.value() < 128 ? penColor.lighter(150) : penColor.darker(150));
|
||||||
|
|
||||||
|
painter.setBrush(color);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing, false);
|
||||||
|
const QFontMetricsF fm(note.font());
|
||||||
|
const int inc = note.underMouse() ? 1 : 0;
|
||||||
|
const int ascent = fm.ascent();
|
||||||
|
const int margin = (note.lineHeight() - ascent) / 2;
|
||||||
|
painter.drawRect(margin - inc, margin - inc, ascent - 1 + 2 * inc, ascent - 1 + 2 * inc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorPickerInlineNoteProvider::inlineNoteActivated(const KTextEditor::InlineNote ¬e, Qt::MouseButtons, const QPoint &)
|
||||||
|
{
|
||||||
|
const auto line = note.position().line();
|
||||||
|
auto colorEnd = note.position().column();
|
||||||
|
|
||||||
|
const QVector<int> &colorNoteIndices = m_colorNoteIndices[line].colorNoteIndices;
|
||||||
|
// Since the colorNoteIndices are inserted in left-to-right (increasing) order in inlineNotes, we can use binary search to find the index (or color note
|
||||||
|
// number) for the line
|
||||||
|
const int colorNoteNumber = std::lower_bound(colorNoteIndices.cbegin(), colorNoteIndices.cend(), colorEnd) - colorNoteIndices.cbegin();
|
||||||
|
auto colorStart = m_colorNoteIndices[line].otherColorIndices[colorNoteNumber];
|
||||||
|
if (colorStart > colorEnd) {
|
||||||
|
colorEnd = colorStart;
|
||||||
|
colorStart = note.position().column();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto oldColor = QColor(m_doc->text({line, colorStart, line, colorEnd}));
|
||||||
|
QColorDialog::ColorDialogOptions dialogOptions = QColorDialog::ShowAlphaChannel;
|
||||||
|
QString title = i18n("Select Color (Hex output)");
|
||||||
|
if (!m_doc->isReadWrite()) {
|
||||||
|
dialogOptions |= QColorDialog::NoButtons;
|
||||||
|
title = i18n("View Color [Read only]");
|
||||||
|
}
|
||||||
|
const QColor newColor = QColorDialog::getColor(oldColor, const_cast<KTextEditor::View *>(note.view()), title, dialogOptions);
|
||||||
|
if (!newColor.isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// include alpha channel if the new color has transparency or the old color included transparency (#AARRGGBB, 9 hex digits)
|
||||||
|
auto colorNameFormat = (newColor.alpha() != 255 || colorEnd - colorStart == 9) ? QColor::HexArgb : QColor::HexRgb;
|
||||||
|
m_doc->replaceText({line, colorStart, line, colorEnd}, newColor.name(colorNameFormat));
|
||||||
|
}
|
||||||
|
|
||||||
|
K_PLUGIN_FACTORY_WITH_JSON(KateColorPickerPluginFactory, "katecolorpickerplugin.json", registerPlugin<KateColorPickerPlugin>();)
|
||||||
|
|
||||||
|
KateColorPickerPlugin::KateColorPickerPlugin(QObject *parent, const QList<QVariant> &)
|
||||||
|
: KTextEditor::Plugin(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
KateColorPickerPlugin::~KateColorPickerPlugin() = default;
|
||||||
|
|
||||||
|
QObject *KateColorPickerPlugin::createView(KTextEditor::MainWindow *mainWindow)
|
||||||
|
{
|
||||||
|
m_mainWindow = mainWindow;
|
||||||
|
const auto views = m_mainWindow->views();
|
||||||
|
for (auto view : views) {
|
||||||
|
addDocument(view->document());
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(m_mainWindow, &KTextEditor::MainWindow::viewCreated, this, [this](KTextEditor::View *view) {
|
||||||
|
addDocument(view->document());
|
||||||
|
});
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KateColorPickerPlugin::addDocument(KTextEditor::Document *doc)
|
||||||
|
{
|
||||||
|
if (m_inlineColorNoteProviders.find(doc) == m_inlineColorNoteProviders.end()) {
|
||||||
|
m_inlineColorNoteProviders.emplace(doc, new ColorPickerInlineNoteProvider(doc));
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(doc, &KTextEditor::Document::aboutToClose, this, [this, doc]() {
|
||||||
|
m_inlineColorNoteProviders.erase(doc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void KateColorPickerPlugin::readConfig()
|
||||||
|
{
|
||||||
|
for (const auto &[doc, colorNoteProvider] : m_inlineColorNoteProviders) {
|
||||||
|
Q_UNUSED(doc)
|
||||||
|
colorNoteProvider->updateColorMatchingCriteria();
|
||||||
|
colorNoteProvider->updateNotes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "katecolorpickerplugin.moc"
|
||||||
|
#include "moc_katecolorpickerplugin.cpp"
|
81
katecolorpickerplugin.h
Normal file
81
katecolorpickerplugin.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
SPDX-FileCopyrightText: 2018 Sven Brauch <mail@svenbrauch.de>
|
||||||
|
SPDX-FileCopyrightText: 2018 Michal Srb <michalsrb@gmail.com>
|
||||||
|
SPDX-FileCopyrightText: 2020 Jan Paul Batrina <jpmbatrina01@gmail.com>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include <KTextEditor/ConfigPage>
|
||||||
|
#include <KTextEditor/InlineNoteProvider>
|
||||||
|
#include <KTextEditor/MainWindow>
|
||||||
|
#include <KTextEditor/Plugin>
|
||||||
|
|
||||||
|
#include <QHash>
|
||||||
|
#include <QList>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
|
class ColorPickerInlineNoteProvider : public KTextEditor::InlineNoteProvider
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ColorPickerInlineNoteProvider(KTextEditor::Document *doc);
|
||||||
|
~ColorPickerInlineNoteProvider() override;
|
||||||
|
|
||||||
|
void updateColorMatchingCriteria();
|
||||||
|
// if startLine == -1, update all notes. endLine is optional
|
||||||
|
void updateNotes(int startLine = -1, int endLine = -1);
|
||||||
|
|
||||||
|
QVector<int> inlineNotes(int line) const override;
|
||||||
|
QSize inlineNoteSize(const KTextEditor::InlineNote ¬e) const override;
|
||||||
|
void paintInlineNote(const KTextEditor::InlineNote ¬e, QPainter &painter) const override;
|
||||||
|
void inlineNoteActivated(const KTextEditor::InlineNote ¬e, Qt::MouseButtons buttons, const QPoint &globalPos) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
KTextEditor::Document *m_doc;
|
||||||
|
int m_startChangedLines = -1;
|
||||||
|
int m_endChangedLines = -1;
|
||||||
|
int m_previousNumLines = -1;
|
||||||
|
|
||||||
|
struct ColorIndices {
|
||||||
|
// When m_putPreviewAfterColor is true, otherColorIndices holds the starting color indices while colorNoteIndices holds the end color indices (and vice
|
||||||
|
// versa) colorNoteIndices[i] corresponds to otherColorIndices[i]
|
||||||
|
QVector<int> colorNoteIndices;
|
||||||
|
QVector<int> otherColorIndices;
|
||||||
|
};
|
||||||
|
|
||||||
|
// mutable is used here since InlineNoteProvider::inlineNotes() is const only, and we update the notes lazily (only when inlineNotes() is called)
|
||||||
|
mutable QHash<int, ColorIndices> m_colorNoteIndices;
|
||||||
|
|
||||||
|
QRegularExpression m_colorRegex;
|
||||||
|
QVector<int> m_matchHexLengths;
|
||||||
|
bool m_putPreviewAfterColor;
|
||||||
|
bool m_matchNamedColors;
|
||||||
|
};
|
||||||
|
|
||||||
|
class KateColorPickerPlugin : public KTextEditor::Plugin
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit KateColorPickerPlugin(QObject *parent = nullptr, const QList<QVariant> & = QList<QVariant>());
|
||||||
|
~KateColorPickerPlugin() override;
|
||||||
|
|
||||||
|
QObject *createView(KTextEditor::MainWindow *mainWindow) override;
|
||||||
|
void readConfig();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void addDocument(KTextEditor::Document *doc);
|
||||||
|
|
||||||
|
int configPages() const override
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
KTextEditor::MainWindow *m_mainWindow;
|
||||||
|
std::unordered_map<KTextEditor::Document *, std::unique_ptr<ColorPickerInlineNoteProvider>> m_inlineColorNoteProviders;
|
||||||
|
};
|
75
katecolorpickerplugin.json
Normal file
75
katecolorpickerplugin.json
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
{
|
||||||
|
"KPlugin": {
|
||||||
|
"Description": "Adds an inline Color preview/picker to colors in the text (e.g. #FFFFFF, white)",
|
||||||
|
"Description[az]": "Mətndəki sətirdaxili rəng önizləməsi əlavə edir/mətndəki rəngləri seçə vasitəsi (məs., #FFFFFF, ağ rəng)",
|
||||||
|
"Description[bg]": "Добавя възможност за преглед и избор на цвят в текста (напр.. #FFFFFF, бял)",
|
||||||
|
"Description[ca@valencia]": "Afig una vista prèvia/selector de colors inclòs per als colors del text (p. ex., #FFFFFF, blanc)",
|
||||||
|
"Description[ca]": "Afegeix una vista prèvia/selector de colors inclòs per als colors del text (p. ex., #FFFFFF, blanc)",
|
||||||
|
"Description[de]": "Fügt eine Farbvorschau/Farbauswahl für Farben wie #FFFFFF, white am Zeilenende ein",
|
||||||
|
"Description[el]": "Προσθέτει ένα εμβόλιμο εργαλείο προεπισκόπησης/επιλογής χρώματος στα χρώματα του κειμένου (π.χ. #FFFFFF, λευκό)",
|
||||||
|
"Description[en_GB]": "Adds an inline Colour preview/picker to colours in the text (e.g. #FFFFFF, white)",
|
||||||
|
"Description[eo]": "Aldonas enlinian Koloran antaŭrigardon/elektilon al koloroj en la teksto (ekz. #FFFFFF, blanka)",
|
||||||
|
"Description[es]": "Añade una vista previa/selector de color en línea a los colores del texto (por ejemplo: #FFFFFF, blanco)",
|
||||||
|
"Description[eu]": "Testuko koloreei lerro barruko Kolore aurreikuspegi/hautatzaile bat gehitzen die (adib. #FFFFFF, zuria)",
|
||||||
|
"Description[fi]": "Lisää tekstin väreille (esim. #FFFFFF, white) upotetun väriesikatselun/-valitsimen",
|
||||||
|
"Description[fr]": "Ajoute un aperçu intégré / sélecteur de couleurs pour les couleurs dans le texte (par exemple #FFFFFF, blanc)",
|
||||||
|
"Description[gl]": "Engade un selector e vista previa de cores in situ no texto (p. ex. #FFFFFF, white).",
|
||||||
|
"Description[hu]": "Beágyazott színválasztó a szövegben lévő színekhez (például #FFFFFF, fehér)",
|
||||||
|
"Description[ia]": "Adde un vista preliminar/selectionator de Color a lolores in le texto (p.ex. #FFFFFF, blanco)",
|
||||||
|
"Description[ie]": "Adjunter un visor e selector de colores in li textu (p.ex. #FFFFFF, white)",
|
||||||
|
"Description[it]": "Aggiunge nelle righe del testo un'anteprima colore/selettore (ad es. #FFFFFF, bianco)",
|
||||||
|
"Description[ka]": "ხაზშივე ტექსტის ფერის გადახედვის/ამრჩევის დამატება (მაგ: #FFFFFF, თეთრი)",
|
||||||
|
"Description[ko]": "문자열 내 인라인 색상 미리 보기/선택기 추가(예: #FFFFFF, 흰색)",
|
||||||
|
"Description[nl]": "Voegt een inline kleurenvoorbeeld/kiezer toe aan kleuren in de tekst (bijv. #FFFFFF, wit)",
|
||||||
|
"Description[pl]": "Dodaje wbudowany wybierak barwy dla barw tekstu (np. #FFFFFF, biały)",
|
||||||
|
"Description[pt]": "Adiciona uma antevisão/selector de cores incorporado para as cores no texto (p.ex. #FFFFFF, white)",
|
||||||
|
"Description[ru]": "Добавление в текст встроенного средства предварительного просмотра и выбора цвета (например, #FFFFFF, white (белый))",
|
||||||
|
"Description[sk]": "Pridá vložený náhľad/výber farieb na farby v texte (napr. #FFFFFF,biela)",
|
||||||
|
"Description[sl]": "Doda besedilu vrstni predogled/izbirnik barv (npr. #FFFFFF, bela)",
|
||||||
|
"Description[sv]": "Lägger till en färggranskare/färghämtare på plats i texten (t.ex. #FFFFFF, vit)",
|
||||||
|
"Description[tr]": "Metindeki renklere satır içi renk önizleyici/seçici ekler (örn. #FFFFFF, beyaz)",
|
||||||
|
"Description[uk]": "Додає вбудовану панель попереднього перегляду і піпетку для кольорів у тексті (наприклад, #FFFFFF, білого)",
|
||||||
|
"Description[vi]": "Thêm một bộ xem thử / nhặt màu tại chỗ cho các màu trong văn bản (vd. #FFFFFF, trắng)",
|
||||||
|
"Description[x-test]": "xxAdds an inline Color preview/picker to colors in the text (e.g. #FFFFFF, white)xx",
|
||||||
|
"Description[zh_CN]": "在文本中添加内联的颜色预览/拾色器 (例如 #FFFFFF, 白色)",
|
||||||
|
"Name": "Color Picker",
|
||||||
|
"Name[ar]": "منتق الألوان",
|
||||||
|
"Name[az]": "Rəng seçici",
|
||||||
|
"Name[bg]": "Избиране на цвят",
|
||||||
|
"Name[ca@valencia]": "Selector de color",
|
||||||
|
"Name[ca]": "Selector de color",
|
||||||
|
"Name[cs]": "Kapátko",
|
||||||
|
"Name[de]": "Farbauswahl",
|
||||||
|
"Name[el]": "Επιλογέας χρωμάτων",
|
||||||
|
"Name[en_GB]": "Colour Picker",
|
||||||
|
"Name[eo]": "Kolorelektilo",
|
||||||
|
"Name[es]": "Selector de color",
|
||||||
|
"Name[eu]": "Kolore hautatzailea",
|
||||||
|
"Name[fi]": "Värivalinta",
|
||||||
|
"Name[fr]": "Sélecteur de couleurs",
|
||||||
|
"Name[gl]": "Selector de cores",
|
||||||
|
"Name[hu]": "Színválasztó",
|
||||||
|
"Name[ia]": "Selectionator de color",
|
||||||
|
"Name[ie]": "Selector de color",
|
||||||
|
"Name[it]": "Selettore di colore",
|
||||||
|
"Name[ka]": "ფერის ამრჩევი",
|
||||||
|
"Name[ko]": "색상 선택기",
|
||||||
|
"Name[my]": "အရောင်ရွေးကိရိယာ",
|
||||||
|
"Name[nl]": "Kleurenkiezer",
|
||||||
|
"Name[pl]": "Wybierak barwy",
|
||||||
|
"Name[pt]": "Selector de Cores",
|
||||||
|
"Name[pt_BR]": "Seletor de cores",
|
||||||
|
"Name[ru]": "Выбор цвета",
|
||||||
|
"Name[sk]": "Výber farby",
|
||||||
|
"Name[sl]": "Izbirnik barv",
|
||||||
|
"Name[sv]": "Färgväljare",
|
||||||
|
"Name[tr]": "Renk Seçicisi",
|
||||||
|
"Name[uk]": "Піпетка",
|
||||||
|
"Name[vi]": "Trình nhặt màu",
|
||||||
|
"Name[x-test]": "xxColor Pickerxx",
|
||||||
|
"Name[zh_CN]": "拾色器",
|
||||||
|
"ServiceTypes": [
|
||||||
|
"KTextEditor/Plugin"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user