/*************************************************************************** * This file is part of awesome-widgets * * * * awesome-widgets 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 3 of the * * License, or (at your option) any later version. * * * * awesome-widgets 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 awesome-widgets. If not, see http://www.gnu.org/licenses/ * ***************************************************************************/ #include "dpadds.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "awdebug.h" DPAdds::DPAdds(QObject *_parent) : QObject(_parent) { qSetMessagePattern(AWDebug::LOG_FORMAT); qCDebug(LOG_DP) << __PRETTY_FUNCTION__; for (auto &metadata : AWDebug::getBuildData()) qCDebug(LOG_DP) << metadata; connect(KWindowSystem::self(), SIGNAL(currentDesktopChanged(int)), this, SIGNAL(desktopChanged())); connect(KWindowSystem::self(), SIGNAL(windowAdded(WId)), this, SIGNAL(windowListChanged())); connect(KWindowSystem::self(), SIGNAL(windowRemoved(WId)), this, SIGNAL(windowListChanged())); } DPAdds::~DPAdds() { qCDebug(LOG_DP) << __PRETTY_FUNCTION__; } // HACK: since QML could not use QLoggingCategory I need this hack bool DPAdds::isDebugEnabled() { return LOG_DP().isDebugEnabled(); } int DPAdds::currentDesktop() { return KX11Extras::currentDesktop(); } QStringList DPAdds::dictKeys(const bool _sorted, const QString &_regexp) { qCDebug(LOG_DP) << "Should be sorted" << _sorted << "and filter applied" << _regexp; QStringList allKeys; allKeys.append("mark"); allKeys.append("name"); allKeys.append("number"); allKeys.append("total"); if (_sorted) allKeys.sort(); return allKeys.filter(QRegExp(_regexp)); } int DPAdds::numberOfDesktops() { return KX11Extras::numberOfDesktops(); } QString DPAdds::toolTipImage(const int _desktop) const { qCDebug(LOG_DP) << "Desktop" << _desktop; // drop if no tooltip required if (m_tooltipType == "none") return ""; // prepare DesktopWindowsInfo info = getInfoByDesktop(_desktop); // special tooltip format for names if (m_tooltipType == "names") { QStringList windowList; std::for_each(info.windowsData.cbegin(), info.windowsData.cend(), [&windowList](const WindowData &data) { windowList.append(data.name); }); return QString("
  • %1
").arg(windowList.join("
  • ")); } // init auto *toolTipScene = new QGraphicsScene(); auto *toolTipView = new QGraphicsView(toolTipScene); toolTipView->setStyleSheet("background: transparent"); toolTipView->setContentsMargins(0, 0, 0, 0); toolTipView->setFrameShape(QFrame::NoFrame); toolTipView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); toolTipView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // update auto width = static_cast(info.desktop.width()); auto height = static_cast(info.desktop.height()); float margin = 5.0f * width / 400.0f; toolTipView->resize(static_cast(width + 2.0f * margin), static_cast(height + 2.0f * margin)); toolTipScene->clear(); toolTipScene->setBackgroundBrush(QBrush(Qt::NoBrush)); // borders toolTipScene->addLine(0, 0, 0, height + 2.0 * margin); toolTipScene->addLine(0, height + 2.0 * margin, width + 2.0 * margin, height + 2.0 * margin); toolTipScene->addLine(width + 2.0 * margin, height + 2.0 * margin, width + 2.0 * margin, 0); toolTipScene->addLine(width + 2.0 * margin, 0, 0, 0); if (m_tooltipType == "contours") { QPen pen = QPen(); pen.setWidthF(2.0 * width / 400.0); pen.setColor(QColor(m_tooltipColor)); for (auto &data : info.windowsData) { QRect rect = data.rect; auto left = static_cast(rect.left()); auto right = static_cast(rect.right()); auto top = static_cast(rect.top()); auto bottom = static_cast(rect.bottom()); toolTipScene->addLine(left + margin, bottom + margin, left + margin, top + margin, pen); toolTipScene->addLine(left + margin, top + margin, right + margin, top + margin, pen); toolTipScene->addLine(right + margin, top + margin, right + margin, bottom + margin, pen); toolTipScene->addLine(right + margin, bottom + margin, left + margin, bottom + margin, pen); } } else if (m_tooltipType == "clean") { QScreen *screen = QGuiApplication::primaryScreen(); std::for_each(info.desktopsData.cbegin(), info.desktopsData.cend(), [&toolTipScene, &screen](const WindowData &data) { QPixmap desktop = screen->grabWindow(data.id); toolTipScene->addPixmap(desktop)->setOffset(data.rect.left(), data.rect.top()); }); } else if (m_tooltipType == "windows") { QScreen *screen = QGuiApplication::primaryScreen(); std::for_each(info.desktopsData.cbegin(), info.desktopsData.cend(), [&toolTipScene, &screen](const WindowData &data) { QPixmap desktop = screen->grabWindow(data.id); toolTipScene->addPixmap(desktop)->setOffset(data.rect.left(), data.rect.top()); }); std::for_each(info.windowsData.cbegin(), info.windowsData.cend(), [&toolTipScene, &screen](const WindowData &data) { QPixmap window = screen->grabWindow(data.id); toolTipScene->addPixmap(window)->setOffset(data.rect.left(), data.rect.top()); }); } QPixmap image = toolTipView->grab().scaledToWidth(m_tooltipWidth); QByteArray byteArray; QBuffer buffer(&byteArray); image.save(&buffer, "PNG"); delete toolTipView; delete toolTipScene; return QString("").arg(QString(byteArray.toBase64())); } QString DPAdds::parsePattern(const QString &_pattern, const int _desktop) const { qCDebug(LOG_DP) << "Pattern" << _pattern << "for desktop" << _desktop; QString parsed = _pattern; parsed.replace("$$", "$\\$\\"); for (auto &key : dictKeys()) parsed.replace(QString("$%1").arg(key), valueByKey(key, _desktop)); parsed.replace("$\\$\\", "$$"); return parsed; } void DPAdds::setMark(const QString &_newMark) { qCDebug(LOG_DP) << "Mark" << _newMark; m_mark = _newMark; } void DPAdds::setToolTipData(const QVariantMap &_tooltipData) { qCDebug(LOG_DP) << "Data" << _tooltipData; m_tooltipColor = _tooltipData["tooltipColor"].toString(); m_tooltipType = _tooltipData["tooltipType"].toString(); m_tooltipWidth = _tooltipData["tooltipWidth"].toInt(); } QString DPAdds::infoByKey(const QString &_key) { qCDebug(LOG_AW) << "Requested info for key" << _key; return "(none)"; } QString DPAdds::valueByKey(const QString &_key, int _desktop) const { qCDebug(LOG_DP) << "Requested key" << _key << "for desktop" << _desktop; if (_desktop == -1) _desktop = currentDesktop(); QString currentMark = currentDesktop() == _desktop ? m_mark : ""; if (_key == "mark") return QString("%1") .arg(currentMark, m_mark.count(), QLatin1Char(' ')) .replace(" ", " "); else if (_key == "name") return KX11Extras::desktopName(_desktop).replace(" ", " "); else if (_key == "number") return QString::number(_desktop); else if (_key == "total") return QString::number(numberOfDesktops()); else return ""; } // HACK: this method uses variables from version.h QString DPAdds::getAboutText(const QString &_type) { qCDebug(LOG_DP) << "Type" << _type; return AWDebug::getAboutText(_type); } QVariantMap DPAdds::getFont(const QVariantMap &_defaultFont) { qCDebug(LOG_DP) << "Default font is" << _defaultFont; QVariantMap fontMap; int ret = 0; CFont defaultCFont = CFont(_defaultFont["family"].toString(), _defaultFont["size"].toInt(), 400, false, _defaultFont["color"].toString()); CFont font = CFontDialog::getFont(i18n("Select font"), defaultCFont, false, false, &ret); fontMap["applied"] = ret; fontMap["color"] = font.color().name(); fontMap["family"] = font.family(); fontMap["size"] = font.pointSize(); return fontMap; } // to avoid additional object definition this method is static void DPAdds::sendNotification(const QString &_eventId, const QString &_message) { qCDebug(LOG_DP) << "Event" << _eventId << "with message" << _message; KNotification *notification = KNotification::event(_eventId, QString("Desktop Panel ::: %1").arg(_eventId), _message); notification->setComponentName("plasma-applet-org.kde.plasma.desktop-panel"); } // slot for mouse click void DPAdds::setCurrentDesktop(const int _desktop) { qCDebug(LOG_DP) << "Desktop" << _desktop; KX11Extras::setCurrentDesktop(_desktop); } DPAdds::DesktopWindowsInfo DPAdds::getInfoByDesktop(const int _desktop) { qCDebug(LOG_DP) << "Desktop" << _desktop; DesktopWindowsInfo info; info.desktop = KX11Extras::workArea(_desktop); for (auto &id : KX11Extras::windows()) { KWindowInfo winInfo = KWindowInfo( id, NET::Property::WMDesktop | NET::Property::WMGeometry | NET::Property::WMState | NET::Property::WMWindowType | NET::Property::WMVisibleName); if (!winInfo.isOnDesktop(_desktop)) continue; WindowData data; data.id = id; data.name = winInfo.visibleName(); data.rect = winInfo.geometry(); if (winInfo.windowType(NET::WindowTypeMask::NormalMask) == NET::WindowType::Normal) { if (winInfo.isMinimized()) continue; info.windowsData.append(data); } else if (winInfo.windowType(NET::WindowTypeMask::DesktopMask) == NET::WindowType::Desktop) { info.desktopsData.append(data); } } return info; }