Add files from breeze10
This commit is contained in:
parent
4b084789fd
commit
8fb2644d49
45 changed files with 6935 additions and 0 deletions
124
CMakeLists.txt
Normal file
124
CMakeLists.txt
Normal file
|
@ -0,0 +1,124 @@
|
|||
|
||||
project(breeze10)
|
||||
set(PROJECT_VERSION "0.1")
|
||||
set(PROJECT_VERSION_MAJOR 0)
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
|
||||
|
||||
include(WriteBasicConfigVersionFile)
|
||||
include(FeatureSummary)
|
||||
|
||||
find_package(ECM 0.0.9 REQUIRED NO_MODULE)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules")
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_SOURCE_DIR}/cmake)
|
||||
|
||||
include(ECMInstallIcons)
|
||||
include(KDEInstallDirs)
|
||||
include(KDECMakeSettings)
|
||||
include(KDECompilerSettings NO_POLICY_SCOPE)
|
||||
include(GenerateExportHeader)
|
||||
# include(GtkUpdateIconCache)
|
||||
|
||||
find_package(KDecoration2 REQUIRED)
|
||||
|
||||
|
||||
# old stuff
|
||||
add_definitions(-DTRANSLATION_DOMAIN="breeze_kwin_deco")
|
||||
|
||||
find_package(KF5 REQUIRED COMPONENTS CoreAddons GuiAddons ConfigWidgets WindowSystem I18n)
|
||||
find_package(Qt5 CONFIG REQUIRED COMPONENTS DBus)
|
||||
|
||||
### XCB
|
||||
find_package(XCB COMPONENTS XCB)
|
||||
set_package_properties(XCB PROPERTIES
|
||||
DESCRIPTION "X protocol C-language Binding"
|
||||
URL "http://xcb.freedesktop.org"
|
||||
TYPE OPTIONAL
|
||||
PURPOSE "Required to pass style properties to native Windows on X11 Platform"
|
||||
)
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
|
||||
set(BREEZE_HAVE_X11 ${XCB_XCB_FOUND})
|
||||
if (XCB_XCB_FOUND)
|
||||
find_package(Qt5 REQUIRED CONFIG COMPONENTS X11Extras)
|
||||
endif()
|
||||
|
||||
else()
|
||||
|
||||
set(BREEZE_HAVE_X11 FALSE)
|
||||
|
||||
endif()
|
||||
|
||||
################# configuration #################
|
||||
configure_file(config-breeze.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-breeze.h )
|
||||
|
||||
################# includes #################
|
||||
add_subdirectory(libbreezecommon)
|
||||
|
||||
################# newt target #################
|
||||
### plugin classes
|
||||
set(breeze10_SRCS
|
||||
breezebutton.cpp
|
||||
breezedecoration.cpp
|
||||
breezeexceptionlist.cpp
|
||||
breezesettingsprovider.cpp
|
||||
breezesizegrip.cpp)
|
||||
|
||||
kconfig_add_kcfg_files(breeze10_SRCS breezesettings.kcfgc)
|
||||
|
||||
### config classes
|
||||
### they are kept separately because they might move in a separate library in the future
|
||||
set(breeze10_config_SRCS
|
||||
config/breezeconfigwidget.cpp
|
||||
config/breezedetectwidget.cpp
|
||||
config/breezeexceptiondialog.cpp
|
||||
config/breezeexceptionlistwidget.cpp
|
||||
config/breezeexceptionmodel.cpp
|
||||
config/breezeitemmodel.cpp
|
||||
)
|
||||
|
||||
set(breeze10_config_PART_FORMS
|
||||
config/ui/breezeconfigurationui.ui
|
||||
config/ui/breezedetectwidget.ui
|
||||
config/ui/breezeexceptiondialog.ui
|
||||
config/ui/breezeexceptionlistwidget.ui
|
||||
)
|
||||
|
||||
ki18n_wrap_ui(breeze10_config_PART_FORMS_HEADERS ${breeze10_config_PART_FORMS})
|
||||
|
||||
### build library
|
||||
add_library(breeze10 MODULE
|
||||
${breeze10_SRCS}
|
||||
${breeze10_config_SRCS}
|
||||
${breeze10_config_PART_FORMS_HEADERS})
|
||||
|
||||
target_link_libraries(breeze10
|
||||
PUBLIC
|
||||
Qt5::Core
|
||||
Qt5::Gui
|
||||
Qt5::DBus
|
||||
PRIVATE
|
||||
breeze10common5
|
||||
KDecoration2::KDecoration
|
||||
KF5::ConfigCore
|
||||
KF5::CoreAddons
|
||||
KF5::ConfigWidgets
|
||||
KF5::GuiAddons
|
||||
KF5::I18n
|
||||
KF5::WindowSystem)
|
||||
|
||||
if(BREEZE_HAVE_X11)
|
||||
target_link_libraries(breeze10
|
||||
PUBLIC
|
||||
Qt5::X11Extras
|
||||
XCB::XCB)
|
||||
endif()
|
||||
|
||||
|
||||
install(TARGETS breeze10 DESTINATION ${PLUGIN_INSTALL_DIR}/org.kde.kdecoration2)
|
||||
install(FILES config/breeze10config.desktop DESTINATION ${SERVICES_INSTALL_DIR})
|
||||
# install(TARGETS breezedecoration DESTINATION ${PLUGIN_INSTALL_DIR}/org.kde.kdecoration2)
|
||||
# install(FILES config/breezedecorationconfig.desktop DESTINATION ${SERVICES_INSTALL_DIR})
|
3
ChangeLog
Normal file
3
ChangeLog
Normal file
|
@ -0,0 +1,3 @@
|
|||
V5.16
|
||||
---------
|
||||
* Initial release.
|
4
Messages.sh
Normal file
4
Messages.sh
Normal file
|
@ -0,0 +1,4 @@
|
|||
#!bin/sh
|
||||
$EXTRACTRC `find . -name \*.rc -o -name \*.ui -o -name \*.kcfg` >> rc.cpp
|
||||
$XGETTEXT `find . -name \*.cc -o -name \*.cpp -o -name \*.h` -o $podir/breeze_kwin_deco.pot
|
||||
rm -f rc.cpp
|
5
NEWS
Normal file
5
NEWS
Normal file
|
@ -0,0 +1,5 @@
|
|||
Latest version:
|
||||
|
||||
18 Jun 2019, V5.16
|
||||
|
||||
See "ChangeLog" for changes.
|
53
breeze.h
Normal file
53
breeze.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
#ifndef breeze_h
|
||||
#define breeze_h
|
||||
|
||||
/*
|
||||
* Copyright 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "breezesettings.h"
|
||||
|
||||
#include <QSharedPointer>
|
||||
#include <QList>
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
//* convenience typedefs
|
||||
using InternalSettingsPtr = QSharedPointer<InternalSettings>;
|
||||
using InternalSettingsList = QList<InternalSettingsPtr>;
|
||||
using InternalSettingsListIterator = QListIterator<InternalSettingsPtr>;
|
||||
|
||||
//* metrics
|
||||
enum Metrics
|
||||
{
|
||||
|
||||
// shadow dimensions (pixels)
|
||||
Shadow_Overlap = 3,
|
||||
|
||||
};
|
||||
|
||||
//* exception
|
||||
enum ExceptionMask
|
||||
{
|
||||
None = 0,
|
||||
BorderSize = 1<<4
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
16
breeze.json
Normal file
16
breeze.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"KPlugin": {
|
||||
"Description": "Window decoration using the Breeze visual style for the Plasma Desktop",
|
||||
"EnabledByDefault": true,
|
||||
"Id": "com.github.fauzie811.breeze10",
|
||||
"Name": "Breeze10",
|
||||
"ServiceTypes": [
|
||||
"org.kde.kdecoration2"
|
||||
]
|
||||
},
|
||||
"org.kde.kdecoration2": {
|
||||
"blur": true,
|
||||
"defaultTheme": "Breeze10",
|
||||
"kcmodule": true
|
||||
}
|
||||
}
|
531
breezebutton.cpp
Normal file
531
breezebutton.cpp
Normal file
|
@ -0,0 +1,531 @@
|
|||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
* Copyright 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "breezebutton.h"
|
||||
|
||||
#include <KDecoration2/DecoratedClient>
|
||||
#include <KColorUtils>
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
using KDecoration2::ColorRole;
|
||||
using KDecoration2::ColorGroup;
|
||||
using KDecoration2::DecorationButtonType;
|
||||
|
||||
|
||||
//__________________________________________________________________
|
||||
Button::Button(DecorationButtonType type, Decoration* decoration, QObject* parent)
|
||||
: DecorationButton(type, decoration, parent)
|
||||
, m_animation( new QPropertyAnimation( this ) )
|
||||
{
|
||||
|
||||
// setup animation
|
||||
m_animation->setStartValue( 0 );
|
||||
m_animation->setEndValue( 1.0 );
|
||||
m_animation->setTargetObject( this );
|
||||
m_animation->setPropertyName( "opacity" );
|
||||
m_animation->setEasingCurve( QEasingCurve::InOutQuad );
|
||||
|
||||
// setup default geometry
|
||||
const int height = decoration->buttonHeight();
|
||||
const int width = height * (type == DecorationButtonType::Menu ? 1.0 : 1.5);
|
||||
setGeometry(QRect(0, 0, width, height));
|
||||
setIconSize(QSize( width, height ));
|
||||
|
||||
// connections
|
||||
connect(decoration->client().data(), SIGNAL(iconChanged(QIcon)), this, SLOT(update()));
|
||||
connect(decoration->settings().data(), &KDecoration2::DecorationSettings::reconfigured, this, &Button::reconfigure);
|
||||
connect( this, &KDecoration2::DecorationButton::hoveredChanged, this, &Button::updateAnimationState );
|
||||
|
||||
reconfigure();
|
||||
|
||||
}
|
||||
|
||||
//__________________________________________________________________
|
||||
Button::Button(QObject *parent, const QVariantList &args)
|
||||
: Button(args.at(0).value<DecorationButtonType>(), args.at(1).value<Decoration*>(), parent)
|
||||
{
|
||||
m_flag = FlagStandalone;
|
||||
//! icon size must return to !valid because it was altered from the default constructor,
|
||||
//! in Standalone mode the button is not using the decoration metrics but its geometry
|
||||
m_iconSize = QSize(-1, -1);
|
||||
}
|
||||
|
||||
//__________________________________________________________________
|
||||
Button *Button::create(DecorationButtonType type, KDecoration2::Decoration *decoration, QObject *parent)
|
||||
{
|
||||
if (auto d = qobject_cast<Decoration*>(decoration))
|
||||
{
|
||||
Button *b = new Button(type, d, parent);
|
||||
switch( type )
|
||||
{
|
||||
|
||||
case DecorationButtonType::Close:
|
||||
b->setVisible( d->client().data()->isCloseable() );
|
||||
QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::closeableChanged, b, &Breeze::Button::setVisible );
|
||||
break;
|
||||
|
||||
case DecorationButtonType::Maximize:
|
||||
b->setVisible( d->client().data()->isMaximizeable() );
|
||||
QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::maximizeableChanged, b, &Breeze::Button::setVisible );
|
||||
break;
|
||||
|
||||
case DecorationButtonType::Minimize:
|
||||
b->setVisible( d->client().data()->isMinimizeable() );
|
||||
QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::minimizeableChanged, b, &Breeze::Button::setVisible );
|
||||
break;
|
||||
|
||||
case DecorationButtonType::ContextHelp:
|
||||
b->setVisible( d->client().data()->providesContextHelp() );
|
||||
QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::providesContextHelpChanged, b, &Breeze::Button::setVisible );
|
||||
break;
|
||||
|
||||
case DecorationButtonType::Shade:
|
||||
b->setVisible( d->client().data()->isShadeable() );
|
||||
QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::shadeableChanged, b, &Breeze::Button::setVisible );
|
||||
break;
|
||||
|
||||
case DecorationButtonType::Menu:
|
||||
QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::iconChanged, b, [b]() { b->update(); });
|
||||
break;
|
||||
|
||||
default: break;
|
||||
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
//__________________________________________________________________
|
||||
void Button::paint(QPainter *painter, const QRect &repaintRegion)
|
||||
{
|
||||
Q_UNUSED(repaintRegion)
|
||||
|
||||
if (!decoration()) return;
|
||||
|
||||
painter->save();
|
||||
|
||||
// translate from offset
|
||||
if( m_flag == FlagFirstInList ) painter->translate( m_offset );
|
||||
else painter->translate( 0, m_offset.y() );
|
||||
|
||||
if( !m_iconSize.isValid() ) m_iconSize = geometry().size().toSize();
|
||||
|
||||
// menu button
|
||||
if (type() == DecorationButtonType::Menu)
|
||||
{
|
||||
|
||||
// const QRectF iconRect( geometry().topLeft(), m_iconSize );
|
||||
const int menuIconSize = (qobject_cast<Decoration *>(decoration()))->iconSize();
|
||||
const qreal topLeft = (geometry().width()/2) - (menuIconSize/2);
|
||||
|
||||
const QRectF iconRect(topLeft + geometry().left(), topLeft + geometry().top(), menuIconSize, menuIconSize);
|
||||
decoration()->client().data()->icon().paint(painter, iconRect.toRect());
|
||||
|
||||
} else {
|
||||
|
||||
drawIcon( painter );
|
||||
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
|
||||
}
|
||||
|
||||
//__________________________________________________________________
|
||||
void Button::drawIcon( QPainter *painter ) const
|
||||
{
|
||||
|
||||
painter->setRenderHints( QPainter::Antialiasing );
|
||||
|
||||
/*
|
||||
scale painter so that its window matches QRect( 0, 0, 45, 30 )
|
||||
this makes all further rendering and scaling simpler
|
||||
all further rendering is preformed inside QRect( 0, 0, 45, 30 )
|
||||
*/
|
||||
painter->translate( geometry().topLeft() );
|
||||
|
||||
const qreal height( m_iconSize.height() );
|
||||
const qreal width( m_iconSize.width() );
|
||||
if ( height != 30 )
|
||||
painter->scale( width/45, height/30 );
|
||||
|
||||
// render background
|
||||
const QColor backgroundColor( this->backgroundColor() );
|
||||
|
||||
auto d = qobject_cast<Decoration*>( decoration() );
|
||||
bool isInactive(d && !d->client().data()->isActive()
|
||||
&& !isHovered() && !isPressed()
|
||||
&& m_animation->state() != QPropertyAnimation::Running);
|
||||
QColor inactiveCol(Qt::gray);
|
||||
if (isInactive)
|
||||
{
|
||||
int gray = qGray(d->titleBarColor().rgb());
|
||||
if (gray <= 200) {
|
||||
gray += 55;
|
||||
gray = qMax(gray, 115);
|
||||
}
|
||||
else gray -= 45;
|
||||
inactiveCol = QColor(gray, gray, gray);
|
||||
}
|
||||
|
||||
// render mark
|
||||
const QColor foregroundColor( this->foregroundColor() );
|
||||
if( foregroundColor.isValid() )
|
||||
{
|
||||
|
||||
// setup painter
|
||||
QPen pen( foregroundColor );
|
||||
pen.setCapStyle( Qt::FlatCap );
|
||||
pen.setJoinStyle( Qt::MiterJoin );
|
||||
// pen.setWidthF( 1.0*qMax((qreal)1.0, 30/width ) );
|
||||
pen.setWidthF( 1.0 );
|
||||
|
||||
switch( type() )
|
||||
{
|
||||
|
||||
case DecorationButtonType::Close:
|
||||
{
|
||||
if( backgroundColor.isValid() )
|
||||
{
|
||||
painter->setPen( Qt::NoPen );
|
||||
painter->setBrush( backgroundColor );
|
||||
painter->drawRect( QRectF( 0, 0, 45, 30 ) );
|
||||
}
|
||||
pen.setWidthF( 1.1 );
|
||||
painter->setPen( pen );
|
||||
painter->setBrush( Qt::NoBrush );
|
||||
|
||||
painter->drawLine( QPointF( 18, 10 ), QPointF( 28, 20 ) );
|
||||
painter->drawLine( QPointF( 18, 20 ), QPointF( 28, 10 ) );
|
||||
pen.setWidthF( 1.0 );
|
||||
break;
|
||||
}
|
||||
|
||||
case DecorationButtonType::Maximize:
|
||||
{
|
||||
if( backgroundColor.isValid() )
|
||||
{
|
||||
painter->setPen( Qt::NoPen );
|
||||
painter->setBrush( backgroundColor );
|
||||
painter->drawRect( QRectF( 0, 0, 45, 30 ) );
|
||||
}
|
||||
|
||||
painter->setPen( pen );
|
||||
painter->setBrush( Qt::NoBrush );
|
||||
|
||||
if (isChecked())
|
||||
{
|
||||
painter->drawRect(QRectF(18.5, 12.5, 7.0, 7.0));
|
||||
painter->drawPolyline(QPolygonF()
|
||||
<< QPointF(20.5, 12.5) << QPointF(20.5, 10.5) << QPointF(27.5, 10.5) << QPointF(27.5, 17.5) << QPointF(25.5, 17.5));
|
||||
}
|
||||
else {
|
||||
painter->drawRect(QRectF(18.5, 10.5, 9.0, 9.0));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DecorationButtonType::Minimize:
|
||||
{
|
||||
if( backgroundColor.isValid() )
|
||||
{
|
||||
painter->setPen( Qt::NoPen );
|
||||
painter->setBrush( backgroundColor );
|
||||
painter->drawRect( QRectF( 0, 0, 45, 30 ) );
|
||||
}
|
||||
|
||||
painter->setPen( pen );
|
||||
painter->setBrush( Qt::NoBrush );
|
||||
|
||||
painter->drawLine( QPointF( 18, 15.5 ), QPointF( 28, 15.5 ) );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DecorationButtonType::OnAllDesktops:
|
||||
{
|
||||
painter->setPen( Qt::NoPen );
|
||||
if( backgroundColor.isValid() )
|
||||
{
|
||||
painter->setBrush( backgroundColor );
|
||||
painter->drawRect( QRectF( 0, 0, 45, 30 ) );
|
||||
}
|
||||
painter->setBrush( foregroundColor );
|
||||
|
||||
if( isChecked()) {
|
||||
|
||||
// outer ring
|
||||
painter->drawRect( QRectF( 16, 9, 12, 12 ) );
|
||||
|
||||
// center dot
|
||||
QColor backgroundColor( this->backgroundColor() );
|
||||
if( !backgroundColor.isValid() && d ) backgroundColor = d->titleBarColor();
|
||||
|
||||
if( backgroundColor.isValid() )
|
||||
{
|
||||
painter->setBrush( backgroundColor );
|
||||
painter->drawRect( QRectF( 21, 14, 2, 2 ) );
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
painter->drawPolygon( QPolygonF()
|
||||
<< QPointF( 19.5, 14.5 )
|
||||
<< QPointF( 25, 9 )
|
||||
<< QPointF( 28, 12 )
|
||||
<< QPointF( 22.5, 17.5 ) );
|
||||
|
||||
painter->setPen( pen );
|
||||
painter->drawLine( QPointF( 18.5, 13.5 ), QPointF( 23.5, 18.5 ) );
|
||||
painter->drawLine( QPointF( 25, 12 ), QPointF( 17.5, 19.5 ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case DecorationButtonType::Shade:
|
||||
{
|
||||
if( backgroundColor.isValid() )
|
||||
{
|
||||
painter->setPen( Qt::NoPen );
|
||||
painter->setBrush( backgroundColor );
|
||||
painter->drawRect( QRectF( 0, 0, 45, 30 ) );
|
||||
}
|
||||
painter->setPen( pen );
|
||||
painter->setBrush( Qt::NoBrush );
|
||||
|
||||
painter->drawLine( 18, 12, 26, 12 );
|
||||
if (isChecked()) {
|
||||
painter->drawPolyline( QPolygonF()
|
||||
<< QPointF( 18, 15 )
|
||||
<< QPointF( 22, 19 )
|
||||
<< QPointF( 26, 15 ) );
|
||||
|
||||
} else {
|
||||
painter->drawPolyline( QPolygonF()
|
||||
<< QPointF( 18, 19 )
|
||||
<< QPointF( 22, 15 )
|
||||
<< QPointF( 26, 19 ) );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case DecorationButtonType::KeepBelow:
|
||||
{
|
||||
if( backgroundColor.isValid() )
|
||||
{
|
||||
painter->setPen( Qt::NoPen );
|
||||
painter->setBrush( backgroundColor );
|
||||
painter->drawRect( QRectF( 0, 0, 45, 30 ) );
|
||||
}
|
||||
painter->setPen( pen );
|
||||
painter->setBrush( Qt::NoBrush );
|
||||
|
||||
painter->drawPolyline( QPolygonF()
|
||||
<< QPointF( 18, 11 )
|
||||
<< QPointF( 22, 15 )
|
||||
<< QPointF( 26, 11 ) );
|
||||
|
||||
painter->drawPolyline( QPolygonF()
|
||||
<< QPointF( 18, 15 )
|
||||
<< QPointF( 22, 19 )
|
||||
<< QPointF( 26, 15 ) );
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case DecorationButtonType::KeepAbove:
|
||||
{
|
||||
if( backgroundColor.isValid() )
|
||||
{
|
||||
painter->setPen( Qt::NoPen );
|
||||
painter->setBrush( backgroundColor );
|
||||
painter->drawRect( QRectF( 0, 0, 45, 30 ) );
|
||||
}
|
||||
painter->setPen( pen );
|
||||
painter->setBrush( Qt::NoBrush );
|
||||
|
||||
painter->drawPolyline( QPolygonF()
|
||||
<< QPointF( 18, 15 )
|
||||
<< QPointF( 22, 11 )
|
||||
<< QPointF( 26, 15 ) );
|
||||
|
||||
painter->drawPolyline( QPolygonF()
|
||||
<< QPointF( 18, 19 )
|
||||
<< QPointF( 22, 15 )
|
||||
<< QPointF( 26, 19 ) );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case DecorationButtonType::ApplicationMenu:
|
||||
{
|
||||
if( backgroundColor.isValid() )
|
||||
{
|
||||
painter->setPen( Qt::NoPen );
|
||||
painter->setBrush( backgroundColor );
|
||||
painter->drawRect( QRectF( 0, 0, 45, 30 ) );
|
||||
}
|
||||
painter->setPen( pen );
|
||||
painter->setBrush( Qt::NoBrush );
|
||||
|
||||
painter->drawLine( QPointF( 15, 11.5 ), QPointF( 30, 11.5 ) );
|
||||
painter->drawLine( QPointF( 15, 15.5 ), QPointF( 30, 15.5 ) );
|
||||
painter->drawLine( QPointF( 15, 19.5 ), QPointF( 30, 19.5 ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case DecorationButtonType::ContextHelp:
|
||||
{
|
||||
if( backgroundColor.isValid() )
|
||||
{
|
||||
painter->setPen( Qt::NoPen );
|
||||
painter->setBrush( backgroundColor );
|
||||
painter->drawRect( QRectF( 0, 0, 45, 30 ) );
|
||||
}
|
||||
painter->setPen( pen );
|
||||
painter->setBrush( Qt::NoBrush );
|
||||
|
||||
QPainterPath path;
|
||||
path.moveTo( 18, 12 );
|
||||
path.arcTo( QRectF( 18, 9.5, 8, 5 ), 180, -180 );
|
||||
path.cubicTo( QPointF(26.5, 15.5), QPointF( 22, 13.5 ), QPointF( 22, 17.5 ) );
|
||||
painter->drawPath( path );
|
||||
|
||||
painter->drawPoint( 22, 21 );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//__________________________________________________________________
|
||||
QColor Button::foregroundColor() const
|
||||
{
|
||||
auto d = qobject_cast<Decoration*>( decoration() );
|
||||
if( !d ) {
|
||||
|
||||
return QColor();
|
||||
|
||||
} else if( ( type() == DecorationButtonType::KeepBelow || type() == DecorationButtonType::KeepAbove ) && isChecked() ) {
|
||||
|
||||
return d->titleBarColor();
|
||||
|
||||
} else if( m_animation->state() == QPropertyAnimation::Running && type() == DecorationButtonType::Close ) {
|
||||
|
||||
return KColorUtils::mix( d->fontColor(), Qt::white, m_opacity );
|
||||
|
||||
} else if( isHovered() && type() == DecorationButtonType::Close ) {
|
||||
|
||||
return Qt::white;
|
||||
|
||||
} else {
|
||||
|
||||
return d->fontColor();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//__________________________________________________________________
|
||||
QColor Button::backgroundColor() const
|
||||
{
|
||||
auto d = qobject_cast<Decoration*>( decoration() );
|
||||
if( !d ) {
|
||||
|
||||
return QColor();
|
||||
|
||||
}
|
||||
|
||||
if( isPressed() ) {
|
||||
|
||||
if( type() == DecorationButtonType::Close ) return KColorUtils::mix( Qt::red, Qt::black, 0.3 );
|
||||
else return KColorUtils::mix( d->titleBarColor(), d->fontColor(), 0.3 );
|
||||
|
||||
} else if( ( type() == DecorationButtonType::KeepBelow || type() == DecorationButtonType::KeepAbove ) && isChecked() ) {
|
||||
|
||||
return d->fontColor();
|
||||
|
||||
} else if( m_animation->state() == QPropertyAnimation::Running ) {
|
||||
|
||||
if( type() == DecorationButtonType::Close ) return KColorUtils::mix( d->titleBarColor(), Qt::red, m_opacity );
|
||||
else {
|
||||
|
||||
QColor color( KColorUtils::mix( d->titleBarColor(), d->fontColor(), 0.2 ) );
|
||||
color.setAlpha( color.alpha()*m_opacity );
|
||||
return color;
|
||||
|
||||
}
|
||||
|
||||
} else if( isHovered() ) {
|
||||
|
||||
if( type() == DecorationButtonType::Close ) return Qt::red;
|
||||
else return KColorUtils::mix( d->titleBarColor(), d->fontColor(), 0.2 );
|
||||
|
||||
} else {
|
||||
|
||||
return QColor();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
void Button::reconfigure()
|
||||
{
|
||||
|
||||
// animation
|
||||
auto d = qobject_cast<Decoration*>(decoration());
|
||||
if( d ) m_animation->setDuration( d->internalSettings()->animationsDuration() );
|
||||
|
||||
}
|
||||
|
||||
//__________________________________________________________________
|
||||
void Button::updateAnimationState( bool hovered )
|
||||
{
|
||||
|
||||
auto d = qobject_cast<Decoration*>(decoration());
|
||||
if( !(d && d->internalSettings()->animationsEnabled() ) ) return;
|
||||
|
||||
QAbstractAnimation::Direction dir = hovered ? QPropertyAnimation::Forward : QPropertyAnimation::Backward;
|
||||
if( m_animation->state() == QPropertyAnimation::Running && m_animation->direction() != dir )
|
||||
m_animation->stop();
|
||||
m_animation->setDirection( dir );
|
||||
if( m_animation->state() != QPropertyAnimation::Running ) m_animation->start();
|
||||
|
||||
}
|
||||
|
||||
} // namespace
|
140
breezebutton.h
Normal file
140
breezebutton.h
Normal file
|
@ -0,0 +1,140 @@
|
|||
#ifndef BREEZE_BUTTONS_H
|
||||
#define BREEZE_BUTTONS_H
|
||||
|
||||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
* Copyright 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <KDecoration2/DecorationButton>
|
||||
#include "breezedecoration.h"
|
||||
|
||||
#include <QHash>
|
||||
#include <QImage>
|
||||
#include <QPropertyAnimation>
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
class Button : public KDecoration2::DecorationButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
//* declare active state opacity
|
||||
Q_PROPERTY( qreal opacity READ opacity WRITE setOpacity )
|
||||
|
||||
public:
|
||||
|
||||
//* constructor
|
||||
explicit Button(QObject *parent, const QVariantList &args);
|
||||
|
||||
//* destructor
|
||||
virtual ~Button() = default;
|
||||
|
||||
//* button creation
|
||||
static Button *create(KDecoration2::DecorationButtonType type, KDecoration2::Decoration *decoration, QObject *parent);
|
||||
|
||||
//* render
|
||||
virtual void paint(QPainter *painter, const QRect &repaintRegion) override;
|
||||
|
||||
//* flag
|
||||
enum Flag
|
||||
{
|
||||
FlagNone,
|
||||
FlagStandalone,
|
||||
FlagFirstInList,
|
||||
FlagLastInList
|
||||
};
|
||||
|
||||
//* flag
|
||||
void setFlag( Flag value )
|
||||
{ m_flag = value; }
|
||||
|
||||
//* standalone buttons
|
||||
bool isStandAlone() const { return m_flag == FlagStandalone; }
|
||||
|
||||
//* offset
|
||||
void setOffset( const QPointF& value )
|
||||
{ m_offset = value; }
|
||||
|
||||
//* horizontal offset, for rendering
|
||||
void setHorizontalOffset( qreal value )
|
||||
{ m_offset.setX( value ); }
|
||||
|
||||
//* vertical offset, for rendering
|
||||
void setVerticalOffset( qreal value )
|
||||
{ m_offset.setY( value ); }
|
||||
|
||||
//* set icon size
|
||||
void setIconSize( const QSize& value )
|
||||
{ m_iconSize = value; }
|
||||
|
||||
//*@name active state change animation
|
||||
//@{
|
||||
void setOpacity( qreal value )
|
||||
{
|
||||
if( m_opacity == value ) return;
|
||||
m_opacity = value;
|
||||
update();
|
||||
}
|
||||
|
||||
qreal opacity() const
|
||||
{ return m_opacity; }
|
||||
|
||||
//@}
|
||||
|
||||
private Q_SLOTS:
|
||||
|
||||
//* apply configuration changes
|
||||
void reconfigure();
|
||||
|
||||
//* animation state
|
||||
void updateAnimationState(bool);
|
||||
|
||||
private:
|
||||
|
||||
//* private constructor
|
||||
explicit Button(KDecoration2::DecorationButtonType type, Decoration *decoration, QObject *parent = nullptr);
|
||||
|
||||
//* draw button icon
|
||||
void drawIcon( QPainter *) const;
|
||||
|
||||
//*@name colors
|
||||
//@{
|
||||
QColor foregroundColor() const;
|
||||
QColor backgroundColor() const;
|
||||
//@}
|
||||
|
||||
Flag m_flag = FlagNone;
|
||||
|
||||
//* active state change animation
|
||||
QPropertyAnimation *m_animation;
|
||||
|
||||
//* vertical offset (for rendering)
|
||||
QPointF m_offset;
|
||||
|
||||
//* icon size
|
||||
QSize m_iconSize;
|
||||
|
||||
//* active state change opacity
|
||||
qreal m_opacity = 0;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
768
breezedecoration.cpp
Normal file
768
breezedecoration.cpp
Normal file
|
@ -0,0 +1,768 @@
|
|||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
* Copyright 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "breezedecoration.h"
|
||||
|
||||
#include "breeze.h"
|
||||
#include "breezesettingsprovider.h"
|
||||
#include "config-breeze.h"
|
||||
#include "config/breezeconfigwidget.h"
|
||||
|
||||
#include "breezebutton.h"
|
||||
#include "breezesizegrip.h"
|
||||
|
||||
#include "breezeboxshadowrenderer.h"
|
||||
|
||||
#include <KDecoration2/DecoratedClient>
|
||||
#include <KDecoration2/DecorationButtonGroup>
|
||||
#include <KDecoration2/DecorationSettings>
|
||||
#include <KDecoration2/DecorationShadow>
|
||||
|
||||
#include <KConfigGroup>
|
||||
#include <KColorUtils>
|
||||
#include <KSharedConfig>
|
||||
#include <KPluginFactory>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QTextStream>
|
||||
#include <QTimer>
|
||||
|
||||
#if BREEZE_HAVE_X11
|
||||
#include <QX11Info>
|
||||
#endif
|
||||
|
||||
#include <cmath>
|
||||
|
||||
K_PLUGIN_FACTORY_WITH_JSON(
|
||||
BreezeDecoFactory,
|
||||
"breeze.json",
|
||||
registerPlugin<Breeze::Decoration>();
|
||||
registerPlugin<Breeze::Button>(QStringLiteral("button"));
|
||||
registerPlugin<Breeze::ConfigWidget>(QStringLiteral("kcmodule"));
|
||||
)
|
||||
|
||||
namespace
|
||||
{
|
||||
struct ShadowParams {
|
||||
ShadowParams()
|
||||
: offset(QPoint(0, 0))
|
||||
, radius(0)
|
||||
, opacity(0) {}
|
||||
|
||||
ShadowParams(const QPoint &offset, int radius, qreal opacity)
|
||||
: offset(offset)
|
||||
, radius(radius)
|
||||
, opacity(opacity) {}
|
||||
|
||||
QPoint offset;
|
||||
int radius;
|
||||
qreal opacity;
|
||||
};
|
||||
|
||||
struct CompositeShadowParams {
|
||||
CompositeShadowParams() = default;
|
||||
|
||||
CompositeShadowParams(
|
||||
const QPoint &offset,
|
||||
const ShadowParams &shadow1,
|
||||
const ShadowParams &shadow2)
|
||||
: offset(offset)
|
||||
, shadow1(shadow1)
|
||||
, shadow2(shadow2) {}
|
||||
|
||||
bool isNone() const {
|
||||
return qMax(shadow1.radius, shadow2.radius) == 0;
|
||||
}
|
||||
|
||||
QPoint offset;
|
||||
ShadowParams shadow1;
|
||||
ShadowParams shadow2;
|
||||
};
|
||||
|
||||
const CompositeShadowParams s_shadowParams[] = {
|
||||
// None
|
||||
CompositeShadowParams(),
|
||||
// Small
|
||||
CompositeShadowParams(
|
||||
QPoint(0, 4),
|
||||
ShadowParams(QPoint(0, 0), 16, 1),
|
||||
ShadowParams(QPoint(0, -2), 8, 0.4)),
|
||||
// Medium
|
||||
CompositeShadowParams(
|
||||
QPoint(0, 8),
|
||||
ShadowParams(QPoint(0, 0), 32, 0.9),
|
||||
ShadowParams(QPoint(0, -4), 16, 0.3)),
|
||||
// Large
|
||||
CompositeShadowParams(
|
||||
QPoint(0, 12),
|
||||
ShadowParams(QPoint(0, 0), 48, 0.8),
|
||||
ShadowParams(QPoint(0, -6), 24, 0.2)),
|
||||
// Very large
|
||||
CompositeShadowParams(
|
||||
QPoint(0, 16),
|
||||
ShadowParams(QPoint(0, 0), 64, 0.7),
|
||||
ShadowParams(QPoint(0, -8), 32, 0.1)),
|
||||
};
|
||||
|
||||
inline CompositeShadowParams lookupShadowParams(int size)
|
||||
{
|
||||
switch (size) {
|
||||
case Breeze::InternalSettings::ShadowNone:
|
||||
return s_shadowParams[0];
|
||||
case Breeze::InternalSettings::ShadowSmall:
|
||||
return s_shadowParams[1];
|
||||
case Breeze::InternalSettings::ShadowMedium:
|
||||
return s_shadowParams[2];
|
||||
case Breeze::InternalSettings::ShadowLarge:
|
||||
return s_shadowParams[3];
|
||||
case Breeze::InternalSettings::ShadowVeryLarge:
|
||||
return s_shadowParams[4];
|
||||
default:
|
||||
// Fallback to the Large size.
|
||||
return s_shadowParams[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
using KDecoration2::ColorRole;
|
||||
using KDecoration2::ColorGroup;
|
||||
using KDecoration2::DecorationButtonType;
|
||||
|
||||
//________________________________________________________________
|
||||
static int g_sDecoCount = 0;
|
||||
static int g_shadowSizeEnum = InternalSettings::ShadowLarge;
|
||||
static int g_shadowStrength = 255;
|
||||
static QColor g_shadowColor = Qt::black;
|
||||
static QSharedPointer<KDecoration2::DecorationShadow> g_sShadow;
|
||||
|
||||
//________________________________________________________________
|
||||
Decoration::Decoration(QObject *parent, const QVariantList &args)
|
||||
: KDecoration2::Decoration(parent, args)
|
||||
, m_animation( new QPropertyAnimation( this ) )
|
||||
{
|
||||
g_sDecoCount++;
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
Decoration::~Decoration()
|
||||
{
|
||||
g_sDecoCount--;
|
||||
if (g_sDecoCount == 0) {
|
||||
// last deco destroyed, clean up shadow
|
||||
g_sShadow.clear();
|
||||
}
|
||||
|
||||
deleteSizeGrip();
|
||||
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
void Decoration::setOpacity( qreal value )
|
||||
{
|
||||
if( m_opacity == value ) return;
|
||||
m_opacity = value;
|
||||
update();
|
||||
|
||||
if( m_sizeGrip ) m_sizeGrip->update();
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
QColor Decoration::titleBarColor() const
|
||||
{
|
||||
|
||||
auto c = client().data();
|
||||
if( hideTitleBar() ) return c->color( ColorGroup::Inactive, ColorRole::TitleBar );
|
||||
else if( m_animation->state() == QPropertyAnimation::Running )
|
||||
{
|
||||
return KColorUtils::mix(
|
||||
c->color( ColorGroup::Inactive, ColorRole::TitleBar ),
|
||||
c->color( ColorGroup::Active, ColorRole::TitleBar ),
|
||||
m_opacity );
|
||||
} else return c->color( c->isActive() ? ColorGroup::Active : ColorGroup::Inactive, ColorRole::TitleBar );
|
||||
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
QColor Decoration::fontColor() const
|
||||
{
|
||||
|
||||
auto c = client().data();
|
||||
if( m_animation->state() == QPropertyAnimation::Running )
|
||||
{
|
||||
return KColorUtils::mix(
|
||||
c->color( ColorGroup::Inactive, ColorRole::Foreground ),
|
||||
c->color( ColorGroup::Active, ColorRole::Foreground ),
|
||||
m_opacity );
|
||||
} else return c->color( c->isActive() ? ColorGroup::Active : ColorGroup::Inactive, ColorRole::Foreground );
|
||||
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
void Decoration::init()
|
||||
{
|
||||
auto c = client().data();
|
||||
|
||||
// active state change animation
|
||||
m_animation->setStartValue( 0 );
|
||||
m_animation->setEndValue( 1.0 );
|
||||
m_animation->setTargetObject( this );
|
||||
m_animation->setPropertyName( "opacity" );
|
||||
m_animation->setEasingCurve( QEasingCurve::InOutQuad );
|
||||
|
||||
reconfigure();
|
||||
updateTitleBar();
|
||||
auto s = settings();
|
||||
connect(s.data(), &KDecoration2::DecorationSettings::borderSizeChanged, this, &Decoration::recalculateBorders);
|
||||
|
||||
// a change in font might cause the borders to change
|
||||
recalculateBorders();
|
||||
connect(s.data(), &KDecoration2::DecorationSettings::spacingChanged, this, &Decoration::recalculateBorders);
|
||||
|
||||
// buttons
|
||||
connect(s.data(), &KDecoration2::DecorationSettings::spacingChanged, this, &Decoration::updateButtonsGeometryDelayed);
|
||||
connect(s.data(), &KDecoration2::DecorationSettings::decorationButtonsLeftChanged, this, &Decoration::updateButtonsGeometryDelayed);
|
||||
connect(s.data(), &KDecoration2::DecorationSettings::decorationButtonsRightChanged, this, &Decoration::updateButtonsGeometryDelayed);
|
||||
|
||||
// full reconfiguration
|
||||
connect(s.data(), &KDecoration2::DecorationSettings::reconfigured, this, &Decoration::reconfigure);
|
||||
connect(s.data(), &KDecoration2::DecorationSettings::reconfigured, SettingsProvider::self(), &SettingsProvider::reconfigure, Qt::UniqueConnection );
|
||||
connect(s.data(), &KDecoration2::DecorationSettings::reconfigured, this, &Decoration::updateButtonsGeometryDelayed);
|
||||
|
||||
connect(c, &KDecoration2::DecoratedClient::adjacentScreenEdgesChanged, this, &Decoration::recalculateBorders);
|
||||
connect(c, &KDecoration2::DecoratedClient::maximizedHorizontallyChanged, this, &Decoration::recalculateBorders);
|
||||
connect(c, &KDecoration2::DecoratedClient::maximizedVerticallyChanged, this, &Decoration::recalculateBorders);
|
||||
connect(c, &KDecoration2::DecoratedClient::shadedChanged, this, &Decoration::recalculateBorders);
|
||||
connect(c, &KDecoration2::DecoratedClient::captionChanged, this,
|
||||
[this]()
|
||||
{
|
||||
// update the caption area
|
||||
update(titleBar());
|
||||
}
|
||||
);
|
||||
|
||||
connect(c, &KDecoration2::DecoratedClient::activeChanged, this, &Decoration::updateAnimationState);
|
||||
connect(c, &KDecoration2::DecoratedClient::widthChanged, this, &Decoration::updateTitleBar);
|
||||
connect(c, &KDecoration2::DecoratedClient::maximizedChanged, this, &Decoration::updateTitleBar);
|
||||
//connect(c, &KDecoration2::DecoratedClient::maximizedChanged, this, &Decoration::setOpaque);
|
||||
|
||||
connect(c, &KDecoration2::DecoratedClient::widthChanged, this, &Decoration::updateButtonsGeometry);
|
||||
connect(c, &KDecoration2::DecoratedClient::maximizedChanged, this, &Decoration::updateButtonsGeometry);
|
||||
connect(c, &KDecoration2::DecoratedClient::adjacentScreenEdgesChanged, this, &Decoration::updateButtonsGeometry);
|
||||
connect(c, &KDecoration2::DecoratedClient::shadedChanged, this, &Decoration::updateButtonsGeometry);
|
||||
|
||||
createButtons();
|
||||
createShadow();
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
void Decoration::updateTitleBar()
|
||||
{
|
||||
auto s = settings();
|
||||
auto c = client().data();
|
||||
const bool maximized = isMaximized();
|
||||
const int width = c->width() - (borderSize()*2);
|
||||
const int height = maximized ? borderTop() : borderTop() - borderSize();
|
||||
const int x = borderSize();
|
||||
const int y = maximized ? 0 : borderSize();
|
||||
setTitleBar(QRect(x, y, width, height));
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
void Decoration::updateAnimationState()
|
||||
{
|
||||
if( m_internalSettings->animationsEnabled() )
|
||||
{
|
||||
|
||||
auto c = client().data();
|
||||
m_animation->setDirection( c->isActive() ? QPropertyAnimation::Forward : QPropertyAnimation::Backward );
|
||||
if( m_animation->state() != QPropertyAnimation::Running ) m_animation->start();
|
||||
|
||||
} else {
|
||||
|
||||
update();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
void Decoration::updateSizeGripVisibility()
|
||||
{
|
||||
auto c = client().data();
|
||||
if( m_sizeGrip )
|
||||
{ m_sizeGrip->setVisible( c->isResizeable() && !isMaximized() && !c->isShaded() ); }
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
int Decoration::borderSize(bool bottom) const
|
||||
{
|
||||
const int baseSize = settings()->smallSpacing();
|
||||
if( m_internalSettings && (m_internalSettings->mask() & BorderSize ) )
|
||||
{
|
||||
switch (m_internalSettings->borderSize()) {
|
||||
case InternalSettings::BorderNone: return 0;
|
||||
case InternalSettings::BorderNoSides: return bottom ? qMax(4, baseSize) : 0;
|
||||
default:
|
||||
case InternalSettings::BorderTiny: return baseSize/2;
|
||||
case InternalSettings::BorderNormal: return baseSize;
|
||||
case InternalSettings::BorderLarge: return baseSize*2;
|
||||
case InternalSettings::BorderVeryLarge: return baseSize*3;
|
||||
case InternalSettings::BorderHuge: return baseSize*4;
|
||||
case InternalSettings::BorderVeryHuge: return baseSize*5;
|
||||
case InternalSettings::BorderOversized: return baseSize*8;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
switch (settings()->borderSize()) {
|
||||
case KDecoration2::BorderSize::None: return 0;
|
||||
case KDecoration2::BorderSize::NoSides: return bottom ? qMax(4, baseSize) : 0;
|
||||
default:
|
||||
case KDecoration2::BorderSize::Tiny: return baseSize/2;
|
||||
case KDecoration2::BorderSize::Normal: return baseSize;
|
||||
case KDecoration2::BorderSize::Large: return baseSize*2;
|
||||
case KDecoration2::BorderSize::VeryLarge: return baseSize*3;
|
||||
case KDecoration2::BorderSize::Huge: return baseSize*4;
|
||||
case KDecoration2::BorderSize::VeryHuge: return baseSize*5;
|
||||
case KDecoration2::BorderSize::Oversized: return baseSize*8;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
void Decoration::reconfigure()
|
||||
{
|
||||
|
||||
m_internalSettings = SettingsProvider::self()->internalSettings( this );
|
||||
|
||||
// animation
|
||||
m_animation->setDuration( m_internalSettings->animationsDuration() );
|
||||
|
||||
// borders
|
||||
recalculateBorders();
|
||||
|
||||
// shadow
|
||||
createShadow();
|
||||
|
||||
// size grip
|
||||
if( hasNoBorders() && m_internalSettings->drawSizeGrip() ) createSizeGrip();
|
||||
else deleteSizeGrip();
|
||||
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
void Decoration::recalculateBorders()
|
||||
{
|
||||
auto c = client().data();
|
||||
auto s = settings();
|
||||
|
||||
// left, right and bottom borders
|
||||
const int left = isLeftEdge() ? 0 : borderSize();
|
||||
const int right = isRightEdge() ? 0 : borderSize();
|
||||
const int bottom = (c->isShaded() || isBottomEdge()) ? 0 : borderSize(true);
|
||||
|
||||
int top = 0;
|
||||
if( hideTitleBar() ) top = bottom;
|
||||
else {
|
||||
top += isMaximized() ? 0 : borderSize();
|
||||
QFont f; f.fromString(m_internalSettings->titleBarFont());
|
||||
QFontMetrics fm(f);
|
||||
top += qMax(fm.height(), buttonHeight() );
|
||||
}
|
||||
|
||||
setBorders(QMargins(left, top, right, bottom));
|
||||
|
||||
// extended sizes
|
||||
const int extSize = s->largeSpacing();
|
||||
int extSides = 0;
|
||||
int extTop = 0;
|
||||
int extBottom = 0;
|
||||
if( hasNoBorders() || borderSize() < 2 )
|
||||
{
|
||||
extSides = extSize;
|
||||
extBottom = extSize;
|
||||
extTop = extSize;
|
||||
} else if( hasNoSideBorders() ) {
|
||||
extSides = extSize;
|
||||
}
|
||||
|
||||
setResizeOnlyBorders(QMargins(extSides, extTop, extSides, extBottom));
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
void Decoration::createButtons()
|
||||
{
|
||||
m_leftButtons = new KDecoration2::DecorationButtonGroup(KDecoration2::DecorationButtonGroup::Position::Left, this, &Button::create);
|
||||
m_rightButtons = new KDecoration2::DecorationButtonGroup(KDecoration2::DecorationButtonGroup::Position::Right, this, &Button::create);
|
||||
updateButtonsGeometry();
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
void Decoration::updateButtonsGeometryDelayed()
|
||||
{ QTimer::singleShot( 0, this, &Decoration::updateButtonsGeometry ); }
|
||||
|
||||
//________________________________________________________________
|
||||
void Decoration::updateButtonsGeometry()
|
||||
{
|
||||
const auto s = settings();
|
||||
|
||||
// adjust button position
|
||||
const int bHeight = buttonHeight();
|
||||
foreach( const QPointer<KDecoration2::DecorationButton>& button, m_leftButtons->buttons() + m_rightButtons->buttons() )
|
||||
{
|
||||
const int bWidth = buttonHeight() * (button.data()->type() == DecorationButtonType::Menu ? 1.0 : 1.5);
|
||||
button.data()->setGeometry( QRectF( QPoint( 0, 0 ), QSizeF( bWidth, bHeight ) ) );
|
||||
static_cast<Button*>( button.data() )->setIconSize( QSize( bWidth, bHeight ) );
|
||||
}
|
||||
|
||||
const bool maximized = isMaximized();
|
||||
|
||||
// left buttons
|
||||
if( !m_leftButtons->buttons().isEmpty() )
|
||||
{
|
||||
|
||||
m_leftButtons->setSpacing(0);
|
||||
|
||||
m_leftButtons->setPos(QPointF(borderLeft(), maximized ? 0 : borderSize()));
|
||||
|
||||
}
|
||||
|
||||
// right buttons
|
||||
if( !m_rightButtons->buttons().isEmpty() )
|
||||
{
|
||||
|
||||
m_rightButtons->setSpacing(0);
|
||||
|
||||
// padding
|
||||
m_rightButtons->setPos(QPointF(size().width() - m_rightButtons->geometry().width() - borderRight(), maximized ? 0 : borderSize()));
|
||||
|
||||
}
|
||||
|
||||
update();
|
||||
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
void Decoration::paint(QPainter *painter, const QRect &repaintRegion)
|
||||
{
|
||||
// TODO: optimize based on repaintRegion
|
||||
auto c = client().data();
|
||||
auto s = settings();
|
||||
|
||||
const bool maximized = isMaximized();
|
||||
|
||||
// paint background
|
||||
if( borderSize() > 0 )
|
||||
{
|
||||
painter->fillRect(rect(), Qt::transparent);
|
||||
painter->save();
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
painter->setPen(Qt::NoPen);
|
||||
|
||||
QColor winCol = c->isActive() ? KColorUtils::mix( titleBarColor(), Qt::black, 0.3 ) : titleBarColor();
|
||||
winCol.setAlpha(titleBarAlpha());
|
||||
painter->setBrush(winCol);
|
||||
|
||||
// clip away the titlebar part
|
||||
if( !hideTitleBar() )
|
||||
{
|
||||
QRegion outerReg(rect());
|
||||
QRegion innerReg(QRect(borderLeft(), maximized ? 0 : borderSize(), size().width() - borderLeft() - borderRight(), buttonHeight()));
|
||||
painter->setClipRegion(outerReg.subtracted(innerReg));
|
||||
}
|
||||
|
||||
painter->drawRect( rect() );
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
if( !hideTitleBar() ) paintTitleBar(painter, repaintRegion);
|
||||
|
||||
if( hasBorders() && !s->isAlphaChannelSupported() )
|
||||
{
|
||||
painter->save();
|
||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
||||
painter->setBrush( Qt::NoBrush );
|
||||
painter->setPen( c->isActive() ?
|
||||
c->color( ColorGroup::Active, ColorRole::TitleBar ):
|
||||
c->color( ColorGroup::Inactive, ColorRole::Foreground ) );
|
||||
|
||||
painter->drawRect( rect().adjusted( 0, 0, -1, -1 ) );
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
void Decoration::paintTitleBar(QPainter *painter, const QRect &repaintRegion)
|
||||
{
|
||||
const auto c = client().data();
|
||||
const bool maximized = isMaximized();
|
||||
const QRect titleRect(QPoint(borderLeft(), maximized ? 0 : borderSize()), QSize(size().width() - borderLeft() - borderRight(), buttonHeight()));
|
||||
|
||||
if ( !titleRect.intersects(repaintRegion) ) return;
|
||||
|
||||
painter->save();
|
||||
painter->setPen(Qt::NoPen);
|
||||
|
||||
QColor titleBarColor = this->titleBarColor();
|
||||
titleBarColor.setAlpha(titleBarAlpha());
|
||||
|
||||
painter->setBrush( titleBarColor );
|
||||
|
||||
auto s = settings();
|
||||
painter->drawRect(titleRect);
|
||||
|
||||
painter->restore();
|
||||
|
||||
// draw caption
|
||||
QFont f; f.fromString(m_internalSettings->titleBarFont());
|
||||
// KDE needs this FIXME: Why?
|
||||
QFontDatabase fd; f.setStyleName(fd.styleString(f));
|
||||
painter->setFont(f);
|
||||
painter->setPen( fontColor() );
|
||||
const auto cR = captionRect();
|
||||
const QString caption = painter->fontMetrics().elidedText(c->caption(), Qt::ElideMiddle, cR.first.width());
|
||||
painter->drawText(cR.first, cR.second | Qt::TextSingleLine, caption);
|
||||
|
||||
// draw all buttons
|
||||
m_leftButtons->paint(painter, repaintRegion);
|
||||
m_rightButtons->paint(painter, repaintRegion);
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
int Decoration::buttonHeight() const
|
||||
{
|
||||
const int baseSize = 10; //settings()->gridUnit();
|
||||
switch( m_internalSettings->buttonSize() )
|
||||
{
|
||||
case InternalSettings::ButtonTiny: return baseSize;
|
||||
case InternalSettings::ButtonSmall: return baseSize*2;
|
||||
default:
|
||||
case InternalSettings::ButtonDefault: return baseSize*3;
|
||||
case InternalSettings::ButtonLarge: return baseSize*4;
|
||||
case InternalSettings::ButtonVeryLarge: return baseSize*5;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
int Decoration::iconSize() const
|
||||
{
|
||||
const int baseSize = 16;
|
||||
switch( m_internalSettings->buttonSize() )
|
||||
{
|
||||
case InternalSettings::ButtonTiny: return baseSize/2;
|
||||
case InternalSettings::ButtonSmall: return baseSize;
|
||||
default:
|
||||
case InternalSettings::ButtonDefault: return baseSize;
|
||||
case InternalSettings::ButtonLarge: return baseSize*1.5;
|
||||
case InternalSettings::ButtonVeryLarge: return baseSize*2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
QPair<QRect,Qt::Alignment> Decoration::captionRect() const
|
||||
{
|
||||
if( hideTitleBar() ) return qMakePair( QRect(), Qt::AlignCenter );
|
||||
else {
|
||||
|
||||
auto c = client().data();
|
||||
int leftOffset = m_leftButtons->buttons().isEmpty() ?
|
||||
4.0*settings()->smallSpacing():
|
||||
m_leftButtons->geometry().x() + m_leftButtons->geometry().width() + 4.0*settings()->smallSpacing();
|
||||
|
||||
if (!m_leftButtons->buttons().isEmpty()
|
||||
&& m_leftButtons->buttons().last().data()->type() == DecorationButtonType::Menu
|
||||
&& m_internalSettings->titleAlignment() == InternalSettings::AlignLeft)
|
||||
{
|
||||
leftOffset -= 4.0 * settings()->smallSpacing();
|
||||
}
|
||||
|
||||
|
||||
const int rightOffset = m_rightButtons->buttons().isEmpty() ?
|
||||
4.0*settings()->smallSpacing() :
|
||||
size().width() - m_rightButtons->geometry().x() + 4.0*settings()->smallSpacing();
|
||||
|
||||
const int yOffset = isMaximized() ? 0 : borderSize();
|
||||
const QRect maxRect( leftOffset, yOffset, size().width() - leftOffset - rightOffset, buttonHeight() );
|
||||
|
||||
switch( m_internalSettings->titleAlignment() )
|
||||
{
|
||||
case InternalSettings::AlignLeft:
|
||||
return qMakePair( maxRect, Qt::AlignVCenter|Qt::AlignLeft );
|
||||
|
||||
case InternalSettings::AlignRight:
|
||||
return qMakePair( maxRect, Qt::AlignVCenter|Qt::AlignRight );
|
||||
|
||||
case InternalSettings::AlignCenter:
|
||||
return qMakePair( maxRect, Qt::AlignCenter );
|
||||
|
||||
default:
|
||||
case InternalSettings::AlignCenterFullWidth:
|
||||
{
|
||||
|
||||
// full caption rect
|
||||
const QRect fullRect = QRect( 0, yOffset, size().width(), buttonHeight() );
|
||||
QFont f; f.fromString(m_internalSettings->titleBarFont());
|
||||
QFontMetrics fm(f);
|
||||
QRect boundingRect( fm.boundingRect( c->caption()) );
|
||||
|
||||
// text bounding rect
|
||||
boundingRect.setTop( yOffset );
|
||||
boundingRect.setHeight( buttonHeight() );
|
||||
boundingRect.moveLeft( ( size().width() - boundingRect.width() )/2 );
|
||||
|
||||
if( boundingRect.left() < leftOffset ) return qMakePair( maxRect, Qt::AlignVCenter|Qt::AlignLeft );
|
||||
else if( boundingRect.right() > size().width() - rightOffset ) return qMakePair( maxRect, Qt::AlignVCenter|Qt::AlignRight );
|
||||
else return qMakePair(fullRect, Qt::AlignCenter);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//________________________________________________________________
|
||||
void Decoration::createShadow()
|
||||
{
|
||||
if (!g_sShadow
|
||||
||g_shadowSizeEnum != m_internalSettings->shadowSize()
|
||||
|| g_shadowStrength != m_internalSettings->shadowStrength()
|
||||
|| g_shadowColor != m_internalSettings->shadowColor())
|
||||
{
|
||||
g_shadowSizeEnum = m_internalSettings->shadowSize();
|
||||
g_shadowStrength = m_internalSettings->shadowStrength();
|
||||
g_shadowColor = m_internalSettings->shadowColor();
|
||||
|
||||
const CompositeShadowParams params = lookupShadowParams(g_shadowSizeEnum);
|
||||
if (params.isNone()) {
|
||||
g_sShadow.clear();
|
||||
setShadow(g_sShadow);
|
||||
return;
|
||||
}
|
||||
|
||||
auto withOpacity = [](const QColor &color, qreal opacity) -> QColor {
|
||||
QColor c(color);
|
||||
c.setAlphaF(opacity);
|
||||
return c;
|
||||
};
|
||||
|
||||
const QSize boxSize = BoxShadowRenderer::calculateMinimumBoxSize(params.shadow1.radius)
|
||||
.expandedTo(BoxShadowRenderer::calculateMinimumBoxSize(params.shadow2.radius));
|
||||
|
||||
BoxShadowRenderer shadowRenderer;
|
||||
shadowRenderer.setBorderRadius(0.5);
|
||||
shadowRenderer.setBoxSize(boxSize);
|
||||
shadowRenderer.setDevicePixelRatio(1.0); // TODO: Create HiDPI shadows?
|
||||
|
||||
const qreal strength = static_cast<qreal>(g_shadowStrength) / 255.0;
|
||||
shadowRenderer.addShadow(params.shadow1.offset, params.shadow1.radius,
|
||||
withOpacity(g_shadowColor, params.shadow1.opacity * strength));
|
||||
shadowRenderer.addShadow(params.shadow2.offset, params.shadow2.radius,
|
||||
withOpacity(g_shadowColor, params.shadow2.opacity * strength));
|
||||
|
||||
QImage shadowTexture = shadowRenderer.render();
|
||||
|
||||
QPainter painter(&shadowTexture);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
const QRect outerRect = shadowTexture.rect();
|
||||
|
||||
QRect boxRect(QPoint(0, 0), boxSize);
|
||||
boxRect.moveCenter(outerRect.center());
|
||||
|
||||
// Mask out inner rect.
|
||||
const QMargins padding = QMargins(
|
||||
boxRect.left() - outerRect.left() - Metrics::Shadow_Overlap - params.offset.x(),
|
||||
boxRect.top() - outerRect.top() - Metrics::Shadow_Overlap - params.offset.y(),
|
||||
outerRect.right() - boxRect.right() - Metrics::Shadow_Overlap + params.offset.x(),
|
||||
outerRect.bottom() - boxRect.bottom() - Metrics::Shadow_Overlap + params.offset.y());
|
||||
const QRect innerRect = outerRect - padding;
|
||||
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(Qt::black);
|
||||
painter.setCompositionMode(QPainter::CompositionMode_DestinationOut);
|
||||
painter.drawRoundedRect(innerRect, 0.5, 0.5);
|
||||
|
||||
// Draw outline.
|
||||
painter.setPen(withOpacity(g_shadowColor, 0.2 * strength));
|
||||
painter.setBrush(Qt::NoBrush);
|
||||
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
painter.drawRoundedRect(innerRect, -0.5, -0.5);
|
||||
|
||||
painter.end();
|
||||
|
||||
g_sShadow = QSharedPointer<KDecoration2::DecorationShadow>::create();
|
||||
g_sShadow->setPadding(padding);
|
||||
g_sShadow->setInnerShadowRect(QRect(outerRect.center(), QSize(1, 1)));
|
||||
g_sShadow->setShadow(shadowTexture);
|
||||
}
|
||||
|
||||
setShadow(g_sShadow);
|
||||
}
|
||||
|
||||
//_________________________________________________________________
|
||||
void Decoration::createSizeGrip()
|
||||
{
|
||||
|
||||
// do nothing if size grip already exist
|
||||
if( m_sizeGrip ) return;
|
||||
|
||||
#if BREEZE_HAVE_X11
|
||||
if( !QX11Info::isPlatformX11() ) return;
|
||||
|
||||
// access client
|
||||
auto c = client().data();
|
||||
if( !c ) return;
|
||||
|
||||
if( c->windowId() != 0 )
|
||||
{
|
||||
m_sizeGrip = new SizeGrip( this );
|
||||
connect( c, &KDecoration2::DecoratedClient::maximizedChanged, this, &Decoration::updateSizeGripVisibility );
|
||||
connect( c, &KDecoration2::DecoratedClient::shadedChanged, this, &Decoration::updateSizeGripVisibility );
|
||||
connect( c, &KDecoration2::DecoratedClient::resizeableChanged, this, &Decoration::updateSizeGripVisibility );
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//_________________________________________________________________
|
||||
void Decoration::deleteSizeGrip()
|
||||
{
|
||||
if( m_sizeGrip )
|
||||
{
|
||||
m_sizeGrip->deleteLater();
|
||||
m_sizeGrip = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
#include "breezedecoration.moc"
|
221
breezedecoration.h
Normal file
221
breezedecoration.h
Normal file
|
@ -0,0 +1,221 @@
|
|||
#ifndef BREEZE_DECORATION_H
|
||||
#define BREEZE_DECORATION_H
|
||||
|
||||
/*
|
||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
|
||||
* Copyright 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "breeze.h"
|
||||
#include "breezesettings.h"
|
||||
|
||||
#include <KDecoration2/Decoration>
|
||||
#include <KDecoration2/DecoratedClient>
|
||||
#include <KDecoration2/DecorationSettings>
|
||||
|
||||
#include <QPalette>
|
||||
#include <QPropertyAnimation>
|
||||
#include <QVariant>
|
||||
|
||||
namespace KDecoration2
|
||||
{
|
||||
class DecorationButton;
|
||||
class DecorationButtonGroup;
|
||||
}
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
class SizeGrip;
|
||||
class Decoration : public KDecoration2::Decoration
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
//* declare active state opacity
|
||||
Q_PROPERTY( qreal opacity READ opacity WRITE setOpacity )
|
||||
|
||||
public:
|
||||
|
||||
//* constructor
|
||||
explicit Decoration(QObject *parent = nullptr, const QVariantList &args = QVariantList());
|
||||
|
||||
//* destructor
|
||||
virtual ~Decoration();
|
||||
|
||||
//* paint
|
||||
void paint(QPainter *painter, const QRect &repaintRegion) override;
|
||||
|
||||
//* internal settings
|
||||
InternalSettingsPtr internalSettings() const
|
||||
{ return m_internalSettings; }
|
||||
|
||||
//* caption height
|
||||
int captionHeight() const;
|
||||
|
||||
//* button height
|
||||
int buttonHeight() const;
|
||||
|
||||
//* icon size
|
||||
int iconSize() const;
|
||||
|
||||
//*@name active state change animation
|
||||
//@{
|
||||
void setOpacity( qreal );
|
||||
|
||||
qreal opacity() const
|
||||
{ return m_opacity; }
|
||||
|
||||
//@}
|
||||
|
||||
//*@name colors
|
||||
//@{
|
||||
QColor titleBarColor() const;
|
||||
QColor outlineColor() const;
|
||||
QColor fontColor() const;
|
||||
//@}
|
||||
|
||||
//*@name maximization modes
|
||||
//@{
|
||||
inline bool isMaximized() const;
|
||||
inline bool isMaximizedHorizontally() const;
|
||||
inline bool isMaximizedVertically() const;
|
||||
|
||||
inline bool isLeftEdge() const;
|
||||
inline bool isRightEdge() const;
|
||||
inline bool isTopEdge() const;
|
||||
inline bool isBottomEdge() const;
|
||||
|
||||
inline bool hideTitleBar() const;
|
||||
//@}
|
||||
|
||||
public Q_SLOTS:
|
||||
void init() override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void reconfigure();
|
||||
void recalculateBorders();
|
||||
void updateButtonsGeometry();
|
||||
void updateButtonsGeometryDelayed();
|
||||
void updateTitleBar();
|
||||
void updateAnimationState();
|
||||
void updateSizeGripVisibility();
|
||||
|
||||
private:
|
||||
|
||||
//* return the rect in which caption will be drawn
|
||||
QPair<QRect,Qt::Alignment> captionRect() const;
|
||||
|
||||
void createButtons();
|
||||
void paintTitleBar(QPainter *painter, const QRect &repaintRegion);
|
||||
void createShadow();
|
||||
|
||||
//*@name border size
|
||||
//@{
|
||||
int borderSize(bool bottom = false) const;
|
||||
inline bool hasBorders() const;
|
||||
inline bool hasNoBorders() const;
|
||||
inline bool hasNoSideBorders() const;
|
||||
//@}
|
||||
|
||||
//*@name color customization
|
||||
//@{
|
||||
inline bool opaqueTitleBar() const;
|
||||
inline int titleBarAlpha() const;
|
||||
//@}
|
||||
|
||||
//*@name size grip
|
||||
//@{
|
||||
void createSizeGrip();
|
||||
void deleteSizeGrip();
|
||||
SizeGrip* sizeGrip() const
|
||||
{ return m_sizeGrip; }
|
||||
//@}
|
||||
|
||||
InternalSettingsPtr m_internalSettings;
|
||||
KDecoration2::DecorationButtonGroup *m_leftButtons = nullptr;
|
||||
KDecoration2::DecorationButtonGroup *m_rightButtons = nullptr;
|
||||
|
||||
//* size grip widget
|
||||
SizeGrip *m_sizeGrip = nullptr;
|
||||
|
||||
//* active state change animation
|
||||
QPropertyAnimation *m_animation;
|
||||
|
||||
//* active state change opacity
|
||||
qreal m_opacity = 0;
|
||||
|
||||
};
|
||||
|
||||
bool Decoration::hasBorders() const
|
||||
{
|
||||
if( m_internalSettings && m_internalSettings->mask() & BorderSize ) return m_internalSettings->borderSize() > InternalSettings::BorderNoSides;
|
||||
else return settings()->borderSize() > KDecoration2::BorderSize::NoSides;
|
||||
}
|
||||
|
||||
bool Decoration::hasNoBorders() const
|
||||
{
|
||||
if( m_internalSettings && m_internalSettings->mask() & BorderSize ) return m_internalSettings->borderSize() == InternalSettings::BorderNone;
|
||||
else return settings()->borderSize() == KDecoration2::BorderSize::None;
|
||||
}
|
||||
|
||||
bool Decoration::hasNoSideBorders() const
|
||||
{
|
||||
if( m_internalSettings && m_internalSettings->mask() & BorderSize ) return m_internalSettings->borderSize() == InternalSettings::BorderNoSides;
|
||||
else return settings()->borderSize() == KDecoration2::BorderSize::NoSides;
|
||||
}
|
||||
|
||||
bool Decoration::isMaximized() const
|
||||
{ return client().data()->isMaximized() && !m_internalSettings->drawBorderOnMaximizedWindows(); }
|
||||
|
||||
bool Decoration::isMaximizedHorizontally() const
|
||||
{ return client().data()->isMaximizedHorizontally() && !m_internalSettings->drawBorderOnMaximizedWindows(); }
|
||||
|
||||
bool Decoration::isMaximizedVertically() const
|
||||
{ return client().data()->isMaximizedVertically() && !m_internalSettings->drawBorderOnMaximizedWindows(); }
|
||||
|
||||
bool Decoration::isLeftEdge() const
|
||||
{ return (client().data()->isMaximizedHorizontally() || client().data()->adjacentScreenEdges().testFlag( Qt::LeftEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); }
|
||||
|
||||
bool Decoration::isRightEdge() const
|
||||
{ return (client().data()->isMaximizedHorizontally() || client().data()->adjacentScreenEdges().testFlag( Qt::RightEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); }
|
||||
|
||||
bool Decoration::isTopEdge() const
|
||||
{ return (client().data()->isMaximizedVertically() || client().data()->adjacentScreenEdges().testFlag( Qt::TopEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); }
|
||||
|
||||
bool Decoration::isBottomEdge() const
|
||||
{ return (client().data()->isMaximizedVertically() || client().data()->adjacentScreenEdges().testFlag( Qt::BottomEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); }
|
||||
|
||||
bool Decoration::hideTitleBar() const
|
||||
{ return m_internalSettings->hideTitleBar() && !client().data()->isShaded(); }
|
||||
|
||||
bool Decoration::opaqueTitleBar() const
|
||||
{ return m_internalSettings->opaqueTitleBar(); }
|
||||
|
||||
int Decoration::titleBarAlpha() const
|
||||
{
|
||||
if (m_internalSettings->opaqueTitleBar())
|
||||
return 255;
|
||||
int a = m_internalSettings->opacityOverride() > -1 ? m_internalSettings->opacityOverride()
|
||||
: m_internalSettings->backgroundOpacity();
|
||||
a = qBound(0, a, 100);
|
||||
return qRound(static_cast<qreal>(a) * static_cast<qreal>(2.55));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
131
breezeexceptionlist.cpp
Normal file
131
breezeexceptionlist.cpp
Normal file
|
@ -0,0 +1,131 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
// breezeexceptionlist.cpp
|
||||
// window decoration exceptions
|
||||
// -------------------
|
||||
//
|
||||
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "breezeexceptionlist.h"
|
||||
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
//______________________________________________________________
|
||||
void ExceptionList::readConfig( KSharedConfig::Ptr config )
|
||||
{
|
||||
|
||||
_exceptions.clear();
|
||||
|
||||
QString groupName;
|
||||
for( int index = 0; config->hasGroup( groupName = exceptionGroupName( index ) ); ++index )
|
||||
{
|
||||
|
||||
// create exception
|
||||
InternalSettings exception;
|
||||
|
||||
// reset group
|
||||
readConfig( &exception, config.data(), groupName );
|
||||
|
||||
// create new configuration
|
||||
InternalSettingsPtr configuration( new InternalSettings() );
|
||||
configuration.data()->load();
|
||||
|
||||
// apply changes from exception
|
||||
configuration->setEnabled( exception.enabled() );
|
||||
configuration->setExceptionType( exception.exceptionType() );
|
||||
configuration->setExceptionPattern( exception.exceptionPattern() );
|
||||
configuration->setMask( exception.mask() );
|
||||
|
||||
// propagate all features found in mask to the output configuration
|
||||
if( exception.mask() & BorderSize ) configuration->setBorderSize( exception.borderSize() );
|
||||
configuration->setHideTitleBar( exception.hideTitleBar() );
|
||||
configuration->setOpaqueTitleBar( exception.opaqueTitleBar() );
|
||||
configuration->setOpacityOverride( exception.opacityOverride() );
|
||||
configuration->setIsDialog( exception.isDialog() );
|
||||
|
||||
// append to exceptions
|
||||
_exceptions.append( configuration );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//______________________________________________________________
|
||||
void ExceptionList::writeConfig( KSharedConfig::Ptr config )
|
||||
{
|
||||
|
||||
// remove all existing exceptions
|
||||
QString groupName;
|
||||
for( int index = 0; config->hasGroup( groupName = exceptionGroupName( index ) ); ++index )
|
||||
{ config->deleteGroup( groupName ); }
|
||||
|
||||
// rewrite current exceptions
|
||||
int index = 0;
|
||||
foreach( const InternalSettingsPtr& exception, _exceptions )
|
||||
{
|
||||
|
||||
writeConfig( exception.data(), config.data(), exceptionGroupName( index ) );
|
||||
++index;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//_______________________________________________________________________
|
||||
QString ExceptionList::exceptionGroupName( int index )
|
||||
{ return QString( "Windeco Exception %1" ).arg( index ); }
|
||||
|
||||
//______________________________________________________________
|
||||
void ExceptionList::writeConfig( KCoreConfigSkeleton* skeleton, KConfig* config, const QString& groupName )
|
||||
{
|
||||
|
||||
// list of items to be written
|
||||
QStringList keys = { "Enabled", "ExceptionPattern", "ExceptionType", "HideTitleBar", "IsDialog", "OpaqueTitleBar", "OpacityOverride", "Mask", "BorderSize"};
|
||||
|
||||
// write all items
|
||||
foreach( auto key, keys )
|
||||
{
|
||||
KConfigSkeletonItem* item( skeleton->findItem( key ) );
|
||||
if( !item ) continue;
|
||||
|
||||
if( !groupName.isEmpty() ) item->setGroup( groupName );
|
||||
KConfigGroup configGroup( config, item->group() );
|
||||
configGroup.writeEntry( item->key(), item->property() );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//______________________________________________________________
|
||||
void ExceptionList::readConfig( KCoreConfigSkeleton* skeleton, KConfig* config, const QString& groupName )
|
||||
{
|
||||
|
||||
foreach( KConfigSkeletonItem* item, skeleton->items() )
|
||||
{
|
||||
if( !groupName.isEmpty() ) item->setGroup( groupName );
|
||||
item->readConfig( config );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
79
breezeexceptionlist.h
Normal file
79
breezeexceptionlist.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
#ifndef breezeexceptionlist_h
|
||||
#define breezeexceptionlist_h
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// breezeexceptionlist.h
|
||||
// window decoration exceptions
|
||||
// -------------------
|
||||
//
|
||||
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "breezesettings.h"
|
||||
#include "breeze.h"
|
||||
|
||||
#include <KSharedConfig>
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
//! breeze exceptions list
|
||||
class ExceptionList
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
//! constructor from list
|
||||
explicit ExceptionList( const InternalSettingsList& exceptions = InternalSettingsList() ):
|
||||
_exceptions( exceptions )
|
||||
{}
|
||||
|
||||
//! exceptions
|
||||
const InternalSettingsList& get( void ) const
|
||||
{ return _exceptions; }
|
||||
|
||||
//! read from KConfig
|
||||
void readConfig( KSharedConfig::Ptr );
|
||||
|
||||
//! write to kconfig
|
||||
void writeConfig( KSharedConfig::Ptr );
|
||||
|
||||
protected:
|
||||
|
||||
//! generate exception group name for given exception index
|
||||
static QString exceptionGroupName( int index );
|
||||
|
||||
//! read configuration
|
||||
static void readConfig( KCoreConfigSkeleton*, KConfig*, const QString& );
|
||||
|
||||
//! write configuration
|
||||
static void writeConfig( KCoreConfigSkeleton*, KConfig*, const QString& );
|
||||
|
||||
private:
|
||||
|
||||
//! exceptions
|
||||
InternalSettingsList _exceptions;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
6
breezesettings.kcfgc
Normal file
6
breezesettings.kcfgc
Normal file
|
@ -0,0 +1,6 @@
|
|||
File=breezesettingsdata.kcfg
|
||||
ClassName=InternalSettings
|
||||
NameSpace=Breeze
|
||||
Singleton=false
|
||||
Mutators=true
|
||||
GlobalEnums=true
|
152
breezesettingsdata.kcfg
Normal file
152
breezesettingsdata.kcfg
Normal file
|
@ -0,0 +1,152 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE kcfg SYSTEM "http://www.kde.org/standards/kcfg/1.0/kcfg.dtd">
|
||||
<kcfg>
|
||||
<kcfgfile name="breezerc"/>
|
||||
|
||||
<!-- common options -->
|
||||
<group name="Common">
|
||||
|
||||
<entry name="ShadowStrength" type = "Int">
|
||||
<default>255</default>
|
||||
<min>25</min>
|
||||
<max>255</max>
|
||||
</entry>
|
||||
|
||||
<!-- shadow -->
|
||||
<entry name="ShadowSize" type = "Enum">
|
||||
<choices>
|
||||
<choice name="ShadowNone"/>
|
||||
<choice name="ShadowSmall"/>
|
||||
<choice name="ShadowMedium"/>
|
||||
<choice name="ShadowLarge"/>
|
||||
<choice name="ShadowVeryLarge"/>
|
||||
</choices>
|
||||
<default>ShadowLarge</default>
|
||||
</entry>
|
||||
|
||||
<entry name="ShadowColor" type = "Color">
|
||||
<default>0, 0, 0</default>
|
||||
</entry>
|
||||
|
||||
<!-- close button -->
|
||||
<entry name="OutlineCloseButton" type = "Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
|
||||
</group>
|
||||
|
||||
<group name="Windeco">
|
||||
|
||||
<!-- border size -->
|
||||
<!--
|
||||
this one is used only for window specific settings, since the default is globally set by kwin
|
||||
the enumeration must be kept in sync with kwin's global settings
|
||||
-->
|
||||
<entry name="BorderSize" type = "Enum">
|
||||
<choices>
|
||||
<choice name="BorderNone" />
|
||||
<choice name="BorderNoSides" />
|
||||
<choice name="BorderTiny" />
|
||||
<choice name="BorderNormal" />
|
||||
<choice name="BorderLarge" />
|
||||
<choice name="BorderVeryLarge" />
|
||||
<choice name="BorderHuge" />
|
||||
<choice name="BorderVeryHuge" />
|
||||
<choice name="BorderOversized" />
|
||||
</choices>
|
||||
<default>BorderNoSides</default>
|
||||
</entry>
|
||||
|
||||
<!-- title alignment -->
|
||||
<entry name="TitleAlignment" type="Enum">
|
||||
<choices>
|
||||
<choice name="AlignLeft" />
|
||||
<choice name="AlignCenter" />
|
||||
<choice name="AlignCenterFullWidth" />
|
||||
<choice name="AlignRight" />
|
||||
</choices>
|
||||
<default>AlignCenterFullWidth</default>
|
||||
</entry>
|
||||
|
||||
<!-- button size -->
|
||||
<entry name="ButtonSize" type="Enum">
|
||||
<choices>
|
||||
<choice name="ButtonTiny" />
|
||||
<choice name="ButtonSmall" />
|
||||
<choice name="ButtonDefault" />
|
||||
<choice name="ButtonLarge" />
|
||||
<choice name="ButtonVeryLarge" />
|
||||
</choices>
|
||||
<default>ButtonDefault</default>
|
||||
</entry>
|
||||
|
||||
<!-- maximized windows -->
|
||||
<entry name="DrawBorderOnMaximizedWindows" type = "Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
|
||||
<entry name="DrawTitleBarSeparator" type = "Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
|
||||
<entry name="BackgroundOpacity" type = "Int">
|
||||
<default>100</default>
|
||||
</entry>
|
||||
|
||||
<entry name="TitleBarFont" type = "String"/>
|
||||
|
||||
<!-- size grip -->
|
||||
<entry name="DrawSizeGrip" type = "Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
|
||||
<!-- animations -->
|
||||
<entry name="AnimationsEnabled" type = "Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
|
||||
<entry name="AnimationsDuration" type = "Int">
|
||||
<default>150</default>
|
||||
</entry>
|
||||
|
||||
<!-- hide title bar -->
|
||||
<entry name="HideTitleBar" type = "Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
|
||||
<!-- opaque title bar -->
|
||||
<entry name="OpaqueTitleBar" type = "Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
|
||||
<entry name="OpacityOverride" type = "Int">
|
||||
<default>-1</default>
|
||||
</entry>
|
||||
|
||||
<!-- dialogs -->
|
||||
<entry name="IsDialog" type = "Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
|
||||
<!-- window specific settings -->
|
||||
<entry name="ExceptionType" type="Enum">
|
||||
<choices>
|
||||
<choice name="ExceptionWindowClassName" />
|
||||
<choice name="ExceptionWindowTitle" />
|
||||
</choices>
|
||||
<default>ExceptionWindowClassName</default>
|
||||
</entry>
|
||||
|
||||
<entry name="ExceptionPattern" type = "String"/>
|
||||
|
||||
<entry name="Enabled" type = "Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
|
||||
<entry name="Mask" type = "Int">
|
||||
<default>0</default>
|
||||
</entry>
|
||||
|
||||
</group>
|
||||
|
||||
</kcfg>
|
139
breezesettingsprovider.cpp
Normal file
139
breezesettingsprovider.cpp
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "breezesettingsprovider.h"
|
||||
|
||||
#include "breezeexceptionlist.h"
|
||||
|
||||
#include <KWindowInfo>
|
||||
|
||||
#include <QTextStream>
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
SettingsProvider *SettingsProvider::s_self = nullptr;
|
||||
|
||||
//__________________________________________________________________
|
||||
SettingsProvider::SettingsProvider():
|
||||
m_config( KSharedConfig::openConfig( QStringLiteral("breezerc") ) )
|
||||
{ reconfigure(); }
|
||||
|
||||
//__________________________________________________________________
|
||||
SettingsProvider::~SettingsProvider()
|
||||
{ s_self = nullptr; }
|
||||
|
||||
//__________________________________________________________________
|
||||
SettingsProvider *SettingsProvider::self()
|
||||
{
|
||||
// TODO: this is not thread safe!
|
||||
if (!s_self)
|
||||
{ s_self = new SettingsProvider(); }
|
||||
|
||||
return s_self;
|
||||
}
|
||||
|
||||
//__________________________________________________________________
|
||||
void SettingsProvider::reconfigure()
|
||||
{
|
||||
if( !m_defaultSettings )
|
||||
{
|
||||
m_defaultSettings = InternalSettingsPtr(new InternalSettings());
|
||||
m_defaultSettings->setCurrentGroup( QStringLiteral("Windeco") );
|
||||
}
|
||||
|
||||
m_defaultSettings->load();
|
||||
|
||||
ExceptionList exceptions;
|
||||
exceptions.readConfig( m_config );
|
||||
m_exceptions = exceptions.get();
|
||||
|
||||
}
|
||||
|
||||
//__________________________________________________________________
|
||||
InternalSettingsPtr SettingsProvider::internalSettings( Decoration *decoration ) const
|
||||
{
|
||||
|
||||
QString windowTitle;
|
||||
QString className;
|
||||
|
||||
// get the client
|
||||
auto client = decoration->client().data();
|
||||
|
||||
foreach( auto internalSettings, m_exceptions )
|
||||
{
|
||||
|
||||
// discard disabled exceptions
|
||||
if( !internalSettings->enabled() ) continue;
|
||||
|
||||
// discard exceptions with empty exception pattern
|
||||
if( internalSettings->exceptionPattern().isEmpty() ) continue;
|
||||
|
||||
if (internalSettings->isDialog())
|
||||
{
|
||||
KWindowInfo info(client->windowId(), NET::WMWindowType);
|
||||
if (info.valid()
|
||||
&& info.windowType(NET::NormalMask | NET::DialogMask) != NET::Dialog) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
decide which value is to be compared
|
||||
to the regular expression, based on exception type
|
||||
*/
|
||||
QString value;
|
||||
switch( internalSettings->exceptionType() )
|
||||
{
|
||||
case InternalSettings::ExceptionWindowTitle:
|
||||
{
|
||||
value = windowTitle.isEmpty() ? (windowTitle = client->caption()):windowTitle;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
case InternalSettings::ExceptionWindowClassName:
|
||||
{
|
||||
if( className.isEmpty() )
|
||||
{
|
||||
// retrieve class name
|
||||
KWindowInfo info( client->windowId(), nullptr, NET::WM2WindowClass );
|
||||
QString window_className( QString::fromUtf8(info.windowClassName()) );
|
||||
QString window_class( QString::fromUtf8(info.windowClassClass()) );
|
||||
className = window_className + QStringLiteral(" ") + window_class;
|
||||
}
|
||||
|
||||
value = className;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check matching
|
||||
if( QRegExp( internalSettings->exceptionPattern() ).indexIn( value ) >= 0 )
|
||||
{ return internalSettings; }
|
||||
|
||||
}
|
||||
|
||||
return m_defaultSettings;
|
||||
|
||||
}
|
||||
|
||||
}
|
76
breezesettingsprovider.h
Normal file
76
breezesettingsprovider.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
#ifndef breezesettingsprovider_h
|
||||
#define breezesettingsprovider_h
|
||||
/*
|
||||
* Copyright 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "breezedecoration.h"
|
||||
#include "breezesettings.h"
|
||||
#include "breeze.h"
|
||||
|
||||
#include <KSharedConfig>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
class SettingsProvider: public QObject
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
//* destructor
|
||||
~SettingsProvider();
|
||||
|
||||
//* singleton
|
||||
static SettingsProvider *self();
|
||||
|
||||
//* internal settings for given decoration
|
||||
InternalSettingsPtr internalSettings(Decoration *) const;
|
||||
|
||||
public Q_SLOTS:
|
||||
|
||||
//* reconfigure
|
||||
void reconfigure();
|
||||
|
||||
private:
|
||||
|
||||
//* contructor
|
||||
SettingsProvider();
|
||||
|
||||
//* default configuration
|
||||
InternalSettingsPtr m_defaultSettings;
|
||||
|
||||
//* exceptions
|
||||
InternalSettingsList m_exceptions;
|
||||
|
||||
//* config object
|
||||
KSharedConfigPtr m_config;
|
||||
|
||||
//* singleton
|
||||
static SettingsProvider *s_self;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
303
breezesizegrip.cpp
Normal file
303
breezesizegrip.cpp
Normal file
|
@ -0,0 +1,303 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2014 by Hugo Pereira Da Costa <hugo.pereira@free.fr> *
|
||||
* *
|
||||
* 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 "breezesizegrip.h"
|
||||
|
||||
#include <KDecoration2/DecoratedClient>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QPolygon>
|
||||
#include <QTimer>
|
||||
|
||||
#if BREEZE_HAVE_X11
|
||||
#include <QX11Info>
|
||||
#endif
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
//* scoped pointer convenience typedef
|
||||
template <typename T> using ScopedPointer = QScopedPointer<T, QScopedPointerPodDeleter>;
|
||||
|
||||
//_____________________________________________
|
||||
SizeGrip::SizeGrip( Decoration* decoration ):QWidget(nullptr)
|
||||
,m_decoration( decoration )
|
||||
{
|
||||
|
||||
setAttribute(Qt::WA_NoSystemBackground );
|
||||
setAutoFillBackground( false );
|
||||
|
||||
// cursor
|
||||
setCursor( Qt::SizeFDiagCursor );
|
||||
|
||||
// size
|
||||
setFixedSize( QSize( GripSize, GripSize ) );
|
||||
|
||||
// mask
|
||||
setMask( QRegion( QVector<QPoint>{
|
||||
QPoint( 0, GripSize ),
|
||||
QPoint( GripSize, 0 ),
|
||||
QPoint( GripSize, GripSize ),
|
||||
QPoint( 0, GripSize )} ) );
|
||||
|
||||
// embed
|
||||
embed();
|
||||
updatePosition();
|
||||
|
||||
// connections
|
||||
auto c = decoration->client().data();
|
||||
connect( c, &KDecoration2::DecoratedClient::widthChanged, this, &SizeGrip::updatePosition );
|
||||
connect( c, &KDecoration2::DecoratedClient::heightChanged, this, &SizeGrip::updatePosition );
|
||||
connect( c, &KDecoration2::DecoratedClient::activeChanged, this, &SizeGrip::updateActiveState );
|
||||
|
||||
// show
|
||||
show();
|
||||
|
||||
}
|
||||
|
||||
//_____________________________________________
|
||||
SizeGrip::~SizeGrip()
|
||||
{}
|
||||
|
||||
//_____________________________________________
|
||||
void SizeGrip::updateActiveState()
|
||||
{
|
||||
#if BREEZE_HAVE_X11
|
||||
if( QX11Info::isPlatformX11() )
|
||||
{
|
||||
const quint32 value = XCB_STACK_MODE_ABOVE;
|
||||
xcb_configure_window( QX11Info::connection(), winId(), XCB_CONFIG_WINDOW_STACK_MODE, &value );
|
||||
xcb_map_window( QX11Info::connection(), winId() );
|
||||
}
|
||||
#endif
|
||||
|
||||
update();
|
||||
|
||||
}
|
||||
|
||||
//_____________________________________________
|
||||
void SizeGrip::embed()
|
||||
{
|
||||
|
||||
#if BREEZE_HAVE_X11
|
||||
|
||||
if( !QX11Info::isPlatformX11() ) return;
|
||||
auto c = m_decoration.data()->client().data();
|
||||
|
||||
xcb_window_t windowId = c->windowId();
|
||||
if( windowId )
|
||||
{
|
||||
|
||||
/*
|
||||
find client's parent
|
||||
we want the size grip to be at the same level as the client in the stack
|
||||
*/
|
||||
xcb_window_t current = windowId;
|
||||
auto connection = QX11Info::connection();
|
||||
xcb_query_tree_cookie_t cookie = xcb_query_tree_unchecked( connection, current );
|
||||
ScopedPointer<xcb_query_tree_reply_t> tree(xcb_query_tree_reply( connection, cookie, nullptr ) );
|
||||
if( !tree.isNull() && tree->parent ) current = tree->parent;
|
||||
|
||||
// reparent
|
||||
xcb_reparent_window( connection, winId(), current, 0, 0 );
|
||||
setWindowTitle( "Breeze::SizeGrip" );
|
||||
|
||||
} else {
|
||||
|
||||
hide();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//_____________________________________________
|
||||
void SizeGrip::paintEvent( QPaintEvent* )
|
||||
{
|
||||
|
||||
if( !m_decoration ) return;
|
||||
|
||||
// get relevant colors
|
||||
const QColor backgroundColor( m_decoration.data()->titleBarColor() );
|
||||
|
||||
// create and configure painter
|
||||
QPainter painter(this);
|
||||
painter.setRenderHints(QPainter::Antialiasing );
|
||||
|
||||
painter.setPen( Qt::NoPen );
|
||||
painter.setBrush( backgroundColor );
|
||||
|
||||
// polygon
|
||||
painter.drawPolygon( QVector<QPoint> {
|
||||
QPoint( 0, GripSize ),
|
||||
QPoint( GripSize, 0 ),
|
||||
QPoint( GripSize, GripSize ),
|
||||
QPoint( 0, GripSize )} );
|
||||
}
|
||||
|
||||
//_____________________________________________
|
||||
void SizeGrip::mousePressEvent( QMouseEvent* event )
|
||||
{
|
||||
|
||||
switch (event->button())
|
||||
{
|
||||
|
||||
case Qt::RightButton:
|
||||
{
|
||||
hide();
|
||||
QTimer::singleShot(5000, this, SLOT(show()));
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::MidButton:
|
||||
{
|
||||
hide();
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::LeftButton:
|
||||
if( rect().contains( event->pos() ) )
|
||||
{ sendMoveResizeEvent( event->pos() ); }
|
||||
break;
|
||||
|
||||
default: break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//_______________________________________________________________________________
|
||||
void SizeGrip::updatePosition()
|
||||
{
|
||||
|
||||
#if BREEZE_HAVE_X11
|
||||
if( !QX11Info::isPlatformX11() ) return;
|
||||
|
||||
auto c = m_decoration.data()->client().data();
|
||||
QPoint position(
|
||||
c->width() - GripSize - Offset,
|
||||
c->height() - GripSize - Offset );
|
||||
|
||||
quint32 values[2] = { quint32(position.x()), quint32(position.y()) };
|
||||
xcb_configure_window( QX11Info::connection(), winId(), XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, values );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//_____________________________________________
|
||||
void SizeGrip::sendMoveResizeEvent( QPoint position )
|
||||
{
|
||||
|
||||
#if BREEZE_HAVE_X11
|
||||
if( !QX11Info::isPlatformX11() ) return;
|
||||
|
||||
// pointer to connection
|
||||
auto connection( QX11Info::connection() );
|
||||
|
||||
// client
|
||||
auto c = m_decoration.data()->client().data();
|
||||
|
||||
/*
|
||||
get root position matching position
|
||||
need to use xcb because the embedding of the widget
|
||||
breaks QT's mapToGlobal and other methods
|
||||
*/
|
||||
QPoint rootPosition( position );
|
||||
xcb_get_geometry_cookie_t cookie( xcb_get_geometry( connection, winId() ) );
|
||||
ScopedPointer<xcb_get_geometry_reply_t> reply( xcb_get_geometry_reply( connection, cookie, nullptr ) );
|
||||
if( reply )
|
||||
{
|
||||
|
||||
// translate coordinates
|
||||
xcb_translate_coordinates_cookie_t coordCookie( xcb_translate_coordinates(
|
||||
connection, winId(), reply.data()->root,
|
||||
-reply.data()->border_width,
|
||||
-reply.data()->border_width ) );
|
||||
|
||||
ScopedPointer< xcb_translate_coordinates_reply_t> coordReply( xcb_translate_coordinates_reply( connection, coordCookie, nullptr ) );
|
||||
|
||||
if( coordReply )
|
||||
{
|
||||
rootPosition.rx() += coordReply.data()->dst_x;
|
||||
rootPosition.ry() += coordReply.data()->dst_y;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// move/resize atom
|
||||
if( !m_moveResizeAtom )
|
||||
{
|
||||
|
||||
// create atom if not found
|
||||
const QString atomName( "_NET_WM_MOVERESIZE" );
|
||||
xcb_intern_atom_cookie_t cookie( xcb_intern_atom( connection, false, atomName.size(), qPrintable( atomName ) ) );
|
||||
ScopedPointer<xcb_intern_atom_reply_t> reply( xcb_intern_atom_reply( connection, cookie, nullptr ) );
|
||||
m_moveResizeAtom = reply ? reply->atom:0;
|
||||
|
||||
}
|
||||
|
||||
if( !m_moveResizeAtom ) return;
|
||||
|
||||
// button release event
|
||||
xcb_button_release_event_t releaseEvent;
|
||||
memset(&releaseEvent, 0, sizeof(releaseEvent));
|
||||
|
||||
releaseEvent.response_type = XCB_BUTTON_RELEASE;
|
||||
releaseEvent.event = winId();
|
||||
releaseEvent.child = XCB_WINDOW_NONE;
|
||||
releaseEvent.root = QX11Info::appRootWindow();
|
||||
releaseEvent.event_x = position.x();
|
||||
releaseEvent.event_y = position.y();
|
||||
releaseEvent.root_x = rootPosition.x();
|
||||
releaseEvent.root_y = rootPosition.y();
|
||||
releaseEvent.detail = XCB_BUTTON_INDEX_1;
|
||||
releaseEvent.state = XCB_BUTTON_MASK_1;
|
||||
releaseEvent.time = XCB_CURRENT_TIME;
|
||||
releaseEvent.same_screen = true;
|
||||
xcb_send_event( connection, false, winId(), XCB_EVENT_MASK_BUTTON_RELEASE, reinterpret_cast<const char*>(&releaseEvent));
|
||||
|
||||
xcb_ungrab_pointer( connection, XCB_TIME_CURRENT_TIME );
|
||||
|
||||
// move resize event
|
||||
xcb_client_message_event_t clientMessageEvent;
|
||||
memset(&clientMessageEvent, 0, sizeof(clientMessageEvent));
|
||||
|
||||
clientMessageEvent.response_type = XCB_CLIENT_MESSAGE;
|
||||
clientMessageEvent.type = m_moveResizeAtom;
|
||||
clientMessageEvent.format = 32;
|
||||
clientMessageEvent.window = c->windowId();
|
||||
clientMessageEvent.data.data32[0] = rootPosition.x();
|
||||
clientMessageEvent.data.data32[1] = rootPosition.y();
|
||||
clientMessageEvent.data.data32[2] = 4; // bottom right
|
||||
clientMessageEvent.data.data32[3] = Qt::LeftButton;
|
||||
clientMessageEvent.data.data32[4] = 0;
|
||||
|
||||
xcb_send_event( connection, false, QX11Info::appRootWindow(),
|
||||
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
|
||||
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
|
||||
reinterpret_cast<const char*>(&clientMessageEvent) );
|
||||
|
||||
xcb_flush( connection );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
}
|
100
breezesizegrip.h
Normal file
100
breezesizegrip.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
#ifndef breezesizegrip_h
|
||||
#define breezesizegrip_h
|
||||
|
||||
/*************************************************************************
|
||||
* Copyright (C) 2014 by Hugo Pereira Da Costa <hugo.pereira@free.fr> *
|
||||
* *
|
||||
* 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 "breezedecoration.h"
|
||||
#include "config-breeze.h"
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QPaintEvent>
|
||||
#include <QWidget>
|
||||
#include <QPointer>
|
||||
|
||||
#if BREEZE_HAVE_X11
|
||||
#include <xcb/xcb.h>
|
||||
#endif
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
//* implements size grip for all widgets
|
||||
class SizeGrip: public QWidget
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
//* constructor
|
||||
explicit SizeGrip( Decoration* );
|
||||
|
||||
//* constructor
|
||||
virtual ~SizeGrip();
|
||||
|
||||
protected Q_SLOTS:
|
||||
|
||||
//* update background color
|
||||
void updateActiveState();
|
||||
|
||||
//* update position
|
||||
void updatePosition();
|
||||
|
||||
//* embed into parent widget
|
||||
void embed();
|
||||
|
||||
protected:
|
||||
|
||||
//*@name event handlers
|
||||
//@{
|
||||
|
||||
//* paint
|
||||
virtual void paintEvent( QPaintEvent* ) override;
|
||||
|
||||
//* mouse press
|
||||
virtual void mousePressEvent( QMouseEvent* ) override;
|
||||
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
//* send resize event
|
||||
void sendMoveResizeEvent( QPoint );
|
||||
|
||||
//* grip size
|
||||
enum {
|
||||
Offset = 0,
|
||||
GripSize = 14
|
||||
};
|
||||
|
||||
//* decoration
|
||||
QPointer<Decoration> m_decoration;
|
||||
|
||||
//* move/resize atom
|
||||
#if BREEZE_HAVE_X11
|
||||
xcb_atom_t m_moveResizeAtom = 0;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
20
cmake/Modules/FindFFTW.cmake
Normal file
20
cmake/Modules/FindFFTW.cmake
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Find the FFTW library
|
||||
#
|
||||
# Usage:
|
||||
# find_package(FFTW [REQUIRED])
|
||||
#
|
||||
# It sets the following variables:
|
||||
# FFTW_FOUND
|
||||
# FFTW_INCLUDES
|
||||
# FFTW_LIBRARIES
|
||||
|
||||
|
||||
find_path(FFTW_INCLUDES fftw3.h)
|
||||
|
||||
find_library(FFTW_LIBRARIES NAMES fftw3)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(FFTW DEFAULT_MSG
|
||||
FFTW_INCLUDES FFTW_LIBRARIES)
|
||||
|
||||
mark_as_advanced(FFTW_INCLUDES FFTW_LIBRARIES)
|
28
config-breeze.h.cmake
Normal file
28
config-breeze.h.cmake
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* config-breeze.h. Generated by cmake from config-breeze.h.cmake */
|
||||
|
||||
/*************************************************************************
|
||||
* Copyright (C) 2014 by Hugo Pereira Da Costa <hugo.pereira@free.fr> *
|
||||
* *
|
||||
* 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 . *
|
||||
*************************************************************************/
|
||||
|
||||
#ifndef config_breeze_h
|
||||
#define config_breeze_h
|
||||
|
||||
/* Define to 1 if XCB libraries are found */
|
||||
#cmakedefine01 BREEZE_HAVE_X11
|
||||
|
||||
#endif
|
15
config/breeze10config.desktop
Normal file
15
config/breeze10config.desktop
Normal file
|
@ -0,0 +1,15 @@
|
|||
[Desktop Entry]
|
||||
Exec=kcmshell5 breeze10config
|
||||
Icon=preferences-system-windows
|
||||
Type=Service
|
||||
X-KDE-ServiceTypes=KCModule
|
||||
|
||||
X-KDE-Library=org.kde.kdecoration2/breeze10
|
||||
X-KDE-PluginKeyword=kcmodule
|
||||
X-KDE-ParentApp=kcontrol
|
||||
X-KDE-Weight=60
|
||||
X-KDE-PluginInfo-Name=Breeze10
|
||||
|
||||
Name=Breeze10
|
||||
Comment=Modify the appearance of window decorations
|
||||
X-KDE-Keywords=breeze10,decoration
|
323
config/breezeconfigwidget.cpp
Normal file
323
config/breezeconfigwidget.cpp
Normal file
|
@ -0,0 +1,323 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
// breezeconfigurationui.cpp
|
||||
// -------------------
|
||||
//
|
||||
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "breezeconfigwidget.h"
|
||||
#include "breezeexceptionlist.h"
|
||||
#include "breezesettings.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusMessage>
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
//_________________________________________________________
|
||||
ConfigWidget::ConfigWidget( QWidget* parent, const QVariantList &args ):
|
||||
KCModule(parent, args),
|
||||
m_configuration( KSharedConfig::openConfig( QStringLiteral( "breezerc" ) ) ),
|
||||
m_changed( false )
|
||||
{
|
||||
|
||||
// configuration
|
||||
m_ui.setupUi( this );
|
||||
|
||||
// track ui changes
|
||||
connect( m_ui.titleAlignment, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) );
|
||||
connect( m_ui.buttonSize, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) );
|
||||
connect( m_ui.drawBorderOnMaximizedWindows, SIGNAL(clicked()), SLOT(updateChanged()) );
|
||||
connect( m_ui.drawSizeGrip, SIGNAL(clicked()), SLOT(updateChanged()) );
|
||||
connect( m_ui.opacitySpinBox, QOverload<int>::of(&QSpinBox::valueChanged), [=](int /*i*/){updateChanged();} );
|
||||
|
||||
connect( m_ui.fontComboBox, &QFontComboBox::currentFontChanged, [this] { updateChanged(); } );
|
||||
connect( m_ui.fontSizeSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), [=](int /*i*/){updateChanged();} );
|
||||
connect(m_ui.weightComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), [this] { updateChanged(); } );
|
||||
connect( m_ui.italicCheckBox, &QCheckBox::stateChanged, [this] { updateChanged(); } );
|
||||
|
||||
// track animations changes
|
||||
connect( m_ui.animationsEnabled, SIGNAL(clicked()), SLOT(updateChanged()) );
|
||||
connect( m_ui.animationsDuration, SIGNAL(valueChanged(int)), SLOT(updateChanged()) );
|
||||
|
||||
// track shadows changes
|
||||
connect( m_ui.shadowSize, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) );
|
||||
connect( m_ui.shadowStrength, SIGNAL(valueChanged(int)), SLOT(updateChanged()) );
|
||||
connect( m_ui.shadowColor, SIGNAL(changed(QColor)), SLOT(updateChanged()) );
|
||||
|
||||
// track exception changes
|
||||
connect( m_ui.exceptions, SIGNAL(changed(bool)), SLOT(updateChanged()) );
|
||||
|
||||
}
|
||||
|
||||
//_________________________________________________________
|
||||
void ConfigWidget::load()
|
||||
{
|
||||
|
||||
// create internal settings and load from rc files
|
||||
m_internalSettings = InternalSettingsPtr( new InternalSettings() );
|
||||
m_internalSettings->load();
|
||||
|
||||
// assign to ui
|
||||
m_ui.titleAlignment->setCurrentIndex( m_internalSettings->titleAlignment() );
|
||||
m_ui.buttonSize->setCurrentIndex( m_internalSettings->buttonSize() );
|
||||
m_ui.drawBorderOnMaximizedWindows->setChecked( m_internalSettings->drawBorderOnMaximizedWindows() );
|
||||
m_ui.drawSizeGrip->setChecked( m_internalSettings->drawSizeGrip() );
|
||||
m_ui.animationsEnabled->setChecked( m_internalSettings->animationsEnabled() );
|
||||
m_ui.animationsDuration->setValue( m_internalSettings->animationsDuration() );
|
||||
m_ui.opacitySpinBox->setValue( m_internalSettings->backgroundOpacity() );
|
||||
|
||||
QString fontStr = m_internalSettings->titleBarFont();
|
||||
if (fontStr.isEmpty())
|
||||
fontStr = QLatin1String("Sans,11,-1,5,50,0,0,0,0,0");
|
||||
QFont f; f.fromString( fontStr );
|
||||
m_ui.fontComboBox->setCurrentFont( f );
|
||||
m_ui.fontSizeSpinBox->setValue( f.pointSize() );
|
||||
int w = f.weight();
|
||||
switch (w) {
|
||||
case QFont::Medium:
|
||||
m_ui.weightComboBox->setCurrentIndex(1);
|
||||
break;
|
||||
case QFont::DemiBold:
|
||||
m_ui.weightComboBox->setCurrentIndex(2);
|
||||
break;
|
||||
case QFont::Bold:
|
||||
m_ui.weightComboBox->setCurrentIndex(3);
|
||||
break;
|
||||
case QFont::ExtraBold:
|
||||
m_ui.weightComboBox->setCurrentIndex(4);
|
||||
break;
|
||||
case QFont::Black:
|
||||
m_ui.weightComboBox->setCurrentIndex(5);
|
||||
break;
|
||||
default:
|
||||
m_ui.weightComboBox->setCurrentIndex(0);
|
||||
break;
|
||||
}
|
||||
m_ui.italicCheckBox->setChecked( f.italic() );
|
||||
|
||||
// load shadows
|
||||
if( m_internalSettings->shadowSize() <= InternalSettings::ShadowVeryLarge ) m_ui.shadowSize->setCurrentIndex( m_internalSettings->shadowSize() );
|
||||
else m_ui.shadowSize->setCurrentIndex( InternalSettings::ShadowLarge );
|
||||
|
||||
m_ui.shadowStrength->setValue( qRound(qreal(m_internalSettings->shadowStrength()*100)/255 ) );
|
||||
m_ui.shadowColor->setColor( m_internalSettings->shadowColor() );
|
||||
|
||||
// load exceptions
|
||||
ExceptionList exceptions;
|
||||
exceptions.readConfig( m_configuration );
|
||||
m_ui.exceptions->setExceptions( exceptions.get() );
|
||||
setChanged( false );
|
||||
|
||||
}
|
||||
|
||||
//_________________________________________________________
|
||||
void ConfigWidget::save()
|
||||
{
|
||||
|
||||
// create internal settings and load from rc files
|
||||
m_internalSettings = InternalSettingsPtr( new InternalSettings() );
|
||||
m_internalSettings->load();
|
||||
|
||||
// apply modifications from ui
|
||||
m_internalSettings->setTitleAlignment( m_ui.titleAlignment->currentIndex() );
|
||||
m_internalSettings->setButtonSize( m_ui.buttonSize->currentIndex() );
|
||||
m_internalSettings->setDrawBorderOnMaximizedWindows( m_ui.drawBorderOnMaximizedWindows->isChecked() );
|
||||
m_internalSettings->setDrawSizeGrip( m_ui.drawSizeGrip->isChecked() );
|
||||
m_internalSettings->setAnimationsEnabled( m_ui.animationsEnabled->isChecked() );
|
||||
m_internalSettings->setAnimationsDuration( m_ui.animationsDuration->value() );
|
||||
m_internalSettings->setBackgroundOpacity(m_ui.opacitySpinBox->value());
|
||||
|
||||
QFont f = m_ui.fontComboBox->currentFont();
|
||||
f.setPointSize(m_ui.fontSizeSpinBox->value());
|
||||
int indx = m_ui.weightComboBox->currentIndex();
|
||||
switch (indx) {
|
||||
case 1:
|
||||
f.setWeight(QFont::Medium);
|
||||
break;
|
||||
case 2:
|
||||
f.setWeight(QFont::DemiBold);
|
||||
break;
|
||||
case 3:
|
||||
f.setWeight(QFont::Bold);
|
||||
break;
|
||||
case 4:
|
||||
f.setWeight(QFont::ExtraBold);
|
||||
break;
|
||||
case 5:
|
||||
f.setWeight(QFont::Black);
|
||||
break;
|
||||
default:
|
||||
f.setBold(false);
|
||||
break;
|
||||
}
|
||||
f.setItalic(m_ui.italicCheckBox->isChecked());
|
||||
m_internalSettings->setTitleBarFont(f.toString());
|
||||
|
||||
m_internalSettings->setShadowSize( m_ui.shadowSize->currentIndex() );
|
||||
m_internalSettings->setShadowStrength( qRound( qreal(m_ui.shadowStrength->value()*255)/100 ) );
|
||||
m_internalSettings->setShadowColor( m_ui.shadowColor->color() );
|
||||
|
||||
// save configuration
|
||||
m_internalSettings->save();
|
||||
|
||||
// get list of exceptions and write
|
||||
InternalSettingsList exceptions( m_ui.exceptions->exceptions() );
|
||||
ExceptionList( exceptions ).writeConfig( m_configuration );
|
||||
|
||||
// sync configuration
|
||||
m_configuration->sync();
|
||||
setChanged( false );
|
||||
|
||||
// needed to tell kwin to reload when running from external kcmshell
|
||||
{
|
||||
QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
}
|
||||
|
||||
// needed for breeze style to reload shadows
|
||||
{
|
||||
QDBusMessage message( QDBusMessage::createSignal("/BreezeDecoration", "org.kde.Breeze.Style", "reparseConfiguration") );
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//_________________________________________________________
|
||||
void ConfigWidget::defaults()
|
||||
{
|
||||
|
||||
// create internal settings and load from rc files
|
||||
m_internalSettings = InternalSettingsPtr( new InternalSettings() );
|
||||
m_internalSettings->setDefaults();
|
||||
|
||||
// assign to ui
|
||||
m_ui.titleAlignment->setCurrentIndex( m_internalSettings->titleAlignment() );
|
||||
m_ui.buttonSize->setCurrentIndex( m_internalSettings->buttonSize() );
|
||||
m_ui.drawBorderOnMaximizedWindows->setChecked( m_internalSettings->drawBorderOnMaximizedWindows() );
|
||||
m_ui.drawSizeGrip->setChecked( m_internalSettings->drawSizeGrip() );
|
||||
m_ui.animationsEnabled->setChecked( m_internalSettings->animationsEnabled() );
|
||||
m_ui.animationsDuration->setValue( m_internalSettings->animationsDuration() );
|
||||
m_ui.opacitySpinBox->setValue( m_internalSettings->backgroundOpacity() );
|
||||
|
||||
QFont f; f.fromString("Sans,11,-1,5,50,0,0,0,0,0");
|
||||
m_ui.fontComboBox->setCurrentFont( f );
|
||||
m_ui.fontSizeSpinBox->setValue( f.pointSize() );
|
||||
int w = f.weight();
|
||||
switch (w) {
|
||||
case QFont::Medium:
|
||||
m_ui.weightComboBox->setCurrentIndex(1);
|
||||
break;
|
||||
case QFont::DemiBold:
|
||||
m_ui.weightComboBox->setCurrentIndex(2);
|
||||
break;
|
||||
case QFont::Bold:
|
||||
m_ui.weightComboBox->setCurrentIndex(3);
|
||||
break;
|
||||
case QFont::ExtraBold:
|
||||
m_ui.weightComboBox->setCurrentIndex(4);
|
||||
break;
|
||||
case QFont::Black:
|
||||
m_ui.weightComboBox->setCurrentIndex(5);
|
||||
break;
|
||||
default:
|
||||
m_ui.weightComboBox->setCurrentIndex(0);
|
||||
break;
|
||||
}
|
||||
m_ui.italicCheckBox->setChecked( f.italic() );
|
||||
|
||||
m_ui.shadowSize->setCurrentIndex( m_internalSettings->shadowSize() );
|
||||
m_ui.shadowStrength->setValue( qRound(qreal(m_internalSettings->shadowStrength()*100)/255 ) );
|
||||
m_ui.shadowColor->setColor( m_internalSettings->shadowColor() );
|
||||
|
||||
}
|
||||
|
||||
//_______________________________________________
|
||||
void ConfigWidget::updateChanged()
|
||||
{
|
||||
|
||||
// check configuration
|
||||
if( !m_internalSettings ) return;
|
||||
|
||||
// track modifications
|
||||
bool modified( false );
|
||||
QFont f; f.fromString( m_internalSettings->titleBarFont() );
|
||||
|
||||
if( m_ui.titleAlignment->currentIndex() != m_internalSettings->titleAlignment() ) modified = true;
|
||||
else if( m_ui.buttonSize->currentIndex() != m_internalSettings->buttonSize() ) modified = true;
|
||||
else if( m_ui.drawBorderOnMaximizedWindows->isChecked() != m_internalSettings->drawBorderOnMaximizedWindows() ) modified = true;
|
||||
else if( m_ui.drawSizeGrip->isChecked() != m_internalSettings->drawSizeGrip() ) modified = true;
|
||||
else if( m_ui.opacitySpinBox->value() != m_internalSettings->backgroundOpacity() ) modified = true;
|
||||
|
||||
// font (also see below)
|
||||
else if( m_ui.fontComboBox->currentFont().toString() != f.family() ) modified = true;
|
||||
else if( m_ui.fontSizeSpinBox->value() != f.pointSize() ) modified = true;
|
||||
else if( m_ui.italicCheckBox->isChecked() != f.italic() ) modified = true;
|
||||
|
||||
// animations
|
||||
else if( m_ui.animationsEnabled->isChecked() != m_internalSettings->animationsEnabled() ) modified = true;
|
||||
else if( m_ui.animationsDuration->value() != m_internalSettings->animationsDuration() ) modified = true;
|
||||
|
||||
// shadows
|
||||
else if( m_ui.shadowSize->currentIndex() != m_internalSettings->shadowSize() ) modified = true;
|
||||
else if( qRound( qreal(m_ui.shadowStrength->value()*255)/100 ) != m_internalSettings->shadowStrength() ) modified = true;
|
||||
else if( m_ui.shadowColor->color() != m_internalSettings->shadowColor() ) modified = true;
|
||||
|
||||
// exceptions
|
||||
else if( m_ui.exceptions->isChanged() ) modified = true;
|
||||
else {
|
||||
int indx = m_ui.weightComboBox->currentIndex();
|
||||
switch (indx) {
|
||||
case 1:
|
||||
if (f.weight() != QFont::Medium) modified = true;
|
||||
break;
|
||||
case 2:
|
||||
if (f.weight() != QFont::DemiBold) modified = true;
|
||||
break;
|
||||
case 3:
|
||||
if (f.weight() != QFont::Bold) modified = true;
|
||||
break;
|
||||
case 4:
|
||||
if (f.weight() != QFont::ExtraBold) modified = true;
|
||||
break;
|
||||
case 5:
|
||||
if (f.weight() != QFont::Black) modified = true;
|
||||
break;
|
||||
default:
|
||||
if (f.bold()) modified = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
setChanged( modified );
|
||||
|
||||
}
|
||||
|
||||
//_______________________________________________
|
||||
void ConfigWidget::setChanged( bool value )
|
||||
{
|
||||
emit changed( value );
|
||||
}
|
||||
|
||||
}
|
93
config/breezeconfigwidget.h
Normal file
93
config/breezeconfigwidget.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
#ifndef breezeconfigwidget_h
|
||||
#define breezeconfigwidget_h
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// breezeconfigurationui.h
|
||||
// -------------------
|
||||
//
|
||||
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "ui_breezeconfigurationui.h"
|
||||
#include "breezeexceptionlistwidget.h"
|
||||
#include "breezesettings.h"
|
||||
#include "breeze.h"
|
||||
|
||||
#include <KCModule>
|
||||
#include <KSharedConfig>
|
||||
|
||||
#include <QWidget>
|
||||
#include <QSharedPointer>
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
//_____________________________________________
|
||||
class ConfigWidget: public KCModule
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
//* constructor
|
||||
explicit ConfigWidget( QWidget*, const QVariantList& );
|
||||
|
||||
//* destructor
|
||||
virtual ~ConfigWidget() = default;
|
||||
|
||||
//* default
|
||||
void defaults() override;
|
||||
|
||||
//* load configuration
|
||||
void load() override;
|
||||
|
||||
//* save configuration
|
||||
void save() override;
|
||||
|
||||
protected Q_SLOTS:
|
||||
|
||||
//* update changed state
|
||||
virtual void updateChanged();
|
||||
|
||||
protected:
|
||||
|
||||
//* set changed state
|
||||
void setChanged( bool );
|
||||
|
||||
private:
|
||||
|
||||
//* ui
|
||||
Ui_BreezeConfigurationUI m_ui;
|
||||
|
||||
//* kconfiguration object
|
||||
KSharedConfig::Ptr m_configuration;
|
||||
|
||||
//* internal exception
|
||||
InternalSettingsPtr m_internalSettings;
|
||||
|
||||
//* changed state
|
||||
bool m_changed;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
131
config/breezedecorationconfig.desktop
Normal file
131
config/breezedecorationconfig.desktop
Normal file
|
@ -0,0 +1,131 @@
|
|||
[Desktop Entry]
|
||||
Exec=kcmshell5 breezedecorationconfig
|
||||
Icon=preferences-system-windows
|
||||
Type=Service
|
||||
X-KDE-ServiceTypes=KCModule
|
||||
|
||||
X-KDE-Library=org.kde.kdecoration2/breezedecoration
|
||||
X-KDE-PluginKeyword=kcmodule
|
||||
X-KDE-ParentApp=kcontrol
|
||||
X-KDE-Weight=60
|
||||
|
||||
Name=Breeze Window Decoration
|
||||
Name[ca]=Decoració de les finestres Brisa
|
||||
Name[ca@valencia]=Decoració de les finestres Brisa
|
||||
Name[cs]=Dekorace oken Breeze
|
||||
Name[da]=Breeze vinduesdekoration
|
||||
Name[de]=Breeze-Fensterdekoration
|
||||
Name[el]=Διακοσμήσεις παραθύρου Breeze
|
||||
Name[en_GB]=Breeze Window Decoration
|
||||
Name[es]=Decoración de ventanas Brisa
|
||||
Name[eu]=Breeze leihoen apaindura
|
||||
Name[fi]=Breeze-ikkunankehys
|
||||
Name[fr]=Décoration de fenêtre Brise
|
||||
Name[gl]=Decoración de xanela de Breeze
|
||||
Name[hu]=Breeze ablakdekoráció
|
||||
Name[ia]=Decoration de fenestra Breeze
|
||||
Name[id]=Dekorasi Jendela Breeze
|
||||
Name[it]=Decorazione delle finestre di Brezza
|
||||
Name[ko]=Breeze 창 장식
|
||||
Name[nl]=Breeze vensterdecoratie
|
||||
Name[nn]=Breeze-vindaugsdekorasjon
|
||||
Name[pl]=Wygląd okien Bryzy
|
||||
Name[pt]=Decoração de Janelas Brisa
|
||||
Name[pt_BR]=Decorações da janela Breeze
|
||||
Name[ru]=Оформление окон Breeze
|
||||
Name[sk]=Dekorácie okien Breeze
|
||||
Name[sl]=Okraski oken Sapica
|
||||
Name[sr]=Поветарчева декорација прозора
|
||||
Name[sr@ijekavian]=Поветарчева декорација прозора
|
||||
Name[sr@ijekavianlatin]=Povetarčeva dekoracija prozora
|
||||
Name[sr@latin]=Povetarčeva dekoracija prozora
|
||||
Name[sv]=Breeze fönsterdekoration
|
||||
Name[tr]=Breeze Pencere Dekorasyonu
|
||||
Name[uk]=Декорації вікон Breeze
|
||||
Name[x-test]=xxBreeze Window Decorationxx
|
||||
Name[zh_CN]=微风窗口装饰
|
||||
Name[zh_TW]=Breeze 視窗裝飾
|
||||
Comment=Modify the appearance of window decorations
|
||||
Comment[ar]=عدّل مظهر زخرفات النّوافذ
|
||||
Comment[ca]=Modifica l'aparença de les decoracions de les finestres
|
||||
Comment[ca@valencia]=Modifica l'aparença de les decoracions de les finestres
|
||||
Comment[cs]=Změnit vzhled dekorace oken
|
||||
Comment[da]=Ændr vinduesdekorationers udseende
|
||||
Comment[de]=Das Erscheinungsbild der Fensterdekorationen ändern
|
||||
Comment[el]=Τροποποίηση εμφάνισης της διακόσμησης παραθύρου
|
||||
Comment[en_GB]=Modify the appearance of window decorations
|
||||
Comment[es]=Modificar el aspecto de las decoraciones de las ventanas
|
||||
Comment[et]=Akna dekoratsioonide välimuse muutmine
|
||||
Comment[eu]=Aldatu leiho apainduren itxura
|
||||
Comment[fi]=Muuta ikkunoiden kehysten ulkoasua
|
||||
Comment[fr]=Modifier l'apparence des décorations des fenêtres
|
||||
Comment[gl]=Modifica a aparencia da decoración da xanela
|
||||
Comment[he]=התאם את מראה מסגרות החלונות
|
||||
Comment[hu]=Az ablakdekorációk megjelenésének módosítása
|
||||
Comment[ia]=Modifica le apparentia de decorationes de fenestra
|
||||
Comment[id]=Memodofikasi penampilan dekorasi jendela
|
||||
Comment[it]=Modifica l'aspetto delle decorazioni delle finestre
|
||||
Comment[ko]=창 장식의 모습을 수정합니다
|
||||
Comment[lt]=Keisti lango dekoracijų išvaizdą
|
||||
Comment[nb]=Endre utseende for vindusdekorasjoner
|
||||
Comment[nl]=Wijzig het uiterlijk van vensterdecoraties
|
||||
Comment[nn]=Endra utsjånad på vindaugspynt
|
||||
Comment[pl]=Zmień wygląd i wystrój okien
|
||||
Comment[pt]=Modificar a aparência das decorações das janelas
|
||||
Comment[pt_BR]=Modifica a aparência das decorações da janela
|
||||
Comment[ro]=Modifică aspectul decorațiilor pentru ferestre
|
||||
Comment[ru]=Настройка заголовков окон в стиле Breeze
|
||||
Comment[sk]=Zmena vzhľadu dekorácie okien
|
||||
Comment[sl]=Spremenite videz okraskov oken
|
||||
Comment[sr]=Измените изглед декорација прозора
|
||||
Comment[sr@ijekavian]=Измијените изглед декорација прозора
|
||||
Comment[sr@ijekavianlatin]=Izmijenite izgled dekoracija prozora
|
||||
Comment[sr@latin]=Izmenite izgled dekoracija prozora
|
||||
Comment[sv]=Ändra utseendet hos fönsterdekorationer
|
||||
Comment[tr]=Pencere dekorasyonlarının görünümünü değiştir
|
||||
Comment[uk]=Зміна вигляду декорацій вікон
|
||||
Comment[x-test]=xxModify the appearance of window decorationsxx
|
||||
Comment[zh_CN]=修改窗口装饰外观
|
||||
Comment[zh_TW]=變更視窗裝飾外觀
|
||||
X-KDE-Keywords=breeze,decoration
|
||||
X-KDE-Keywords[ar]=نسيم,زخرفة
|
||||
X-KDE-Keywords[ca]=breeze,brisa,decoració
|
||||
X-KDE-Keywords[ca@valencia]=breeze,brisa,decoració
|
||||
X-KDE-Keywords[cs]=breeze,dekorace
|
||||
X-KDE-Keywords[da]=breeze,dekoration
|
||||
X-KDE-Keywords[de]=Breeze-Dekoration
|
||||
X-KDE-Keywords[el]=breeze,διακόσμηση
|
||||
X-KDE-Keywords[en_GB]=breeze,decoration
|
||||
X-KDE-Keywords[es]=breeze,brisa,decoración
|
||||
X-KDE-Keywords[et]=breeze,dekoratsioon
|
||||
X-KDE-Keywords[eu]=breeze,apainketa,apaindura
|
||||
X-KDE-Keywords[fi]=breeze,decoration,kehys,koriste,koristus,ikkunakehys
|
||||
X-KDE-Keywords[fr]=breeze,décoration
|
||||
X-KDE-Keywords[gl]=breeze,decoración
|
||||
X-KDE-Keywords[he]=breeze,decoration,מסגרת
|
||||
X-KDE-Keywords[hu]=breeze,dekoráció
|
||||
X-KDE-Keywords[ia]=breeze,decoration
|
||||
X-KDE-Keywords[id]=breeze,dekorasi
|
||||
X-KDE-Keywords[it]=brezza,decorazione
|
||||
X-KDE-Keywords[ko]=breeze,decoration,장식
|
||||
X-KDE-Keywords[lt]=breeze,kekoracija
|
||||
X-KDE-Keywords[nb]=beeze,dekorasjon
|
||||
X-KDE-Keywords[nl]=breeze,decoratie
|
||||
X-KDE-Keywords[nn]=breeze,dekorasjonar,pynt
|
||||
X-KDE-Keywords[pl]=breeze,dekoracja,bryza,wystrój
|
||||
X-KDE-Keywords[pt]=brisa,decoração
|
||||
X-KDE-Keywords[pt_BR]=breeze,decoração
|
||||
X-KDE-Keywords[ro]=briză,breeze,decorare,decorație
|
||||
X-KDE-Keywords[ru]=breeze,бриз,decoration,декорации окон,оформление окон
|
||||
X-KDE-Keywords[sk]=breeze,dekorácia
|
||||
X-KDE-Keywords[sl]=sapica,okraski
|
||||
X-KDE-Keywords[sr]=breeze,decoration,Поветарац,декорација
|
||||
X-KDE-Keywords[sr@ijekavian]=breeze,decoration,Поветарац,декорација
|
||||
X-KDE-Keywords[sr@ijekavianlatin]=breeze,decoration,Povetarac,dekoracija
|
||||
X-KDE-Keywords[sr@latin]=breeze,decoration,Povetarac,dekoracija
|
||||
X-KDE-Keywords[sv]=breeze,dekoration
|
||||
X-KDE-Keywords[tr]=esinti,dekorasyon
|
||||
X-KDE-Keywords[uk]=breeze,decoration,бриз,декорації,декорація,обрамлення
|
||||
X-KDE-Keywords[x-test]=xxbreezexx,xxdecorationxx
|
||||
X-KDE-Keywords[zh_CN]=breeze,decoration,微风,装饰
|
||||
X-KDE-Keywords[zh_TW]=breeze,decoration
|
182
config/breezedetectwidget.cpp
Normal file
182
config/breezedetectwidget.cpp
Normal file
|
@ -0,0 +1,182 @@
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// breezedetectwidget.cpp
|
||||
// Note: this class is a stripped down version of
|
||||
// /kdebase/workspace/kwin/kcmkwin/kwinrules/detectwidget.cpp
|
||||
// Copyright (c) 2004 Lubos Lunak <l.lunak@kde.org>
|
||||
// -------------------
|
||||
//
|
||||
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "breezedetectwidget.h"
|
||||
|
||||
#include "breeze.h"
|
||||
|
||||
#include <KWindowInfo>
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QMouseEvent>
|
||||
#include <config-breeze.h>
|
||||
#if BREEZE_HAVE_X11
|
||||
#include <QX11Info>
|
||||
#include <xcb/xcb.h>
|
||||
#endif
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
//_________________________________________________________
|
||||
DetectDialog::DetectDialog( QWidget* parent ):
|
||||
QDialog( parent )
|
||||
{
|
||||
|
||||
// setup
|
||||
m_ui.setupUi( this );
|
||||
|
||||
connect( m_ui.buttonBox->button( QDialogButtonBox::Cancel ), SIGNAL(clicked()), this, SLOT(close()) );
|
||||
m_ui.windowClassCheckBox->setChecked( true );
|
||||
|
||||
#if BREEZE_HAVE_X11
|
||||
if (QX11Info::isPlatformX11()) {
|
||||
// create atom
|
||||
xcb_connection_t* connection( QX11Info::connection() );
|
||||
const QString atomName( QStringLiteral( "WM_STATE" ) );
|
||||
xcb_intern_atom_cookie_t cookie( xcb_intern_atom( connection, false, atomName.size(), qPrintable( atomName ) ) );
|
||||
QScopedPointer<xcb_intern_atom_reply_t, QScopedPointerPodDeleter> reply( xcb_intern_atom_reply( connection, cookie, nullptr) );
|
||||
m_wmStateAtom = reply ? reply->atom : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//_________________________________________________________
|
||||
void DetectDialog::detect( WId window )
|
||||
{
|
||||
if( window == 0 ) selectWindow();
|
||||
else readWindow( window );
|
||||
}
|
||||
|
||||
//_________________________________________________________
|
||||
void DetectDialog::readWindow( WId window )
|
||||
{
|
||||
|
||||
if( window == 0 )
|
||||
{
|
||||
emit detectionDone( false );
|
||||
return;
|
||||
}
|
||||
|
||||
m_info.reset(new KWindowInfo( window, NET::WMAllProperties, NET::WM2AllProperties ));
|
||||
if( !m_info->valid())
|
||||
{
|
||||
emit detectionDone( false );
|
||||
return;
|
||||
}
|
||||
|
||||
const QString wmClassClass( QString::fromUtf8( m_info->windowClassClass() ) );
|
||||
const QString wmClassName( QString::fromUtf8( m_info->windowClassName() ) );
|
||||
|
||||
m_ui.windowClass->setText( QStringLiteral( "%1 (%2 %3)" ).arg( wmClassClass ).arg( wmClassName ).arg( wmClassClass ) );
|
||||
m_ui.windowTitle->setText( m_info->name() );
|
||||
emit detectionDone( exec() == QDialog::Accepted );
|
||||
|
||||
}
|
||||
|
||||
//_________________________________________________________
|
||||
void DetectDialog::selectWindow()
|
||||
{
|
||||
|
||||
// use a dialog, so that all user input is blocked
|
||||
// use WX11BypassWM and moving away so that it's not actually visible
|
||||
// grab only mouse, so that keyboard can be used e.g. for switching windows
|
||||
m_grabber = new QDialog( nullptr, Qt::X11BypassWindowManagerHint );
|
||||
m_grabber->move( -1000, -1000 );
|
||||
m_grabber->setModal( true );
|
||||
m_grabber->show();
|
||||
|
||||
// need to explicitly override cursor for Qt5
|
||||
qApp->setOverrideCursor( Qt::CrossCursor );
|
||||
m_grabber->grabMouse( Qt::CrossCursor );
|
||||
m_grabber->installEventFilter( this );
|
||||
|
||||
}
|
||||
|
||||
//_________________________________________________________
|
||||
bool DetectDialog::eventFilter( QObject* o, QEvent* e )
|
||||
{
|
||||
// check object and event type
|
||||
if( o != m_grabber ) return false;
|
||||
if( e->type() != QEvent::MouseButtonRelease ) return false;
|
||||
|
||||
// need to explicitely release cursor for Qt5
|
||||
qApp->restoreOverrideCursor();
|
||||
|
||||
// delete old m_grabber
|
||||
delete m_grabber;
|
||||
m_grabber = nullptr;
|
||||
|
||||
// check button
|
||||
if( static_cast< QMouseEvent* >( e )->button() != Qt::LeftButton ) return true;
|
||||
|
||||
// read window information
|
||||
readWindow( findWindow() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//_________________________________________________________
|
||||
WId DetectDialog::findWindow()
|
||||
{
|
||||
|
||||
#if BREEZE_HAVE_X11
|
||||
if (!QX11Info::isPlatformX11()) {
|
||||
return 0;
|
||||
}
|
||||
// check atom
|
||||
if( !m_wmStateAtom ) return 0;
|
||||
|
||||
xcb_connection_t* connection( QX11Info::connection() );
|
||||
xcb_window_t parent( QX11Info::appRootWindow() );
|
||||
|
||||
// why is there a loop of only 10 here
|
||||
for( int i = 0; i < 10; ++i )
|
||||
{
|
||||
|
||||
// query pointer
|
||||
xcb_query_pointer_cookie_t pointerCookie( xcb_query_pointer( connection, parent ) );
|
||||
QScopedPointer<xcb_query_pointer_reply_t, QScopedPointerPodDeleter> pointerReply( xcb_query_pointer_reply( connection, pointerCookie, nullptr ) );
|
||||
if( !( pointerReply && pointerReply->child ) ) return 0;
|
||||
|
||||
const xcb_window_t child( pointerReply->child );
|
||||
xcb_get_property_cookie_t cookie( xcb_get_property( connection, 0, child, m_wmStateAtom, XCB_GET_PROPERTY_TYPE_ANY, 0, 0 ) );
|
||||
QScopedPointer<xcb_get_property_reply_t, QScopedPointerPodDeleter> reply( xcb_get_property_reply( connection, cookie, nullptr ) );
|
||||
if( reply && reply->type ) return child;
|
||||
else parent = child;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
113
config/breezedetectwidget.h
Normal file
113
config/breezedetectwidget.h
Normal file
|
@ -0,0 +1,113 @@
|
|||
#ifndef breezedetectwidget_h
|
||||
#define breezedetectwidget_h
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// breezedetectwidget.h
|
||||
// Note: this class is a stripped down version of
|
||||
// /kdebase/workspace/kwin/kcmkwin/kwinrules/detectwidget.h
|
||||
// Copyright (c) 2004 Lubos Lunak <l.lunak@kde.org>
|
||||
|
||||
// -------------------
|
||||
//
|
||||
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "breezesettings.h"
|
||||
#include "ui_breezedetectwidget.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QCheckBox>
|
||||
#include <QDialog>
|
||||
#include <QEvent>
|
||||
#include <QLabel>
|
||||
|
||||
#include <kwindowsystem.h>
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
class DetectDialog : public QDialog
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
//* constructor
|
||||
explicit DetectDialog( QWidget* );
|
||||
|
||||
//* read window properties or select one from mouse grab
|
||||
void detect( WId window );
|
||||
|
||||
//* selected class
|
||||
QByteArray selectedClass() const;
|
||||
|
||||
//* window information
|
||||
const KWindowInfo& windowInfo() const
|
||||
{ return *(m_info.data()); }
|
||||
|
||||
//* exception type
|
||||
InternalSettings::EnumExceptionType exceptionType() const
|
||||
{
|
||||
if( m_ui.windowClassCheckBox->isChecked() ) return InternalSettings::ExceptionWindowClassName;
|
||||
else if( m_ui.windowTitleCheckBox->isChecked() ) return InternalSettings::ExceptionWindowTitle;
|
||||
else return InternalSettings::ExceptionWindowClassName;
|
||||
}
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
void detectionDone( bool );
|
||||
|
||||
protected:
|
||||
|
||||
bool eventFilter( QObject* o, QEvent* e ) override;
|
||||
|
||||
private:
|
||||
|
||||
//* select window from grab
|
||||
void selectWindow();
|
||||
|
||||
//* read window properties
|
||||
void readWindow( WId window );
|
||||
|
||||
//* find window under cursor
|
||||
WId findWindow();
|
||||
|
||||
//* execute
|
||||
void executeDialog();
|
||||
|
||||
//* ui
|
||||
Ui::BreezeDetectWidget m_ui;
|
||||
|
||||
//* invisible dialog used to grab mouse
|
||||
QDialog* m_grabber = nullptr;
|
||||
|
||||
//* current window information
|
||||
QScopedPointer<KWindowInfo> m_info;
|
||||
|
||||
//* wm state atom
|
||||
quint32 m_wmStateAtom = 0;
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
197
config/breezeexceptiondialog.cpp
Normal file
197
config/breezeexceptiondialog.cpp
Normal file
|
@ -0,0 +1,197 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
// breezeexceptiondialog.cpp
|
||||
// -------------------
|
||||
//
|
||||
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "breezeexceptiondialog.h"
|
||||
#include "breezedetectwidget.h"
|
||||
#include "config-breeze.h"
|
||||
|
||||
#if BREEZE_HAVE_X11
|
||||
#include <QX11Info>
|
||||
#endif
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
//___________________________________________
|
||||
ExceptionDialog::ExceptionDialog( QWidget* parent ):
|
||||
QDialog( parent )
|
||||
{
|
||||
|
||||
m_ui.setupUi( this );
|
||||
|
||||
connect( m_ui.buttonBox->button( QDialogButtonBox::Cancel ), SIGNAL(clicked()), this, SLOT(close()) );
|
||||
|
||||
// store checkboxes from ui into list
|
||||
m_checkboxes.insert( BorderSize, m_ui.borderSizeCheckBox );
|
||||
|
||||
// detect window properties
|
||||
connect( m_ui.detectDialogButton, SIGNAL(clicked()), SLOT(selectWindowProperties()) );
|
||||
|
||||
// connections
|
||||
connect( m_ui.exceptionType, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) );
|
||||
connect( m_ui.exceptionEditor, SIGNAL(textChanged(QString)), SLOT(updateChanged()) );
|
||||
connect( m_ui.borderSizeComboBox, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) );
|
||||
|
||||
for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter )
|
||||
{ connect( iter.value(), SIGNAL(clicked()), SLOT(updateChanged()) ); }
|
||||
|
||||
connect( m_ui.hideTitleBar, SIGNAL(clicked()), SLOT(updateChanged()) );
|
||||
connect( m_ui.opaqueTitleBar, SIGNAL(clicked()), SLOT(updateChanged()) );
|
||||
m_ui.opacityOverrideLabelSpinBox->setSpecialValueText(tr("None"));
|
||||
connect( m_ui.opacityOverrideLabelSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), [=](int /*i*/){updateChanged();} );
|
||||
connect( m_ui.isDialog, SIGNAL(clicked()), SLOT(updateChanged()) );
|
||||
|
||||
// hide detection dialog on non X11 platforms
|
||||
#if BREEZE_HAVE_X11
|
||||
if( !QX11Info::isPlatformX11() ) m_ui.detectDialogButton->hide();
|
||||
#else
|
||||
m_ui.detectDialogButton->hide();
|
||||
#endif
|
||||
}
|
||||
|
||||
//___________________________________________
|
||||
void ExceptionDialog::setException( InternalSettingsPtr exception )
|
||||
{
|
||||
|
||||
// store exception internally
|
||||
m_exception = exception;
|
||||
|
||||
// type
|
||||
m_ui.exceptionType->setCurrentIndex(m_exception->exceptionType() );
|
||||
m_ui.exceptionEditor->setText( m_exception->exceptionPattern() );
|
||||
m_ui.borderSizeComboBox->setCurrentIndex( m_exception->borderSize() );
|
||||
m_ui.hideTitleBar->setChecked( m_exception->hideTitleBar() );
|
||||
m_ui.opaqueTitleBar->setChecked( m_exception->opaqueTitleBar() );
|
||||
m_ui.opacityOverrideLabelSpinBox->setValue( m_exception->opacityOverride() );
|
||||
m_ui.isDialog->setChecked( m_exception->isDialog() );
|
||||
|
||||
// mask
|
||||
for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter )
|
||||
{ iter.value()->setChecked( m_exception->mask() & iter.key() ); }
|
||||
|
||||
setChanged( false );
|
||||
|
||||
}
|
||||
|
||||
//___________________________________________
|
||||
void ExceptionDialog::save()
|
||||
{
|
||||
m_exception->setExceptionType( m_ui.exceptionType->currentIndex() );
|
||||
m_exception->setExceptionPattern( m_ui.exceptionEditor->text() );
|
||||
m_exception->setBorderSize( m_ui.borderSizeComboBox->currentIndex() );
|
||||
m_exception->setHideTitleBar( m_ui.hideTitleBar->isChecked() );
|
||||
m_exception->setOpaqueTitleBar( m_ui.opaqueTitleBar->isChecked() );
|
||||
m_exception->setOpacityOverride( m_ui.opacityOverrideLabelSpinBox->value() );
|
||||
m_exception->setIsDialog( m_ui.isDialog->isChecked() );
|
||||
|
||||
// mask
|
||||
unsigned int mask = None;
|
||||
for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter )
|
||||
{ if( iter.value()->isChecked() ) mask |= iter.key(); }
|
||||
|
||||
m_exception->setMask( mask );
|
||||
|
||||
setChanged( false );
|
||||
|
||||
}
|
||||
|
||||
//___________________________________________
|
||||
void ExceptionDialog::updateChanged()
|
||||
{
|
||||
bool modified( false );
|
||||
if( m_exception->exceptionType() != m_ui.exceptionType->currentIndex() ) modified = true;
|
||||
else if( m_exception->exceptionPattern() != m_ui.exceptionEditor->text() ) modified = true;
|
||||
else if( m_exception->borderSize() != m_ui.borderSizeComboBox->currentIndex() ) modified = true;
|
||||
else if( m_exception->hideTitleBar() != m_ui.hideTitleBar->isChecked() ) modified = true;
|
||||
else if( m_exception->opaqueTitleBar() != m_ui.opaqueTitleBar->isChecked() ) modified = true;
|
||||
else if( m_exception->opacityOverride() != m_ui.opacityOverrideLabelSpinBox->value() ) modified = true;
|
||||
else if( m_exception->isDialog() != m_ui.isDialog->isChecked() ) modified = true;
|
||||
else
|
||||
{
|
||||
// check mask
|
||||
for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter )
|
||||
{
|
||||
if( iter.value()->isChecked() != (bool)( m_exception->mask() & iter.key() ) )
|
||||
{
|
||||
modified = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setChanged( modified );
|
||||
|
||||
}
|
||||
|
||||
//___________________________________________
|
||||
void ExceptionDialog::selectWindowProperties()
|
||||
{
|
||||
|
||||
// create widget
|
||||
if( !m_detectDialog )
|
||||
{
|
||||
m_detectDialog = new DetectDialog( this );
|
||||
connect( m_detectDialog, SIGNAL(detectionDone(bool)), SLOT(readWindowProperties(bool)) );
|
||||
}
|
||||
|
||||
m_detectDialog->detect(0);
|
||||
|
||||
}
|
||||
|
||||
//___________________________________________
|
||||
void ExceptionDialog::readWindowProperties( bool valid )
|
||||
{
|
||||
Q_CHECK_PTR( m_detectDialog );
|
||||
if( valid )
|
||||
{
|
||||
|
||||
// type
|
||||
m_ui.exceptionType->setCurrentIndex( m_detectDialog->exceptionType() );
|
||||
|
||||
// window info
|
||||
const KWindowInfo& info( m_detectDialog->windowInfo() );
|
||||
|
||||
switch( m_detectDialog->exceptionType() )
|
||||
{
|
||||
|
||||
default:
|
||||
case InternalSettings::ExceptionWindowClassName:
|
||||
m_ui.exceptionEditor->setText( QString::fromUtf8( info.windowClassClass() ) );
|
||||
break;
|
||||
|
||||
case InternalSettings::ExceptionWindowTitle:
|
||||
m_ui.exceptionEditor->setText( info.name() );
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
delete m_detectDialog;
|
||||
m_detectDialog = nullptr;
|
||||
|
||||
}
|
||||
|
||||
}
|
114
config/breezeexceptiondialog.h
Normal file
114
config/breezeexceptiondialog.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
#ifndef breezeexceptiondialog_h
|
||||
#define breezeexceptiondialog_h
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// breezeexceptiondialog.h
|
||||
// -------------------
|
||||
//
|
||||
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "ui_breezeexceptiondialog.h"
|
||||
#include "breeze.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QMap>
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
class DetectDialog;
|
||||
|
||||
//* breeze exceptions list
|
||||
class ExceptionDialog: public QDialog
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
//* constructor
|
||||
explicit ExceptionDialog( QWidget* parent );
|
||||
|
||||
//* destructor
|
||||
virtual ~ExceptionDialog()
|
||||
{}
|
||||
|
||||
//* set exception
|
||||
void setException( InternalSettingsPtr );
|
||||
|
||||
//* save exception
|
||||
void save();
|
||||
|
||||
//* true if changed
|
||||
virtual bool isChanged() const
|
||||
{ return m_changed; }
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
//* emmited when changed
|
||||
void changed( bool );
|
||||
|
||||
protected:
|
||||
|
||||
//* set changed state
|
||||
virtual void setChanged( bool value )
|
||||
{
|
||||
m_changed = value;
|
||||
emit changed( value );
|
||||
}
|
||||
|
||||
protected Q_SLOTS:
|
||||
|
||||
//* check whether configuration is changed and emit appropriate signal if yes
|
||||
virtual void updateChanged();
|
||||
|
||||
private Q_SLOTS:
|
||||
|
||||
//* select window properties from grabbed pointers
|
||||
void selectWindowProperties();
|
||||
|
||||
//* read properties of selected window
|
||||
void readWindowProperties( bool );
|
||||
|
||||
private:
|
||||
|
||||
//* map mask and checkbox
|
||||
using CheckBoxMap=QMap< ExceptionMask, QCheckBox*>;
|
||||
|
||||
Ui::BreezeExceptionDialog m_ui;
|
||||
|
||||
//* map mask and checkbox
|
||||
CheckBoxMap m_checkboxes;
|
||||
|
||||
//* internal exception
|
||||
InternalSettingsPtr m_exception;
|
||||
|
||||
//* detection dialog
|
||||
DetectDialog* m_detectDialog = nullptr;
|
||||
|
||||
//* changed state
|
||||
bool m_changed = false;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
345
config/breezeexceptionlistwidget.cpp
Normal file
345
config/breezeexceptionlistwidget.cpp
Normal file
|
@ -0,0 +1,345 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
// breezeexceptionlistwidget.cpp
|
||||
// -------------------
|
||||
//
|
||||
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "breezeexceptionlistwidget.h"
|
||||
#include "breezeexceptiondialog.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QPointer>
|
||||
#include <QIcon>
|
||||
|
||||
//__________________________________________________________
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
//__________________________________________________________
|
||||
ExceptionListWidget::ExceptionListWidget( QWidget* parent ):
|
||||
QWidget( parent )
|
||||
{
|
||||
|
||||
// ui
|
||||
m_ui.setupUi( this );
|
||||
|
||||
// list
|
||||
m_ui.exceptionListView->setAllColumnsShowFocus( true );
|
||||
m_ui.exceptionListView->setRootIsDecorated( false );
|
||||
m_ui.exceptionListView->setSortingEnabled( false );
|
||||
m_ui.exceptionListView->setModel( &model() );
|
||||
m_ui.exceptionListView->sortByColumn( ExceptionModel::ColumnType );
|
||||
m_ui.exceptionListView->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Ignored ) );
|
||||
|
||||
m_ui.moveUpButton->setIcon( QIcon::fromTheme( QStringLiteral( "arrow-up" ) ) );
|
||||
m_ui.moveDownButton->setIcon( QIcon::fromTheme( QStringLiteral( "arrow-down" ) ) );
|
||||
m_ui.addButton->setIcon( QIcon::fromTheme( QStringLiteral( "list-add" ) ) );
|
||||
m_ui.removeButton->setIcon( QIcon::fromTheme( QStringLiteral( "list-remove" ) ) );
|
||||
m_ui.editButton->setIcon( QIcon::fromTheme( QStringLiteral( "edit-rename" ) ) );
|
||||
|
||||
connect( m_ui.addButton, SIGNAL(clicked()), SLOT(add()) );
|
||||
connect( m_ui.editButton, SIGNAL(clicked()), SLOT(edit()) );
|
||||
connect( m_ui.removeButton, SIGNAL(clicked()), SLOT(remove()) );
|
||||
connect( m_ui.moveUpButton, SIGNAL(clicked()), SLOT(up()) );
|
||||
connect( m_ui.moveDownButton, SIGNAL(clicked()), SLOT(down()) );
|
||||
|
||||
connect( m_ui.exceptionListView, SIGNAL(activated(QModelIndex)), SLOT(edit()) );
|
||||
connect( m_ui.exceptionListView, SIGNAL(clicked(QModelIndex)), SLOT(toggle(QModelIndex)) );
|
||||
connect( m_ui.exceptionListView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(updateButtons()) );
|
||||
|
||||
updateButtons();
|
||||
resizeColumns();
|
||||
|
||||
|
||||
}
|
||||
|
||||
//__________________________________________________________
|
||||
void ExceptionListWidget::setExceptions( const InternalSettingsList& exceptions )
|
||||
{
|
||||
model().set( exceptions );
|
||||
resizeColumns();
|
||||
setChanged( false );
|
||||
}
|
||||
|
||||
//__________________________________________________________
|
||||
InternalSettingsList ExceptionListWidget::exceptions()
|
||||
{
|
||||
return model().get();
|
||||
setChanged( false );
|
||||
}
|
||||
|
||||
//__________________________________________________________
|
||||
void ExceptionListWidget::updateButtons()
|
||||
{
|
||||
|
||||
bool hasSelection( !m_ui.exceptionListView->selectionModel()->selectedRows().empty() );
|
||||
m_ui.removeButton->setEnabled( hasSelection );
|
||||
m_ui.editButton->setEnabled( hasSelection );
|
||||
|
||||
m_ui.moveUpButton->setEnabled( hasSelection && !m_ui.exceptionListView->selectionModel()->isRowSelected( 0, QModelIndex() ) );
|
||||
m_ui.moveDownButton->setEnabled( hasSelection && !m_ui.exceptionListView->selectionModel()->isRowSelected( model().rowCount()-1, QModelIndex() ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
//_______________________________________________________
|
||||
void ExceptionListWidget::add()
|
||||
{
|
||||
|
||||
|
||||
QPointer<ExceptionDialog> dialog = new ExceptionDialog( this );
|
||||
dialog->setWindowTitle( i18n( "New Exception - Breeze Settings" ) );
|
||||
InternalSettingsPtr exception( new InternalSettings() );
|
||||
|
||||
exception->load();
|
||||
|
||||
dialog->setException( exception );
|
||||
|
||||
// run dialog and check existence
|
||||
if( !dialog->exec() )
|
||||
{
|
||||
delete dialog;
|
||||
return;
|
||||
}
|
||||
|
||||
dialog->save();
|
||||
delete dialog;
|
||||
|
||||
// check exceptions
|
||||
if( !checkException( exception ) ) return;
|
||||
|
||||
// create new item
|
||||
model().add( exception );
|
||||
setChanged( true );
|
||||
|
||||
// make sure item is selected
|
||||
QModelIndex index( model().index( exception ) );
|
||||
if( index != m_ui.exceptionListView->selectionModel()->currentIndex() )
|
||||
{
|
||||
m_ui.exceptionListView->selectionModel()->select( index, QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows );
|
||||
m_ui.exceptionListView->selectionModel()->setCurrentIndex( index, QItemSelectionModel::Current|QItemSelectionModel::Rows );
|
||||
}
|
||||
|
||||
resizeColumns();
|
||||
|
||||
}
|
||||
|
||||
//_______________________________________________________
|
||||
void ExceptionListWidget::edit()
|
||||
{
|
||||
|
||||
// retrieve selection
|
||||
QModelIndex current( m_ui.exceptionListView->selectionModel()->currentIndex() );
|
||||
if( ! model().contains( current ) ) return;
|
||||
|
||||
InternalSettingsPtr exception( model().get( current ) );
|
||||
|
||||
// create dialog
|
||||
QPointer<ExceptionDialog> dialog( new ExceptionDialog( this ) );
|
||||
dialog->setWindowTitle( i18n( "Edit Exception - Breeze Settings" ) );
|
||||
dialog->setException( exception );
|
||||
|
||||
// map dialog
|
||||
if( !dialog->exec() )
|
||||
{
|
||||
delete dialog;
|
||||
return;
|
||||
}
|
||||
|
||||
// check modifications
|
||||
if( !dialog->isChanged() ) return;
|
||||
|
||||
// retrieve exception
|
||||
dialog->save();
|
||||
delete dialog;
|
||||
|
||||
// check new exception validity
|
||||
checkException( exception );
|
||||
resizeColumns();
|
||||
|
||||
setChanged( true );
|
||||
|
||||
}
|
||||
|
||||
//_______________________________________________________
|
||||
void ExceptionListWidget::remove()
|
||||
{
|
||||
|
||||
// confirmation dialog
|
||||
{
|
||||
QMessageBox messageBox( QMessageBox::Question, i18n("Question - Breeze Settings" ), i18n("Remove selected exception?"), QMessageBox::Yes | QMessageBox::Cancel );
|
||||
messageBox.button( QMessageBox::Yes )->setText( i18n("Remove") );
|
||||
messageBox.setDefaultButton( QMessageBox::Cancel );
|
||||
if( messageBox.exec() == QMessageBox::Cancel ) return;
|
||||
}
|
||||
|
||||
// remove
|
||||
model().remove( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) );
|
||||
resizeColumns();
|
||||
updateButtons();
|
||||
|
||||
setChanged( true );
|
||||
|
||||
}
|
||||
|
||||
//_______________________________________________________
|
||||
void ExceptionListWidget::toggle( const QModelIndex& index )
|
||||
{
|
||||
|
||||
if( !model().contains( index ) ) return;
|
||||
if( index.column() != ExceptionModel::ColumnEnabled ) return;
|
||||
|
||||
// get matching exception
|
||||
InternalSettingsPtr exception( model().get( index ) );
|
||||
exception->setEnabled( !exception->enabled() );
|
||||
setChanged( true );
|
||||
|
||||
}
|
||||
|
||||
//_______________________________________________________
|
||||
void ExceptionListWidget::up()
|
||||
{
|
||||
|
||||
InternalSettingsList selection( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) );
|
||||
if( selection.empty() ) { return; }
|
||||
|
||||
// retrieve selected indexes in list and store in model
|
||||
QModelIndexList selectedIndices( m_ui.exceptionListView->selectionModel()->selectedRows() );
|
||||
InternalSettingsList selectedExceptions( model().get( selectedIndices ) );
|
||||
|
||||
InternalSettingsList currentException( model().get() );
|
||||
InternalSettingsList newExceptions;
|
||||
|
||||
for( InternalSettingsList::const_iterator iter = currentException.constBegin(); iter != currentException.constEnd(); ++iter )
|
||||
{
|
||||
|
||||
// check if new list is not empty, current index is selected and last index is not.
|
||||
// if yes, move.
|
||||
if(
|
||||
!( newExceptions.empty() ||
|
||||
selectedIndices.indexOf( model().index( *iter ) ) == -1 ||
|
||||
selectedIndices.indexOf( model().index( newExceptions.back() ) ) != -1
|
||||
) )
|
||||
{
|
||||
InternalSettingsPtr last( newExceptions.back() );
|
||||
newExceptions.removeLast();
|
||||
newExceptions.append( *iter );
|
||||
newExceptions.append( last );
|
||||
} else newExceptions.append( *iter );
|
||||
|
||||
}
|
||||
|
||||
model().set( newExceptions );
|
||||
|
||||
// restore selection
|
||||
m_ui.exceptionListView->selectionModel()->select( model().index( selectedExceptions.front() ), QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows );
|
||||
for( InternalSettingsList::const_iterator iter = selectedExceptions.constBegin(); iter != selectedExceptions.constEnd(); ++iter )
|
||||
{ m_ui.exceptionListView->selectionModel()->select( model().index( *iter ), QItemSelectionModel::Select|QItemSelectionModel::Rows ); }
|
||||
|
||||
setChanged( true );
|
||||
|
||||
}
|
||||
|
||||
//_______________________________________________________
|
||||
void ExceptionListWidget::down()
|
||||
{
|
||||
|
||||
InternalSettingsList selection( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) );
|
||||
if( selection.empty() )
|
||||
{ return; }
|
||||
|
||||
// retrieve selected indexes in list and store in model
|
||||
QModelIndexList selectedIndices( m_ui.exceptionListView->selectionModel()->selectedIndexes() );
|
||||
InternalSettingsList selectedExceptions( model().get( selectedIndices ) );
|
||||
|
||||
InternalSettingsList currentExceptions( model().get() );
|
||||
InternalSettingsList newExceptions;
|
||||
|
||||
InternalSettingsListIterator iter( currentExceptions );
|
||||
iter.toBack();
|
||||
while( iter.hasPrevious() )
|
||||
{
|
||||
|
||||
InternalSettingsPtr current( iter.previous() );
|
||||
|
||||
// check if new list is not empty, current index is selected and last index is not.
|
||||
// if yes, move.
|
||||
if(
|
||||
!( newExceptions.empty() ||
|
||||
selectedIndices.indexOf( model().index( current ) ) == -1 ||
|
||||
selectedIndices.indexOf( model().index( newExceptions.front() ) ) != -1
|
||||
) )
|
||||
{
|
||||
|
||||
InternalSettingsPtr first( newExceptions.front() );
|
||||
newExceptions.removeFirst();
|
||||
newExceptions.prepend( current );
|
||||
newExceptions.prepend( first );
|
||||
|
||||
} else newExceptions.prepend( current );
|
||||
}
|
||||
|
||||
model().set( newExceptions );
|
||||
|
||||
// restore selection
|
||||
m_ui.exceptionListView->selectionModel()->select( model().index( selectedExceptions.front() ), QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows );
|
||||
for( InternalSettingsList::const_iterator iter = selectedExceptions.constBegin(); iter != selectedExceptions.constEnd(); ++iter )
|
||||
{ m_ui.exceptionListView->selectionModel()->select( model().index( *iter ), QItemSelectionModel::Select|QItemSelectionModel::Rows ); }
|
||||
|
||||
setChanged( true );
|
||||
|
||||
}
|
||||
|
||||
//_______________________________________________________
|
||||
void ExceptionListWidget::resizeColumns() const
|
||||
{
|
||||
m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnEnabled );
|
||||
m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnType );
|
||||
m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnRegExp );
|
||||
}
|
||||
|
||||
//_______________________________________________________
|
||||
bool ExceptionListWidget::checkException( InternalSettingsPtr exception )
|
||||
{
|
||||
|
||||
while( exception->exceptionPattern().isEmpty() || !QRegExp( exception->exceptionPattern() ).isValid() )
|
||||
{
|
||||
|
||||
QMessageBox::warning( this, i18n( "Warning - Breeze Settings" ), i18n("Regular Expression syntax is incorrect") );
|
||||
QPointer<ExceptionDialog> dialog( new ExceptionDialog( this ) );
|
||||
dialog->setException( exception );
|
||||
if( dialog->exec() == QDialog::Rejected )
|
||||
{
|
||||
delete dialog;
|
||||
return false;
|
||||
}
|
||||
|
||||
dialog->save();
|
||||
delete dialog;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
124
config/breezeexceptionlistwidget.h
Normal file
124
config/breezeexceptionlistwidget.h
Normal file
|
@ -0,0 +1,124 @@
|
|||
#ifndef breezeexceptionlistwidget_h
|
||||
#define breezeexceptionlistwidget_h
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// breezeexceptionlistwidget.h
|
||||
// -------------------
|
||||
//
|
||||
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "ui_breezeexceptionlistwidget.h"
|
||||
#include "breezeexceptionmodel.h"
|
||||
|
||||
//* QDialog used to commit selected files
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
class ExceptionListWidget: public QWidget
|
||||
{
|
||||
|
||||
//* Qt meta object
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
//* constructor
|
||||
explicit ExceptionListWidget( QWidget* = nullptr );
|
||||
|
||||
//* set exceptions
|
||||
void setExceptions( const InternalSettingsList& );
|
||||
|
||||
//* get exceptions
|
||||
InternalSettingsList exceptions();
|
||||
|
||||
//* true if changed
|
||||
virtual bool isChanged() const
|
||||
{ return m_changed; }
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
//* emitted when changed
|
||||
void changed( bool );
|
||||
|
||||
protected:
|
||||
|
||||
//* model
|
||||
const ExceptionModel& model() const
|
||||
{ return m_model; }
|
||||
|
||||
//* model
|
||||
ExceptionModel& model()
|
||||
{ return m_model; }
|
||||
|
||||
protected Q_SLOTS:
|
||||
|
||||
//* update button states
|
||||
virtual void updateButtons();
|
||||
|
||||
//* add
|
||||
virtual void add();
|
||||
|
||||
//* edit
|
||||
virtual void edit();
|
||||
|
||||
//* remove
|
||||
virtual void remove();
|
||||
|
||||
//* toggle
|
||||
virtual void toggle( const QModelIndex& );
|
||||
|
||||
//* move up
|
||||
virtual void up();
|
||||
|
||||
//* move down
|
||||
virtual void down();
|
||||
|
||||
protected:
|
||||
|
||||
//* resize columns
|
||||
void resizeColumns() const;
|
||||
|
||||
//* check exception
|
||||
bool checkException( InternalSettingsPtr );
|
||||
|
||||
//* set changed state
|
||||
virtual void setChanged( bool value )
|
||||
{
|
||||
m_changed = value;
|
||||
emit changed( value );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//* model
|
||||
ExceptionModel m_model;
|
||||
|
||||
//* ui
|
||||
Ui_BreezeExceptionListWidget m_ui;
|
||||
|
||||
//* changed state
|
||||
bool m_changed = false;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
107
config/breezeexceptionmodel.cpp
Normal file
107
config/breezeexceptionmodel.cpp
Normal file
|
@ -0,0 +1,107 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
// breezeexceptionmodel.cpp
|
||||
// -------------------
|
||||
//
|
||||
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "breezeexceptionmodel.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
//_______________________________________________
|
||||
const QString ExceptionModel::m_columnTitles[ ExceptionModel::nColumns ] =
|
||||
{
|
||||
QStringLiteral( "" ),
|
||||
i18n("Exception Type"),
|
||||
i18n("Regular Expression")
|
||||
};
|
||||
|
||||
//__________________________________________________________________
|
||||
QVariant ExceptionModel::data( const QModelIndex& index, int role ) const
|
||||
{
|
||||
|
||||
// check index, role and column
|
||||
if( !index.isValid() ) return QVariant();
|
||||
|
||||
// retrieve associated file info
|
||||
const InternalSettingsPtr& configuration( get(index) );
|
||||
|
||||
// return text associated to file and column
|
||||
if( role == Qt::DisplayRole )
|
||||
{
|
||||
|
||||
switch( index.column() )
|
||||
{
|
||||
case ColumnType:
|
||||
{
|
||||
switch( configuration->exceptionType() )
|
||||
{
|
||||
|
||||
case InternalSettings::ExceptionWindowTitle:
|
||||
return i18n( "Window Title" );
|
||||
|
||||
default:
|
||||
case InternalSettings::ExceptionWindowClassName:
|
||||
return i18n( "Window Class Name" );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case ColumnRegExp: return configuration->exceptionPattern();
|
||||
default: return QVariant();
|
||||
break;
|
||||
}
|
||||
|
||||
} else if( role == Qt::CheckStateRole && index.column() == ColumnEnabled ) {
|
||||
|
||||
return configuration->enabled() ? Qt::Checked : Qt::Unchecked;
|
||||
|
||||
} else if( role == Qt::ToolTipRole && index.column() == ColumnEnabled ) {
|
||||
|
||||
return i18n("Enable/disable this exception");
|
||||
|
||||
}
|
||||
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
//__________________________________________________________________
|
||||
QVariant ExceptionModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
|
||||
if(
|
||||
orientation == Qt::Horizontal &&
|
||||
role == Qt::DisplayRole &&
|
||||
section >= 0 &&
|
||||
section < nColumns )
|
||||
{ return m_columnTitles[section]; }
|
||||
|
||||
// return empty
|
||||
return QVariant();
|
||||
|
||||
}
|
||||
|
||||
}
|
81
config/breezeexceptionmodel.h
Normal file
81
config/breezeexceptionmodel.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
#ifndef breezeexceptionmodel_h
|
||||
#define breezeexceptionmodel_h
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// breezeexceptionmodel.h
|
||||
// -------------------
|
||||
//
|
||||
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "breezelistmodel.h"
|
||||
#include "breezesettings.h"
|
||||
#include "breeze.h"
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
//* qlistview for object counters
|
||||
class ExceptionModel: public ListModel<InternalSettingsPtr>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
//* number of columns
|
||||
enum { nColumns = 3 };
|
||||
|
||||
//* column type enumeration
|
||||
enum ColumnType {
|
||||
ColumnEnabled,
|
||||
ColumnType,
|
||||
ColumnRegExp
|
||||
};
|
||||
|
||||
|
||||
//*@name methods reimplemented from base class
|
||||
//@{
|
||||
|
||||
//* return data for a given index
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
//* header data
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
|
||||
//* number of columns for a given index
|
||||
int columnCount(const QModelIndex& ) const override
|
||||
{ return nColumns; }
|
||||
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
//* sort
|
||||
void privateSort( int, Qt::SortOrder ) override
|
||||
{}
|
||||
|
||||
private:
|
||||
|
||||
//* column titles
|
||||
static const QString m_columnTitles[ nColumns ];
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
68
config/breezeitemmodel.cpp
Normal file
68
config/breezeitemmodel.cpp
Normal file
|
@ -0,0 +1,68 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
// itemmodel.cpp
|
||||
// -------------------
|
||||
//
|
||||
// Copyright (c) 2009-2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "breezeitemmodel.h"
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
//_______________________________________________________________
|
||||
ItemModel::ItemModel( QObject* parent ):
|
||||
QAbstractItemModel( parent )
|
||||
{}
|
||||
|
||||
//____________________________________________________________
|
||||
void ItemModel::sort( int column, Qt::SortOrder order )
|
||||
{
|
||||
|
||||
// store column and order
|
||||
m_sortColumn = column;
|
||||
m_sortOrder = order;
|
||||
|
||||
// emit signals and call private methods
|
||||
emit layoutAboutToBeChanged();
|
||||
privateSort( column, order );
|
||||
emit layoutChanged();
|
||||
|
||||
}
|
||||
|
||||
//____________________________________________________________
|
||||
QModelIndexList ItemModel::indexes( int column, const QModelIndex& parent ) const
|
||||
{
|
||||
QModelIndexList out;
|
||||
int rows( rowCount( parent ) );
|
||||
for( int row = 0; row < rows; row++ )
|
||||
{
|
||||
QModelIndex index( this->index( row, column, parent ) );
|
||||
if( !index.isValid() ) continue;
|
||||
out.append( index );
|
||||
out += indexes( column, index );
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
}
|
113
config/breezeitemmodel.h
Normal file
113
config/breezeitemmodel.h
Normal file
|
@ -0,0 +1,113 @@
|
|||
#ifndef ItemModel_h
|
||||
#define ItemModel_h
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// itemmodel.h
|
||||
// -------------------
|
||||
//
|
||||
// Copyright (c) 2009-2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
//* Job model. Stores job information for display in lists
|
||||
class ItemModel : public QAbstractItemModel
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
//* constructor
|
||||
explicit ItemModel(QObject *parent = nullptr);
|
||||
|
||||
//* destructor
|
||||
virtual ~ItemModel()
|
||||
{}
|
||||
|
||||
//* return all indexes in model starting from parent [recursive]
|
||||
QModelIndexList indexes( int column = 0, const QModelIndex& parent = QModelIndex() ) const;
|
||||
|
||||
//*@name sorting
|
||||
//@{
|
||||
|
||||
//* sort
|
||||
virtual void sort()
|
||||
{ sort( sortColumn(), sortOrder() ); }
|
||||
|
||||
//* sort
|
||||
void sort( int column, Qt::SortOrder order = Qt::AscendingOrder ) override;
|
||||
|
||||
//* current sorting column
|
||||
const int& sortColumn() const
|
||||
{ return m_sortColumn; }
|
||||
|
||||
//* current sort order
|
||||
const Qt::SortOrder& sortOrder() const
|
||||
{ return m_sortOrder; }
|
||||
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
//* this sort columns without calling the layout changed callbacks
|
||||
void privateSort()
|
||||
{ privateSort( m_sortColumn, m_sortOrder ); }
|
||||
|
||||
//* private sort, with no signals emmitted
|
||||
virtual void privateSort( int column, Qt::SortOrder order ) = 0;
|
||||
|
||||
//* used to sort items in list
|
||||
class SortFTor
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
//* constructor
|
||||
explicit SortFTor( const int& type, Qt::SortOrder order = Qt::AscendingOrder ):
|
||||
_type( type ),
|
||||
_order( order )
|
||||
{}
|
||||
|
||||
protected:
|
||||
|
||||
//* column
|
||||
int _type;
|
||||
|
||||
//* order
|
||||
Qt::SortOrder _order;
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
//* sorting column
|
||||
int m_sortColumn = 0;
|
||||
|
||||
//* sorting order
|
||||
Qt::SortOrder m_sortOrder = Qt::AscendingOrder;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
365
config/breezelistmodel.h
Normal file
365
config/breezelistmodel.h
Normal file
|
@ -0,0 +1,365 @@
|
|||
#ifndef ListModel_h
|
||||
#define ListModel_h
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// listmodel.h
|
||||
// -------------------
|
||||
//
|
||||
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "breezeitemmodel.h"
|
||||
|
||||
#include <QSet>
|
||||
#include <QList>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
//! Job model. Stores job information for display in lists
|
||||
template<class T> class ListModel : public ItemModel
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
//! value type
|
||||
typedef T ValueType;
|
||||
|
||||
//! reference
|
||||
typedef T& Reference;
|
||||
|
||||
//! pointer
|
||||
typedef T* Pointer;
|
||||
|
||||
//! value list and iterators
|
||||
typedef QList<ValueType> List;
|
||||
typedef QListIterator<ValueType> ListIterator;
|
||||
typedef QMutableListIterator<ValueType> MutableListIterator;
|
||||
|
||||
//! list of vector
|
||||
// typedef QSet<ValueType> Set;
|
||||
|
||||
//! constructor
|
||||
ListModel(QObject *parent = nullptr):
|
||||
ItemModel( parent )
|
||||
{}
|
||||
|
||||
//! destructor
|
||||
virtual ~ListModel()
|
||||
{}
|
||||
|
||||
//!@name methods reimplemented from base class
|
||||
//@{
|
||||
|
||||
//! flags
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override
|
||||
{
|
||||
if (!index.isValid()) return nullptr;
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
}
|
||||
|
||||
//! unique index for given row, column and parent index
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override
|
||||
{
|
||||
|
||||
// check if index is valid
|
||||
if( !hasIndex( row, column, parent ) ) return QModelIndex();
|
||||
|
||||
// return invalid index if parent is valid
|
||||
if( parent.isValid() ) return QModelIndex();
|
||||
|
||||
// check against _values
|
||||
return ( row < (int) _values.size() ) ? createIndex( row, column ):QModelIndex();
|
||||
|
||||
}
|
||||
|
||||
//! index of parent
|
||||
QModelIndex parent(const QModelIndex &) const override
|
||||
{ return QModelIndex(); }
|
||||
|
||||
//! number of rows below given index
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override
|
||||
{ return parent.isValid() ? 0:_values.size(); }
|
||||
|
||||
//@}
|
||||
|
||||
//!@name selection
|
||||
//@{
|
||||
|
||||
//! clear internal list selected items
|
||||
virtual void clearSelectedIndexes()
|
||||
{ _selection.clear(); }
|
||||
|
||||
//! store index internal selection state
|
||||
virtual void setIndexSelected( const QModelIndex& index, bool value )
|
||||
{
|
||||
if( value ) _selection.push_back( get(index) );
|
||||
else _selection.erase( std::remove( _selection.begin(), _selection.end(), get(index) ), _selection.end() );
|
||||
}
|
||||
|
||||
//! get list of internal selected items
|
||||
virtual QModelIndexList selectedIndexes() const
|
||||
{
|
||||
|
||||
QModelIndexList out;
|
||||
for( typename List::const_iterator iter = _selection.begin(); iter != _selection.end(); iter++ )
|
||||
{
|
||||
QModelIndex index( ListModel::index( *iter ) );
|
||||
if( index.isValid() ) out.push_back( index );
|
||||
}
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//!@name interface
|
||||
//@{
|
||||
|
||||
//! add value
|
||||
virtual void add( const ValueType& value )
|
||||
{
|
||||
|
||||
emit layoutAboutToBeChanged();
|
||||
_add( value );
|
||||
privateSort();
|
||||
emit layoutChanged();
|
||||
|
||||
}
|
||||
|
||||
//! add values
|
||||
virtual void add( const List& values )
|
||||
{
|
||||
|
||||
// check if not empty
|
||||
// this avoids sending useless signals
|
||||
if( values.empty() ) return;
|
||||
|
||||
emit layoutAboutToBeChanged();
|
||||
|
||||
for( typename List::const_iterator iter = values.begin(); iter != values.end(); iter++ )
|
||||
{ _add( *iter ); }
|
||||
|
||||
privateSort();
|
||||
emit layoutChanged();
|
||||
|
||||
}
|
||||
|
||||
|
||||
//! insert values
|
||||
virtual void insert( const QModelIndex& index, const ValueType& value )
|
||||
{
|
||||
emit layoutAboutToBeChanged();
|
||||
_insert( index, value );
|
||||
emit layoutChanged();
|
||||
}
|
||||
|
||||
//! insert values
|
||||
virtual void insert( const QModelIndex& index, const List& values )
|
||||
{
|
||||
emit layoutAboutToBeChanged();
|
||||
|
||||
// need to loop in reverse order so that the "values" ordering is preserved
|
||||
ListIterator iter( values );
|
||||
iter.toBack();
|
||||
while( iter.hasPrevious() )
|
||||
{ _insert( index, iter.previous() ); }
|
||||
|
||||
emit layoutChanged();
|
||||
|
||||
}
|
||||
|
||||
//! insert values
|
||||
virtual void replace( const QModelIndex& index, const ValueType& value )
|
||||
{
|
||||
if( !index.isValid() ) add( value );
|
||||
else {
|
||||
emit layoutAboutToBeChanged();
|
||||
setIndexSelected( index, false );
|
||||
_values[index.row()] = value;
|
||||
setIndexSelected( index, true );
|
||||
emit layoutChanged();
|
||||
}
|
||||
}
|
||||
|
||||
//! remove
|
||||
virtual void remove( const ValueType& value )
|
||||
{
|
||||
|
||||
emit layoutAboutToBeChanged();
|
||||
_remove( value );
|
||||
emit layoutChanged();
|
||||
|
||||
}
|
||||
|
||||
//! remove
|
||||
virtual void remove( const List& values )
|
||||
{
|
||||
|
||||
// check if not empty
|
||||
// this avoids sending useless signals
|
||||
if( values.empty() ) return;
|
||||
|
||||
emit layoutAboutToBeChanged();
|
||||
for( typename List::const_iterator iter = values.begin(); iter != values.end(); iter++ )
|
||||
{ _remove( *iter ); }
|
||||
emit layoutChanged();
|
||||
|
||||
}
|
||||
|
||||
//! clear
|
||||
virtual void clear()
|
||||
{ set( List() ); }
|
||||
|
||||
//! update values from list
|
||||
/*!
|
||||
values that are not found in current are removed
|
||||
new values are set to the end.
|
||||
This is slower than the "set" method, but the selection is not cleared in the process
|
||||
*/
|
||||
virtual void update( List values )
|
||||
{
|
||||
|
||||
emit layoutAboutToBeChanged();
|
||||
|
||||
// store values to be removed
|
||||
List removed_values;
|
||||
|
||||
// update values that are common to both lists
|
||||
for( typename List::iterator iter = _values.begin(); iter != _values.end(); iter++ )
|
||||
{
|
||||
|
||||
// see if iterator is in list
|
||||
typename List::iterator found_iter( std::find( values.begin(), values.end(), *iter ) );
|
||||
if( found_iter == values.end() ) removed_values.push_back( *iter );
|
||||
else {
|
||||
*iter = *found_iter;
|
||||
values.erase( found_iter );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// remove values that have not been found in new list
|
||||
for( typename List::const_iterator iter = removed_values.constBegin(); iter != removed_values.constEnd(); iter++ )
|
||||
{ _remove( *iter ); }
|
||||
|
||||
// add remaining values
|
||||
for( typename List::const_iterator iter = values.constBegin(); iter != values.constEnd(); iter++ )
|
||||
{ _add( *iter ); }
|
||||
|
||||
privateSort();
|
||||
emit layoutChanged();
|
||||
|
||||
}
|
||||
|
||||
//! set all values
|
||||
virtual void set( const List& values )
|
||||
{
|
||||
|
||||
emit layoutAboutToBeChanged();
|
||||
_values = values;
|
||||
_selection.clear();
|
||||
privateSort();
|
||||
emit layoutChanged();
|
||||
}
|
||||
|
||||
//! return all values
|
||||
const List& get() const
|
||||
{ return _values; }
|
||||
|
||||
//! return value for given index
|
||||
virtual ValueType get( const QModelIndex& index ) const
|
||||
{ return (index.isValid() && index.row() < int(_values.size()) ) ? _values[index.row()]:ValueType(); }
|
||||
|
||||
//! return value for given index
|
||||
virtual ValueType& get( const QModelIndex& index )
|
||||
{
|
||||
Q_ASSERT( index.isValid() && index.row() < int( _values.size() ) );
|
||||
return _values[index.row()];
|
||||
}
|
||||
|
||||
//! return all values
|
||||
List get( const QModelIndexList& indexes ) const
|
||||
{
|
||||
List out;
|
||||
for( QModelIndexList::const_iterator iter = indexes.begin(); iter != indexes.end(); iter++ )
|
||||
{ if( iter->isValid() && iter->row() < int(_values.size()) ) out.push_back( get( *iter ) ); }
|
||||
return out;
|
||||
}
|
||||
|
||||
//! return index associated to a given value
|
||||
virtual QModelIndex index( const ValueType& value, int column = 0 ) const
|
||||
{
|
||||
for( int row = 0; row < _values.size(); ++row )
|
||||
{ if( value == _values[row] ) return index( row, column ); }
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//! return true if model contains given index
|
||||
virtual bool contains( const QModelIndex& index ) const
|
||||
{ return index.isValid() && index.row() < _values.size(); }
|
||||
|
||||
protected:
|
||||
|
||||
//! return all values
|
||||
List& _get()
|
||||
{ return _values; }
|
||||
|
||||
//! add, without update
|
||||
virtual void _add( const ValueType& value )
|
||||
{
|
||||
typename List::iterator iter = std::find( _values.begin(), _values.end(), value );
|
||||
if( iter == _values.end() ) _values.push_back( value );
|
||||
else *iter = value;
|
||||
}
|
||||
|
||||
//! add, without update
|
||||
virtual void _insert( const QModelIndex& index, const ValueType& value )
|
||||
{
|
||||
if( !index.isValid() ) add( value );
|
||||
int row = 0;
|
||||
typename List::iterator iter( _values.begin() );
|
||||
for( ;iter != _values.end() && row != index.row(); iter++, row++ )
|
||||
{}
|
||||
|
||||
_values.insert( iter, value );
|
||||
}
|
||||
|
||||
//! remove, without update
|
||||
virtual void _remove( const ValueType& value )
|
||||
{
|
||||
_values.erase( std::remove( _values.begin(), _values.end(), value ), _values.end() );
|
||||
_selection.erase( std::remove( _selection.begin(), _selection.end(), value ), _selection.end() );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//! values
|
||||
List _values;
|
||||
|
||||
//! selection
|
||||
List _selection;
|
||||
|
||||
};
|
||||
}
|
||||
#endif
|
552
config/ui/breezeconfigurationui.ui
Normal file
552
config/ui/breezeconfigurationui.ui
Normal file
|
@ -0,0 +1,552 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BreezeConfigurationUI</class>
|
||||
<widget class="QWidget" name="BreezeConfigurationUI">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>428</width>
|
||||
<height>418</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>General</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Tit&le alignment:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>titleAlignment</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="titleAlignment">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Left</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Center</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Center (Full Width)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Right</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>B&utton size:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>buttonSize</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="buttonSize">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Tiny</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox Button size:">Small</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox Button size:">Medium</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox Button size:">Large</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox Button size:">Very Large</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="drawBorderOnMaximizedWindows">
|
||||
<property name="text">
|
||||
<string>Allow resizing maximized windows from window edges</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="drawSizeGrip">
|
||||
<property name="text">
|
||||
<string>Add handle to resize windows with no border</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="3">
|
||||
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,0,0,1">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Opacity:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="opacitySpinBox">
|
||||
<property name="suffix">
|
||||
<string> %</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="3">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Font:</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0" colspan="5">
|
||||
<widget class="QFontComboBox" name="fontComboBox"/>
|
||||
</item>
|
||||
<item row="1" column="1" alignment="Qt::AlignLeft">
|
||||
<widget class="QSpinBox" name="fontSizeSpinBox">
|
||||
<property name="minimum">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Size:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Weight:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="weightComboBox">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Normal</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Medium</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>DemiBold</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Bold</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>ExtraBold</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Black</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="italicCheckBox">
|
||||
<property name="text">
|
||||
<string>Italic</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="3">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>Animations</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="animationsDurationLabel">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Anima&tions duration:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>animationsDuration</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="animationsDuration">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> ms</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>500</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="animationsEnabled">
|
||||
<property name="text">
|
||||
<string>Enable animations</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="3">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_4">
|
||||
<attribute name="title">
|
||||
<string>Shadows</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Si&ze:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>shadowSize</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="shadowSize">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox Button size:">None</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox Button size:">Small</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox Button size:">Medium</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox Button size:">Large</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox Button size:">Very Large</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string comment="strength of the shadow (from transparent to opaque)">S&trength:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>shadowStrength</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="shadowStrength">
|
||||
<property name="suffix">
|
||||
<string>%</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Color:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="KColorButton" name="shadowColor"/>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>Window-Specific Overrides</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="Breeze::ExceptionListWidget" name="exceptions" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>KColorButton</class>
|
||||
<extends>QPushButton</extends>
|
||||
<header>kcolorbutton.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>Breeze::ExceptionListWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>config/breezeexceptionlistwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>tabWidget</tabstop>
|
||||
<tabstop>titleAlignment</tabstop>
|
||||
<tabstop>buttonSize</tabstop>
|
||||
<tabstop>drawBorderOnMaximizedWindows</tabstop>
|
||||
<tabstop>drawSizeGrip</tabstop>
|
||||
<tabstop>animationsEnabled</tabstop>
|
||||
<tabstop>animationsDuration</tabstop>
|
||||
<tabstop>shadowSize</tabstop>
|
||||
<tabstop>shadowStrength</tabstop>
|
||||
<tabstop>shadowColor</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>animationsEnabled</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>animationsDurationLabel</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>34</x>
|
||||
<y>194</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>84</x>
|
||||
<y>221</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>animationsEnabled</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>animationsDuration</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>108</x>
|
||||
<y>194</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>141</x>
|
||||
<y>229</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
146
config/ui/breezedetectwidget.ui
Normal file
146
config/ui/breezedetectwidget.ui
Normal file
|
@ -0,0 +1,146 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BreezeDetectWidget</class>
|
||||
<widget class="QDialog" name="BreezeDetectWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>239</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Information about Selected Window</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Class: </string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="windowClass">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Title: </string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="windowTitle">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Window Property Selection</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="windowClassCheckBox">
|
||||
<property name="text">
|
||||
<string>Use window class (whole application)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="windowTitleCheckBox">
|
||||
<property name="locale">
|
||||
<locale language="French" country="France"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use window title</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>BreezeDetectWidget</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>BreezeDetectWidget</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
333
config/ui/breezeexceptiondialog.ui
Normal file
333
config/ui/breezeexceptiondialog.ui
Normal file
|
@ -0,0 +1,333 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BreezeExceptionDialog</class>
|
||||
<widget class="QDialog" name="BreezeExceptionDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>362</width>
|
||||
<height>321</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Window Identification</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>&Matching window property: </string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>exceptionType</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Regular expression &to match: </string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>exceptionEditor</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="detectDialogButton">
|
||||
<property name="text">
|
||||
<string>Detect Window Properties</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="exceptionEditor">
|
||||
<property name="showClearButton" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="exceptionType">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Window Class Name</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Window Title</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Decoration Options</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="borderSizeCheckBox">
|
||||
<property name="text">
|
||||
<string>Border size:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="borderSizeComboBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox Border size:">No Border</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox Border size:">No Side Borders</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox Border size:">Tiny</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox Border size:">Normal</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox Border size:">Large</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox Border size:">Very Large</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox Border size:">Huge</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox Border size:">Very Huge</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string comment="@item:inlistbox Border size:">Oversized</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="isDialog">
|
||||
<property name="text">
|
||||
<string>Only for dialogs</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="hideTitleBar">
|
||||
<property name="text">
|
||||
<string>Hide window title bar</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="opaqueTitleBar">
|
||||
<property name="text">
|
||||
<string>Opaque title bar</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="opacityOverrideLabel">
|
||||
<property name="text">
|
||||
<string>Override opacity:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="opacityOverrideLabelSpinBox">
|
||||
<property name="suffix">
|
||||
<string>%</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>BreezeExceptionDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>252</x>
|
||||
<y>342</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>BreezeExceptionDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>320</x>
|
||||
<y>342</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>borderSizeCheckBox</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>borderSizeComboBox</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>125</x>
|
||||
<y>162</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>316</x>
|
||||
<y>163</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>opaqueTitleBar</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>opacityOverrideLabel</receiver>
|
||||
<slot>setDisabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>104</x>
|
||||
<y>202</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>82</x>
|
||||
<y>229</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>opaqueTitleBar</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>opacityOverrideLabelSpinBox</receiver>
|
||||
<slot>setDisabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>104</x>
|
||||
<y>202</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>166</x>
|
||||
<y>229</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
114
config/ui/breezeexceptionlistwidget.ui
Normal file
114
config/ui/breezeexceptionlistwidget.ui
Normal file
|
@ -0,0 +1,114 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BreezeExceptionListWidget</class>
|
||||
<widget class="QWidget" name="BreezeExceptionListWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>473</width>
|
||||
<height>182</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0" rowspan="6">
|
||||
<widget class="QTreeView" name="exceptionListView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="moveUpButton">
|
||||
<property name="text">
|
||||
<string>Move Up</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="moveDownButton">
|
||||
<property name="text">
|
||||
<string>Move Down</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="addButton">
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QPushButton" name="removeButton">
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QPushButton" name="editButton">
|
||||
<property name="text">
|
||||
<string>Edit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>exceptionListView</tabstop>
|
||||
<tabstop>moveUpButton</tabstop>
|
||||
<tabstop>moveDownButton</tabstop>
|
||||
<tabstop>addButton</tabstop>
|
||||
<tabstop>removeButton</tabstop>
|
||||
<tabstop>editButton</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
29
libbreezecommon/CMakeLists.txt
Normal file
29
libbreezecommon/CMakeLists.txt
Normal file
|
@ -0,0 +1,29 @@
|
|||
################# dependencies #################
|
||||
|
||||
### Qt/KDE
|
||||
find_package(Qt5 REQUIRED CONFIG COMPONENTS Widgets)
|
||||
|
||||
################# configuration #################
|
||||
configure_file(config-breezecommon.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-breezecommon.h )
|
||||
|
||||
################# breezestyle target #################
|
||||
set(breeze10common_LIB_SRCS
|
||||
breezeboxshadowrenderer.cpp
|
||||
)
|
||||
|
||||
add_library(breeze10common5 ${breeze10common_LIB_SRCS})
|
||||
|
||||
generate_export_header(breeze10common5
|
||||
BASE_NAME breezecommon
|
||||
EXPORT_FILE_NAME breezecommon_export.h)
|
||||
|
||||
target_link_libraries(breeze10common5
|
||||
PUBLIC
|
||||
Qt5::Core
|
||||
Qt5::Gui)
|
||||
|
||||
set_target_properties(breeze10common5 PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR})
|
||||
|
||||
install(TARGETS breeze10common5 ${INSTALL_TARGETS_DEFAULT_ARGS} LIBRARY NAMELINK_SKIP)
|
358
libbreezecommon/breezeboxshadowrenderer.cpp
Normal file
358
libbreezecommon/breezeboxshadowrenderer.cpp
Normal file
|
@ -0,0 +1,358 @@
|
|||
/*
|
||||
* Copyright (C) 2018 Vlad Zagorodniy <vladzzag@gmail.com>
|
||||
*
|
||||
* The box blur implementation is based on AlphaBoxBlur from Firefox.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
// own
|
||||
#include "breezeboxshadowrenderer.h"
|
||||
|
||||
// auto-generated
|
||||
#include "config-breezecommon.h"
|
||||
|
||||
// Qt
|
||||
#include <QPainter>
|
||||
|
||||
#include <QtMath>
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
static inline int calculateBlurRadius(qreal stdDev)
|
||||
{
|
||||
// See https://www.w3.org/TR/SVG11/filters.html#feGaussianBlurElement
|
||||
const qreal gaussianScaleFactor = (3.0 * qSqrt(2.0 * M_PI) / 4.0) * 1.5;
|
||||
return qMax(2, qFloor(stdDev * gaussianScaleFactor + 0.5));
|
||||
}
|
||||
|
||||
static inline qreal calculateBlurStdDev(int radius)
|
||||
{
|
||||
// See https://www.w3.org/TR/css-backgrounds-3/#shadow-blur
|
||||
return radius * 0.5;
|
||||
}
|
||||
|
||||
static inline QSize calculateBlurExtent(int radius)
|
||||
{
|
||||
const int blurRadius = calculateBlurRadius(calculateBlurStdDev(radius));
|
||||
return QSize(blurRadius, blurRadius);
|
||||
}
|
||||
|
||||
struct BoxLobes
|
||||
{
|
||||
int left; ///< how many pixels sample to the left
|
||||
int right; ///< how many pixels sample to the right
|
||||
};
|
||||
|
||||
/**
|
||||
* Compute box filter parameters.
|
||||
*
|
||||
* @param radius The blur radius.
|
||||
* @returns Parameters for three box filters.
|
||||
**/
|
||||
static QVector<BoxLobes> computeLobes(int radius)
|
||||
{
|
||||
const int blurRadius = calculateBlurRadius(calculateBlurStdDev(radius));
|
||||
const int z = blurRadius / 3;
|
||||
|
||||
int major;
|
||||
int minor;
|
||||
int final;
|
||||
|
||||
switch (blurRadius % 3) {
|
||||
case 0:
|
||||
major = z;
|
||||
minor = z;
|
||||
final = z;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
major = z + 1;
|
||||
minor = z;
|
||||
final = z;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
major = z + 1;
|
||||
minor = z;
|
||||
final = z + 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
||||
Q_ASSERT(major + minor + final == blurRadius);
|
||||
|
||||
return {
|
||||
{major, minor},
|
||||
{minor, major},
|
||||
{final, final}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a row with a box filter.
|
||||
*
|
||||
* @param src The start of the row.
|
||||
* @param dst The destination.
|
||||
* @param width The width of the row, in pixels.
|
||||
* @param horizontalStride The number of bytes from one alpha value to the
|
||||
* next alpha value.
|
||||
* @param verticalStride The number of bytes from one row to the next row.
|
||||
* @param lobes Params of the box filter.
|
||||
* @param transposeInput Whether the input is transposed.
|
||||
* @param transposeOutput Whether the output should be transposed.
|
||||
**/
|
||||
static inline void boxBlurRowAlpha(const uint8_t *src, uint8_t *dst, int width, int horizontalStride,
|
||||
int verticalStride, const BoxLobes &lobes, bool transposeInput,
|
||||
bool transposeOutput)
|
||||
{
|
||||
const int inputStep = transposeInput ? verticalStride : horizontalStride;
|
||||
const int outputStep = transposeOutput ? verticalStride : horizontalStride;
|
||||
|
||||
const int boxSize = lobes.left + 1 + lobes.right;
|
||||
const int reciprocal = (1 << 24) / boxSize;
|
||||
|
||||
uint32_t alphaSum = (boxSize + 1) / 2;
|
||||
|
||||
const uint8_t *left = src;
|
||||
const uint8_t *right = src;
|
||||
uint8_t *out = dst;
|
||||
|
||||
const uint8_t firstValue = src[0];
|
||||
const uint8_t lastValue = src[(width - 1) * inputStep];
|
||||
|
||||
alphaSum += firstValue * lobes.left;
|
||||
|
||||
const uint8_t *initEnd = src + (boxSize - lobes.left) * inputStep;
|
||||
while (right < initEnd) {
|
||||
alphaSum += *right;
|
||||
right += inputStep;
|
||||
}
|
||||
|
||||
const uint8_t *leftEnd = src + boxSize * inputStep;
|
||||
while (right < leftEnd) {
|
||||
*out = (alphaSum * reciprocal) >> 24;
|
||||
alphaSum += *right - firstValue;
|
||||
right += inputStep;
|
||||
out += outputStep;
|
||||
}
|
||||
|
||||
const uint8_t *centerEnd = src + width * inputStep;
|
||||
while (right < centerEnd) {
|
||||
*out = (alphaSum * reciprocal) >> 24;
|
||||
alphaSum += *right - *left;
|
||||
left += inputStep;
|
||||
right += inputStep;
|
||||
out += outputStep;
|
||||
}
|
||||
|
||||
const uint8_t *rightEnd = dst + width * outputStep;
|
||||
while (out < rightEnd) {
|
||||
*out = (alphaSum * reciprocal) >> 24;
|
||||
alphaSum += lastValue - *left;
|
||||
left += inputStep;
|
||||
out += outputStep;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Blur the alpha channel of a given image.
|
||||
*
|
||||
* @param image The input image.
|
||||
* @param radius The blur radius.
|
||||
* @param rect Specifies what part of the image to blur. If nothing is provided, then
|
||||
* the whole alpha channel of the input image will be blurred.
|
||||
**/
|
||||
static inline void boxBlurAlpha(QImage &image, int radius, const QRect &rect = {})
|
||||
{
|
||||
if (radius < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QVector<BoxLobes> lobes = computeLobes(radius);
|
||||
|
||||
const QRect blurRect = rect.isNull() ? image.rect() : rect;
|
||||
|
||||
const int alphaOffset = QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3;
|
||||
const int width = blurRect.width();
|
||||
const int height = blurRect.height();
|
||||
const int rowStride = image.bytesPerLine();
|
||||
const int pixelStride = image.depth() >> 3;
|
||||
|
||||
const int bufferStride = qMax(width, height) * pixelStride;
|
||||
QScopedPointer<uint8_t, QScopedPointerArrayDeleter<uint8_t> > buf(new uint8_t[2 * bufferStride]);
|
||||
uint8_t *buf1 = buf.data();
|
||||
uint8_t *buf2 = buf1 + bufferStride;
|
||||
|
||||
// Blur the image in horizontal direction.
|
||||
for (int i = 0; i < height; ++i) {
|
||||
uint8_t *row = image.scanLine(blurRect.y() + i) + blurRect.x() * pixelStride + alphaOffset;
|
||||
boxBlurRowAlpha(row, buf1, width, pixelStride, rowStride, lobes[0], false, false);
|
||||
boxBlurRowAlpha(buf1, buf2, width, pixelStride, rowStride, lobes[1], false, false);
|
||||
boxBlurRowAlpha(buf2, row, width, pixelStride, rowStride, lobes[2], false, false);
|
||||
}
|
||||
|
||||
// Blur the image in vertical direction.
|
||||
for (int i = 0; i < width; ++i) {
|
||||
uint8_t *column = image.scanLine(blurRect.y()) + (blurRect.x() + i) * pixelStride + alphaOffset;
|
||||
boxBlurRowAlpha(column, buf1, height, pixelStride, rowStride, lobes[0], true, false);
|
||||
boxBlurRowAlpha(buf1, buf2, height, pixelStride, rowStride, lobes[1], false, false);
|
||||
boxBlurRowAlpha(buf2, column, height, pixelStride, rowStride, lobes[2], false, true);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void mirrorTopLeftQuadrant(QImage &image)
|
||||
{
|
||||
const int width = image.width();
|
||||
const int height = image.height();
|
||||
|
||||
const int centerX = qCeil(width * 0.5);
|
||||
const int centerY = qCeil(height * 0.5);
|
||||
|
||||
const int alphaOffset = QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3;
|
||||
const int stride = image.depth() >> 3;
|
||||
|
||||
for (int y = 0; y < centerY; ++y) {
|
||||
uint8_t *in = image.scanLine(y) + alphaOffset;
|
||||
uint8_t *out = in + (width - 1) * stride;
|
||||
|
||||
for (int x = 0; x < centerX; ++x, in += stride, out -= stride) {
|
||||
*out = *in;
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = 0; y < centerY; ++y) {
|
||||
const uint8_t *in = image.scanLine(y) + alphaOffset;
|
||||
uint8_t *out = image.scanLine(width - y - 1) + alphaOffset;
|
||||
|
||||
for (int x = 0; x < width; ++x, in += stride, out += stride) {
|
||||
*out = *in;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void renderShadow(QPainter *painter, const QRect &rect, qreal borderRadius, const QPoint &offset, int radius, const QColor &color)
|
||||
{
|
||||
const QSize inflation = calculateBlurExtent(radius);
|
||||
const QSize size = rect.size() + 2 * inflation;
|
||||
|
||||
const qreal dpr = painter->device()->devicePixelRatioF();
|
||||
|
||||
QImage shadow(size * dpr, QImage::Format_ARGB32_Premultiplied);
|
||||
shadow.setDevicePixelRatio(dpr);
|
||||
shadow.fill(Qt::transparent);
|
||||
|
||||
QRect boxRect(QPoint(0, 0), rect.size());
|
||||
boxRect.moveCenter(QRect(QPoint(0, 0), size).center());
|
||||
|
||||
const qreal xRadius = 2.0 * borderRadius / boxRect.width();
|
||||
const qreal yRadius = 2.0 * borderRadius / boxRect.height();
|
||||
|
||||
QPainter shadowPainter;
|
||||
shadowPainter.begin(&shadow);
|
||||
shadowPainter.setRenderHint(QPainter::Antialiasing);
|
||||
shadowPainter.setPen(Qt::NoPen);
|
||||
shadowPainter.setBrush(Qt::black);
|
||||
shadowPainter.drawRoundedRect(boxRect, xRadius, yRadius);
|
||||
shadowPainter.end();
|
||||
|
||||
// Because the shadow texture is symmetrical, that's enough to blur
|
||||
// only the top-left quadrant and then mirror it.
|
||||
const QRect blurRect(0, 0, qCeil(shadow.width() * 0.5), qCeil(shadow.height() * 0.5));
|
||||
const int scaledRadius = qRound(radius * dpr);
|
||||
boxBlurAlpha(shadow, scaledRadius, blurRect);
|
||||
mirrorTopLeftQuadrant(shadow);
|
||||
|
||||
// Give the shadow a tint of the desired color.
|
||||
shadowPainter.begin(&shadow);
|
||||
shadowPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
||||
shadowPainter.fillRect(shadow.rect(), color);
|
||||
shadowPainter.end();
|
||||
|
||||
// Actually, present the shadow.
|
||||
QRect shadowRect = shadow.rect();
|
||||
shadowRect.setSize(shadowRect.size() / dpr);
|
||||
shadowRect.moveCenter(rect.center() + offset);
|
||||
painter->drawImage(shadowRect, shadow);
|
||||
}
|
||||
|
||||
void BoxShadowRenderer::setBoxSize(const QSize &size)
|
||||
{
|
||||
m_boxSize = size;
|
||||
}
|
||||
|
||||
void BoxShadowRenderer::setBorderRadius(qreal radius)
|
||||
{
|
||||
m_borderRadius = radius;
|
||||
}
|
||||
|
||||
void BoxShadowRenderer::setDevicePixelRatio(qreal dpr)
|
||||
{
|
||||
m_dpr = dpr;
|
||||
}
|
||||
|
||||
void BoxShadowRenderer::addShadow(const QPoint &offset, int radius, const QColor &color)
|
||||
{
|
||||
Shadow shadow = {};
|
||||
shadow.offset = offset;
|
||||
shadow.radius = radius;
|
||||
shadow.color = color;
|
||||
m_shadows.append(shadow);
|
||||
}
|
||||
|
||||
QImage BoxShadowRenderer::render() const
|
||||
{
|
||||
if (m_shadows.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
QSize canvasSize;
|
||||
for (const Shadow &shadow : qAsConst(m_shadows)) {
|
||||
canvasSize = canvasSize.expandedTo(
|
||||
calculateMinimumShadowTextureSize(m_boxSize, shadow.radius, shadow.offset));
|
||||
}
|
||||
|
||||
QImage canvas(canvasSize * m_dpr, QImage::Format_ARGB32_Premultiplied);
|
||||
canvas.setDevicePixelRatio(m_dpr);
|
||||
canvas.fill(Qt::transparent);
|
||||
|
||||
QRect boxRect(QPoint(0, 0), m_boxSize);
|
||||
boxRect.moveCenter(QRect(QPoint(0, 0), canvasSize).center());
|
||||
|
||||
QPainter painter(&canvas);
|
||||
for (const Shadow &shadow : qAsConst(m_shadows)) {
|
||||
renderShadow(&painter, boxRect, m_borderRadius, shadow.offset, shadow.radius, shadow.color);
|
||||
}
|
||||
painter.end();
|
||||
|
||||
return canvas;
|
||||
}
|
||||
|
||||
QSize BoxShadowRenderer::calculateMinimumBoxSize(int radius)
|
||||
{
|
||||
const QSize blurExtent = calculateBlurExtent(radius);
|
||||
return 2 * blurExtent + QSize(1, 1);
|
||||
}
|
||||
|
||||
QSize BoxShadowRenderer::calculateMinimumShadowTextureSize(const QSize &boxSize, int radius, const QPoint &offset)
|
||||
{
|
||||
return boxSize + 2 * calculateBlurExtent(radius) + QSize(qAbs(offset.x()), qAbs(offset.y()));
|
||||
}
|
||||
|
||||
} // namespace Breeze
|
105
libbreezecommon/breezeboxshadowrenderer.h
Normal file
105
libbreezecommon/breezeboxshadowrenderer.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright (C) 2018 Vlad Zagorodniy <vladzzag@gmail.com>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// own
|
||||
#include "breezecommon_export.h"
|
||||
|
||||
// Qt
|
||||
#include <QColor>
|
||||
#include <QImage>
|
||||
#include <QPoint>
|
||||
#include <QSize>
|
||||
|
||||
namespace Breeze
|
||||
{
|
||||
|
||||
class BREEZECOMMON_EXPORT BoxShadowRenderer
|
||||
{
|
||||
public:
|
||||
// Compiler generated constructors & destructor are fine.
|
||||
|
||||
/**
|
||||
* Set the size of the box.
|
||||
* @param size The size of the box.
|
||||
**/
|
||||
void setBoxSize(const QSize &size);
|
||||
|
||||
/**
|
||||
* Set the radius of box' corners.
|
||||
* @param radius The border radius, in pixels.
|
||||
**/
|
||||
void setBorderRadius(qreal radius);
|
||||
|
||||
/**
|
||||
* Set the device pixel ratio of the resulting shadow texture.
|
||||
* @param dpr The device pixel ratio.
|
||||
**/
|
||||
void setDevicePixelRatio(qreal dpr);
|
||||
|
||||
/**
|
||||
* Add a shadow.
|
||||
* @param offset The offset of the shadow.
|
||||
* @param radius The blur radius.
|
||||
* @param color The color of the shadow.
|
||||
**/
|
||||
void addShadow(const QPoint &offset, int radius, const QColor &color);
|
||||
|
||||
/**
|
||||
* Render the shadow.
|
||||
**/
|
||||
QImage render() const;
|
||||
|
||||
/**
|
||||
* Calculate the minimum size of the box.
|
||||
*
|
||||
* This helper computes the minimum size of the box so the shadow behind it has
|
||||
* full its strength.
|
||||
*
|
||||
* @param radius The blur radius of the shadow.
|
||||
**/
|
||||
static QSize calculateMinimumBoxSize(int radius);
|
||||
|
||||
/**
|
||||
* Calculate the minimum size of the shadow texture.
|
||||
*
|
||||
* This helper computes the minimum size of the resulting texture so the shadow
|
||||
* is not clipped.
|
||||
*
|
||||
* @param boxSize The size of the box.
|
||||
* @param radius The blur radius.
|
||||
* @param offset The offset of the shadow.
|
||||
**/
|
||||
static QSize calculateMinimumShadowTextureSize(const QSize &boxSize, int radius, const QPoint &offset);
|
||||
|
||||
private:
|
||||
QSize m_boxSize;
|
||||
qreal m_borderRadius = 0.0;
|
||||
qreal m_dpr = 1.0;
|
||||
|
||||
struct Shadow {
|
||||
QPoint offset;
|
||||
int radius;
|
||||
QColor color;
|
||||
};
|
||||
|
||||
QVector<Shadow> m_shadows;
|
||||
};
|
||||
|
||||
} // namespace Breeze
|
28
libbreezecommon/config-breezecommon.h.cmake
Normal file
28
libbreezecommon/config-breezecommon.h.cmake
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* config-breezecommon.h. Generated by cmake from config-breezecommon.h.cmake */
|
||||
|
||||
/*************************************************************************
|
||||
* Copyright (C) 2014 by Hugo Pereira Da Costa <hugo.pereira@free.fr> *
|
||||
* *
|
||||
* 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 . *
|
||||
*************************************************************************/
|
||||
|
||||
#ifndef config_breeze_common_h
|
||||
#define config_breeze_common_h
|
||||
|
||||
/* Define to 1 if breeze is compiled against KDE4 */
|
||||
#cmakedefine01 BREEZE_COMMON_USE_KDE4
|
||||
|
||||
#endif
|
BIN
screenshots/Desktop.png
Normal file
BIN
screenshots/Desktop.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 899 KiB |
BIN
screenshots/Settings.png
Normal file
BIN
screenshots/Settings.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
Loading…
Reference in a new issue