diff --git a/kcms/cursortheme/kcm_cursortheme.desktop b/kcms/cursortheme/kcm_cursortheme.desktop index a62fbc0a1..7dde2368a 100644 --- a/kcms/cursortheme/kcm_cursortheme.desktop +++ b/kcms/cursortheme/kcm_cursortheme.desktop @@ -1,164 +1,164 @@ [Desktop Entry] Exec=kcmshell5 kcm_cursortheme Icon=edit-select Type=Service X-KDE-ServiceTypes=KCModule X-KDE-Library=kcm_cursortheme X-KDE-ParentApp=kcontrol X-KDE-System-Settings-Parent-Category=workspacetheme X-DocPath=kcontrol/cursortheme/index.html X-KDE-Weight=60 -Name=Cursor Theme +Name=Cursors Name[ar]=سمة المؤشّر Name[bg]=Тема за курсора Name[bn]=কার্সর থীম Name[bs]=Tema pokazivača Name[ca]=Tema de cursor Name[ca@valencia]=Tema de cursor Name[cs]=Motiv kurzorů Name[da]=Markørtema Name[de]=Zeigerdesign Name[el]=Θέμα δρομέα Name[en_GB]=Cursor Theme Name[es]=Tema de cursores Name[et]=Kursoriteema Name[eu]=Kurtsorearen gaia Name[fi]=Osoitinteema Name[fr]=Thème du pointeur de la souris Name[ga]=Téama Cúrsóra Name[gl]=Tema do cursor Name[he]=ערכת־נושא למצביע העכבר Name[hi]=संकेतक प्रसंग Name[hr]=Tema pokazivača Name[hu]=Kurzortéma Name[ia]=Thema de cursor Name[id]=Tema Kursor Name[is]=Bendilþema Name[it]=Tema dei puntatori Name[ja]=カーソルテーマ Name[kk]=Меңзер нақышы Name[km]=ស្បែក​ទស្សន៍ទ្រនិច Name[kn]=ಸ್ಥಳಸೂಚಕ (ಕರ್ಸರ್) ಪರಿಸರವಿನ್ಯಾಸ Name[ko]=커서 테마 Name[lt]=Žymeklių apipavidalinimas Name[lv]=Kursora tēma Name[mr]=कर्सर शैली Name[nb]=Pekertema Name[nds]=Wieserutsehn Name[nl]=Cursorthema Name[nn]=Peikartema Name[pa]=ਕਰਸਰ ਥੀਮ Name[pl]=Zestawy wskaźników Name[pt]=Tema de Cursores Name[pt_BR]=Tema de cursores Name[ro]=Tematica de cursor Name[ru]=Тема курсоров Name[sk]=Téma kurzora Name[sl]=Tema kazalke Name[sr]=Тема показивача Name[sr@ijekavian]=Тема показивача Name[sr@ijekavianlatin]=Tema pokazivača Name[sr@latin]=Tema pokazivača Name[sv]=Muspekartema Name[th]=ชุดเคอร์เซอร์ Name[tr]=İmleç Teması Name[ug]=نۇربەلگە ئۆرنىكى Name[uk]=Тема вказівника Name[vi]=Sắc thái con trỏ Name[wa]=Tinme do cursoe Name[x-test]=xxCursor Themexx Name[zh_CN]=光标主题 Name[zh_TW]=游標主題 -Comment=Mouse Cursor Theme +Comment=Choose the mouse cursor theme Comment[ar]=سمة مؤشّر الفأرة Comment[bs]=Tema kursora miša Comment[ca]=Tema de cursor del ratolí Comment[ca@valencia]=Tema de cursor del ratolí Comment[cs]=Motiv kurzorů myši Comment[da]=Markørtema Comment[de]=Mauszeigerdesign Comment[el]=Θέμα δρομέα ποντικιού Comment[en_GB]=Mouse Cursor Theme Comment[es]=Tema de cursores del ratón Comment[et]=Hiirekursori teema Comment[eu]=Sagu-kurtsoreen gaia Comment[fi]=Osoitinteema Comment[fr]=Thème du pointeur de la souris Comment[gl]=Tema do cursor do rato Comment[he]=ערכת־נושא למצביעי העכבר Comment[hu]=Egérkurzor témája Comment[id]=Tema Kursor Mouse Comment[is]=Bendilþema fyrir mús Comment[it]=Tema dei puntatori del mouse Comment[ja]=マウスカーソルテーマ Comment[ko]=마우스 커서 테마 Comment[lt]=Žymeklių apipavidalinimas Comment[mr]=माउस कर्सर शैली Comment[nb]=Musepekertema Comment[nds]=Utsehn vun den Muuswieser Comment[nl]=Muiscursorthema Comment[nn]=Peikartema Comment[pa]=ਮਾਊਸ ਕਰਸਰ ਥੀਮ Comment[pl]=Zestawy wskaźników myszy Comment[pt]=Tema de Cursores do Rato Comment[pt_BR]=Tema de cursores do mouse Comment[ru]=Тема курсоров мыши Comment[sk]=Téma kurzora myši Comment[sl]=Tema miškine kazalke Comment[sr]=Тема показивача миша Comment[sr@ijekavian]=Тема показивача миша Comment[sr@ijekavianlatin]=Tema pokazivača miša Comment[sr@latin]=Tema pokazivača miša Comment[sv]=Muspekartema Comment[tr]=Fare İmleç Teması Comment[uk]=Тема вказівника миші Comment[x-test]=xxMouse Cursor Themexx Comment[zh_CN]=鼠标光标主题 Comment[zh_TW]=滑鼠游標主題 X-KDE-Keywords=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance X-KDE-Keywords[ar]=فأرة,مؤشّر,مؤشر,سمة,ثيم,مظهر المؤشّر,لون المؤشّر,سمة المؤشّر,سمة الفأرة,مظهر الفأرة,بشرات الفأرة,ألوان المؤشّر,مظهر المؤشّر X-KDE-Keywords[bs]=Miš,kursor,tema,pojavljivanje kurosra,boja kursora,tema kursora,tema miša,pojavljivanje miša,površina miša,pokazatelj boja,pojava boja X-KDE-Keywords[ca]=Ratolí,Cursor,Tema,Aparença de cursor,Color de cursor,Tema de cursor,Tema de ratolí,Aparença de ratolí,Pells de ratolí,Colors d'apuntador,Aparença d'apuntador X-KDE-Keywords[ca@valencia]=Ratolí,Cursor,Tema,Aparença de cursor,Color de cursor,Tema de cursor,Tema de ratolí,Aparença de ratolí,Pells de ratolí,Colors d'apuntador,Aparença d'apuntador X-KDE-Keywords[da]=Mus,markør,cursor,tema,markørens udseende,markørfarve,markørtema,musetema,musens udseende,museskin X-KDE-Keywords[de]=Maus,Zeiger,Mauszeiger,Zeigerfarbe,Zeigerdesign X-KDE-Keywords[el]=ποντίκι,δρομέας,θέμα,εμφάνιση δρομέα,χρώμα δρομέα,θέμα δρομέα,θέμα ποντικιού,εμφάνιση ποντικιού,θέματα ποντικιού,χρώματα δείκτη,εμφάνιση δείκτη X-KDE-Keywords[en_GB]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Colour,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colours,Pointer Appearance X-KDE-Keywords[es]=Ratón,Cursor,Tema,Apariencia del cursor,Color del cursor,Tema del cursor,Tema del ratón,Apariencia del ratón,Pieles del ratón,Colores del puntero,Apariencia del puntero X-KDE-Keywords[et]=Hiir,Kursor,Teema,Kursori välimus,Kursori värv,Kursori teema,Hiireteema,Hiire välimus,Hiire nahad,Osutusseadme värvid,Osutusseadme välimus X-KDE-Keywords[eu]=sagu,kurtsore,gai,kurtsorearen itsura,kurtsorearen kolorea,saguaren gaia,saguaren itxura,saguaren azalak,erakuslearen koloreak,erakuslearen itxura X-KDE-Keywords[fi]=hiiri,osoitin,teema,osoittimen ulkoasu,osoittimen väri,osoitinteema,hiiren teema,hiiriteema,hiiren ulkoasu,hiiriteemat,osoitinvärit X-KDE-Keywords[fr]=Souris, Curseur, Thème, Apparence du curseur, Couleur du curseur, Thème de curseurs, Thème de la souris, Apparence de la souris, Revêtement de la souris, Couleur du pointeur, Apparence du pointeur X-KDE-Keywords[gl]=rato, cursor, tema, aparencia do cursor, cor do cursor, tema do cursor, tema do rato, aparencia do rato, cor do rato, punteiro, cor do punteiro, aparencia do punteiro, tema do punteiro X-KDE-Keywords[hu]=Egér,Kurzor,Téma,Kurzormegjelenés,Kurzorszín,Kurzortéma,Egértéma,Egérmegjelenés,Egérfelületek,Mutató színek,Mutató megjelenés X-KDE-Keywords[ia]=Mus,Cursor,Thema,Apparentia,Cursor,Color,Thema de Cursor,Thema de Mus, Apparentia de Mus,Pelles de Mus,Colores de punctator,Apparentia de punctator X-KDE-Keywords[id]=Mouse,Kursor,Tema,Penampilan Kursor,Warna Kursor,Tema Kursor,Tema Mouse,Penampilan Mouse,Kulit Mouse,Warna Penunjuk,Penampilan Penunjuk X-KDE-Keywords[it]=Mouse,Puntatore,Aspetto puntatore,Colore puntatore,Tema puntatore,Tema mouse,Aspetto mouse,Skin mouse,Colore puntatore,Aspetto puntatore X-KDE-Keywords[kk]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance X-KDE-Keywords[km]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance X-KDE-Keywords[ko]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance,마우스,커서,커서 테마,포인터 X-KDE-Keywords[mr]=माऊस, कर्सर, थीम, कर्सर, अपिरिअन्स, कर्सर, कलर, कर्सर थीम, माऊस थीम, माऊस अपिरिअन्स, माऊस स्कीन्स, पॉईटर अपिरिअन्स X-KDE-Keywords[nb]=Mus,peker,tema,pekerutseende,pekerfarge,pekertema,musetema,musutseende,museskins,pekerfarger,pekeerutseende X-KDE-Keywords[nds]=Muus,Wieser,Muster, Wieserutsehn,Klöör,Utsehn X-KDE-Keywords[nl]=Muis,Cursor,Thema,Uiterlijk van cursor,kleur van cursor,Thema van cursor,Thema van muis,uiterlijk van muis,Muisoppervlak,Kleuren van aanwijzer,Uiterlijk van aanwijzer X-KDE-Keywords[nn]=mus,peikar,tema,peikarutsjånad,peikarfarge,peikartema,musetema,musutsjånad,musedrakt,peikarfargar,peikarutsjånad X-KDE-Keywords[pl]=Mysz,Kursor,Motyw,Wygląd kursora,Kolor kursora,Motyw kursora,Motyw myszy,Wygląd myszy,Skórki myszy,Kolory wskaźnika,Wygląd wskaźnika X-KDE-Keywords[pt]=Rato,Cursor,Tema,Aparência do Cursor,Cor do Cursor,Tema do Cursor,Tema do Rato,Aparência do Rato,Visuais do Rato,Cores do Cursor X-KDE-Keywords[pt_BR]=Mouse,Cursor,Tema,Aparência do cursor,Cor do cursor,Tema do cursor,Tema do mouse,Aparência do mouse,Visuais do mouse,Cores do ponteiro,Aparência do ponteiro X-KDE-Keywords[ru]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance,мышь,курсор,тема,внешний вид курсора мыши,цвет указателя,внешний вид указателя X-KDE-Keywords[sk]=Myš, kurzor,téma,vzhľad kurzora,farba kurzora,téma kurzora,téma myši,vzhľad myši,skiny myši,farby ukazovateľa,vzhľad ukazovateľa X-KDE-Keywords[sl]=miška,kazalec,kurzor,kazalka,tema,videz kazalca,videz kazalke,barva kazalca,barva kazalke,tema kazalcev,tema kazalk,tema miške,videz miške,preobleke miške,teme miške X-KDE-Keywords[sr]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance,миш,показивач,курсор,тема,изглед показивача,боја показивача,тема показивача,тема миша,изглед миша,пресвлаке миша,боје показивача X-KDE-Keywords[sr@ijekavian]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance,миш,показивач,курсор,тема,изглед показивача,боја показивача,тема показивача,тема миша,изглед миша,пресвлаке миша,боје показивача X-KDE-Keywords[sr@ijekavianlatin]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance,miš,pokazivač,kursor,tema,izgled pokazivača,boja pokazivača,tema pokazivača,tema miša,izgled miša,presvlake miša,boje pokazivača X-KDE-Keywords[sr@latin]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance,miš,pokazivač,kursor,tema,izgled pokazivača,boja pokazivača,tema pokazivača,tema miša,izgled miša,presvlake miša,boje pokazivača X-KDE-Keywords[sv]=Mus,Pekare,Tema,Utseende,Färg,Pekartema,Mustema,Musutseende,Musskal,Pekarfärger,Pekarutseende X-KDE-Keywords[tr]=Fare,İşaretçi,Tema,İşaretçi Görünümü,İşaretçi Rengi,İşaretçi Teması,Fare Teması,Fare Görünümü,Fare Kabuğu,İşaretçi Renkleri,İşaretçi Görünümü X-KDE-Keywords[uk]=миша,вказівник,тема,вигляд вказівника,колір вказівника,тема вказівника,тема миші,вигляд миші,Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance X-KDE-Keywords[x-test]=xxMousexx,xxCursorxx,xxThemexx,xxCursor Appearancexx,xxCursor Colorxx,xxCursor Themexx,xxMouse Themexx,xxMouse Appearancexx,xxMouse Skinsxx,xxPointer Colorsxx,xxPointer Appearancexx X-KDE-Keywords[zh_CN]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance,鼠标,指针,主题,指针外观,指针颜色,指针主题,鼠标主题,鼠标外观,鼠标皮肤,指针外观 X-KDE-Keywords[zh_TW]=Mouse,Cursor,Theme,Cursor Appearance,Cursor Color,Cursor Theme,Mouse Theme,Mouse Appearance,Mouse Skins,Pointer Colors,Pointer Appearance diff --git a/kcms/cursortheme/kcmcursortheme.cpp b/kcms/cursortheme/kcmcursortheme.cpp index 96206e92d..2aa71ec15 100644 --- a/kcms/cursortheme/kcmcursortheme.cpp +++ b/kcms/cursortheme/kcmcursortheme.cpp @@ -1,601 +1,601 @@ /* * Copyright © 2003-2007 Fredrik Höglund * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "kcmcursortheme.h" #include "xcursor/thememodel.h" #include "xcursor/sortproxymodel.h" #include "xcursor/cursortheme.h" #include "xcursor/previewwidget.h" #include "../krdb/krdb.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_XFIXES # include #endif K_PLUGIN_FACTORY_WITH_JSON(CursorThemeConfigFactory, "kcm_cursortheme.json", registerPlugin();) CursorThemeConfig::CursorThemeConfig(QObject *parent, const QVariantList &args) : KQuickAddons::ConfigModule(parent, args), m_appliedSize(0), m_preferredSize(0), m_selectedThemeRow(-1), m_originalSelectedThemeRow(-1), m_canInstall(true), m_canResize(true), m_canConfigure(true) { qmlRegisterType("org.kde.private.kcm_cursortheme", 1, 0, "PreviewWidget"); qmlRegisterType(); - KAboutData* aboutData = new KAboutData(QStringLiteral("kcm_cursortheme"), i18n("Cursor Theme"), - QStringLiteral("1.0"), QString(i18n("Mouse Cursor Theme settings")), KAboutLicense::GPL, i18n("(c) 2003-2007 Fredrik Höglund")); + KAboutData* aboutData = new KAboutData(QStringLiteral("kcm_cursortheme"), i18n("Cursors"), + QStringLiteral("1.0"), QString(i18n("Choose the mouse cursor theme")), KAboutLicense::GPL, i18n("(c) 2003-2007 Fredrik Höglund")); aboutData->addAuthor(i18n("Fredrik Höglund")); aboutData->addAuthor(i18n("Marco Martin")); setAboutData(aboutData); m_model = new CursorThemeModel(this); m_proxyModel = new SortProxyModel(this); m_proxyModel->setSourceModel(m_model); m_proxyModel->setFilterCaseSensitivity(Qt::CaseSensitive); m_proxyModel->sort(NameColumn, Qt::AscendingOrder); m_sizesModel = new QStandardItemModel(this); // Disable the install button if we can't install new themes to ~/.icons, // or Xcursor isn't set up to look for cursor themes there. if (!m_model->searchPaths().contains(QDir::homePath() + "/.icons") || !iconsIsWritable()) { setCanInstall(false); } } CursorThemeConfig::~CursorThemeConfig() { /* */ } void CursorThemeConfig::setCanInstall(bool can) { if (m_canInstall == can) { return; } m_canInstall = can; emit canInstallChanged(); } bool CursorThemeConfig::canInstall() const { return m_canInstall; } void CursorThemeConfig::setCanResize(bool can) { if (m_canResize == can) { return; } m_canResize = can; emit canResizeChanged(); } bool CursorThemeConfig::canResize() const { return m_canResize; } void CursorThemeConfig::setCanConfigure(bool can) { if (m_canConfigure == can) { return; } m_canConfigure = can; emit canConfigureChanged(); } bool CursorThemeConfig::canConfigure() const { return m_canConfigure; } void CursorThemeConfig::setSelectedThemeRow(int row) { if (m_selectedThemeRow == row) { return; } m_selectedThemeRow = row; emit selectedThemeRowChanged(); updateSizeComboBox(); QModelIndex selected = selectedIndex(); if (selected.isValid()) { const CursorTheme *theme = m_proxyModel->theme(selected); } setNeedsSave(m_originalSelectedThemeRow != m_selectedThemeRow || m_originalPreferredSize != m_preferredSize); } int CursorThemeConfig::selectedThemeRow() const { return m_selectedThemeRow; } void CursorThemeConfig::setPreferredSize(int size) { if (m_preferredSize == size) { return; } m_preferredSize = size; emit preferredSizeChanged(); setNeedsSave(m_originalSelectedThemeRow != m_selectedThemeRow || m_originalPreferredSize != m_preferredSize); } int CursorThemeConfig::preferredSize() const { return m_preferredSize; } QAbstractItemModel *CursorThemeConfig::cursorsModel() { return m_proxyModel; } QAbstractItemModel *CursorThemeConfig::sizesModel() { return m_sizesModel; } bool CursorThemeConfig::iconsIsWritable() const { const QFileInfo icons = QFileInfo(QDir::homePath() + "/.icons"); const QFileInfo home = QFileInfo(QDir::homePath()); return ((icons.exists() && icons.isDir() && icons.isWritable()) || (!icons.exists() && home.isWritable())); } void CursorThemeConfig::updateSizeComboBox() { // clear the combo box m_sizesModel->clear(); // refill the combo box and adopt its icon size QModelIndex selected = selectedIndex(); int maxIconWidth = 0; int maxIconHeight = 0; if (selected.isValid()) { const CursorTheme *theme = m_proxyModel->theme(selected); const QList sizes = theme->availableSizes(); QIcon m_icon; // only refill the combobox if there is more that 1 size if (sizes.size() > 1) { int i; QList comboBoxList; QPixmap m_pixmap; // insert the items m_pixmap = theme->createIcon(0); if (m_pixmap.width() > maxIconWidth) { maxIconWidth = m_pixmap.width(); } if (m_pixmap.height() > maxIconHeight) { maxIconHeight = m_pixmap.height(); } QStandardItem *item = new QStandardItem(QIcon(m_pixmap), i18nc("@item:inlistbox size", "Resolution dependent")); item->setData(0); m_sizesModel->appendRow(item); comboBoxList << 0; foreach (i, sizes) { m_pixmap = theme->createIcon(i); if (m_pixmap.width() > maxIconWidth) { maxIconWidth = m_pixmap.width(); } if (m_pixmap.height() > maxIconHeight) { maxIconHeight = m_pixmap.height(); } QStandardItem *item = new QStandardItem(QIcon(m_pixmap), QString::number(i)); item->setData(i); m_sizesModel->appendRow(item); comboBoxList << i; }; // select an item int selectItem = comboBoxList.indexOf(m_preferredSize); // m_preferredSize not available for this theme if (selectItem < 0) { /* Search the value next to m_preferredSize. The first entry (0) is ignored. (If m_preferredSize would have been 0, then we would had found it yet. As m_preferredSize is not 0, we won't default to "automatic size".)*/ int j; int distance; int smallestDistance; selectItem = 1; j = comboBoxList.value(selectItem); smallestDistance = j < m_preferredSize ? m_preferredSize - j : j - m_preferredSize; for (int i = 2; i < comboBoxList.size(); ++i) { j = comboBoxList.value(i); distance = j < m_preferredSize ? m_preferredSize - j : j - m_preferredSize; if (distance < smallestDistance || (distance == smallestDistance && j > m_preferredSize)) { smallestDistance = distance; selectItem = i; }; } }; setPreferredSize(selectItem); }; }; // enable or disable the combobox KConfig c("kcminputrc"); KConfigGroup cg(&c, "Mouse"); if (cg.isEntryImmutable("cursorSize")) { setCanResize(false); } else { setCanResize(m_sizesModel->rowCount() > 0); }; } bool CursorThemeConfig::applyTheme(const CursorTheme *theme, const int size) { // Require the Xcursor version that shipped with X11R6.9 or greater, since // in previous versions the Xfixes code wasn't enabled due to a bug in the // build system (freedesktop bug #975). #if HAVE_XFIXES && XFIXES_MAJOR >= 2 && XCURSOR_LIB_VERSION >= 10105 if (!theme) { return false; } if (!CursorTheme::haveXfixes()) { return false; } QByteArray themeName = QFile::encodeName(theme->name()); // Set up the proper launch environment for newly started apps OrgKdeKLauncherInterface klauncher(QStringLiteral("org.kde.klauncher5"), QStringLiteral("/KLauncher"), QDBusConnection::sessionBus()); klauncher.setLaunchEnv(QStringLiteral("XCURSOR_THEME"), themeName); // Update the Xcursor X resources runRdb(0); // Notify all applications that the cursor theme has changed KGlobalSettings::self()->emitChange(KGlobalSettings::CursorChanged); // Reload the standard cursors QStringList names; // Qt cursors names << "left_ptr" << "up_arrow" << "cross" << "wait" << "left_ptr_watch" << "ibeam" << "size_ver" << "size_hor" << "size_bdiag" << "size_fdiag" << "size_all" << "split_v" << "split_h" << "pointing_hand" << "openhand" << "closedhand" << "forbidden" << "whats_this" << "copy" << "move" << "link"; // X core cursors names << "X_cursor" << "right_ptr" << "hand1" << "hand2" << "watch" << "xterm" << "crosshair" << "left_ptr_watch" << "center_ptr" << "sb_h_double_arrow" << "sb_v_double_arrow" << "fleur" << "top_left_corner" << "top_side" << "top_right_corner" << "right_side" << "bottom_right_corner" << "bottom_side" << "bottom_left_corner" << "left_side" << "question_arrow" << "pirate"; foreach (const QString &name, names) { XFixesChangeCursorByName(QX11Info::display(), theme->loadCursor(name, size), QFile::encodeName(name)); } return true; #else Q_UNUSED(theme) return false; #endif } void CursorThemeConfig::save() { const CursorTheme *theme = selectedIndex().isValid() ? m_proxyModel->theme(selectedIndex()) : nullptr; KConfig config("kcminputrc"); KConfigGroup c(&config, "Mouse"); if (theme) { c.writeEntry("cursorTheme", theme->name()); }; c.writeEntry("cursorSize", m_preferredSize); c.sync(); if (!applyTheme(theme, m_preferredSize)) { emit showInfoMessage(i18n("You have to restart the Plasma session for these changes to take effect.")); } m_appliedIndex = selectedIndex(); m_appliedSize = m_preferredSize; m_originalSelectedThemeRow = m_selectedThemeRow; m_originalPreferredSize = m_preferredSize; setNeedsSave(false); } void CursorThemeConfig::load() { // Get the name of the theme libXcursor currently uses QString currentTheme; if (QX11Info::isPlatformX11()) { currentTheme = XcursorGetTheme(QX11Info::display()); } // Get the name of the theme KDE is configured to use KConfig c("kcminputrc"); KConfigGroup cg(&c, "Mouse"); currentTheme = cg.readEntry("cursorTheme", currentTheme); // Find the theme in the listview if (!currentTheme.isEmpty()) { m_appliedIndex = m_proxyModel->findIndex(currentTheme); } else { m_appliedIndex = m_proxyModel->defaultIndex(); } // Disable the listview and the buttons if we're in kiosk mode if (cg.isEntryImmutable("cursorTheme")) { setCanConfigure(false); setCanInstall(false); } // Load cursor size int size = cg.readEntry("cursorSize", 0); if (size <= 0) { m_preferredSize = 0; } else { m_preferredSize = size; } updateSizeComboBox(); // This handles also the kiosk mode m_appliedSize = size; const CursorTheme *theme = m_proxyModel->theme(m_appliedIndex); setSelectedThemeRow(m_appliedIndex.row()); m_originalSelectedThemeRow = m_selectedThemeRow; m_originalPreferredSize = m_preferredSize; setNeedsSave(false); } void CursorThemeConfig::defaults() { QModelIndex defaultIndex = m_proxyModel->findIndex("breeze_cursors"); setSelectedThemeRow(defaultIndex.row()); m_preferredSize = 0; updateSizeComboBox(); setNeedsSave(m_originalSelectedThemeRow != m_selectedThemeRow || m_originalPreferredSize != m_preferredSize); } void CursorThemeConfig::selectionChanged() { updateSizeComboBox(); setNeedsSave(m_originalSelectedThemeRow != m_selectedThemeRow || m_originalPreferredSize != m_preferredSize); //setNeedsSave(m_appliedIndex != selectedIndex()); } QModelIndex CursorThemeConfig::selectedIndex() const { return m_proxyModel->index(m_selectedThemeRow, 0); } void CursorThemeConfig::getNewClicked() { KNS3::DownloadDialog dialog("xcursor.knsrc", nullptr); if (dialog.exec()) { KNS3::Entry::List list = dialog.changedEntries(); if (!list.isEmpty()) { m_model->refreshList(); } } } void CursorThemeConfig::installThemeFromFile(const QUrl &url) { if (url.isLocalFile()) { installThemeFile(url.toLocalFile()); return; } m_tempInstallFile.reset(new QTemporaryFile()); if (!m_tempInstallFile->open()) { emit showErrorMessage(i18n("Unable to create a temporary file.")); m_tempInstallFile.reset(); return; } KIO::FileCopyJob *job = KIO::file_copy(url,QUrl::fromLocalFile(m_tempInstallFile->fileName()), -1, KIO::Overwrite); job->uiDelegate()->setAutoErrorHandlingEnabled(true); connect(job, &KIO::FileCopyJob::result, this, [this, url](KJob *job) { if (job->error() != KJob::NoError) { emit showErrorMessage(i18n("Unable to download the icon theme archive: %1", job->errorText())); return; } installThemeFile(m_tempInstallFile->fileName()); m_tempInstallFile.reset(); }); } void CursorThemeConfig::installThemeFile(const QString &path) { KTar archive(path); archive.open(QIODevice::ReadOnly); const KArchiveDirectory *archiveDir = archive.directory(); QStringList themeDirs; // Extract the dir names of the cursor themes in the archive, and // append them to themeDirs foreach(const QString &name, archiveDir->entries()) { const KArchiveEntry *entry = archiveDir->entry(name); if (entry->isDirectory() && entry->name().toLower() != "default") { const KArchiveDirectory *dir = static_cast(entry); if (dir->entry("index.theme") && dir->entry("cursors")) { themeDirs << dir->name(); } } } if (themeDirs.isEmpty()) { emit showErrorMessage(i18n("The file is not a valid icon theme archive.")); return; } // The directory we'll install the themes to QString destDir = QDir::homePath() + "/.icons/"; if (!QDir().mkpath(destDir)) { emit showErrorMessage(i18n("Failed to create 'icons' folder.")); return; }; // Process each cursor theme in the archive foreach (const QString &dirName, themeDirs) { QDir dest(destDir + dirName); if (dest.exists()) { QString question = i18n("A theme named %1 already exists in your icon " "theme folder. Do you want replace it with this one?", dirName); int answer = KMessageBox::warningContinueCancel(nullptr, question, i18n("Overwrite Theme?"), KStandardGuiItem::overwrite()); if (answer != KMessageBox::Continue) { continue; } // ### If the theme that's being replaced is the current theme, it // will cause cursor inconsistencies in newly started apps. } // ### Should we check if a theme with the same name exists in a global theme dir? // If that's the case it will effectively replace it, even though the global theme // won't be deleted. Checking for this situation is easy, since the global theme // will be in the listview. Maybe this should never be allowed since it might // result in strange side effects (from the average users point of view). OTOH // a user might want to do this 'upgrade' a global theme. const KArchiveDirectory *dir = static_cast (archiveDir->entry(dirName)); dir->copyTo(dest.path()); m_model->addTheme(dest); } archive.close(); emit showSuccessMessage(i18n("Theme installed successfully.")); m_model->refreshList(); } void CursorThemeConfig::removeTheme(int row) { QModelIndex idx = m_proxyModel->index(row, 0); if (!idx.isValid()) { return; } const CursorTheme *theme = m_proxyModel->theme(idx); // Don't let the user delete the currently configured theme if (idx == m_appliedIndex) { KMessageBox::sorry(nullptr, i18n("You cannot delete the theme you are currently " "using.
You have to switch to another theme first.
")); return; } // Get confirmation from the user QString question = i18n("Are you sure you want to remove the " "%1 cursor theme?
" "This will delete all the files installed by this theme.
", theme->title()); int answer = KMessageBox::warningContinueCancel(nullptr, question, i18n("Confirmation"), KStandardGuiItem::del()); if (answer != KMessageBox::Continue) { return; } // Delete the theme from the harddrive KIO::del(QUrl::fromLocalFile(theme->path())); // async // Remove the theme from the model m_proxyModel->removeTheme(idx); // TODO: // Since it's possible to substitute cursors in a system theme by adding a local // theme with the same name, we shouldn't remove the theme from the list if it's // still available elsewhere. We could add a // bool CursorThemeModel::tryAddTheme(const QString &name), and call that, but // since KIO::del() is an asynchronos operation, the theme we're deleting will be // readded to the list again before KIO has removed it. } #include "kcmcursortheme.moc" diff --git a/kcms/cursortheme/package/contents/ui/main.qml b/kcms/cursortheme/package/contents/ui/main.qml index c890b816d..ca92c6949 100644 --- a/kcms/cursortheme/package/contents/ui/main.qml +++ b/kcms/cursortheme/package/contents/ui/main.qml @@ -1,181 +1,181 @@ /* Copyright (c) 2015 Marco Martin This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.7 import QtQuick.Window 2.2 // for Screen import QtQuick.Layouts 1.1 import QtQuick.Controls 2.2 as QtControls import QtQuick.Dialogs 1.1 as QtDialogs import org.kde.kirigami 2.4 as Kirigami import org.kde.kconfig 1.0 // for KAuthorized import org.kde.kcm 1.1 as KCM import org.kde.private.kcm_cursortheme 1.0 KCM.GridViewKCM { - KCM.ConfigModule.quickHelp: i18n("This module lets you configure the mouse cursor theme used.") + KCM.ConfigModule.quickHelp: i18n("This module lets you choose the mouse cursor theme.") view.model: kcm.cursorsModel view.delegate: Delegate {} view.onCurrentIndexChanged: { kcm.selectedThemeRow = view.currentIndex; view.positionViewAtIndex(view.currentIndex, view.GridView.Beginning); } DropArea { anchors.fill: parent onEntered: { if (!drag.hasUrls) { drag.accepted = false; } } onDropped: kcm.installThemeFromFile(drop.urls[0]) } Connections { target: kcm onSelectedThemeRowChanged: view.currentIndex = kcm.selectedThemeRow; } footer: ColumnLayout { id: footerLayout Kirigami.InlineMessage { id: infoLabel Layout.fillWidth: true showCloseButton: true Connections { target: kcm onShowSuccessMessage: { infoLabel.type = Kirigami.MessageType.Positive; infoLabel.text = message; infoLabel.visible = true; } onShowInfoMessage: { infoLabel.type = Kirigami.MessageType.Information; infoLabel.text = message; infoLabel.visible = true; } onShowErrorMessage: { infoLabel.type = Kirigami.MessageType.Error; infoLabel.text = message; infoLabel.visible = true; } } } RowLayout { id: row1 //spacer Item { Layout.fillWidth: true Layout.fillHeight: true } RowLayout { id: comboLayout enabled: kcm.canResize QtControls.Label { text: i18n("Size:") } QtControls.ComboBox { id: sizeCombo currentIndex: 0 onCountChanged: currentIndex = 0 model: kcm.sizesModel textRole: "display" onCurrentTextChanged: { kcm.preferredSize = isNaN(parseInt(sizeCombo.currentText)) ? 0 : parseInt(sizeCombo.currentText); } delegate: QtControls.ItemDelegate { id: sizeComboDelegate readonly property int size: parseInt(model.display) width: parent.width highlighted: ListView.isCurrentItem text: model.display contentItem: RowLayout { Kirigami.Icon { source: model.decoration smooth: true width: sizeComboDelegate.size / Screen.devicePixelRatio height: sizeComboDelegate.size / Screen.devicePixelRatio visible: valid && sizeComboDelegate.size > 0 } QtControls.Label { Layout.fillWidth: true color: sizeComboDelegate.highlighted ? Kirigami.Theme.highlightedTextColor : Kirigami.Theme.textColor text: model[sizeCombo.textRole] } } } } } RowLayout { parent: footerLayout.x + footerLayout.width - comboLayout.width > width ? row1 : row2 QtControls.Button { icon.name: "document-import" text: i18n("&Install From File...") onClicked: fileDialogLoader.active = true; enabled: kcm.canInstall } QtControls.Button { icon.name: "get-hot-new-stuff" text: i18n("&Get New Cursors...") onClicked: kcm.getNewClicked(); enabled: kcm.canInstall visible: KAuthorized.authorize("ghns") } } } RowLayout { id: row2 visible: children.length > 1 //spacer Item { Layout.fillWidth: true Layout.fillHeight: true } } } Loader { id: fileDialogLoader active: false sourceComponent: QtDialogs.FileDialog { title: i18n("Open Theme") folder: shortcuts.home nameFilters: [ i18n("Cursor Theme Files (*.tar.gz *.tar.bz2)") ] Component.onCompleted: open() onAccepted: { kcm.installThemeFromFile(fileUrls[0]) fileDialogLoader.active = false } onRejected: { fileDialogLoader.active = false } } } } diff --git a/kcms/cursortheme/package/metadata.desktop b/kcms/cursortheme/package/metadata.desktop index 0b5d09c43..85b63c065 100644 --- a/kcms/cursortheme/package/metadata.desktop +++ b/kcms/cursortheme/package/metadata.desktop @@ -1,122 +1,122 @@ [Desktop Entry] -Name=Cursor Theme +Name=Cursors Name[ar]=سمة المؤشّر Name[bg]=Тема за курсора Name[bn]=কার্সর থীম Name[bs]=Tema pokazivača Name[ca]=Tema de cursor Name[ca@valencia]=Tema de cursor Name[cs]=Motiv kurzorů Name[da]=Markørtema Name[de]=Zeigerdesign Name[el]=Θέμα δρομέα Name[en_GB]=Cursor Theme Name[es]=Tema de cursores Name[et]=Kursoriteema Name[eu]=Kurtsorearen gaia Name[fi]=Osoitinteema Name[fr]=Thème du pointeur de la souris Name[ga]=Téama Cúrsóra Name[gl]=Tema do cursor Name[he]=ערכת־נושא למצביע העכבר Name[hi]=संकेतक प्रसंग Name[hr]=Tema pokazivača Name[hu]=Kurzortéma Name[ia]=Thema de cursor Name[id]=Tema Kursor Name[is]=Bendilþema Name[it]=Tema dei puntatori Name[ja]=カーソルテーマ Name[kk]=Меңзер нақышы Name[km]=ស្បែក​ទស្សន៍ទ្រនិច Name[kn]=ಸ್ಥಳಸೂಚಕ (ಕರ್ಸರ್) ಪರಿಸರವಿನ್ಯಾಸ Name[ko]=커서 테마 Name[lt]=Žymeklių apipavidalinimas Name[lv]=Kursora tēma Name[mr]=कर्सर शैली Name[nb]=Pekertema Name[nds]=Wieserutsehn Name[nl]=Cursorthema Name[nn]=Peikartema Name[pa]=ਕਰਸਰ ਥੀਮ Name[pl]=Zestawy wskaźników Name[pt]=Tema de Cursores Name[pt_BR]=Tema de cursores Name[ro]=Tematica de cursor Name[ru]=Тема курсоров Name[sk]=Téma kurzora Name[sl]=Tema kazalke Name[sr]=Тема показивача Name[sr@ijekavian]=Тема показивача Name[sr@ijekavianlatin]=Tema pokazivača Name[sr@latin]=Tema pokazivača Name[sv]=Muspekartema Name[th]=ชุดเคอร์เซอร์ Name[tr]=İmleç Teması Name[ug]=نۇربەلگە ئۆرنىكى Name[uk]=Тема вказівника Name[vi]=Sắc thái con trỏ Name[wa]=Tinme do cursoe Name[x-test]=xxCursor Themexx Name[zh_CN]=光标主题 Name[zh_TW]=游標主題 -Comment=Mouse Cursor Theme +Comment=Choose the mouse cursor theme Comment[ar]=سمة مؤشّر الفأرة Comment[bs]=Tema kursora miša Comment[ca]=Tema de cursor del ratolí Comment[ca@valencia]=Tema de cursor del ratolí Comment[cs]=Motiv kurzorů myši Comment[da]=Markørtema Comment[de]=Mauszeigerdesign Comment[el]=Θέμα δρομέα ποντικιού Comment[en_GB]=Mouse Cursor Theme Comment[es]=Tema de cursores del ratón Comment[et]=Hiirekursori teema Comment[eu]=Sagu-kurtsoreen gaia Comment[fi]=Osoitinteema Comment[fr]=Thème du pointeur de la souris Comment[gl]=Tema do cursor do rato Comment[he]=ערכת־נושא למצביעי העכבר Comment[hu]=Egérkurzor témája Comment[id]=Tema Kursor Mouse Comment[is]=Bendilþema fyrir mús Comment[it]=Tema dei puntatori del mouse Comment[ja]=マウスカーソルテーマ Comment[ko]=마우스 커서 테마 Comment[lt]=Žymeklių apipavidalinimas Comment[mr]=माउस कर्सर शैली Comment[nb]=Musepekertema Comment[nds]=Utsehn vun den Muuswieser Comment[nl]=Muiscursorthema Comment[nn]=Peikartema Comment[pa]=ਮਾਊਸ ਕਰਸਰ ਥੀਮ Comment[pl]=Zestawy wskaźników myszy Comment[pt]=Tema de Cursores do Rato Comment[pt_BR]=Tema de cursores do mouse Comment[ru]=Тема курсоров мыши Comment[sk]=Téma kurzora myši Comment[sl]=Tema miškine kazalke Comment[sr]=Тема показивача миша Comment[sr@ijekavian]=Тема показивача миша Comment[sr@ijekavianlatin]=Tema pokazivača miša Comment[sr@latin]=Tema pokazivača miša Comment[sv]=Muspekartema Comment[tr]=Fare İmleç Teması Comment[uk]=Тема вказівника миші Comment[x-test]=xxMouse Cursor Themexx Comment[zh_CN]=鼠标光标主题 Comment[zh_TW]=滑鼠游標主題 Icon=edit-select Keywords= Type=Service X-KDE-ParentApp= X-KDE-PluginInfo-Author=Marco Martin X-KDE-PluginInfo-Email=mart@kde.org X-KDE-PluginInfo-License=GPL X-KDE-PluginInfo-Name=kcm_cursortheme X-KDE-PluginInfo-Version= X-KDE-PluginInfo-Website=https://www.kde.org/plasma-desktop X-KDE-ServiceTypes=Plasma/Generic X-Plasma-API=declarativeappletscript X-Plasma-MainScript=ui/main.qml