generic: drop scripting support

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2023-10-09 04:53:49 +03:00
parent ebcdc394b2
commit 1cad595824
444 changed files with 411 additions and 55392 deletions

View file

@ -44,7 +44,6 @@ set_package_properties(X11 PROPERTIES
TYPE REQUIRED
)
add_feature_info("libXcomposite" X11_Xcomposite_FOUND "The X11 Composite extension library may be used by Plasma and KWin")
add_feature_info("libXSync" X11_XSync_FOUND "The X11 synchronization may be used by KWin")
add_feature_info("libXinput" X11_Xinput_FOUND "The X11 XINPUT extension library may be used by touchpad handler")
add_feature_info("libXRes" X11_XRes_FOUND "The X Resource library may be used by ksysguard")
@ -217,12 +216,6 @@ add_feature_info(wrestool
"ICO thumbnails support in KIO slave"
)
find_program(QRENCODE_EXECUTABLE qrencode)
add_feature_info(qrencode
QRENCODE_EXECUTABLE
"QR Code support in klipper"
)
find_program(CTAGS_EXECUTABLE ctags ctags-universal ctags-exuberant exctags uctags)
add_feature_info(ctags
CTAGS_EXECUTABLE
@ -291,7 +284,6 @@ add_subdirectory(qguiplatformplugin_kde)
add_subdirectory(ksysguard)
add_subdirectory(kcontrol)
add_subdirectory(klipper)
add_subdirectory(kmenuedit)
add_subdirectory(krunner)
add_subdirectory(kinfocenter)
@ -306,7 +298,6 @@ endif(LightDM_FOUND)
add_subdirectory(cursors)
add_subdirectory(plasma)
add_subdirectory(statusnotifierwatcher)
add_subdirectory(kstyles)
# Imported from kde-runtime and other sub-projects

View file

@ -7,12 +7,9 @@ check_function_exists(nice HAVE_NICE)
check_include_files(malloc.h HAVE_MALLOC_H)
kde4_bool_to_01(FONTCONFIG_FOUND HAVE_FONTCONFIG) # kcontrol/fonts
kde4_bool_to_01(FREETYPE_FOUND HAVE_FREETYPE) # kcontrol/fonts
kde4_bool_to_01(X11_Xcomposite_FOUND HAVE_XCOMPOSITE) # plasma, kwin
kde4_bool_to_01(X11_Xcursor_FOUND HAVE_XCURSOR) # many uses
kde4_bool_to_01(X11_Xdamage_FOUND HAVE_XDAMAGE) # kwin
kde4_bool_to_01(X11_Xfixes_FOUND HAVE_XFIXES) # klipper, kicker, kwin
kde4_bool_to_01(X11_Xfixes_FOUND HAVE_XFIXES) # kicker, kwin
kde4_bool_to_01(X11_Xkb_FOUND HAVE_XKB) # kglobalaccel
kde4_bool_to_01(X11_Xrandr_FOUND HAVE_XRANDR) # kwin
kde4_bool_to_01(X11_XSync_FOUND HAVE_XSYNC) # kwin
kde4_bool_to_01(X11_XRes_FOUND HAVE_XRES) # ksysguard
kde4_bool_to_01(X11_dpms_FOUND HAVE_DPMS) # kscreensaver

View file

@ -1,15 +1,6 @@
/* Define if you have the XRandR extension */
#cmakedefine HAVE_XRANDR 1
/* Define if you have the XDamage extension */
#cmakedefine HAVE_XDAMAGE 1
/* Define if you have the XKB extension */
#cmakedefine HAVE_XKB 1
/* Define if you have the XComposite extension */
#cmakedefine HAVE_XCOMPOSITE 1
/* Define to 1 if you have Xcursor */
#cmakedefine HAVE_XCURSOR 1

View file

@ -188,4 +188,3 @@ MimeType=inode/directory;
InitialPreference=10
StartupNotify=true
X-KDE-MediaPlayer=informationpanel
X-KDE-HasTrayOption=true

View file

@ -341,7 +341,7 @@ void KateView::setupActions()
m_cut = a = ac->addAction(KStandardAction::Cut, this, SLOT(cut()));
a->setWhatsThis(i18n("Cut the selected text and move it to the clipboard"));
m_paste = a = ac->addAction(KStandardAction::PasteText, this, SLOT(paste()));
m_paste = a = ac->addAction(KStandardAction::Paste, this, SLOT(paste()));
a->setWhatsThis(i18n("Paste previously copied or cut clipboard contents"));
m_copy = a = ac->addAction(KStandardAction::Copy, this, SLOT(copy()));

View file

@ -121,7 +121,6 @@ MimeType=text/plain;
Exec=kate --icon '%i' --caption '%c' -b %U
StartupNotify=true
X-KDE-HasTempFileOption=true
X-KDE-HasTrayOption=true
Icon=kate
X-DocPath=kate/index.html
Type=Application

View file

@ -84,11 +84,6 @@ Name[zh_CN]=三个修饰键的 KDE 默认值
Name[zh_TW]=KDE 預設 3 個變更鍵
Uses Win Modifier=false
[klipper][Global Shortcuts]
clipboard_action=Ctrl+Alt+X
repeat_action=Ctrl+Alt+R
show-on-mouse-pos=Ctrl+Alt+V
[krunner][Global Shortcuts]
Run Command=Alt+F2
Show System Activity=Ctrl+Esc
@ -128,8 +123,8 @@ Walk Through Desktop List (Reverse)=Ctrl+Shift+Tab
Walk Through Desktop List=Ctrl+Tab
Walk Through Desktops (Reverse)=none
Walk Through Desktops=none
Walk Through Windows (Reverse)=Alt+Shift+Tab
Walk Through Windows=Alt+Tab
Toggle Present Windows (Current desktop)=Alt+Tab
Toggle Present Windows (Window class)=Alt+Shift+Tab
Window Close=Alt+F4
Window Lower=none
Window Maximize Horizontal=none

View file

@ -84,11 +84,6 @@ Name[zh_CN]=四个修饰键的 KDE 默认值
Name[zh_TW]=KDE 預設 4 個變更鍵
Uses Win Modifier=true
[klipper][Global Shortcuts]
clipboard_action=Meta+Ctrl+X
repeat_action=Meta+Ctrl+R
show-on-mouse-pos=Meta+Ctrl+V
[krunner][Global Shortcuts]
Run Command=Meta+Return; Alt+F2
Show System Activity=Meta+Ctrl+Pause
@ -128,8 +123,8 @@ Walk Through Desktop List (Reverse)=none
Walk Through Desktop List=none
Walk Through Desktops (Reverse)=Meta+Shift+Tab
Walk Through Desktops=Meta+Tab
Walk Through Windows (Reverse)=Alt+Shift+Tab
Walk Through Windows=Alt+Tab
Toggle Present Windows (Current desktop)=Alt+Tab
Toggle Present Windows (Window class)=Alt+Shift+Tab
Window Close=Alt+Esc; Alt+F4
Window Lower=none
Window Maximize Horizontal=Meta+=

View file

@ -89,11 +89,6 @@ Name[zh_CN]=Mac 方案
Name[zh_TW]=Mac 機制
Uses Win Modifier=true
[klipper][Global Shortcuts]
clipboard_action=Ctrl+Alt+X
repeat_action=Ctrl+Alt+R
show-on-mouse-pos=Ctrl+Alt+V
[krunner][Global Shortcuts]
Run Command=Alt+F2
Show System Activity=Ctrl+Esc
@ -133,8 +128,8 @@ Walk Through Desktop List (Reverse)=none
Walk Through Desktop List=none
Walk Through Desktops (Reverse)=Alt+Shift+Tab
Walk Through Desktops=Alt+Tab
Walk Through Windows (Reverse)=Ctrl+Shift+Tab
Walk Through Windows=Ctrl+Tab
Toggle Present Windows (Current desktop)=Ctrl+Tab
Toggle Present Windows (Window class)=Ctrl+Shift+Tab
Window Close=Alt+F4
Window Lower=none
Window Maximize Horizontal=none

View file

@ -29,7 +29,6 @@ foreach my $file( @ARGV )
my $process = 0;
my @kwin;
my @krunner;
my @klipper;
my @kxkb;
for( <$FILEHD> )
{
@ -65,10 +64,6 @@ foreach my $file( @ARGV )
/Switch to Next Keyboard Layout/ and do { push @kxkb, $_; next; };
/clipboard_action/ and do { push @klipper, $_; next; };
/repeat_action/ and do { push @klipper, $_; next; };
/show_klipper_popup/ and do { push @klipper, $_; next; };
/Halt without Confirmation/ and do { s/Halt without Confirmation/Halt Without Confirmation/; push @krunner, $_; next; };
/Lock Session/ and do { push @krunner, $_; next; };
/Log Out/ and do { push @krunner, $_; next; };
@ -82,8 +77,6 @@ foreach my $file( @ARGV )
print $OLDHD $_;
}
print $NEWHD "\n[klipper][Global Shortcuts]\n";
print $NEWHD sort @klipper;
print $NEWHD "\n[krunner][Global Shortcuts]\n";
print $NEWHD sort @krunner;
print $NEWHD "\n[kwin][Global Shortcuts]\n";

View file

@ -89,11 +89,6 @@ Name[zh_CN]=Unix 方案
Name[zh_TW]=UNIX 機制
Uses Win Modifier=false
[klipper][Global Shortcuts]
clipboard_action=none
repeat_action=Ctrl+Alt+R
show-on-mouse-pos=none
[krunner][Global Shortcuts]
Run Command=Alt+F2
Show System Activity=Ctrl+Esc
@ -133,8 +128,8 @@ Walk Through Desktop List (Reverse)=Ctrl+Shift+Tab
Walk Through Desktop List=none
Walk Through Desktops (Reverse)=none
Walk Through Desktops=Ctrl+Tab
Walk Through Windows (Reverse)=Alt+Shift+Tab
Walk Through Windows=Alt+F11
Toggle Present Windows (Current desktop)=Alt+F11
Toggle Present Windows (Window class)=Alt+Shift+Tab
Window Close=none
Window Lower=none
Window Maximize Horizontal=none

View file

@ -88,11 +88,6 @@ Name[zh_CN]=Windows 方案(无 Win 键)
Name[zh_TW]=Windows 機制(沒有 Win 鍵)
Uses Win Modifier=false
[klipper][Global Shortcuts]
clipboard_action=none
repeat_action=none
show-on-mouse-pos=none
[krunner][Global Shortcuts]
Run Command=none
Show System Activity=Ctrl+Alt+Del
@ -132,8 +127,8 @@ Walk Through Desktop List (Reverse)=none
Walk Through Desktop List=none
Walk Through Desktops (Reverse)=Ctrl+Alt+Shift+Tab
Walk Through Desktops=Ctrl+Alt+Tab
Walk Through Windows (Reverse)=Alt+Shift+Tab
Walk Through Windows=Alt+Tab
Toggle Present Windows (Current desktop)=Alt+Tab
Toggle Present Windows (Window class)=Alt+Shift+Tab
Window Close=Alt+F4
Window Lower=none
Window Maximize Horizontal=none

View file

@ -88,11 +88,6 @@ Name[zh_CN]=Windows 方案(有 Win 键)
Name[zh_TW]=Windows 機制(有 Win 鍵)
Uses Win Modifier=true
[klipper][Global Shortcuts]
clipboard_action=none
repeat_action=none
show-on-mouse-pos=none
[krunner][Global Shortcuts]
Run Command=Meta+R
Show System Activity=Ctrl+Alt+Del
@ -132,8 +127,8 @@ Walk Through Desktop List (Reverse)=none
Walk Through Desktop List=none
Walk Through Desktops (Reverse)=Meta+Shift+Tab
Walk Through Desktops=Meta+Tab
Walk Through Windows (Reverse)=Alt+Shift+Tab
Walk Through Windows=Alt+Tab
Toggle Present Windows (Current desktop)=Alt+Tab
Toggle Present Windows (Window class)=Alt+Shift+Tab
Window Close=Alt+F4
Window Lower=none
Window Maximize Horizontal=none

View file

@ -83,11 +83,6 @@ Name[x-test]=xxWindowMaker (3 Modifier Keys)xx
Name[zh_CN]=WindowMaker (三个修饰键)
Name[zh_TW]=WindowMaker3 個變更鍵)
[klipper][Global Shortcuts]
clipboard_action=Ctrl+Alt+X
repeat_action=Ctrl+Alt+R
show-on-mouse-pos=Ctrl+Alt+V
[krunner][Global Shortcuts]
Run Command=Alt+F2
Show System Activity=Ctrl+Esc
@ -127,8 +122,8 @@ Walk Through Desktop List (Reverse)=Ctrl+Shift+Tab
Walk Through Desktop List=Ctrl+Tab
Walk Through Desktops (Reverse)=none
Walk Through Desktops=none
Walk Through Windows (Reverse)=Alt+Shift+Tab
Walk Through Windows=Alt+Tab
Toggle Present Windows (Current desktop)=Alt+Tab
Toggle Present Windows (Window class)=Alt+Shift+Tab
Window Close=Alt+Esc
Window Lower=none
Window Maximize Horizontal=none

View file

@ -42,34 +42,8 @@ install(
########### next target ###############
set(krandrtray_SRCS
${randrinternal_PART_SRCS}
main.cpp
krandrtray.cpp
krandrapp.cpp
)
add_executable(krandrtray ${krandrtray_SRCS})
target_link_libraries(krandrtray
KDE4::kcmutils
${X11_Xrandr_LIB}
${X11_LIBRARIES}
)
install(
TARGETS krandrtray
DESTINATION ${KDE4_BIN_INSTALL_DIR}
)
########### next target ###############
install(
FILES randr.desktop
DESTINATION ${KDE4_SERVICES_INSTALL_DIR}
)
install(
PROGRAMS krandrtray.desktop
DESTINATION ${KDE4_XDG_APPS_INSTALL_DIR}
)

View file

@ -1,48 +0,0 @@
/*
* Copyright (c) 2007 Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net>
* Copyright (c) 2002,2003 Hamish Rodda <rodda@kde.org>
*
* 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 <kdebug.h>
#include <config-X11.h>
#include "krandrapp.h"
#include "moc_krandrapp.cpp"
#include "krandrtray.h"
#include "randrscreen.h"
#include <X11/Xlib.h>
KRandRApp::KRandRApp()
{
m_display = new RandRDisplay();
m_tray = new KRandRSystemTray(m_display);
m_tray->setObjectName("RANDRTray");
// do not close when the last window is closed:
// the system tray is not considered a window, so when the confirm dialog is
// closed, the application exits
setQuitOnLastWindowClosed(false);
}
bool KRandRApp::x11EventFilter(XEvent* e)
{
if (m_display->canHandle(e)) {
m_display->handleEvent(e);
}
return KApplication::x11EventFilter(e);
}

View file

@ -1,42 +0,0 @@
/*
* Copyright (c) 2007 Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net>
* Copyright (c) 2002 Hamish Rodda <rodda@kde.org>
*
* 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 KRANDRAPP_H
#define KRANDRAPP_H
#include <kuniqueapplication.h>
class KRandRSystemTray;
class RandRConfig;
class RandRDisplay;
class KRandRApp : public KUniqueApplication
{
Q_OBJECT
public:
KRandRApp();
virtual bool x11EventFilter(XEvent * e);
private:
KRandRSystemTray *m_tray;
RandRDisplay *m_display;
};
#endif // KRANDRAPP_H

View file

@ -1,441 +0,0 @@
/*
* Copyright (c) 2007 Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net>
* Copyright (c) 2002,2003 Hamish Rodda <rodda@kde.org>
*
* 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 <config-X11.h>
#include "krandrtray.h"
#include "moc_krandrtray.cpp"
#include "randrscreen.h"
#include "randroutput.h"
#include "randrmode.h"
#include <QtGui/qevent.h>
#include <QVariant>
#include <KAction>
#include <KActionCollection>
#include <KApplication>
#include <KCMultiDialog>
#include <KComponentData>
#include <KHelpMenu>
#include <KIcon>
#include <KIconLoader>
#include <KLocale>
#include <KMenu>
#include <KWindowSystem>
KRandRSystemTray::KRandRSystemTray(RandRDisplay *dpy, QWidget* parent)
: KStatusNotifierItem(parent),
m_help(new KHelpMenu(parent, KGlobal::mainComponent().aboutData(), false, actionCollection())),
m_display(dpy)
{
setIconByName("preferences-desktop-display-randr");
setCategory(Hardware);
m_menu = new KMenu(associatedWidget());
setContextMenu(m_menu);
setStatus(Active);
//TODO: probably we need an about to show signal
connect(m_menu, SIGNAL(aboutToShow()), this, SLOT(slotPrepareMenu()));
m_display->refresh();
updateToolTip();
OutputMap outputs = m_display->currentScreen()->outputs();
foreach(RandROutput *output, outputs) {
connect(output, SIGNAL(outputChanged(RROutput,int)), this, SLOT(slotPrepareMenu()));
connect(output, SIGNAL(outputChanged(RROutput,int)), this, SLOT(updateToolTip()));
}
}
KRandRSystemTray::~KRandRSystemTray()
{
if (m_kcm) {
delete m_kcm.data();
}
}
void KRandRSystemTray::activate(const QPoint &pos)
{
Q_UNUSED(pos)
slotPrefs();
}
void KRandRSystemTray::slotPrepareMenu()
{
QAction *action;
m_menu->clear();
if (!m_display->isValid()) {
action = m_menu->addAction(i18n("Required X Extension Not Available"));
action->setEnabled(false);
} else {
m_screenPopups.clear();
for (int s = 0; s < m_display->numScreens(); s++) {
m_display->setCurrentScreen(s);
if (s == QX11Info::appScreen()) {
/*lastIndex = menu->insertItem(i18n("Screen %1").arg(s+1));
menu->setItemEnabled(lastIndex, false);*/
} else {
KMenu* subMenu = new KMenu(i18n("Screen %1", s+1), m_menu );
subMenu->setObjectName( QString("screen%1").arg(s+1) );
m_screenPopups.append(subMenu);
populateMenu(subMenu);
action = m_menu->addMenu(subMenu);
connect(subMenu, SIGNAL(activated(int)), SLOT(slotScreenActivated()));
}
}
m_display->setCurrentScreen(m_display->screenIndexOfWidget(m_menu));
if (m_display->needsRefresh()) {
kDebug() << "Configuration dirty, reloading settings...";
m_display->refresh();
updateToolTip();
}
populateMenu(m_menu);
}
m_menu->addSeparator();
KAction *actPrefs = actionCollection()->addAction( QString() );
actPrefs->setIcon( KIcon( "configure" ) );
actPrefs->setText( i18n( "Configure Display..." ) );
connect( actPrefs, SIGNAL(triggered(bool)), SLOT(slotPrefs()) );
m_menu->addAction( actPrefs );
m_menu->addMenu(/*SmallIcon("help-contents"),KStandardGuiItem::help().text(),*/ m_help->menu());
QAction *quitAction = actionCollection()->action(KStandardAction::name(KStandardAction::Quit));
m_menu->addAction( quitAction );
}
void KRandRSystemTray::slotScreenActivated()
{
m_display->setCurrentScreen(m_screenPopups.indexOf(static_cast<KMenu*>(sender())));
}
void KRandRSystemTray::updateToolTip()
{
const QString icon = "preferences-desktop-display-randr";
QString title = i18n("Display");
QString subTitle = i18n("Resize, rotate and configure screens.");
if (m_display->isValid()) {
OutputMap outputs = m_display->currentScreen()->outputs();
if (outputs.count() <= 0) {
return;
}
RandRScreen *screen = m_display->currentScreen();
Q_ASSERT(screen);
if (screen->outputsUnified() && screen->connectedCount() > 1) {
SizeList sizes = screen->unifiedSizes();
if (!sizes.isEmpty()) {
const QSize currentSize = screen->rect().size();
subTitle = i18n("Resolution: %1 x %2",
QString::number(currentSize.width()),
QString::number(currentSize.height()));
int rotations = screen->unifiedRotations();
if (rotations != RandR::Rotate0) {
int rotation = RandR::Rotate0;
foreach (RandROutput *output, screen->outputs()) {
if (output->isActive()) {
rotation = output->rotation();
break;
}
}
if (rotation != RandR::Rotate0) {
subTitle += "<br>" + i18n("Rotation: %1", RandR::rotationName(1 << rotation));
}
}
}
} else {
QString details = "<table>";
bool first = true;
foreach(RandROutput *output, outputs) {
if (output->isConnected()) {
if (!output->isActive()) {
details += "<tr><td>&nbsp;</td></tr>";
details += "<tr><th align=\"left\" colspan=\"2\">" + output->name()
+ " (" + i18n("Disabled") + ") </th></tr>";
} else {
if (first) {
first = false;
details += "<tr><td>&nbsp;</td></tr>";
} else {
details += "<tr><td>&nbsp;</td></tr>";
}
details += "<tr><th align=\"left\" colspan=\"2\">" + output->name()
+ "</th></tr>";
QSize currentSize = output->rect().size();
if (output->rotation() & (RandR::Rotate90 | RandR::Rotate270)) {
currentSize = QSize(currentSize.height(), currentSize.width());
}
details += "<tr>" + i18n("<td align=\"right\">Resolution: </td><td>%1 x %2</td></tr>",
QString::number(currentSize.width()),
QString::number(currentSize.height()));
RateList rates = output->refreshRates();
if (rates.count()) {
details += "<tr><td align=\"right\">" + i18n("Refresh: ") + "</td><td>"
+ ki18n("%1 Hz").subs(output->refreshRate(), 0, 'f', 1).toString()
+ "</td></tr>";
}
int rotations = output->rotations();
if (rotations != RandR::Rotate0 && output->rotation() != RandR::Rotate0) {
details += "<tr><td align=\"right\">" + i18n("Rotation: ") + "</td><td>"
+ RandR::rotationName(1 << output->rotation())
+ "</td></tr>";
}
}
}
}
if (details != "<table>") {
subTitle = details + "</table>";
}
}
}
setToolTip(icon, title, subTitle);
}
void KRandRSystemTray::populateMenu(KMenu* menu)
{
QAction *action;
QActionGroup *actionGroup;
OutputMap outputs = m_display->currentScreen()->outputs();
if (outputs.count() <= 0) {
return;
}
RandRScreen *screen = m_display->currentScreen();
Q_ASSERT(screen);
// if the outputs are unified, do not show output-specific size
// changing options in the tray.
if (screen->outputsUnified() && screen->connectedCount() > 1) {
SizeList sizes = screen->unifiedSizes();
if (sizes.count()) {
// populate unified sizes
QSize currentSize;
currentSize = screen->rect().size();
menu->addTitle(SmallIcon("view-fullscreen"), i18n("Screen Size"));
actionGroup = populateSizes(menu, sizes, currentSize);
connect(actionGroup, SIGNAL(triggered(QAction*)), screen, SLOT(slotResizeUnified(QAction*)));
// if the outputs are unified, we can rotate the screen on all outputs
int rotations = screen->unifiedRotations();
if (rotations != RandR::Rotate0) {
menu->addTitle(SmallIcon("view-refresh"), i18n("Orientation"));
int rotation = RandR::Rotate0;
foreach(RandROutput *output, screen->outputs()) {
if (output->isActive()) {
rotation = output->rotation();
break;
}
}
actionGroup = populateRotations(menu, rotations, rotation);
connect(actionGroup, SIGNAL(triggered(QAction*)), screen, SLOT(slotRotateUnified(QAction*)));
}
}
} else {
if (screen->connectedCount() != 1) {
menu->addTitle(SmallIcon("view-fullscreen"), i18n("Outputs"));
}
RandROutput *primary = screen->primaryOutput();
foreach(RandROutput *output, outputs) {
if (output->isConnected()) {
KMenu *outputMenu;
if (screen->connectedCount() == 1) {
outputMenu = menu;
} else {
outputMenu = new KMenu(output->name());
}
outputMenu->setIcon(SmallIcon(output->icon()));
outputMenu->addTitle(SmallIcon("view-fullscreen"), i18n("%1 - Screen Size", output->name()));
QSize currentSize = output->rect().size();
// if the output is rotated 90 or 270, the returned rect is inverted
// so we need to invert the size before comparing
if (output->rotation() & (RandR::Rotate90 | RandR::Rotate270)) {
currentSize = QSize(currentSize.height(), currentSize.width());
}
actionGroup = populateSizes(outputMenu, output->sizes(), currentSize);
connect(
actionGroup, SIGNAL(triggered(QAction*)),
output, SLOT(slotChangeSize(QAction*)),
Qt::QueuedConnection
);
// if there is only one output active, do not show the disable option
// this prevents the user from doing wrong things ;)
kDebug() << "Active outputs: " << screen->activeCount();
if (screen->activeCount() != 1) {
action = outputMenu->addAction(i18n("Disable"));
if (!output->crtc()) {
QFont font = action->font();
font.setBold(true);
action->setFont(font);
}
connect(action, SIGNAL(triggered(bool)), output, SLOT(slotDisable()));
}
// Display the rotations
int rotations = output->rotations();
// Don't display the rotation options if there is no point (ie. none are supported)
// XFree86 4.3 does not include rotation support.
if (rotations != RandR::Rotate0) {
outputMenu->addTitle(SmallIcon("view-refresh"), i18n("Orientation"));
actionGroup = populateRotations(outputMenu, rotations, output->rotation());
connect(
actionGroup, SIGNAL(triggered(QAction*)),
output, SLOT(slotChangeRotation(QAction*)),
Qt::QueuedConnection
);
}
// refresh rate
RateList rates = output->refreshRates();
if (rates.count()) {
outputMenu->addTitle(SmallIcon("chronometer"), i18n("Refresh Rate"));
actionGroup = populateRates(outputMenu, rates, output->refreshRate());
connect(
actionGroup, SIGNAL(triggered(QAction*)),
output, SLOT(slotChangeRefreshRate(QAction*)),
Qt::QueuedConnection
);
}
if (screen->connectedCount() != 1) {
outputMenu->addSeparator();
action = outputMenu->addAction(
i18nc("(checkbox) designate this output as the primary output", "Primary output"),
output,
SLOT(slotSetAsPrimary(bool))
);
action->setCheckable(true);
action->setChecked(primary == output);
}
if (screen->connectedCount() != 1) {
menu->addMenu(outputMenu);
}
}
}
}
// if there is more than one output connected, give the option to unify the outputs
if (screen->connectedCount() != 1 && !screen->unifiedSizes().isEmpty()) {
menu->addSeparator();
action = menu->addAction( i18n("Unify Outputs"), screen, SLOT(slotUnifyOutputs(bool)) );
action->setCheckable(true);
action->setChecked(screen->outputsUnified());
}
}
QActionGroup *KRandRSystemTray::populateRotations(KMenu *menu, int rotations, int rotation)
{
QAction *action;
QActionGroup *rotateGroup = new QActionGroup(menu);
rotateGroup->setExclusive(true);
for (int i = 0; i < 6; i++) {
if ((1 << i) & rotations) {
action = menu->addAction(QIcon(RandR::rotationIcon(1 << i, rotation)), RandR::rotationName(1 << i));
action->setCheckable(true);
action->setData(1 << i);
if (rotation & (1 << i)) {
action->setChecked(true);
}
rotateGroup->addAction(action);
}
}
return rotateGroup;
}
QActionGroup *KRandRSystemTray::populateSizes(KMenu *menu, const SizeList &sizes, const QSize &size)
{
QAction *action;
QActionGroup *sizeGroup = new QActionGroup(menu);
sizeGroup->setExclusive(true);
for (int i = 0; i < sizes.count(); ++i) {
QSize s = sizes[i];
action = menu->addAction(QString("%1 x %2").arg(s.width()).arg(s.height()));
action->setCheckable(true);
action->setData(s);
if (s == size) {
action->setChecked(true);
}
sizeGroup->addAction(action);
}
return sizeGroup;
}
QActionGroup *KRandRSystemTray::populateRates(KMenu *menu, const RateList &rates, float rate)
{
QAction *action;
QActionGroup *rateGroup = new QActionGroup(menu);
rateGroup->setExclusive(true);
foreach(float r, rates) {
action = menu->addAction(ki18n("%1 Hz").subs(r, 0, 'f', 1).toString());
action->setCheckable(true);
action->setData(r);
if (r == rate) {
action->setChecked(true);
}
rateGroup->addAction(action);
}
return rateGroup;
}
void KRandRSystemTray::slotPrefs()
{
if (!m_kcm) {
KCMultiDialog *kcm = new KCMultiDialog( associatedWidget() );
kcm->setFaceType( KCMultiDialog::Plain );
kcm->setWindowTitle( i18n( "Configure Display" ) );
kcm->addModule( "randr" );
kcm->setAttribute(Qt::WA_DeleteOnClose);
m_kcm = kcm;
} else if (KWindowSystem::activeWindow() == m_kcm.data()->winId()) {
m_kcm.data()->hide();
return;
}
KWindowSystem::setOnDesktop(m_kcm.data()->winId(), KWindowSystem::currentDesktop());
m_kcm.data()->show();
m_kcm.data()->raise();
KWindowSystem::forceActiveWindow(m_kcm.data()->winId());
}
// vim:noet:sts=8:sw=8:

View file

@ -1,259 +0,0 @@
[Desktop Entry]
Name=KRandRTray
Name[af]=KRandRTray
Name[ar]=ضبط شاشة كيدي
Name[ast]=KRandRTray
Name[be]=Змена параметраў манітора
Name[be@latin]=KRandRTray
Name[bg]=KRandRTray
Name[bn]=KRandRTray
Name[bn_IN]=KRandRTray
Name[br]=KRandRTray
Name[bs]=KRandRTray
Name[ca]=KRandRTray
Name[ca@valencia]=KRandRTray
Name[cs]=KRandRTray
Name[csb]=KRandRTray
Name[da]=KRandRTray
Name[de]=KRandRTray
Name[el]=KRandRTray
Name[en_GB]=KRandRTray
Name[eo]=KRandRTray
Name[es]=KRandRTray
Name[et]=KRandRTray
Name[eu]=KRandRTray
Name[fi]=KRandRTray
Name[fr]=KRandRTray
Name[fy]=KRandRTray
Name[ga]=KRandRTray
Name[gl]=KRandRTray
Name[gu]=KRandRTray
Name[he]=KRandRTray
Name[hi]=---
Name[hne]=---
Name[hr]=KRandRTray
Name[hsb]=KRandRTray
Name[hu]=Képernyőfelbontás
Name[ia]=KRandRTray
Name[id]=KRandRTray
Name[is]=KRandRTray
Name[ja]=KRandRTray
Name[ka]=KRandRTray
Name[kk]=KRandRTray
Name[km]=KRandRTray
Name[kn]=
Name[ko]=KRandRTray
Name[ku]=KRandRTray
Name[lt]=KRandRTray
Name[lv]=KRandRTray
Name[mai]=---
Name[mk]=KRandRTray
Name[ml]=KRandRTray
Name[mr]=
Name[ms]=KRandRTray
Name[nb]=KRandRTray
Name[nds]=KRandRTray
Name[ne]=KRandR
Name[nl]=KRandRTray
Name[nn]=KRandRTray
Name[oc]=KRandRTray
Name[or]=KRandRTray
Name[pa]=KRandRTray
Name[pl]=KRandRTray
Name[pt]=KRandRTray
Name[pt_BR]=Ícone do KRandR
Name[ro]=KRandRTray
Name[ru]=KRandRTray
Name[se]=KRandRTray
Name[si]=KRandRTray
Name[sk]=KRandRTray
Name[sl]=KRandRTray
Name[sr]=Крандр-касета
Name[sr@ijekavian]=Крандр-касета
Name[sr@ijekavianlatin]=KRandR-kaseta
Name[sr@latin]=KRandR-kaseta
Name[sv]=Krandrtray
Name[ta]=KRandRTray
Name[te]=KRandRTray
Name[tg]=KRandRTray
Name[th]=KRandRTray
Name[tr]=KRandRTray
Name[ug]=KRandRTray
Name[uk]=KRandRTray
Name[uz]=KRandRTray
Name[uz@cyrillic]=KRandRTray
Name[vi]=KRandRTray
Name[wa]=KRandRTray
Name[x-test]=xxKRandRTrayxx
Name[zh_CN]=KRandRTray
Name[zh_TW]=KRandRTray
GenericName=Screen Resize & Rotate
GenericName[af]=Skerm Hervergroot & Roteer
GenericName[ar]=إعادة تحجيم وتدوير الشاشة
GenericName[ast]=Redimensionar y voltiar pantalla
GenericName[be]=Змена памераў экрана і перагортванне
GenericName[be@latin]=Aplet dla źmieny pamieraŭ i pavarotu ekrana
GenericName[bg]=Големина и въртене на екрана
GenericName[bn]=
GenericName[br]=Adventañ ha treiñ ar skramm
GenericName[bs]=Promjena veličine i rotacija ekrana
GenericName[ca]=Amida i gira la pantalla
GenericName[ca@valencia]=Amida i gira la pantalla
GenericName[cs]=Změna velikosti a rotace obrazovky
GenericName[csb]=Òbrócenié ë zjinaka miarë ekranu
GenericName[cy]=Newid Maint a Cylchdroi'r Sgrîn
GenericName[da]=Ændr størrelse på skærm og Rotér
GenericName[de]=Bildschirmgröße & -ausrichtung ändern
GenericName[el]=Αλλαγή μεγέθους & Περιστροφή οθόνης
GenericName[en_GB]=Screen Resize & Rotate
GenericName[eo]=Regrandigi kaj turni ekranon
GenericName[es]=Redimensionar y rotar pantalla
GenericName[et]=Ekraani suuruse muutmine ja pööramine
GenericName[eu]=Pantailaren neurria-aldatzea eta biratzea
GenericName[fa]=تغییر اندازه و چرخش پرده
GenericName[fi]=Näytön kuvan koon muuttaminen ja kuvan kääntäminen
GenericName[fr]=Redimensionnement et rotation de l'écran
GenericName[fy]=Skerm rotearje en grutte wizigje
GenericName[ga]=An scáileán a rothlú agus a mhéid a athrú
GenericName[gl]=Rotar e mudar o tamaño da pantalla
GenericName[gu]=િ
GenericName[he]=שינוי גודל המסך וסיבובו
GenericName[hi]=
GenericName[hne]=
GenericName[hr]=Veličine i orijentacija zaslona
GenericName[hsb]=Wobrazowku připrawić a wjerćeć
GenericName[hu]=Képernyőbeállító
GenericName[ia]=Redimensiona & Rota le schermo
GenericName[id]=Ubah Ukuran & Rotasi Layar
GenericName[is]=Stærð og snúningur skjáa
GenericName[ja]=
GenericName[ka]=
GenericName[kk]=Экранды өзгерту & бұрау
GenericName[km]=
GenericName[kn]= ಿ ಿಿ
GenericName[ko]=
GenericName[ku]=Guhertina Mezinahî û Hêla Ekranê
GenericName[lt]=Ekrano dydžio keitimas ir pasukimas
GenericName[lv]=Ekrāna izmērs un rotācija
GenericName[mai]=
GenericName[mk]=Големина и ротација на екранот
GenericName[ml]=ി ി ി ിി
GenericName[mr]= ि
GenericName[ms]=Saiz Semula Skrin & Putar
GenericName[nb]=Endre størrelsen på og rotere skjermbildet
GenericName[nds]=Schirmgrött un -utrichten ännern
GenericName[ne]= ि ि
GenericName[nl]=Scherm roteren en grootte wijzigen
GenericName[nn]=Endra storleiken på og roter skjermbiletet
GenericName[or]= ି
GenericName[pa]= -
GenericName[pl]=Obrót i zmiana rozmiaru ekranu
GenericName[pt]=Mudar o Tamanho e Rodar o Ecrã
GenericName[pt_BR]=Redimensionar tela e rotacionar
GenericName[ro]=Redimensionare și rotire ecran
GenericName[ru]=Изменение размера и ориентации экрана
GenericName[se]=Rievdat šearbmagova sturrodaga ja jorat dan
GenericName[si]=
GenericName[sk]=Zmena veľkosti a otočenie obrazovky
GenericName[sl]=Sprememba velikosti in vrtenje zaslona
GenericName[sr]=Промена величине и ротација екрана
GenericName[sr@ijekavian]=Промјена величине и ротација екрана
GenericName[sr@ijekavianlatin]=Promjena veličine i rotacija ekrana
GenericName[sr@latin]=Promena veličine i rotacija ekrana
GenericName[sv]=Ändra skärmstorlek och rotera
GenericName[ta]=ி &
GenericName[te]= ి &
GenericName[tg]=Андоза ва ҷойгиршавии экран
GenericName[th]=
GenericName[tr]=Ekran Boyutlandır ve Döndür
GenericName[ug]=ئېكران چوڭلۇقى ۋە ئايلاندۇر
GenericName[uk]=Зміна розмірів та обертання зображення
GenericName[uz]=Ekraning oʻlchamini oʻzgartirish va burish
GenericName[uz@cyrillic]=Экранинг ўлчамини ўзгартириш ва буриш
GenericName[vi]=Quay và thay đi c màn hình
GenericName[wa]=Candjî l' grandeu del waitroûle eyet l' tourner
GenericName[x-test]=xxScreen Resize & Rotatexx
GenericName[zh_CN]=
GenericName[zh_TW]=調
Comment=A panel applet for resizing and reorientating X screens.
Comment[ar]=لوحة تحكم لتغيير حجم واتجاه شاشات X
Comment[ast]=Una miniaplicación del panel pa redimensionar y reorientar pantalles X.
Comment[be@latin]=Aplet dla paneli, jaki absłuhoŭvaje źmienu pamieraŭ i pavarot ekranaŭ systemy X.
Comment[bg]=Аплет за преоразмеряване и ориентация на X.
Comment[bs]=Panelski aplet za promjenu veličine i orijentacije iks ekrana
Comment[ca]=Una miniaplicació del plafó per a redimensionar i reorientar les pantalles d'X.
Comment[ca@valencia]=Una miniaplicació del plafó per a redimensionar i reorientar les pantalles d'X.
Comment[cs]=Applet pro změnu velikosti a orientace obrazovky
Comment[csb]=Panel apletu do zmianë miarë ë pòłóżenia ekranów X
Comment[da]=Et panelprogram til at ændre størrelse og orientering for X-skærme.
Comment[de]=Ein Werkzeug zum Ändern der Bildschirmgröße und -ausrichtung
Comment[el]=Μια μικροεφαρμογή αλλαγής μεγέθους και προσανατολισμού οθονών Χ.
Comment[en_GB]=A panel applet for resizing and reorientating X screens.
Comment[eo]=Panela aplikaĵeto por regrandigi kaj reorienti la X ekranojn.
Comment[es]=Una miniaplicación del panel para redimensionar y reorientar pantallas X.
Comment[et]=Paneeliaplett X'i ekraanide suuruse muutmiseks ja pööramiseks
Comment[eu]=X pantailak neurriz eta norabidez aldatzeko applet bat.
Comment[fa]=برنامک تابلویی برای تغییر اندازه و تغییر جهت پردههای X.
Comment[fi]=Panelisovelma X-ruutujen koon ja suunnan muuttamiseksi
Comment[fr]=Une applet de tableau de bord pour redimensionner et faire pivoter les écrans X.
Comment[fy]=In paniel applet foar de grutte feroarjen en pleatsbepaling fan X skermen.
Comment[ga]=Feidhmchláirín painéil lenar féidir scáileán X a rothlú agus a mhéid a athrú.
Comment[gl]=Unha applet do panel para mudar o tamaño e reorientar as pantallas das X.
Comment[gu]=X િ
Comment[he]=יישומון לוח לשינוי גודל וכיוון המסך
Comment[hi]= ि िि ि
Comment[hne]= ि िि
Comment[hr]=Applet trake za promjenu veličine i orjentacije X zaslona.
Comment[hsb]=Pasowy applet za připrawjenje a wjerćenje X-wobrazowkow
Comment[hu]=Panel-kisalkalmazás X képernyők átméretezéséhez és elforgatásához
Comment[ia]=Un applet de pannello pro redimensionar e reorientar schermos X.
Comment[id]=Applet panel untuk mengubah ukuran dan mengubah orientasi layar X.
Comment[is]=Smáforrit á spjöld sem stjórnar stærð og snúningi X skjáa.
Comment[ja]=
Comment[kk]=X экрандарының өлшем мен бағдарын өзгерту апплет панелі.
Comment[km]= X 
Comment[kn]= ಿ ಿ (ಿ) ಿ () ()
Comment[ko]=X 릿.
Comment[ku]=Amûreke panelê ji bo guherandina mezinahî û hêla ekranên X.
Comment[lt]=Pulto įskiepis X ekranų dydžio ir orientacijos keitimui
Comment[lv]=Paneļa aplets ekrāna izmēra mainīšanai un rotēšanai.
Comment[mai]= ' ि िि '
Comment[mk]=Аплет за панелот што се користи за менување на големината и ориентацијата на X-екраните.
Comment[ml]= ി ി ിി .
Comment[mr]= िि िि ि .
Comment[nb]=Et panelprogram som skalerer og roterer X-skjermer.
Comment[nds]=En Paneel-Lüttprogramm för't Ännern vun Grött un Utrichten vun X-Schirmen
Comment[ne]= ि : िि
Comment[nl]=Een paneelapplet voor het wijzigen van de grootte en oriëntatie van de schermweergave.
Comment[nn]=Eit panelprogram for endring av skjermoppløysing og skjermretning.
Comment[pa]=X - - ਿ
Comment[pl]=Aplet panelu do zmiany rozmiarów i orientacji ekranów X.
Comment[pt]=Uma 'applet' do painel para mudar o tamanho e rodar os ecrãs no X.
Comment[pt_BR]=Um miniaplicativo do painel para redimensionar e reorientar as telas do X.
Comment[ro]=O miniaplicație de panou care redimensionează și reorientează ecranele X.
Comment[ru]=Виджет панели для изменения размера и ориентации экрана.
Comment[se]=Panelaprográmmaš mii sáhttá rievdadit šearpma čoakkisčuohkku ja jorahit dan.
Comment[si]=X
Comment[sk]=Aplet na zmenu veľkosti a orientácie obrazoviek.
Comment[sl]=Aplet pulta za spreminjanje velikosti in usmeritve zaslonov X.
Comment[sr]=Панелски аплет за промену величине и оријентације икс екрана
Comment[sr@ijekavian]=Панелски аплет за промјену величине и оријентације икс екрана
Comment[sr@ijekavianlatin]=Panelski aplet za promjenu veličine i orijentacije X ekrana
Comment[sr@latin]=Panelski aplet za promenu veličine i orijentacije X ekrana
Comment[sv]=Ett miniprogram för panelen som ändrar storlek och roterar X-skärmar.
Comment[ta]=X ி , ி ிி
Comment[te]=X ి ి .
Comment[th]= X
Comment[tr]=X ekranlarını yeniden boyutlandıran ve yönlerini değiştiren bir panel programcığı
Comment[ug]=X ئېكران چوڭلۇقى ۋە يۆنىلىشىنى تەڭشەيدىغان قوللانچاق
Comment[uk]=Аплет панелі для зміни розміру й орієнтації екранів X.
Comment[vi]=Tiu ng dng trên bng điu khin, đ thay đi kích c ca màn hình X và thay đi v trí.
Comment[wa]=Ene aplikete po candjî l' grandeu eyet tourner li håynaedje so les waitroûles X11
Comment[x-test]=xxA panel applet for resizing and reorientating X screens.xx
Comment[zh_CN]= X
Comment[zh_TW]=調 X
Exec=krandrtray --icon '%i' --caption '%c'
Icon=preferences-desktop-display-randr
Type=Application
OnlyShowIn=KDE;
Categories=Qt;KDE;System;

View file

@ -1,66 +0,0 @@
/*
* Copyright (c) 2002 Hamish Rodda <rodda@kde.org>
*
* 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 KRANDRTRAY_H
#define KRANDRTRAY_H
#include <QtGui/qevent.h>
#include <QtCore/qsharedpointer.h>
#include <QAction>
#include <QActionGroup>
#include <KStatusNotifierItem>
#include "randrdisplay.h"
class KCMultiDialog;
class KHelpMenu;
class KMenu;
class KRandRSystemTray : public KStatusNotifierItem
{
Q_OBJECT
public:
explicit KRandRSystemTray(RandRDisplay *dpy, QWidget* parent = 0);
~KRandRSystemTray();
void activate(const QPoint &pos);
protected Q_SLOTS:
void slotScreenActivated();
void slotPrefs();
void slotPrepareMenu();
void updateToolTip();
private:
void populateMenu(KMenu* menu);
// helper functions
QActionGroup *populateRotations(KMenu *menu, int rotations, int rotation);
QActionGroup *populateSizes(KMenu *menu, const SizeList &sizes, const QSize &size);
QActionGroup *populateRates(KMenu *menu, const RateList &rates, float rate);
KHelpMenu* m_help;
QList<KMenu*> m_screenPopups;
KMenu* m_menu;
RandRDisplay *m_display;
QWeakPointer<KCMultiDialog> m_kcm;
};
#endif // KRANDRTRAY_H

View file

@ -1,52 +0,0 @@
/*
* Copyright (c) 2007 Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net>
* Copyright (c) 2002,2003 Hamish Rodda <rodda@kde.org>
*
* 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 <stdlib.h>
#include <kdebug.h>
#include <klocale.h>
#include <kcmdlineargs.h>
#include <kaboutdata.h>
#include <kglobal.h>
#include "krandrapp.h"
static const char krandrtrayVersion[] = "0.5";
int main(int argc, char **argv)
{
KAboutData aboutData("display-randr", "krandr", ki18n("Resize and Rotate"), krandrtrayVersion,
ki18n("X Resize and Rotate System Tray App"), KAboutData::License_GPL,
ki18n("(c) 2007 Gustavo Pichorim Boiko, 2002-2003 Hamish Rodda"));
aboutData.addAuthor(ki18n("Gustavo Pichorim Boiko"),ki18n("Maintainer"), "gustavo.boiko@kdemail.net");
aboutData.addAuthor(ki18n("Hamish Rodda"),ki18n("Original Author"), "rodda@kde.org");
aboutData.addCredit(ki18n("Lubos Lunak"),ki18n("Many fixes"), "l.lunak@suse.cz");
aboutData.addCredit(ki18n("Harry Bock"),ki18n("Many fixes, multi-head support"), "hbock@providence.edu");
aboutData.setProgramIconName("preferences-desktop-display-randr");
KCmdLineArgs::init(argc,argv,&aboutData);
KCmdLineOptions options;
options.add("login", ki18n("Application is being auto-started at KDE session start"), 0L);
KCmdLineArgs::addCmdLineOptions(options);
KCmdLineArgs::addStdCmdLineOptions();
KRandRApp app;
return app.exec();
}

View file

@ -135,4 +135,3 @@ Comment[zh_CN]=书签组织和编辑器
Comment[zh_TW]=
X-DocPath=konqueror/index.html#bookmarks
Categories=Qt;KDE;Network;WebBrowser;
X-KDE-HasTrayOption=true

View file

@ -5,7 +5,6 @@ Type=Application
X-DocPath=kinfocenter/index.html
StartupNotify=true
OnlyShowIn=KDE;
X-KDE-HasTrayOption=true
Name=KInfoCenter
Name[af]=Inligting Sentrum

View file

@ -1,48 +0,0 @@
set(libklipper_common_SRCS
klipper.cpp
urlgrabber.cpp
configdialog.cpp
history.cpp
historyitem.cpp
historystringitem.cpp
klipperpopup.cpp
popupproxy.cpp
historyimageitem.cpp
historyurlitem.cpp
actionstreewidget.cpp
editactiondialog.cpp
clipcommandprocess.cpp
generalconfig.ui
actionsconfig.ui
editactiondialog.ui
)
kde4_add_kcfg_files(libklipper_common_SRCS klippersettings.kcfgc)
set(klipper_SRCS ${libklipper_common_SRCS} main.cpp tray.cpp)
add_executable(klipper ${klipper_SRCS})
target_link_libraries(klipper
KDE4::kdeui
KDE4::kfile
${QT_QTNETWORK_LIBRARY}
${X11_LIBRARIES}
)
if (X11_Xfixes_FOUND)
target_link_libraries(klipper ${X11_Xfixes_LIB})
endif (X11_Xfixes_FOUND)
install(
TARGETS klipper
DESTINATION ${KDE4_BIN_INSTALL_DIR}
)
install(
PROGRAMS klipper.desktop
DESTINATION ${KDE4_XDG_APPS_INSTALL_DIR}
)
install(
PROGRAMS klipper.desktop
DESTINATION ${KDE4_AUTOSTART_INSTALL_DIR}
)

View file

@ -1,5 +0,0 @@
#!/bin/bash
$EXTRACTRC *.ui *.kcfg >> rc.cpp
$XGETTEXT *.cpp -o $podir/klipper.pot
rm -f rc.cpp

View file

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ActionsWidget</class>
<widget class="QWidget" name="ActionsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>458</width>
<height>360</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="kcfg_ReplayActionInHistory">
<property name="text">
<string>Replay actions on an item selected from history</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="kcfg_StripWhiteSpace">
<property name="text">
<string>Remove whitespace when executing actions</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="kcfg_EnableMagicMimeActions">
<property name="text">
<string>Enable MIME-based actions</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Action list:</string>
</property>
</widget>
</item>
<item>
<widget class="ActionsTreeWidget" name="kcfg_ActionList">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<column>
<property name="text">
<string>Regular Expression</string>
</property>
</column>
<column>
<property name="text">
<string>Description</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pbAddAction">
<property name="text">
<string>Add Action...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbEditAction">
<property name="text">
<string>Edit Action...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbDelAction">
<property name="text">
<string>Delete Action</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbAdvanced">
<property name="text">
<string>Advanced...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Click on a highlighted item's column to change it. &quot;%s&quot; in a command will be replaced with the clipboard contents.&lt;br&gt;For more information about regular expressions, you could have a look at the &lt;a href=&quot;http://en.wikipedia.org/wiki/Regular_expression&quot;&gt;Wikipedia entry about this topic&lt;/a&gt;.</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ActionsTreeWidget</class>
<extends>QTreeWidget</extends>
<header>actionstreewidget.h</header>
</customwidget>
</customwidgets>
<connections/>
</ui>

View file

@ -1,64 +0,0 @@
/*
This file is part of the KDE project
Copyright (C) 2008 by Dmitry Suzdalev <dimsuz@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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "actionstreewidget.h"
#include <KDebug>
ActionsTreeWidget::ActionsTreeWidget(QWidget* parent)
: QTreeWidget(parent), m_actionsChanged(-1), m_modified(false)
{
// these signals indicate that something was changed in actions tree
connect(this, SIGNAL(itemChanged(QTreeWidgetItem*,int)), SLOT(onItemChanged()));
QAbstractItemModel *treeModel = model();
if (treeModel)
{
connect(treeModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(onItemChanged()));
connect(treeModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), SLOT(onItemChanged()));
}
}
void ActionsTreeWidget::onItemChanged()
{
setActionsChanged(true);
}
void ActionsTreeWidget::resetModifiedState()
{
m_modified = false;
m_actionsChanged = -1;
}
void ActionsTreeWidget::setActionsChanged(int isChanged)
{
Q_UNUSED(isChanged)
if (!m_modified)
{
m_actionsChanged = m_actionsChanged ? 1 : 0;
m_modified = true;
emit changed();
}
}
int ActionsTreeWidget::actionsChanged() const
{
return m_actionsChanged;
}

View file

@ -1,76 +0,0 @@
/*
This file is part of the KDE project
Copyright (C) 2008 by Dmitry Suzdalev <dimsuz@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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef ACTIONSTREEWIDGET_H
#define ACTIONSTREEWIDGET_H
#include <QtGui/QTreeWidget>
/**
* Custom tree widget class to make KConfigDialog properly
* highlight Apply button when some action is changed.
* We achieve this by adding custom type handling to KConfigDialogManager
* and by adding a somewhat dummy config entry which gets changed whenever
* some action is changed in treewidget.
* KConfigDialog watches this entry for changes and highlights Apply when needed
*
* @see KConfigDialogManager
*/
class ActionsTreeWidget : public QTreeWidget
{
Q_OBJECT
// this property is int instead of (more logical) bool, because we need a custom handling of
// "default state" and because of our custom use of this property:
//
// We indicate that changes were made to this widget by changing this int value.
// We use it as "if this value is *CHANGED SOMEHOW*, this means that some changes were made to action list",
// If we'd make this property bool, KConfigDialog would highlight "Defaults" button whenever
// this property becomes false, but this is not the way we use this property.
// So we change it from 0 to 1 periodically when something changes. Both 0, 1 values indicate
// change.
//
// We set it to default only when resetModifiedState() is called, i.e. when Apply btn is being
// clicked
//
// Hope this explains it.
// Yeah, this class is a trick :) If there's a better way to properly
// update KConfigDialog buttons whenever "some change occurs to QTreeWidget", let me know (dimsuz)
Q_PROPERTY( int actionsChanged READ actionsChanged WRITE setActionsChanged USER true )
public:
ActionsTreeWidget(QWidget* parent = 0);
void setActionsChanged(int);
int actionsChanged() const;
void resetModifiedState();
signals:
void changed();
private slots:
void onItemChanged();
private:
int m_actionsChanged;
bool m_modified;
};
#endif

View file

@ -1,83 +0,0 @@
/*
Copyright 2009 Esben Mose Hansen <kde@mosehansen.dk>
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 "clipcommandprocess.h"
#include <KCharMacroExpander>
#include "history.h"
#include "historystringitem.h"
#include "urlgrabber.h"
ClipCommandProcess::ClipCommandProcess(const ClipAction& action, const ClipCommand& command, const QString& clip, History* history, const HistoryItem* original_item) :
KProcess(),
m_history(history),
m_historyItem(original_item),
m_newhistoryItem()
{
QHash<QChar,QString> map;
map.insert( 's', clip );
// support %u, %U (indicates url param(s)) and %f, %F (file param(s))
map.insert( 'u', clip );
map.insert( 'U', clip );
map.insert( 'f', clip );
map.insert( 'F', clip );
const QStringList matches = action.regExpMatches();
// support only %0 and the first 9 matches...
const int numMatches = qMin(10, matches.count());
for ( int i = 0; i < numMatches; ++i ) {
map.insert( QChar( '0' + i ), matches.at( i ) );
}
setReadChannel(QProcess::StandardOutput);
setShellCommand(KMacroExpander::expandMacrosShellQuote( command.command, map ).trimmed());
connect(this, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(slotFinished(int,QProcess::ExitStatus)));
if (command.output != ClipCommand::IGNORE) {
connect(this, SIGNAL(readyRead()), SLOT(slotStdOutputAvailable()));
}
if (command.output != ClipCommand::REPLACE) {
m_historyItem = 0L; // Don't replace
}
}
void ClipCommandProcess::slotFinished(int /*exitCode*/, QProcess::ExitStatus /*newState*/)
{
if (m_history) {
// If an history item was provided, remove it so that the new item can replace it
if (m_historyItem) {
m_history->remove(m_historyItem);
}
if (!m_newhistoryItem.isEmpty()) {
m_history->insert(new HistoryStringItem(m_newhistoryItem));
}
}
deleteLater();
}
void ClipCommandProcess::slotStdOutputAvailable()
{
m_newhistoryItem.append(QString::fromLocal8Bit(this->readAllStandardOutput().data()));
}
#include "moc_clipcommandprocess.cpp"

View file

@ -1,44 +0,0 @@
/*
Copyright 2009 Esben Mose Hansen <kde@mosehansen.dk>
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 CLIPCOMMANDPROCESS_H
#define CLIPCOMMANDPROCESS_H
#include <KProcess>
class ClipAction;
class History;
class ClipCommand;
class HistoryItem;
class ClipCommandProcess : public KProcess
{
Q_OBJECT
public:
ClipCommandProcess(const ClipAction& action, const ClipCommand& command, const QString& clip, History* history = 0L, const HistoryItem* original_item = 0L);
public slots:
void slotStdOutputAvailable();
void slotFinished(int exitCode, QProcess::ExitStatus newState);
private:
History* m_history;
const HistoryItem* m_historyItem;
QString m_newhistoryItem;
};
#endif // CLIPCOMMANDPROCESS_H

View file

@ -1,378 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2000 by Carsten Pfeiffer <pfeiffer@kde.org>
Copyright (C) 2008-2009 by Dmitry Suzdalev <dimsuz@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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "configdialog.h"
#include <KLocale>
#include <KMenu>
#include <KShortcutsEditor>
#include <KDebug>
#include <KEditListWidget>
#include "klipper.h"
#include "editactiondialog.h"
GeneralWidget::GeneralWidget(QWidget* parent)
: QWidget(parent)
{
m_ui.setupUi(this);
m_ui.kcfg_TimeoutForActionPopups->setSuffix(ki18np(" second", " seconds"));
m_ui.kcfg_MaxClipItems->setSuffix(ki18np(" entry", " entries"));
}
void GeneralWidget::updateWidgets()
{
if (m_ui.kcfg_IgnoreSelection->isChecked()) {
m_ui.kcfg_SyncClipboards->setEnabled(false);
m_ui.kcfg_SelectionTextOnly->setEnabled(false);
} else if (m_ui.kcfg_SyncClipboards->isChecked()) {
m_ui.kcfg_IgnoreSelection->setEnabled(false);
}
}
ActionsWidget::ActionsWidget(QWidget* parent)
: QWidget(parent), m_editActDlg(0)
{
m_ui.setupUi(this);
m_ui.pbAddAction->setIcon(KIcon("list-add"));
m_ui.pbDelAction->setIcon(KIcon("list-remove"));
m_ui.pbEditAction->setIcon(KIcon("document-edit"));
m_ui.pbAdvanced->setIcon(KIcon("configure"));
const KConfigGroup grp = KGlobal::config()->group("ActionsWidget");
QByteArray hdrState = grp.readEntry("ColumnState", QByteArray());
if (!hdrState.isEmpty())
{
kDebug() << "Restoring column state";
m_ui.kcfg_ActionList->header()->restoreState(QByteArray::fromBase64(hdrState));
}
else
{
m_ui.kcfg_ActionList->header()->resizeSection(0, 250);
}
connect(m_ui.kcfg_ActionList, SIGNAL(itemSelectionChanged()), SLOT(onSelectionChanged()));
connect(m_ui.kcfg_ActionList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
SLOT(onEditAction()));
connect(m_ui.pbAddAction, SIGNAL(clicked()), SLOT(onAddAction()));
connect(m_ui.pbEditAction, SIGNAL(clicked()), SLOT(onEditAction()));
connect(m_ui.pbDelAction, SIGNAL(clicked()), SLOT(onDeleteAction()));
connect(m_ui.pbAdvanced, SIGNAL(clicked()), SLOT(onAdvanced()));
onSelectionChanged();
}
void ActionsWidget::setActionList(const ActionList& list)
{
qDeleteAll( m_actionList );
m_actionList.clear();
foreach (ClipAction* action, list) {
if (!action) {
kDebug() << "action is null!";
continue;
}
// make a copy for us to work with from now on
m_actionList.append( new ClipAction( *action ) );
}
updateActionListView();
}
void ActionsWidget::updateActionListView()
{
m_ui.kcfg_ActionList->clear();
foreach (ClipAction* action, m_actionList) {
if (!action) {
kDebug() << "action is null!";
continue;
}
QTreeWidgetItem *item = new QTreeWidgetItem;
updateActionItem( item, action );
m_ui.kcfg_ActionList->addTopLevelItem( item );
}
// after all actions loaded, reset modified state of tree widget.
// Needed because tree widget reacts on item changed events to tell if it is changed
// this will ensure that apply button state will be correctly changed
m_ui.kcfg_ActionList->resetModifiedState();
}
void ActionsWidget::updateActionItem( QTreeWidgetItem* item, ClipAction* action )
{
if ( !item || !action ) {
kDebug() << "null pointer passed to function, nothing done";
return;
}
// clear children if any
item->takeChildren();
item->setText( 0, action->regExp() );
item->setText( 1, action->description() );
foreach (const ClipCommand& command, action->commands()) {
QStringList cmdProps;
cmdProps << command.command << command.description;
QTreeWidgetItem *child = new QTreeWidgetItem(item, cmdProps);
child->setIcon(0, KIcon(command.icon.isEmpty() ? "system-run" : command.icon));
}
}
void ActionsWidget::setExcludedWMClasses(const QStringList& excludedWMClasses)
{
m_exclWMClasses = excludedWMClasses;
}
QStringList ActionsWidget::excludedWMClasses() const
{
return m_exclWMClasses;
}
ActionList ActionsWidget::actionList() const
{
// return a copy of our action list
ActionList list;
foreach( ClipAction* action, m_actionList ) {
if ( !action ) {
kDebug() << "action is null";
continue;
}
list.append( new ClipAction( *action ) );
}
return list;
}
void ActionsWidget::resetModifiedState()
{
m_ui.kcfg_ActionList->resetModifiedState();
kDebug() << "Saving column state";
KConfigGroup grp = KGlobal::config()->group("ActionsWidget");
grp.writeEntry("ColumnState",
m_ui.kcfg_ActionList->header()->saveState().toBase64());
}
void ActionsWidget::onSelectionChanged()
{
bool itemIsSelected = !m_ui.kcfg_ActionList->selectedItems().isEmpty();
m_ui.pbEditAction->setEnabled(itemIsSelected);
m_ui.pbDelAction->setEnabled(itemIsSelected);
}
void ActionsWidget::onAddAction()
{
if (!m_editActDlg) {
m_editActDlg = new EditActionDialog(this);
}
ClipAction* newAct = new ClipAction;
m_editActDlg->setAction(newAct);
if (m_editActDlg->exec() == QDialog::Accepted) {
m_actionList.append( newAct );
QTreeWidgetItem* item = new QTreeWidgetItem;
updateActionItem( item, newAct );
m_ui.kcfg_ActionList->addTopLevelItem( item );
}
}
void ActionsWidget::onEditAction()
{
if (!m_editActDlg) {
m_editActDlg = new EditActionDialog(this);
}
QTreeWidgetItem *item = m_ui.kcfg_ActionList->currentItem();
int commandIdx = -1;
if (item) {
if (item->parent()) {
commandIdx = item->parent()->indexOfChild( item );
item = item->parent(); // interested in toplevel action
}
int idx = m_ui.kcfg_ActionList->indexOfTopLevelItem( item );
ClipAction* action = m_actionList.at( idx );
if ( !action ) {
kDebug() << "action is null";
return;
}
m_editActDlg->setAction(action, commandIdx);
// dialog will save values into action if user hits OK
m_editActDlg->exec();
updateActionItem(item, action);
}
}
void ActionsWidget::onDeleteAction()
{
QTreeWidgetItem *item = m_ui.kcfg_ActionList->currentItem();
if ( item && item->parent() )
item = item->parent();
if ( item )
{
int idx = m_ui.kcfg_ActionList->indexOfTopLevelItem( item );
m_actionList.removeAt( idx );
}
delete item;
}
void ActionsWidget::onAdvanced()
{
KDialog dlg(this);
dlg.setModal(true);
dlg.setCaption( i18n("Advanced Settings") );
dlg.setButtons( KDialog::Ok | KDialog::Cancel );
AdvancedWidget *widget = new AdvancedWidget(&dlg);
widget->setWMClasses( m_exclWMClasses );
dlg.setMainWidget(widget);
if ( dlg.exec() == KDialog::Accepted ) {
m_exclWMClasses = widget->wmClasses();
}
}
ConfigDialog::ConfigDialog(QWidget* parent, KConfigSkeleton* skeleton, const Klipper* klipper, KActionCollection*collection, bool isApplet)
: KConfigDialog(parent, "preferences", skeleton),
m_generalPage(new GeneralWidget(this)),
m_actionsPage(new ActionsWidget(this)),
m_klipper(klipper)
{
if ( isApplet ) {
setHelp( QString(), "klipper" );
}
addPage(m_generalPage, i18nc("General Config", "General"), "klipper", i18n("General Configuration"));
addPage(m_actionsPage, i18nc("Actions Config", "Actions"), "system-run", i18n("Actions Configuration"));
QWidget* w = new QWidget(this);
m_shortcutsWidget = new KShortcutsEditor( collection, w, KShortcutsEditor::GlobalAction );
addPage(m_shortcutsWidget, i18nc("Shortcuts Config", "Shortcuts"), "configure-shortcuts", i18n("Shortcuts Configuration"));
const KConfigGroup grp = KGlobal::config()->group("ConfigDialog");
restoreDialogSize(grp);
}
ConfigDialog::~ConfigDialog()
{
}
void ConfigDialog::updateSettings()
{
// user clicked Ok or Apply
if (!m_klipper) {
kDebug() << "Klipper object is null";
return;
}
m_shortcutsWidget->save();
m_actionsPage->resetModifiedState();
m_klipper->urlGrabber()->setActionList(m_actionsPage->actionList());
m_klipper->urlGrabber()->setExcludedWMClasses(m_actionsPage->excludedWMClasses());
m_klipper->saveSettings();
KConfigGroup grp = KGlobal::config()->group("ConfigDialog");
saveDialogSize(grp);
}
void ConfigDialog::updateWidgets()
{
// settings were updated, update widgets
if (m_klipper && m_klipper->urlGrabber() ) {
m_actionsPage->setActionList(m_klipper->urlGrabber()->actionList());
m_actionsPage->setExcludedWMClasses(m_klipper->urlGrabber()->excludedWMClasses());
} else {
kDebug() << "Klipper or grabber object is null";
return;
}
m_generalPage->updateWidgets();
}
void ConfigDialog::updateWidgetsDefault()
{
// default widget values requested
m_shortcutsWidget->allDefault();
}
AdvancedWidget::AdvancedWidget( QWidget *parent )
: QWidget(parent)
{
QVBoxLayout *mainLayout = new QVBoxLayout(this);
QGroupBox *groupBox = new QGroupBox(i18n("D&isable Actions for Windows of Type WM_CLASS"), this);
groupBox->setLayout(new QVBoxLayout(groupBox));
editListBox = new KEditListWidget(groupBox);
editListBox->setButtons(KEditListWidget::Add | KEditListWidget::Remove);
editListBox->setCheckAtEntering(true);
editListBox->setWhatsThis(i18n("<qt>This lets you specify windows in which Klipper should "
"not invoke \"actions\". Use<br /><br />"
"<center><b>xprop | grep WM_CLASS</b></center><br />"
"in a terminal to find out the WM_CLASS of a window. "
"Next, click on the window you want to examine. The "
"first string it outputs after the equal sign is the one "
"you need to enter here.</qt>"));
groupBox->layout()->addWidget(editListBox);
mainLayout->addWidget(groupBox);
editListBox->setFocus();
}
AdvancedWidget::~AdvancedWidget()
{
}
void AdvancedWidget::setWMClasses( const QStringList& items )
{
editListBox->setItems(items);
}
QStringList AdvancedWidget::wmClasses() const
{
return editListBox->items();
}
#include "moc_configdialog.cpp"

View file

@ -1,124 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2000 by Carsten Pfeiffer <pfeiffer@kde.org>
Copyright (C) 2008 by Dmitry Suzdalev <dimsuz@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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef CONFIGDIALOG_H
#define CONFIGDIALOG_H
#include <KConfigDialog>
#include "urlgrabber.h"
#include "ui_generalconfig.h"
#include "ui_actionsconfig.h"
class KConfigSkeleton;
class KShortcutsEditor;
class Klipper;
class KEditListWidget;
class KActionCollection;
class EditActionDialog;
class GeneralWidget : public QWidget
{
Q_OBJECT
public:
GeneralWidget(QWidget* parent);
void updateWidgets();
private:
Ui::GeneralWidget m_ui;
};
class ActionsWidget : public QWidget
{
Q_OBJECT
public:
ActionsWidget(QWidget* parent);
void setActionList(const ActionList&);
void setExcludedWMClasses(const QStringList&);
ActionList actionList() const;
QStringList excludedWMClasses() const;
void resetModifiedState();
private slots:
void onSelectionChanged();
void onAddAction();
void onEditAction();
void onDeleteAction();
void onAdvanced();
private:
void updateActionItem( QTreeWidgetItem* item, ClipAction* action );
void updateActionListView();
Ui::ActionsWidget m_ui;
EditActionDialog* m_editActDlg;
/**
* List of actions this page works with
*/
ActionList m_actionList;
QStringList m_exclWMClasses;
};
// only for use inside ActionWidget
class AdvancedWidget : public QWidget
{
Q_OBJECT
public:
explicit AdvancedWidget( QWidget* parent = 0L );
~AdvancedWidget();
void setWMClasses( const QStringList& items );
QStringList wmClasses() const;
private:
KEditListWidget* editListBox;
};
class ConfigDialog : public KConfigDialog
{
Q_OBJECT
public:
ConfigDialog( QWidget* parent, KConfigSkeleton* config, const Klipper* klipper, KActionCollection* collection, bool isApplet );
~ConfigDialog();
private:
// reimp
void updateWidgets();
// reimp
void updateSettings();
// reimp
void updateWidgetsDefault();
private:
GeneralWidget* m_generalPage;
ActionsWidget* m_actionsPage;
KShortcutsEditor* m_shortcutsWidget;
const Klipper* m_klipper;
};
#endif // CONFIGDIALOG_H

View file

@ -1,384 +0,0 @@
/*
This file is part of the KDE project
Copyright (C) 2009 by Dmitry Suzdalev <dimsuz@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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "editactiondialog.h"
#include <QtGui/QItemDelegate>
#include <QtGui/QComboBox>
#include <KDebug>
#include <KLocale>
#include "urlgrabber.h"
#include "ui_editactiondialog.h"
namespace {
static QString output2text(ClipCommand::Output output) {
switch(output) {
case ClipCommand::IGNORE:
return QString(i18n("Ignore"));
case ClipCommand::REPLACE:
return QString(i18n("Replace Clipboard"));
case ClipCommand::ADD:
return QString(i18n("Add to Clipboard"));
}
return QString();
}
}
/**
* Show dropdown of editing Output part of commands
*/
class ActionOutputDelegate : public QItemDelegate {
public:
ActionOutputDelegate(QObject* parent = 0) : QItemDelegate(parent){
}
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/) const {
QComboBox* editor = new QComboBox(parent);
editor->setInsertPolicy(QComboBox::NoInsert);
editor->addItem(output2text(ClipCommand::IGNORE), QVariant::fromValue<ClipCommand::Output>(ClipCommand::IGNORE));
editor->addItem(output2text(ClipCommand::REPLACE), QVariant::fromValue<ClipCommand::Output>(ClipCommand::REPLACE));
editor->addItem(output2text(ClipCommand::ADD), QVariant::fromValue<ClipCommand::Output>(ClipCommand::ADD));
return editor;
}
virtual void setEditorData(QWidget* editor, const QModelIndex& index) const {
QComboBox* ed = static_cast<QComboBox*>(editor);
QVariant data(index.model()->data(index, Qt::EditRole));
ed->setCurrentIndex(static_cast<int>(data.value<ClipCommand::Output>()));
}
virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const {
QComboBox* ed = static_cast<QComboBox*>(editor);
model->setData(index, ed->itemData(ed->currentIndex()));
}
virtual void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& /*index*/) const {
editor->setGeometry(option.rect);
}
};
class ActionDetailModel : public QAbstractTableModel {
public:
ActionDetailModel(ClipAction* action, QObject* parent = 0);
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
virtual Qt::ItemFlags flags(const QModelIndex& index) const;
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
virtual int columnCount(const QModelIndex& parent) const;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
const QList<ClipCommand>& commands() const { return m_commands; }
void addCommand(const ClipCommand& command);
void removeCommand(const QModelIndex& index);
private:
enum column_t {
COMMAND_COL = 0,
OUTPUT_COL = 1,
DESCRIPTION_COL = 2
};
QList<ClipCommand> m_commands;
QVariant displayData(ClipCommand* command, column_t colunm) const;
QVariant editData(ClipCommand* command, column_t column) const;
QVariant decorationData(ClipCommand* command, column_t column) const;
void setIconForCommand(ClipCommand& cmd);
};
ActionDetailModel::ActionDetailModel(ClipAction* action, QObject* parent):
QAbstractTableModel(parent),
m_commands(action->commands())
{
}
Qt::ItemFlags ActionDetailModel::flags(const QModelIndex& /*index*/) const
{
return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
void ActionDetailModel::setIconForCommand(ClipCommand& cmd)
{
// let's try to update icon of the item according to command
QString command = cmd.command;
if ( command.contains( ' ' ) ) {
// get first word
command = command.section( ' ', 0, 0 );
}
QPixmap iconPix = KIconLoader::global()->loadIcon(
command, KIconLoader::Small, 0,
KIconLoader::DefaultState,
QStringList(), 0, true /* canReturnNull */ );
if ( !iconPix.isNull() ) {
cmd.icon = command;
} else {
cmd.icon.clear();
}
}
bool ActionDetailModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
if (role == Qt::EditRole) {
ClipCommand cmd = m_commands.at(index.row());
switch (static_cast<column_t>(index.column())) {
case COMMAND_COL:
cmd.command = value.value<QString>();
setIconForCommand(cmd);
break;
case OUTPUT_COL:
cmd.output = value.value<ClipCommand::Output>();
break;
case DESCRIPTION_COL:
cmd.description = value.value<QString>();
break;
}
m_commands.replace(index.row(), cmd);
emit dataChanged(index, index);
return true;
}
return false;
}
int ActionDetailModel::columnCount(const QModelIndex& /*parent*/) const
{
return 3;
}
int ActionDetailModel::rowCount(const QModelIndex&) const
{
return m_commands.count();
}
QVariant ActionDetailModel::displayData(ClipCommand* command, ActionDetailModel::column_t column) const
{
switch (column) {
case COMMAND_COL:
return command->command;
case OUTPUT_COL:
return output2text(command->output);
case DESCRIPTION_COL:
return command->description;
}
return QVariant();
}
QVariant ActionDetailModel::decorationData(ClipCommand* command, ActionDetailModel::column_t column) const
{
switch (column) {
case COMMAND_COL:
return command->icon.isEmpty() ? KIcon( "system-run" ) : KIcon( command->icon );
case OUTPUT_COL:
case DESCRIPTION_COL:
break;
}
return QVariant();
}
QVariant ActionDetailModel::editData(ClipCommand* command, ActionDetailModel::column_t column) const
{
switch (column) {
case COMMAND_COL:
return command->command;
case OUTPUT_COL:
return QVariant::fromValue<ClipCommand::Output>(command->output);
case DESCRIPTION_COL:
return command->description;
}
return QVariant();
}
QVariant ActionDetailModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
switch(static_cast<column_t>(section)) {
case COMMAND_COL:
return i18n("Command");
case OUTPUT_COL:
return i18n("Output Handling");
case DESCRIPTION_COL:
return i18n("Description");
}
}
return QAbstractTableModel::headerData(section, orientation, role);
}
QVariant ActionDetailModel::data(const QModelIndex& index, int role) const
{
const int column = index.column();
const int row = index.row();
ClipCommand cmd = m_commands.at(row);
switch (role) {
case Qt::DisplayRole:
return displayData(&cmd, static_cast<column_t>(column));
case Qt::DecorationRole:
return decorationData(&cmd, static_cast<column_t>(column));
case Qt::EditRole:
return editData(&cmd, static_cast<column_t>(column));
}
return QVariant();
}
void ActionDetailModel::addCommand(const ClipCommand& command) {
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_commands << command;
endInsertRows();
}
void ActionDetailModel::removeCommand(const QModelIndex& index) {
int row = index.row();
beginRemoveRows(QModelIndex(), row, row);
m_commands.removeAt(row);
endRemoveRows();
}
EditActionDialog::EditActionDialog(QWidget* parent)
: KDialog(parent)
{
setCaption(i18n("Action Properties"));
setButtons(KDialog::Ok | KDialog::Cancel);
QWidget* dlgWidget = new QWidget(this);
m_ui = new Ui_EditActionDialog;
m_ui->setupUi(dlgWidget);
m_ui->leRegExp->setClearButtonShown(true);
m_ui->leDescription->setClearButtonShown(true);
m_ui->pbAddCommand->setIcon(KIcon("list-add"));
m_ui->pbRemoveCommand->setIcon(KIcon("list-remove"));
// For some reason, the default row height is 30 pixel. Set it to the minimum sectionSize instead,
// which is the font height+struts.
m_ui->twCommandList->verticalHeader()->setDefaultSectionSize(m_ui->twCommandList->verticalHeader()->minimumSectionSize());
m_ui->twCommandList->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
setMainWidget(dlgWidget);
connect(m_ui->pbAddCommand, SIGNAL(clicked()), SLOT(onAddCommand()) );
connect(m_ui->pbRemoveCommand, SIGNAL(clicked()), SLOT(onRemoveCommand()) );
const KConfigGroup grp = KGlobal::config()->group("EditActionDialog");
restoreDialogSize(grp);
QByteArray hdrState = grp.readEntry("ColumnState", QByteArray());
if (!hdrState.isEmpty()) {
kDebug() << "Restoring column state";
m_ui->twCommandList->horizontalHeader()->restoreState(QByteArray::fromBase64(hdrState));
}
// do this after restoreState()
m_ui->twCommandList->horizontalHeader()->setHighlightSections(false);
}
EditActionDialog::~EditActionDialog()
{
delete m_ui;
}
void EditActionDialog::setAction(ClipAction* act, int commandIdxToSelect)
{
m_action = act;
m_model = new ActionDetailModel(act, this);
m_ui->twCommandList->setModel(m_model);
m_ui->twCommandList->setItemDelegateForColumn(1, new ActionOutputDelegate);
connect(m_ui->twCommandList->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(onSelectionChanged()));
updateWidgets( commandIdxToSelect );
}
void EditActionDialog::updateWidgets(int commandIdxToSelect)
{
if (!m_action) {
kDebug() << "no action to edit was set";
return;
}
m_ui->leRegExp->setText(m_action->regExp());
m_ui->automatic->setChecked(m_action->automatic());
m_ui->leDescription->setText(m_action->description());
if (commandIdxToSelect != -1) {
m_ui->twCommandList->setCurrentIndex( m_model->index( commandIdxToSelect ,0 ) );
}
// update Remove button
onSelectionChanged();
}
void EditActionDialog::saveAction()
{
if (!m_action) {
kDebug() << "no action to edit was set";
return;
}
m_action->setRegExp( m_ui->leRegExp->text() );
m_action->setDescription( m_ui->leDescription->text() );
m_action->setAutomatic( m_ui->automatic->isChecked() );
m_action->clearCommands();
foreach ( const ClipCommand& cmd, m_model->commands() ){
m_action->addCommand( cmd );
}
}
void EditActionDialog::slotButtonClicked( int button )
{
if ( button == KDialog::Ok ) {
saveAction();
kDebug() << "Saving dialogue state";
KConfigGroup grp = KGlobal::config()->group("EditActionDialog");
saveDialogSize(grp);
grp.writeEntry("ColumnState",
m_ui->twCommandList->horizontalHeader()->saveState().toBase64());
}
KDialog::slotButtonClicked( button );
}
void EditActionDialog::onAddCommand()
{
m_model->addCommand(ClipCommand(i18n( "new command" ),
i18n( "Command Description" ),
true,
"" ));
m_ui->twCommandList->edit( m_model->index( m_model->rowCount()-1, 0 ));
}
void EditActionDialog::onRemoveCommand()
{
m_model->removeCommand(m_ui->twCommandList->selectionModel()->currentIndex());
}
void EditActionDialog::onSelectionChanged()
{
m_ui->pbRemoveCommand->setEnabled( m_ui->twCommandList->selectionModel() && m_ui->twCommandList->selectionModel()->hasSelection() );
}
#include "moc_editactiondialog.cpp"

View file

@ -1,72 +0,0 @@
/*
This file is part of the KDE project
Copyright (C) 2009 by Dmitry Suzdalev <dimsuz@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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef EDIT_ACTION_DIALOG_H
#define EDIT_ACTION_DIALOG_H
#include <KDialog>
QT_BEGIN_NAMESPACE
class Ui_EditActionDialog;
QT_END_NAMESPACE
class ClipAction;
class ActionDetailModel;
class EditActionDialog : public KDialog
{
Q_OBJECT
public:
EditActionDialog(QWidget* parent);
~EditActionDialog();
/**
* Sets the action this dialog will work with
*/
void setAction(ClipAction* act, int commandIdxToSelect = -1);
private slots:
void onAddCommand();
void onRemoveCommand();
void onSelectionChanged();
// void onItemChanged( QTreeWidgetItem*, int );
private:
/**
* Updates dialog's widgets according to values
* in m_action.
* If commandIdxToSelect != -1 this command will be preselected
*/
void updateWidgets(int commandIdxToSelect);
/**
* Saves a values from widgets to action
*/
void saveAction();
virtual void slotButtonClicked( int button );
private:
Ui_EditActionDialog* m_ui;
ClipAction* m_action;
ActionDetailModel* m_model;
};
#endif

View file

@ -1,225 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>EditActionDialog</class>
<widget class="QWidget" name="EditActionDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>362</width>
<height>329</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Action properties:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="2">
<widget class="KLineEdit" name="leRegExp">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="KLineEdit" name="leDescription"/>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Regular expression:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label">
<property name="text">
<string>Description:</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="label_5">
<property name="text">
<string>Automatic:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>automatic</cstring>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QCheckBox" name="automatic">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="label_4">
<property name="text">
<string>List of commands for this action:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>15</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0">
<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>15</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0" colspan="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>15</height>
</size>
</property>
</spacer>
</item>
<item row="6" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pbAddCommand">
<property name="text">
<string>Add Command</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbRemoveCommand">
<property name="text">
<string>Remove Command</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="7" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>15</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="1">
<widget class="QTableView" name="twCommandList">
<property name="toolTip">
<string>Double-click an item to edit</string>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="gridStyle">
<enum>Qt::NoPen</enum>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>twCommandList</tabstop>
<tabstop>leRegExp</tabstop>
<tabstop>automatic</tabstop>
<tabstop>leDescription</tabstop>
<tabstop>pbRemoveCommand</tabstop>
<tabstop>pbAddCommand</tabstop>
</tabstops>
<customwidgets>
<customwidget>
<class>KLineEdit</class>
<extends>QLineEdit</extends>
<header>klineedit.h</header>
</customwidget>
</customwidgets>
<connections/>
</ui>

View file

@ -1,165 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GeneralWidget</class>
<widget class="QWidget" name="GeneralWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>463</width>
<height>417</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="kcfg_KeepClipboardContents">
<property name="text">
<string>Save clipboard contents on exit</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="kcfg_PreventEmptyClipboard">
<property name="text">
<string>Prevent empty clipboard</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="kcfg_IgnoreImages">
<property name="text">
<string>Ignore images</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="selection_group">
<property name="title">
<string>Selection and Clipboard</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="kcfg_IgnoreSelection">
<property name="text">
<string>Ignore selection</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="kcfg_SelectionTextOnly">
<property name="text">
<string>Text selection only</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="kcfg_SyncClipboards">
<property name="text">
<string>Synchronize contents of the clipboard and the selection</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="timeout_label">
<property name="text">
<string>Timeout for action popups:</string>
</property>
</widget>
</item>
<item>
<widget class="KIntSpinBox" name="kcfg_TimeoutForActionPopups">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="history_size_label">
<property name="text">
<string>Clipboard history size:</string>
</property>
</widget>
</item>
<item>
<widget class="KIntSpinBox" name="kcfg_MaxClipItems">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</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>
<customwidgets>
<customwidget>
<class>KIntSpinBox</class>
<extends>QSpinBox</extends>
<header>knuminput.h</header>
</customwidget>
</customwidgets>
<connections>
<connection>
<sender>kcfg_IgnoreSelection</sender>
<signal>clicked(bool)</signal>
<receiver>kcfg_SelectionTextOnly</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>78</x>
<y>213</y>
</hint>
<hint type="destinationlabel">
<x>80</x>
<y>231</y>
</hint>
</hints>
</connection>
<connection>
<sender>kcfg_IgnoreSelection</sender>
<signal>clicked(bool)</signal>
<receiver>kcfg_SyncClipboards</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>209</x>
<y>214</y>
</hint>
<hint type="destinationlabel">
<x>207</x>
<y>265</y>
</hint>
</hints>
</connection>
<connection>
<sender>kcfg_SyncClipboards</sender>
<signal>clicked(bool)</signal>
<receiver>kcfg_IgnoreSelection</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>300</x>
<y>261</y>
</hint>
<hint type="destinationlabel">
<x>301</x>
<y>210</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -1,247 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2004 Esben Mose Hansen <kde@mosehansen.dk>
Copyright (C) by Andrew Stanley-Jones <asj@cban.com>
Copyright (C) 2000 by Carsten Pfeiffer <pfeiffer@kde.org>
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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "history.h"
#include <QtGui/QAction>
#include <KDebug>
#include "historystringitem.h"
#include "klipperpopup.h"
History::History( QObject* parent )
: QObject( parent ),
m_top(0L),
m_popup( new KlipperPopup( this ) ),
m_topIsUserSelected( false ),
m_nextCycle(0L)
{
connect( this, SIGNAL(changed()), m_popup, SLOT(slotHistoryChanged()) );
}
History::~History() {
qDeleteAll(m_items);
}
void History::insert( HistoryItem* item ) {
if ( !item )
return;
m_topIsUserSelected = false;
const HistoryItem* existingItem = this->find(item->uuid());
if ( existingItem ) {
if ( existingItem == m_top) {
return;
}
slotMoveToTop( existingItem->uuid() );
} else {
forceInsert( item );
}
emit topChanged();
}
void History::forceInsert( HistoryItem* item ) {
if ( !item )
return;
if (m_items.find(item->uuid()) != m_items.end()) {
return; // Don't insert duplicates
}
m_nextCycle = m_top;
item->insertBetweeen(m_top ? m_items[m_top->previous_uuid()] : 0L, m_top);
m_items.insert( item->uuid(), item );
m_top = item;
emit changed();
trim();
}
void History::trim() {
int i = m_items.count() - maxSize();
if ( i <= 0 || !m_top )
return;
items_t::iterator bottom = m_items.find(m_top->previous_uuid());
while ( i-- ) {
items_t::iterator it = bottom;
bottom = m_items.find((*bottom)->previous_uuid());
// FIXME: managing memory manually is tedious; use smart pointer instead
delete *it;
m_items.erase(it);
}
(*bottom)->chain(m_top);
if (m_items.size()<=1) {
m_nextCycle = 0L;
}
emit changed();
}
void History::remove( const HistoryItem* newItem ) {
if ( !newItem )
return;
items_t::iterator it = m_items.find(newItem->uuid());
if (it == m_items.end()) {
return;
}
if (*it == m_top) {
m_top = m_items[m_top->next_uuid()];
}
m_items[(*it)->previous_uuid()]->chain(m_items[(*it)->next_uuid()]);
m_items.erase(it);
}
void History::slotClear() {
// FIXME: managing memory manually is tedious; use smart pointer instead
qDeleteAll(m_items);
m_items.clear();
m_top = 0L;
emit changed();
}
void History::slotMoveToTop(QAction* action) {
QByteArray uuid = action->data().toByteArray();
if (uuid.isNull()) // not an action from popupproxy
return;
slotMoveToTop(uuid);
}
void History::slotMoveToTop(const QByteArray& uuid) {
items_t::iterator it = m_items.find(uuid);
if (it == m_items.end()) {
return;
}
if (*it == m_top) {
emit topChanged();
return;
}
m_topIsUserSelected = true;
m_nextCycle = m_top;
m_items[(*it)->previous_uuid()]->chain(m_items[(*it)->next_uuid()]);
(*it)->insertBetweeen(m_items[m_top->previous_uuid()], m_top);
m_top = *it;
emit changed();
emit topChanged();
}
void History::setMaxSize( unsigned max_size ) {
m_maxSize = max_size;
trim();
}
KlipperPopup* History::popup() {
return m_popup;
}
void History::cycleNext() {
if (m_top && m_nextCycle && m_nextCycle != m_top) {
HistoryItem* prev = m_items[m_nextCycle->previous_uuid()];
HistoryItem* next = m_items[m_nextCycle->next_uuid()];
//if we have only two items in clipboard
if (prev == next) {
m_top=m_nextCycle;
}
else {
HistoryItem* endofhist = m_items[m_top->previous_uuid()];
HistoryItem* aftertop = m_items[m_top->next_uuid()];
if (prev == m_top) {
prev = m_nextCycle;
aftertop = m_top;
}
else if (next == m_top) {
next = m_nextCycle;
endofhist = m_top;
}
m_top->insertBetweeen(prev, next);
m_nextCycle->insertBetweeen(endofhist, aftertop);
m_top = m_nextCycle;
m_nextCycle = next;
}
emit changed();
emit topChanged();
}
}
void History::cyclePrev() {
if (m_top && m_nextCycle) {
HistoryItem* prev = m_items[m_nextCycle->previous_uuid()];
if (prev == m_top) {
return;
}
HistoryItem* prevprev = m_items[prev->previous_uuid()];
HistoryItem* aftertop = m_items[m_top->next_uuid()];
//if we have only two items in clipboard
if (m_nextCycle == prevprev) {
m_top=aftertop;
}
else {
HistoryItem* endofhist = m_items[m_top->previous_uuid()];
if (prevprev == m_top) {
prevprev = prev;
aftertop = m_top;
}
else if (m_nextCycle == m_top) {
m_nextCycle = aftertop;
endofhist = m_top;
}
m_top->insertBetweeen(prevprev,m_nextCycle);
prev->insertBetweeen(endofhist, aftertop);
m_nextCycle = m_top;
m_top = prev;
}
emit changed();
emit topChanged();
}
}
const HistoryItem* History::nextInCycle() const
{
return m_nextCycle != m_top ? m_nextCycle : 0L; // pointing to top=no more items
}
const HistoryItem* History::prevInCycle() const
{
if (m_nextCycle) {
const HistoryItem* prev = m_items[m_nextCycle->previous_uuid()];
if (prev != m_top) {
return prev;
}
}
return 0L;
}
const HistoryItem* History::find(const QByteArray& uuid) const
{
items_t::const_iterator it = m_items.find(uuid);
return (it == m_items.end()) ? 0L : *it;
}
#include "moc_history.cpp"

View file

@ -1,185 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2004 Esben Mose Hansen <kde@mosehansen.dk>
Copyright (C) Andrew Stanley-Jones <asj@cban.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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef HISTORY_H
#define HISTORY_H
#include <QtCore/QObject>
#include <QtCore/QHash>
#include <QtCore/QByteArray>
#include "historyitem.h"
#include <QAction>
class KlipperPopup;
class History : public QObject
{
Q_OBJECT
public:
History( QObject* parent );
~History();
/**
* Return (toplevel) popup menu (or default view, of you like)
*/
KlipperPopup* popup();
/**
* Inserts item into clipboard history top
* if duplicate entry exist, the older duplicate is deleted.
* The duplicate concept is "deep", so that two text string
* are considerd duplicate if identical.
*/
void insert( HistoryItem* item );
/**
* Inserts item into clipboard without any checks
* Used when restoring a saved history and internally.
* Don't use this unless you're reasonable certain
* that no duplicates are introduced
*/
void forceInsert( HistoryItem* item );
/**
* Remove (first) history item equal to item from history
*/
void remove( const HistoryItem* item );
/**
* Traversal: Get first item
*/
const HistoryItem* first() const;
/**
* Get item identified by uuid
*/
const HistoryItem* find(const QByteArray& uuid) const;
/**
* @return next item in cycle, or null if at end
*/
const HistoryItem* nextInCycle() const;
/**
* @return previous item in cycle, or null if at top
*/
const HistoryItem* prevInCycle() const;
/**
* True if no history items
*/
bool empty() const { return m_items.isEmpty(); }
/**
* Set maximum history size
*/
void setMaxSize( unsigned max_size );
/**
* Get the maximum history size
*/
unsigned maxSize() const { return m_maxSize; }
/**
* returns true if the user has selected the top item
*/
bool topIsUserSelected() {
return m_topIsUserSelected;
}
/**
* Cycle to next item
*/
void cycleNext();
/**
* Cycle to prev item
*/
void cyclePrev();
public Q_SLOTS:
/**
* move the history in position pos to top
*/
void slotMoveToTop(QAction* action);
/**
* move the history in position pos to top
*/
void slotMoveToTop(const QByteArray& uuid);
/**
* Clear history
*/
void slotClear();
Q_SIGNALS:
void changed();
/**
* Emitted when the first history item has changed.
*/
void topChanged();
private:
/**
* ensure that the number of items does not exceed max_size()
* Deletes items from the end as necessary.
*/
void trim();
private:
typedef QHash<QByteArray, HistoryItem*> items_t;
/**
* The history
*/
items_t m_items;
/**
* First item
*/
HistoryItem* m_top;
/**
* "Default view" --- a popupmenu containing the clipboard history.
*/
KlipperPopup* m_popup;
/**
* The number of clipboard items stored.
*/
unsigned m_maxSize;
/**
* True if the top is selected by the user
*/
bool m_topIsUserSelected;
/**
* The "next" when cycling through the
* history. May be 0, if history is empty
*/
HistoryItem* m_nextCycle;
};
inline const HistoryItem* History::first() const { return m_top; }
#endif

View file

@ -1,66 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2004 Esben Mose Hansen <kde@mosehansen.dk>
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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "klipper.h"
#include "historyimageitem.h"
#include <QtCore/QMimeData>
#include <QCryptographicHash>
#include <KDebug>
namespace {
QByteArray compute_uuid(const QPixmap& data) {
QByteArray buffer;
QDataStream out(&buffer, QIODevice::WriteOnly);
out << data;
return QCryptographicHash::hash(buffer, KlipperHashAlgorithm);
}
}
HistoryImageItem::HistoryImageItem( const QPixmap& data )
: HistoryItem(compute_uuid(data))
, m_data( data )
{
}
QString HistoryImageItem::text() const {
if ( m_text.isNull() ) {
m_text = QString( "%1x%2x%3 %4" )
.arg( m_data.width() )
.arg( m_data.height() )
.arg( m_data.depth() );
}
return m_text;
}
/* virtual */
void HistoryImageItem::write( QDataStream& stream ) const {
stream << QString( "image" ) << m_data;
}
QMimeData* HistoryImageItem::mimeData() const
{
QMimeData *data = new QMimeData();
data->setImageData(m_data.toImage());
return data;
}

View file

@ -1,58 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2004 Esben Mose Hansen <kde@mosehansen.dk>
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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef HISTORYIMAGEITEM_H
#define HISTORYIMAGEITEM_H
#include "historyitem.h"
/**
* A image entry in the clipboard history.
*/
class HistoryImageItem : public HistoryItem
{
public:
HistoryImageItem( const QPixmap& data );
virtual ~HistoryImageItem() {}
virtual QString text() const;
virtual bool operator==( const HistoryItem& rhs) const {
if ( const HistoryImageItem* casted_rhs = dynamic_cast<const HistoryImageItem*>( &rhs ) ) {
return &casted_rhs->m_data == &m_data; // Not perfect, but better than nothing.
}
return false;
}
virtual const QPixmap& image() const { return m_data; }
virtual QMimeData* mimeData() const;
virtual void write( QDataStream& stream ) const;
private:
/**
*
*/
const QPixmap m_data;
/**
* Cache for m_data's string representation
*/
mutable QString m_text;
};
#endif

View file

@ -1,123 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2004 Esben Mose Hansen <kde@mosehansen.dk>
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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "historyitem.h"
#include <QtCore/QMap>
#include <QtGui/QPixmap>
#include <KDebug>
#include "historystringitem.h"
#include "historyimageitem.h"
#include "historyurlitem.h"
HistoryItem::HistoryItem(const QByteArray &uuid)
: m_uuid(uuid)
{
}
HistoryItem::~HistoryItem()
{
}
HistoryItem* HistoryItem::create(const QMimeData *data)
{
#if 0
int i=0;
foreach ( QString format, data->formats() ) {
kDebug() << "format(" << i++ <<"): " << format;
}
#endif
if (KUrl::List::canDecode(data))
{
KUrl::List urls = KUrl::List::fromMimeData(data);
QByteArray bytes = data->data("application/x-kde-cutselection");
bool cut = !bytes.isEmpty() && (bytes.at(0) == '1'); // true if 1
return new HistoryURLItem(urls, cut);
}
if (data->hasText())
{
return new HistoryStringItem(data->text());
}
if (data->hasImage())
{
QImage image = qvariant_cast<QImage>(data->imageData());
return new HistoryImageItem(QPixmap::fromImage(image));
}
return 0; // Failed.
}
HistoryItem* HistoryItem::create(QDataStream &dataStream)
{
if ( dataStream.atEnd() ) {
return 0;
}
QString type;
dataStream >> type;
if ( type == "url" ) {
KUrl::List urls;
int cut = 0;
dataStream >> urls;
dataStream >> cut;
return new HistoryURLItem( urls, cut );
}
if ( type == "string" ) {
QString text;
dataStream >> text;
return new HistoryStringItem( text );
}
if ( type == "image" ) {
QPixmap image;
dataStream >> image;
return new HistoryImageItem( image );
}
kWarning() << "Failed to restore history item: Unknown type \"" << type << "\"" ;
return 0;
}
void HistoryItem::chain(HistoryItem* next)
{
m_next_uuid = next->uuid();
next->m_previous_uuid = uuid();
}
void HistoryItem::insertBetweeen(HistoryItem* prev, HistoryItem* next)
{
if (prev && next) {
prev->chain(this);
chain(next);
} else {
Q_ASSERT(!prev && !next);
// First item in chain
m_next_uuid = m_uuid;
m_previous_uuid = m_uuid;
}
#if 0 // Extra checks, if anyone ever needs them
Q_ASSERT(prev->uuid() == m_previous_uuid);
Q_ASSERT(prev->next_uuid() == m_uuid);
Q_ASSERT(next->previous_uuid() == m_uuid);
Q_ASSERT(next->uuid() == m_next_uuid);
Q_ASSERT(prev->uuid() != uuid());
Q_ASSERT(next->uuid() != uuid());
#endif
}

View file

@ -1,130 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2004 Esben Mose Hansen <kde@mosehansen.dk>
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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef HISTORYITEM_H
#define HISTORYITEM_H
#include <QtGui/QPixmap>
#include <QString>
#include <QMimeData>
#include <QDataStream>
/**
* An entry in the clipboard history.
*/
class HistoryItem
{
public:
HistoryItem(const QByteArray& uuid);
virtual ~HistoryItem();
/**
* Return the current item as text
* An image would be returned as a descriptive
* text, such as 32x43 image.
*/
virtual QString text() const = 0;
/**
* @return uuid of current item.
*/
const QByteArray& uuid() const {
return m_uuid;
}
/**
* Return the current item as pixmap
* A text would be returned as a null pixmap,
* which is also the default implementation
*/
inline virtual const QPixmap& image() const;
/**
* Returns a pointer to a QMimeData suitable for QClipboard::setMimeData().
*/
virtual QMimeData* mimeData() const = 0;
/**
* Write object on datastream
*/
virtual void write( QDataStream& stream ) const = 0;
/**
* Equality.
*/
virtual bool operator==(const HistoryItem& rhs) const = 0;
/**
* Create an HistoryItem from MimeSources (i.e., clipboard data)
* returns null if create fails (e.g, unsupported mimetype)
*/
static HistoryItem* create( const QMimeData* data );
/**
* Create an HistoryItem from data stream (i.e., disk file)
* returns null if creation fails. In this case, the datastream
* is left in an undefined state.
*/
static HistoryItem* create( QDataStream& dataStream );
/**
* Inserts this item between prev and next
*/
void insertBetweeen(HistoryItem* prev, HistoryItem* next);
/**
* Chain this with next
*/
void chain(HistoryItem* next);
/**
* previous item's uuid
*/
const QByteArray& previous_uuid() const {
return m_previous_uuid;
}
/**
* next item's uuid
*/
const QByteArray& next_uuid() const {
return m_next_uuid;
}
private:
QByteArray m_previous_uuid;
QByteArray m_uuid;
QByteArray m_next_uuid;
};
inline
const QPixmap& HistoryItem::image() const {
static QPixmap nullPixmap;
return nullPixmap;
}
inline
QDataStream& operator<<( QDataStream& lhs, HistoryItem const * const rhs ) {
if ( rhs ) {
rhs->write( lhs );
}
return lhs;
}
#endif

View file

@ -1,43 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2004 Esben Mose Hansen <kde@mosehansen.dk>
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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "klipper.h"
#include "historystringitem.h"
#include <QCryptographicHash>
HistoryStringItem::HistoryStringItem( const QString& data )
: HistoryItem(QCryptographicHash::hash(data.toUtf8(), KlipperHashAlgorithm))
, m_data( data )
{
}
/* virtual */
void HistoryStringItem::write( QDataStream& stream ) const {
stream << QString( "string" ) << m_data;
}
QMimeData* HistoryStringItem::mimeData() const
{
QMimeData *data = new QMimeData();
data->setText(m_data);
return data;
}

View file

@ -1,54 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2004 Esben Mose Hansen <kde@mosehansen.dk>
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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef HISTORYSTRINGITEM_H
#define HISTORYSTRINGITEM_H
#include <QtCore/QMimeData>
#include "historyitem.h"
/**
* A string entry in the clipboard history.
*/
class HistoryStringItem : public HistoryItem
{
public:
HistoryStringItem( const QString& data );
virtual ~HistoryStringItem() {}
virtual QString text() const;
virtual bool operator==( const HistoryItem& rhs) const {
if ( const HistoryStringItem* casted_rhs = dynamic_cast<const HistoryStringItem*>( &rhs ) ) {
return casted_rhs->m_data == m_data;
}
return false;
}
virtual QMimeData* mimeData() const;
/**
* Write object on datastream
*/
virtual void write( QDataStream& stream ) const;
private:
QString m_data;
};
inline QString HistoryStringItem::text() const { return m_data; }
#endif

View file

@ -1,67 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2004 Esben Mose Hansen <kde@mosehansen.dk>
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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "klipper.h"
#include "historyurlitem.h"
#include <QtCore/QMimeData>
#include <QCryptographicHash>
namespace {
QByteArray compute_uuid(const KUrl::List& _urls, bool _cut ) {
QCryptographicHash hash(KlipperHashAlgorithm);
foreach(const KUrl& url, _urls) {
hash.addData(url.toEncoded());
hash.addData("\0", 1); // Use binary zero as that is not a valid path character
}
return hash.result();
}
}
HistoryURLItem::HistoryURLItem( const KUrl::List& _urls, bool _cut )
: HistoryItem(compute_uuid(_urls, _cut))
, m_urls( _urls )
, m_cut( _cut )
{
}
/* virtual */
void HistoryURLItem::write( QDataStream& stream ) const
{
stream << QString( "url" ) << m_urls << (int)m_cut;
}
QString HistoryURLItem::text() const {
return m_urls.toStringList().join( " " );
}
QMimeData* HistoryURLItem::mimeData() const {
QMimeData *data = new QMimeData();
m_urls.populateMimeData(data);
data->setData("application/x-kde-cutselection", QByteArray(m_cut ? "1" : "0"));
return data;
}
bool HistoryURLItem::operator==( const HistoryItem& rhs) const
{
if ( const HistoryURLItem* casted_rhs = dynamic_cast<const HistoryURLItem*>( &rhs ) ) {
return casted_rhs->m_urls == m_urls && casted_rhs->m_cut == m_cut;
}
return false;
}

View file

@ -1,46 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2004 Esben Mose Hansen <kde@mosehansen.dk>
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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef HISTORYURLITEM_H
#define HISTORYURLITEM_H
#include <KUrl>
#include "historyitem.h"
/**
* An URL entry in the clipboard history.
*/
class HistoryURLItem : public HistoryItem
{
public:
HistoryURLItem( const KUrl::List& urls, bool cut );
virtual QString text() const;
virtual bool operator==( const HistoryItem& rhs) const;
virtual QMimeData* mimeData() const;
/**
* Write object on datastream
*/
virtual void write( QDataStream& stream ) const;
private:
KUrl::List m_urls;
bool m_cut;
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,269 +0,0 @@
[Desktop Entry]
Name=Klipper
Name[af]=Klipper
Name[ar]=Klipper
Name[ast]=Klipper
Name[be]=Klipper
Name[be@latin]=Klipper
Name[bg]=Klipper
Name[bn]=ি
Name[bn_IN]=Klipper
Name[br]=Klipper
Name[bs]=Kliper
Name[ca]=Klipper
Name[ca@valencia]=Klipper
Name[cs]=Klipper
Name[csb]=Klipper
Name[cy]=Klipper
Name[da]=Klipper
Name[de]=Klipper
Name[el]=Klipper
Name[en_GB]=Klipper
Name[eo]=Poŝilo
Name[es]=Klipper
Name[et]=Klipper
Name[eu]=Klipper
Name[fa]=Klipper
Name[fi]=Klipper
Name[fr]=Klipper
Name[fy]=Klipper
Name[ga]=Klipper
Name[gl]=Klipper
Name[gu]=િ
Name[he]=Klipper
Name[hi]=ि
Name[hne]=ि
Name[hr]=Klipper
Name[hsb]=Klipper
Name[hu]=Klipper
Name[ia]=Klipper
Name[id]=Klipper
Name[is]=Klipper
Name[it]=Klipper
Name[ja]=Klipper
Name[ka]=Klipper
Name[kk]=Алмасу буфері
Name[km]=Klipper
Name[kn]=ಿ
Name[ko]=Klipper
Name[ku]=Klipper
Name[lt]=Klipper
Name[lv]=Klipper
Name[mai]=ि
Name[mk]=Клипер
Name[ml]=ി
Name[mr]=ि
Name[ms]=Klipper
Name[nb]=Klipper
Name[nds]=Klipper
Name[ne]=ि
Name[nl]=Klipper
Name[nn]=Klipper
Name[pa]=ਿ
Name[pl]=Klipper
Name[pt]=Klipper
Name[pt_BR]=Klipper
Name[ro]=Klipper
Name[ru]=Klipper
Name[se]=Klipper
Name[si]=Klipper
Name[sk]=Klipper
Name[sl]=Klipper
Name[sr]=Клипер
Name[sr@ijekavian]=Клипер
Name[sr@ijekavianlatin]=Klipper
Name[sr@latin]=Klipper
Name[sv]=Klipper
Name[ta]=ி
Name[te]=ి
Name[tg]=Клиппер
Name[th]=
Name[tr]=Klipper
Name[ug]=Klipper
Name[uk]=Klipper
Name[uz]=Klipper
Name[uz@cyrillic]=Klipper
Name[vi]=Klipper
Name[wa]=Klipper
Name[xh]=Klipper
Name[x-test]=xxKlipperxx
Name[zh_CN]=Klipper
Name[zh_TW]=(Klipper)
GenericName=Clipboard Tool
GenericName[af]=Klipbord Program
GenericName[ar]=أداة الحافظة
GenericName[ast]=Cartafueyu
GenericName[be]=Буфер абмену
GenericName[be@latin]=Pryłada, jakaja absłuhoŭvaje abmienny bufer
GenericName[bg]=Системен буфер
GenericName[bn]=ি
GenericName[br]=Ostilh ar golver
GenericName[bs]=Alatka za klipbord
GenericName[ca]=Eina de porta-retalls
GenericName[ca@valencia]=Eina de porta-retalls
GenericName[cs]=Program pro práci se schránkou
GenericName[csb]=Nôrzãdze tacnika
GenericName[cy]=Offeryn Gludfwrdd
GenericName[da]=Udklipsholderværktøj
GenericName[de]=Verwaltung der Zwischenablage
GenericName[el]=Εργαλείο πρόχειρου
GenericName[en_GB]=Clipboard Tool
GenericName[eo]=Ilo por la poŝo
GenericName[es]=Portapapeles
GenericName[et]=Lõikepuhvri haldamine
GenericName[eu]=Arbeleko tresna
GenericName[fa]=ابزار تختهیادداشت
GenericName[fi]=Leikepöytätyökalu
GenericName[fr]=Presse-papier
GenericName[fy]=Klamboerdbehear
GenericName[ga]=Uirlis Ghearrthaisce
GenericName[gl]=Utilidade de portarretallos
GenericName[gu]=િ
GenericName[he]=כלי לוח גזירה
GenericName[hi]=ि
GenericName[hne]=ि
GenericName[hr]=Alat međuspremnika
GenericName[hsb]=Zapisnik
GenericName[hu]=Vágólapkezelő
GenericName[ia]=Instrumento de Area de transferentia
GenericName[id]=Alat Papan Klip
GenericName[is]=Klippispjaldstól
GenericName[it]=Strumento per gli appunti
GenericName[ja]=
GenericName[ka]=
GenericName[kk]=Алмасу буфер құралы
GenericName[km]=
GenericName[kn]=ಿಿ (ಿ )
GenericName[ko]=
GenericName[lt]=Laikinos talpyklės priemonė
GenericName[lv]=Starpliktuves rīks
GenericName[mai]=ि
GenericName[mk]=Алатка за табла со исечоци
GenericName[ml]=ി
GenericName[mr]=ि
GenericName[ms]=Alat Klipbod
GenericName[nb]=Utklippstavle
GenericName[nds]=Twischenaflaag-Warktüüch
GenericName[ne]=ि
GenericName[nl]=Klembordbeheer
GenericName[nn]=Utklippstavle
GenericName[pa]=ਿ
GenericName[pl]=Narzędzie schowka
GenericName[pt]=Ferramenta da Área de Transferência
GenericName[pt_BR]=Ferramenta da área de transferência
GenericName[ro]=Utilitar de clipboard
GenericName[ru]=Монитор буфера обмена
GenericName[se]=Čuohpusgirjereaidu
GenericName[si]=
GenericName[sk]=Nástroj pre schránku
GenericName[sl]=Orodje za odložišče
GenericName[sr]=Алатка за клипборд
GenericName[sr@ijekavian]=Алатка за клипборд
GenericName[sr@ijekavianlatin]=Alatka za klipbord
GenericName[sr@latin]=Alatka za klipbord
GenericName[sv]=Klippbordsverktyg
GenericName[ta]=ி ி
GenericName[te]=ి ి
GenericName[tg]=Утилита для буфера обмена
GenericName[th]=
GenericName[tr]=Pano Aracı
GenericName[ug]=چاپلاش تاختىسى قورالى
GenericName[uk]=Утиліта буфера даних
GenericName[uz]=Klipbord vositasi
GenericName[uz@cyrillic]=Клипборд воситаси
GenericName[vi]=Công c bng nh tm
GenericName[wa]=Usteye presse-papî
GenericName[xh]=Isixhobo Sebhodi eqhoboshayo
GenericName[x-test]=xxClipboard Toolxx
GenericName[zh_CN]=
GenericName[zh_TW]=簿
Exec=klipper --icon '%i' --caption '%c'
Icon=klipper
Type=Application
X-DocPath=klipper/index.html
Terminal=false
StartupNotify=false
X-KDE-autostart-condition=klipperrc:General:AutoStart:true
OnlyShowIn=KDE;
Categories=Qt;KDE;Utility;X-KDE-Utilities-Desktop;
Comment=A cut & paste history utility
Comment[af]='n Knip & plak geskiedenis program
Comment[ar]=أداة تاريخ القص واللصق
Comment[ast]=Una utilidá de cortar y apegar historial
Comment[be]=Службовая праграма працы з гісторыяй выразання/устаўкі
Comment[be@latin]=Pryłada dla prahladu historyi aperacyjaŭ vycinańnia dy ŭklejvańnia
Comment[bg]=Инструмент за управление на операциите по копиране и поставяне
Comment[bs]=Alatka za istorijat isecanja i naljepljivanja
Comment[ca]=Una utilitat de la història de tallar i enganxar
Comment[ca@valencia]=Una utilitat de la història de tallar i apegar
Comment[cs]=Nástroj pro historii práce se schránkou
Comment[csb]=Nôrzãdze trzëmôjące historëjã tacnika
Comment[da]=Et værktøj med historik til at klippe ud og indsætte
Comment[de]=Programm zur Verwaltung der Zwischenablage
Comment[el]=Ένα εργαλείο ιστορικού αποκοπής & επικόλλησης
Comment[en_GB]=A cut & paste history utility
Comment[eo]=Ilo por la eltonda kaj alglua historio
Comment[es]=Una utilidad de cortar y pegar historial
Comment[et]=Lõikamiste ja asetamiste ajaloo rakendus
Comment[eu]=Ebaki/Itsatsi historiaren tresna bat
Comment[fa]=برنامه سودمند تاریخچه برش و چسباندن
Comment[fi]=Työkalu leikkaamiseen ja liittämiseen
Comment[fr]=Un outil d'historique de copier / coller
Comment[fy]=Klamboerdhistoarje
Comment[ga]=Uirlis staire gearrtha agus greamaithe
Comment[gl]=Un historial de cortar e apegar
Comment[gu]=િ
Comment[he]=כלי המשמש לשמירת היסטוריה אודות גזירה והדבקה
Comment[hi]= ि ि िि
Comment[hne]= ि ि िि
Comment[hr]=Alat za izrezivanje i preljepljivanje iz povijesti
Comment[hsb]=Nastroj za wutřihanje a zasunjenje z prjedawšich přikazow
Comment[hu]=Kezelőprogram a vágólaphoz (naplózással)
Comment[ia]=Un utilitate per historia de talia & colla
Comment[id]=Sebuah utilitas riwayat potong & tempel
Comment[is]=Klipp & lím sögutól
Comment[it]=Un programma per la cronologia del copia e incolla
Comment[ja]=
Comment[kk]=Қиып алу және орналастыру журналы
Comment[km]=
Comment[kn]=ಿ ಿ ಿ
Comment[ko]=
Comment[lt]=Iškirpti ir padėti istorijos pagalbinė programa
Comment[lv]=Izgriešanas un ielīmēšanas vēstures rīks
Comment[mai]= ि िि
Comment[mk]=Алатка за историјат на сечење и вметнување
Comment[ml]=ി- ിിി.
Comment[mr]= ि ि
Comment[nb]=Et verktøy som viser tidligere utklipp
Comment[nds]=Vörgeschicht vun't Knippen un Infögen
Comment[ne]= ि ि
Comment[nl]=Klembordgeschiedenis
Comment[nn]=Eit verktøy som viser eldre utklipp
Comment[pa]=
Comment[pl]=Narzędzie przechowujące historię schowka
Comment[pt]=Um utilitário de histórico de cópias e colagens
Comment[pt_BR]=Um utilitário com o histórico de recortar e colar
Comment[ro]=Utilitar cu istoria de tăiere și adăugare
Comment[ru]=История буфера обмена
Comment[se]=Reaidu mii čájeha boares čuohppusiid
Comment[si]=
Comment[sk]=Nástroj pre históriu akcií "Vystrihnúť a vložiť"
Comment[sl]=Pripomoček z zgodovino za izreži in prilepi
Comment[sr]=Алатка за историјат исецања и налепљивања
Comment[sr@ijekavian]=Алатка за историјат исецања и налепљивања
Comment[sr@ijekavianlatin]=Alatka za istorijat isecanja i nalepljivanja
Comment[sr@latin]=Alatka za istorijat isecanja i nalepljivanja
Comment[sv]=Ett verktyg med historik för klipp ut och klistra in
Comment[ta]=A cut & paste history utility
Comment[te]=ిి & ిి ి
Comment[tg]=История буфера обмена
Comment[th]=
Comment[tr]=Bir kes & yapıştır geçmişi aracı
Comment[ug]=كەس ۋە چاپلا تارىخىنى باشقۇرۇش قورالى
Comment[uk]=Утиліта журналу буфера даних
Comment[vi]=Công c cha lch s các ct dán
Comment[wa]=Ene ahesse d' istwere di coper/aclacper
Comment[x-test]=xxA cut & paste history utilityxx
Comment[zh_CN]=
Comment[zh_TW]=

View file

@ -1,209 +0,0 @@
/* This file is part of the KDE project
Copyright (C) by Andrew Stanley-Jones <asj@cban.com>
Copyright (C) 2004 Esben Mose Hansen <kde@mosehansen.dk>
Copyright (C) 2008 by Dmitry Suzdalev <dimsuz@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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KLIPPER_H
#define KLIPPER_H
#include <QTime>
#include <QAction>
#include <QMenu>
#include <QMimeData>
#include <QElapsedTimer>
#include <QTimer>
#include <QClipboard>
#include <QCryptographicHash>
#include <KGlobal>
#include "urlgrabber.h"
static const QCryptographicHash::Algorithm KlipperHashAlgorithm = QCryptographicHash::KAT;
class KAction;
class KToggleAction;
class KAboutData;
class KActionCollection;
class URLGrabber;
class History;
class HistoryItem;
class KlipperSessionManager;
class Klipper : public QObject
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.klipper.klipper")
public Q_SLOTS:
Q_SCRIPTABLE QString getClipboardContents();
Q_SCRIPTABLE void setClipboardContents(QString s);
Q_SCRIPTABLE void clearClipboardContents();
Q_SCRIPTABLE void clearClipboardHistory();
Q_SCRIPTABLE void saveClipboardHistory();
Q_SCRIPTABLE QStringList getClipboardHistoryMenu();
Q_SCRIPTABLE QString getClipboardHistoryItem(int i);
Q_SCRIPTABLE void showKlipperPopupMenu();
Q_SCRIPTABLE void showKlipperManuallyInvokeActionMenu();
public:
Klipper(QObject* parent, const KSharedConfigPtr& config);
~Klipper();
/**
* Get clipboard history (the "document")
*/
History* history() { return m_history; }
URLGrabber* urlGrabber() const { return m_myURLGrabber; }
static void createAboutData();
static void destroyAboutData();
static KAboutData* aboutData();
void saveSettings() const;
public Q_SLOTS:
void saveSession();
void slotHistoryTopChanged();
void slotConfigure();
void slotEditData();
void slotShowBarcode();
void slotCycleNext();
void slotCyclePrev();
protected:
/**
* The selection modes
*
* Don't use 1, as I use that as a guard against passing
* a boolean true as a mode.
*/
enum SelectionMode { Clipboard = 2, Selection = 4 };
/**
* Loads history from disk.
*/
bool loadHistory();
/**
* Save history to disk
* @empty save empty history instead of actual history
*/
void saveHistory(bool empty = false);
/**
* Check data in clipboard, and if it passes these checks,
* store the data in the clipboard history.
*/
void checkClipData( bool selectionMode );
/**
* Enter clipboard data in the history.
*/
HistoryItem* applyClipChanges( const QMimeData* data );
void setClipboard( const HistoryItem& item, int mode );
bool ignoreClipboardChanges() const;
KSharedConfigPtr config() const { return m_config; }
bool isApplet() const { return m_config != KGlobal::config(); }
Q_SIGNALS:
void passivePopup(const QString& caption, const QString& text);
public Q_SLOTS:
void slotPopupMenu();
void slotAskClearHistory();
protected Q_SLOTS:
void showPopupMenu( QMenu * );
void slotRepeatAction();
void setURLGrabberEnabled( bool );
void disableURLGrabber();
private Q_SLOTS:
void newClipData( QClipboard::Mode );
void slotClearClipboard();
void slotQuit();
void slotStartShowTimer();
void slotClearOverflow();
void slotCheckPending();
void slotSaveBarcode();
void loadSettings();
private:
static void updateTimestamp();
QClipboard* m_clip;
QElapsedTimer m_showTimer;
History* m_history;
int m_overflowCounter;
KToggleAction* m_toggleURLGrabAction;
KAction* m_clearHistoryAction;
KAction* m_repeatAction;
KAction* m_editAction;
KAction* m_showBarcodeAction;
KAction* m_configureAction;
KAction* m_quitAction;
KAction* m_cycleNextAction;
KAction* m_cyclePrevAction;
KAction* m_showOnMousePos;
bool m_bKeepContents :1;
bool m_bURLGrabber :1;
bool m_bReplayActionInHistory :1;
bool m_bNoNullClipboard :1;
bool m_bIgnoreSelection :1;
bool m_bSynchronize :1;
bool m_bSelectionTextOnly :1;
bool m_bIgnoreImages :1;
/**
* Avoid reacting to our own changes, using this
* lock.
* Don't manupulate this object directly... use the Ignore struct
* instead
*/
int m_locklevel;
URLGrabber* m_myURLGrabber;
QString m_lastURLGrabberTextSelection;
QString m_lastURLGrabberTextClipboard;
KSharedConfigPtr m_config;
QTimer m_overflowClearTimer;
QTimer m_pendingCheckTimer;
bool m_pendingContentsCheck;
QString m_qrencodeexe;
QPixmap m_qrpixmap;
static KAboutData* m_about_data;
bool blockFetchingNewData();
QString cycleText() const;
KlipperSessionManager* m_sessionManager;
KActionCollection* m_collection;
};
#endif

View file

@ -1,76 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
<kcfgfile name="klipperrc"/>
<group name="General">
<entry name="Version" type="String">
<label>Klipper version</label>
</entry>
<entry name="KeepClipboardContents" type="Bool">
<label>Keep clipboard contents</label>
<default>true</default>
</entry>
<entry name="PreventEmptyClipboard" type="Bool">
<label>Prevent empty clipboard</label>
<default>true</default>
<whatsthis>Selecting this option has the effect, that the clipboard can never be emptied. E.g. when an application exits, the clipboard would usually be emptied.</whatsthis>
</entry>
<entry name="IgnoreImages" type="Bool">
<label>Ignore images</label>
<default>true</default>
</entry>
<entry name="IgnoreSelection" type="Bool">
<label>Ignore Selection</label>
<default>false</default>
<whatsthis><qt>When an area of the screen is selected with mouse or keyboard, this is called "the selection".&lt;br/&gt;If this option is set, the selection is not entered into the clipboard history, though it is still available for pasting using the middle mouse button.</qt></whatsthis>
</entry>
<entry name="SyncClipboards" type="Bool">
<label>Synchronize clipboard and selection</label>
<default>false</default>
<whatsthis><qt>When an area of the screen is selected with mouse or keyboard, this is called "the selection".&lt;br/&gt;If this option is selected, the selection and the clipboard is kept the same, so that anything in the selection is immediately available for pasting elsewhere using any method, including the traditional middle mouse button. Otherwise, the selection is recorded in the clipboard history, but the selection can only be pasted using the middle mouse button. Also see the 'Ignore Selection' option.</qt></whatsthis>
</entry>
<entry name="SelectionTextOnly" type="Bool">
<label>Selection text only</label>
<default>true</default>
<whatsthis><qt>When an area of the screen is selected with mouse or keyboard, this is called "the selection".&lt;br/&gt;If this option is selected, only text selections are stored in the history, while images and other selections are not.</qt></whatsthis>
</entry>
<entry name="URLGrabberEnabled" type="Bool">
<label>URL grabber enabled</label>
<default>false</default>
</entry>
<entry name="NoActionsForWM_CLASS" type="StringList">
<default>Navigator,navigator:browser,konqueror,keditbookmarks,mozilla-bin,Mozilla,Opera main window,opera,gnumeric,Gnumeric,Galeon,kcontrol,ksirc,MozillaFirebird-bin,firefox-bin,Firefox-bin,klipper,Gecko,gecko</default>
<label>No actions for WM_CLASS</label>
</entry>
<entry name="TimeoutForActionPopups" type="Int">
<label>Timeout for action popups (seconds)</label>
<default>8</default>
<min>0</min>
<max>200</max>
<tooltip>A value of 0 disables the timeout</tooltip>
</entry>
<entry name="MaxClipItems" type="Int">
<label>Clipboard history size</label>
<default>7</default>
<min>1</min>
<max>2048</max>
</entry>
</group>
<group name="Actions">
<entry name="StripWhiteSpace" type="Bool">
<label>Strip whitespace when executing an action</label>
<default>true</default>
<whatsthis>Sometimes, the selected text has some whitespace at the end, which, if loaded as URL in a browser would cause an error. Enabling this option removes any whitespace at the beginning or end of the selected string (the original clipboard contents will not be modified).</whatsthis>
</entry>
<entry name="ReplayActionInHistory" type="Bool">
<label>Replay action in history</label>
<default>false</default>
</entry>
<entry name="EnableMagicMimeActions" type="Bool">
<label>Enable MIME-based actions</label>
<default>true</default>
</entry>
</group>
</kcfg>

View file

@ -1,300 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2004 Esben Mose Hansen <kde@mosehansen.dk>
Copyright (C) by Andrew Stanley-Jones <asj@cban.com>
Copyright (C) 2000 by Carsten Pfeiffer <pfeiffer@kde.org>
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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "klipperpopup.h"
#include <QtGui/QApplication>
#include <QtGui/qevent.h>
#include <QtGui/QWidgetAction>
#include <QtGui/QDesktopWidget>
#include <KHelpMenu>
#include <KLineEdit>
#include <KLocale>
#include <KWindowSystem>
#include <KDebug>
#include <KIcon>
#include "history.h"
#include "klipper.h"
#include "popupproxy.h"
namespace {
static const int TOP_HISTORY_ITEM_INDEX = 2;
}
// #define DEBUG_EVENTS__
#ifdef DEBUG_EVENTS__
QDebug& operator<<( QDebug& stream, const QKeyEvent& e ) {
stream << "(QKeyEvent(text=" << e.text() << ",key=" << e.key() << ( e.isAccepted()?",accepted":",ignored)" ) << ",count=" << e.count();
if ( e.modifiers() & Qt::AltModifier ) {
stream << ",ALT";
}
if ( e.modifiers() & Qt::ControlModifier ) {
stream << ",CTRL";
}
if ( e.modifiers() & Qt::MetaModifier ) {
stream << ",META";
}
if ( e.modifiers() & Qt::ShiftModifier ) {
stream << ",SHIFT";
}
if ( e.isAutoRepeat() ) {
stream << ",AUTOREPEAT";
}
stream << ")";
return stream;
}
#endif
/**
* Exactly the same as KLineEdit, except that ALL key events are swallowed.
*
* We need this to avoid infinite loop when sending events to the search widget
*/
class KLineEditBlackKey : public KLineEdit {
public:
KLineEditBlackKey( QWidget* parent )
: KLineEdit( parent )
{}
~KLineEditBlackKey() {
}
protected:
virtual void keyPressEvent( QKeyEvent* e ) {
KLineEdit::keyPressEvent( e );
e->accept();
}
};
KlipperPopup::KlipperPopup( History* history )
: m_dirty( true ),
m_textForEmptyHistory( i18n( "<empty clipboard>" ) ),
m_textForNoMatch( i18n( "<no matches>" ) ),
m_history( history ),
m_helpMenu( new KHelpMenu( this, Klipper::aboutData(), false ) ),
m_popupProxy( 0 ),
m_filterWidget( 0 ),
m_filterWidgetAction( 0 ),
m_nHistoryItems( 0 )
{
KWindowInfo windowInfo = KWindowSystem::windowInfo( winId(), NET::WMGeometry );
QRect geometry = windowInfo.geometry();
QRect screen = QApplication::desktop()->screenGeometry(geometry.center());
int menuHeight = ( screen.height() ) * 3/4;
int menuWidth = ( screen.width() ) * 1/3;
m_popupProxy = new PopupProxy( this, menuHeight, menuWidth );
connect( this, SIGNAL(aboutToShow()), SLOT(slotAboutToShow()) );
}
KlipperPopup::~KlipperPopup() {
}
void KlipperPopup::slotAboutToShow() {
if ( m_filterWidget ) {
if ( !m_filterWidget->text().isEmpty() ) {
m_dirty = true;
m_filterWidget->clear();
m_filterWidget->setVisible(false);
m_filterWidgetAction->setVisible(false);
}
}
ensureClean();
}
void KlipperPopup::ensureClean() {
// If the history is unchanged since last menu build, the is no reason
// to rebuild it,
if ( m_dirty ) {
rebuild();
}
}
void KlipperPopup::buildFromScratch() {
addTitle(KIcon("klipper"), i18n("Klipper - Clipboard Tool"));
m_filterWidget = new KLineEditBlackKey(this);
m_filterWidget->setFocusPolicy( Qt::NoFocus );
m_filterWidgetAction = new QWidgetAction(this);
m_filterWidgetAction->setDefaultWidget(m_filterWidget);
m_filterWidgetAction->setVisible(false);
addAction(m_filterWidgetAction);
addSeparator();
for (int i = 0; i < m_actions.count(); i++) {
if (i + 1 == m_actions.count()) {
addMenu(m_helpMenu->menu())->setIcon(KIcon("help-contents"));
addSeparator();
}
addAction(m_actions.at(i));
}
if ( KGlobalSettings::insertTearOffHandle() ) {
setTearOffEnabled(true);
}
}
void KlipperPopup::rebuild( const QString& filter ) {
if (actions().isEmpty()) {
buildFromScratch();
} else {
for ( int i=0; i<m_nHistoryItems; i++ ) {
Q_ASSERT(TOP_HISTORY_ITEM_INDEX < actions().count());
removeAction(actions().at(TOP_HISTORY_ITEM_INDEX));
}
}
// We search case insensitive until one uppercased character appears in the search term
Qt::CaseSensitivity caseSens = (filter.toLower() == filter ? Qt::CaseInsensitive : Qt::CaseSensitive);
QRegExp filterexp( filter, caseSens );
QPalette palette = m_filterWidget->palette();
if ( filterexp.isValid() ) {
palette.setColor( m_filterWidget->foregroundRole(), palette.color(foregroundRole()) );
} else {
palette.setColor( m_filterWidget->foregroundRole(), Qt::red );
}
m_nHistoryItems = m_popupProxy->buildParent( TOP_HISTORY_ITEM_INDEX, filterexp );
if ( m_nHistoryItems == 0 ) {
if ( m_history->empty() ) {
insertAction(actions().at(TOP_HISTORY_ITEM_INDEX), new QAction(m_textForEmptyHistory, this));
} else {
palette.setColor( m_filterWidget->foregroundRole(), Qt::red );
insertAction(actions().at(TOP_HISTORY_ITEM_INDEX), new QAction(m_textForNoMatch, this));
}
m_nHistoryItems++;
} else {
if ( history()->topIsUserSelected() ) {
actions().at(TOP_HISTORY_ITEM_INDEX)->setCheckable(true);
actions().at(TOP_HISTORY_ITEM_INDEX)->setChecked(true);
}
}
m_filterWidget->setPalette( palette );
m_dirty = false;
}
void KlipperPopup::plugAction( QAction* action ) {
m_actions.append(action);
}
/* virtual */
void KlipperPopup::keyPressEvent( QKeyEvent* e ) {
// If alt-something is pressed, select a shortcut
// from the menu. Do this by sending a keyPress
// without the alt-modifier to the superobject.
if ( e->modifiers() & Qt::AltModifier ) {
QKeyEvent ke( QEvent::KeyPress,
e->key(),
e->modifiers() ^ Qt::AltModifier,
e->text(),
e->isAutoRepeat(),
e->count() );
KMenu::keyPressEvent( &ke );
#ifdef DEBUG_EVENTS__
kDebug() << "Passing this event to ancestor (KMenu): " << e << "->" << ke;
#endif
if (ke.isAccepted()) {
e->accept();
return;
} else {
e->ignore();
}
}
// Otherwise, send most events to the search
// widget, except a few used for navigation:
// These go to the superobject.
switch( e->key() ) {
case Qt::Key_Up:
case Qt::Key_Down:
case Qt::Key_Right:
case Qt::Key_Left:
case Qt::Key_Tab:
case Qt::Key_Backtab:
case Qt::Key_Escape:
{
#ifdef DEBUG_EVENTS__
kDebug() << "Passing this event to ancestor (KMenu): " << e;
#endif
KMenu::keyPressEvent(e);
break;
}
case Qt::Key_Return:
case Qt::Key_Enter:
{
KMenu::keyPressEvent(e);
this->hide();
if (activeAction() == m_filterWidgetAction)
setActiveAction(actions().at(TOP_HISTORY_ITEM_INDEX));
break;
}
default:
{
#ifdef DEBUG_EVENTS__
kDebug() << "Passing this event down to child (KLineEdit): " << e;
#endif
setActiveAction(actions().at(actions().indexOf(m_filterWidgetAction)));
QString lastString = m_filterWidget->text();
QApplication::sendEvent(m_filterWidget, e);
if (m_filterWidget->text().isEmpty()) {
if (m_filterWidgetAction->isVisible()) {
m_filterWidget->setVisible(false);
m_filterWidgetAction->setVisible(false);
}
}
else if (!m_filterWidgetAction->isVisible() )
m_filterWidgetAction->setVisible(true);
if (m_filterWidget->text() != lastString) {
m_dirty = true;
rebuild(m_filterWidget->text());
}
break;
} //default:
} //case
}
void KlipperPopup::slotSetTopActive()
{
if (actions().size() > TOP_HISTORY_ITEM_INDEX) {
setActiveAction(actions().at(TOP_HISTORY_ITEM_INDEX));
}
}
#include "moc_klipperpopup.cpp"

View file

@ -1,124 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2004 Esben Mose Hansen <kde@mosehansen.dk>
Copytight (C) by Andrew Stanley-Jones
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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KLIPPERPOPUP_H
#define KLIPPERPOPUP_H
#include <QtCore/QList>
#include <KMenu>
#include <QAction>
#include <QWidgetAction>
#include <QKeyEvent>
class KHelpMenu;
class KLineEdit;
class PopupProxy;
class History;
/**
* Default view of clipboard history.
*
*/
class KlipperPopup : public KMenu
{
Q_OBJECT
public:
explicit KlipperPopup( History* history );
~KlipperPopup();
void plugAction( QAction* action );
/**
* Normally, the popupmenu is only rebuilt just before showing.
* If you need the pixel-size or similar of the this menu, call
* this beforehand.
*/
void ensureClean();
History* history() { return m_history; }
const History* history() const { return m_history; }
public Q_SLOTS:
void slotHistoryChanged() { m_dirty = true; }
void slotAboutToShow();
/**
* set the top history item active, to easy kb navigation
*/
void slotSetTopActive();
private:
void rebuild( const QString& filter = QString() );
void buildFromScratch();
protected:
virtual void keyPressEvent( QKeyEvent* e );
private:
bool m_dirty : 1; // true if menu contents needs to be rebuild.
/**
* Contains the string shown if the menu is empty.
*/
QString m_textForEmptyHistory;
/**
* Contains the string shown if the search string has no
* matches and the menu is not empty.
*/
QString m_textForNoMatch;
/**
* The "document" (clipboard history)
*/
History* m_history;
/**
* The help menu
*/
KHelpMenu* m_helpMenu;
/**
* (unowned) actions to plug into the primary popup menu
*/
QList<QAction*> m_actions;
/**
* Proxy helper object used to track history items
*/
PopupProxy* m_popupProxy;
/**
* search filter widget
*/
KLineEdit* m_filterWidget;
/**
* Action of search widget
*/
QWidgetAction* m_filterWidgetAction;
/**
* The current number of history items in the clipboard
*/
int m_nHistoryItems;
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,7 +0,0 @@
# Code generation options for kconfig_compiler
File=klipper.kcfg
ClassName=KlipperSettings
Singleton=true
CustomAdditions=false
SetUserTexts=true
Mutators=URLGrabberEnabled,NoActionsForWM_CLASS,Version

View file

@ -1,52 +0,0 @@
/* This file is part of the KDE project
Copyright (C) Andrew Stanley-Jones <asj@cban.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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <KLocale>
#include <KCmdLineArgs>
#include <KAboutData>
#include <KUniqueApplication>
#include <KConfigDialogManager>
#include "tray.h"
#include "klipper.h"
int main(int argc, char *argv[])
{
Klipper::createAboutData();
KCmdLineArgs::init( argc, argv, Klipper::aboutData());
if (!KUniqueApplication::start()) {
fprintf(stderr, "Klipper is already running! Check it in the system tray in the panel.\n");
exit(0);
}
KUniqueApplication app;
app.disableSessionManagement();
app.setQuitOnLastWindowClosed( false );
// make KConfigDialog "know" when our actions page is changed
KConfigDialogManager::changedMap()->insert("ActionsTreeWidget", SIGNAL(changed()));
KlipperTray klipper;
int ret = app.exec();
Klipper::destroyAboutData();
return ret;
}

View file

@ -1,182 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2004 Esben Mose Hansen <kde@mosehansen.dk>
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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "popupproxy.h"
#include <QtCore/QRegExp>
#include <QtGui/QStyle>
#include <QtGui/QPixmap>
#include <QtGui/QImage>
#include <QtGui/QStyleOption>
#include <KMenu>
#include <KLocale>
#include <KDebug>
#include "historyitem.h"
#include "history.h"
#include "klipperpopup.h"
PopupProxy::PopupProxy( KlipperPopup* parent, int menu_height, int menu_width )
: QObject( parent ),
m_proxy_for_menu( parent ),
m_spill_uuid(),
m_menu_height( menu_height ),
m_menu_width( menu_width )
{
if (!parent->history()->empty()) {
m_spill_uuid = parent->history()->first()->uuid();
}
connect( parent->history(), SIGNAL(changed()), SLOT(slotHistoryChanged()) );
connect(m_proxy_for_menu, SIGNAL(triggered(QAction*)), parent->history(), SLOT(slotMoveToTop(QAction*)));
}
void PopupProxy::slotHistoryChanged() {
deleteMoreMenus();
}
void PopupProxy::deleteMoreMenus() {
const KMenu* myParent = parent();
if ( myParent != m_proxy_for_menu ) {
KMenu* delme = m_proxy_for_menu;
m_proxy_for_menu = static_cast<KMenu*>( m_proxy_for_menu->parent() );
while ( m_proxy_for_menu != myParent ) {
delme = m_proxy_for_menu;
m_proxy_for_menu = static_cast<KMenu*>( m_proxy_for_menu->parent() );
}
// We are called probably from within the menus event-handler (triggered=>slotMoveToTop=>changed=>slotHistoryChanged=>deleteMoreMenus)
// what can result in a crash if we just delete the menu here (#155196 and #165154) So, delay the delete.
delme->deleteLater();
}
}
int PopupProxy::buildParent( int index, const QRegExp& filter ) {
deleteMoreMenus();
// Start from top of history (again)
m_spill_uuid = parent()->history()->empty() ? QByteArray() : parent()->history()->first()->uuid();
if ( filter.isValid() ) {
m_filter = filter;
}
return insertFromSpill( index );
}
KlipperPopup* PopupProxy::parent() {
return static_cast<KlipperPopup*>( QObject::parent() );
}
void PopupProxy::slotAboutToShow() {
insertFromSpill();
}
void PopupProxy::tryInsertItem( HistoryItem const * const item,
int& remainingHeight,
const int index )
{
QAction *action = new QAction(m_proxy_for_menu);
QPixmap image( item->image() );
if ( image.isNull() ) {
// Squeeze text strings so that do not take up the entire screen (or more)
QString text = m_proxy_for_menu->fontMetrics().elidedText( item->text().simplified(), Qt::ElideMiddle, m_menu_width );
text.replace( '&', "&&" );
action->setText(text);
} else {
#if 0 // not used because QAction#setIcon does not respect this size; it does scale anyway. TODO: find a way to set a bigger image
const QSize max_size( m_menu_width,m_menu_height/4 );
if ( image.height() > max_size.height() || image.width() > max_size.width() ) {
image = image.scaled( max_size, Qt::KeepAspectRatio, Qt::SmoothTransformation );
}
#endif
action->setIcon(QIcon(image));
}
action->setData(item->uuid());
// if the m_proxy_for_menu is a submenu (aka a "More" menu) then it may the case, that there is no other action in that menu yet.
QAction *before = index < m_proxy_for_menu->actions().count() ? m_proxy_for_menu->actions().at(index) : 0;
// insert the new action to the m_proxy_for_menu
m_proxy_for_menu->insertAction(before, action);
// Determine height of a menu item.
QStyleOptionMenuItem style_options;
// It would be much easier to use QMenu::initStyleOptions. But that is protected, so until we have a better
// excuse to subclass that, I'd rather implement this manually.
// Note 2 properties, tabwidth and maxIconWidth, are not available from the public interface, so those are left out (probably not
// important for height. Also, Exlsive checkType is disregarded as I don't think we will ever use it)
style_options.initFrom(m_proxy_for_menu);
style_options.checkType = action->isCheckable() ? QStyleOptionMenuItem::NonExclusive : QStyleOptionMenuItem::NotCheckable;
style_options.checked = action->isChecked();
style_options.font = action->font();
style_options.icon = action->icon();
style_options.menuHasCheckableItems = true;
style_options.menuRect = m_proxy_for_menu->rect();
style_options.text = action->text();
int font_height = QFontMetrics(m_proxy_for_menu->fontMetrics()).height();
int itemheight = m_proxy_for_menu->style()->sizeFromContents(QStyle::CT_MenuItem,
&style_options,
QSize( 0, font_height ),
m_proxy_for_menu).height();
// Subtract the used height
remainingHeight -= itemheight;
}
int PopupProxy::insertFromSpill( int index ) {
const History* history = parent()->history();
// This menu is going to be filled, so we don't need the aboutToShow()
// signal anymore
disconnect( m_proxy_for_menu, 0, this, 0 );
// Insert history items into the current m_proxy_for_menu,
// discarding any that doesn't match the current filter.
// stop when the total number of items equal m_itemsPerMenu;
int count = 0;
int remainingHeight = m_menu_height - m_proxy_for_menu->sizeHint().height();
const HistoryItem* item = history->find(m_spill_uuid);
if (!item) {
return count;
}
do {
if ( m_filter.indexIn( item->text() ) != -1) {
tryInsertItem( item, remainingHeight, index++ );
count++;
}
item = history->find(item->next_uuid());
} while ( item && history->first() != item && remainingHeight >= 0);
m_spill_uuid = item->uuid();
// If there is more items in the history, insert a new "More..." menu and
// make *this a proxy for that menu ('s content).
if (history->first() && m_spill_uuid != history->first()->uuid()) {
KMenu* moreMenu = new KMenu(i18n("&More"), m_proxy_for_menu);
connect(moreMenu, SIGNAL(aboutToShow()), SLOT(slotAboutToShow()));
QAction *before = index < m_proxy_for_menu->actions().count() ? m_proxy_for_menu->actions().at(index) : 0;
m_proxy_for_menu->insertMenu(before, moreMenu);
m_proxy_for_menu = moreMenu;
}
// Return the number of items inserted.
return count;
}
#include "moc_popupproxy.cpp"

View file

@ -1,89 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2004 Esben Mose Hansen <kde@mosehansen.dk>
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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef POPUPPROXY_H
#define POPUPPROXY_H
#include <QtCore/QObject>
#include <QtCore/QRegExp>
#include "history.h"
class KMenu;
class HistoryItem;
class KlipperPopup;
/**
* Proxy helper for the "more" menu item
*
*/
class PopupProxy : public QObject
{
Q_OBJECT
public:
/**
* Inserts up to itemsPerMenu into parent from parent->youngest(),
* and spills any remaining items into a more menu.
*/
PopupProxy( KlipperPopup* parent, int menu_height, int menu_width );
KlipperPopup* parent();
/**
* Called when rebuilding the menu
* Deletes any More menus.. and start (re)inserting into the toplevel menu.
* @param index Items are inserted at index.
* @param filter If non-empty, only insert items that match filter as a regex
* @return number of items inserted.
*/
int buildParent( int index, const QRegExp& filter = QRegExp() );
public Q_SLOTS:
void slotAboutToShow();
void slotHistoryChanged();
private:
/**
* Insert up to m_itemsPerMenu items from spill and a new
* more-menu if necessary.
* @param index Items are inserted at index
* @return number of items inserted.
*/
int insertFromSpill( int index = 0 );
/**
* Insert item into proxy_for_menu at index,
* subtracting the items height from remainingHeight
*/
void tryInsertItem( HistoryItem const * const item, int& remainingHeight, const int index );
/**
* Delete all "More..." menus current created.
*/
void deleteMoreMenus();
private:
KMenu* m_proxy_for_menu;
QByteArray m_spill_uuid;
QRegExp m_filter;
int m_menu_height;
int m_menu_width;
};
#endif

View file

@ -1,79 +0,0 @@
/* This file is part of the KDE project
Copyright (C) by Andrew Stanley-Jones <asj@cban.com>
Copyright (C) 2000 by Carsten Pfeiffer <pfeiffer@kde.org>
Copyright (C) 2004 Esben Mose Hansen <kde@mosehansen.dk>
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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "tray.h"
#include <KGlobal>
#include <KLocale>
#include <KNotification>
#include <KIcon>
#include "klipper.h"
#include "history.h"
#include "klipperpopup.h"
KlipperTray::KlipperTray()
: KStatusNotifierItem()
{
setTitle( i18n( "Klipper" ) );
setIconByName( "klipper" );
setToolTip( "klipper", i18n( "Clipboard Contents" ), i18n( "Clipboard is empty" ) );
setCategory( SystemServices );
setStatus( Active );
setStandardActionsEnabled( false );
m_klipper = new Klipper( this, KGlobal::config());
setContextMenu( m_klipper->history()->popup() );
setAssociatedWidget( m_klipper->history()->popup() );
connect( m_klipper->history(), SIGNAL(changed()), SLOT(slotSetToolTipFromHistory()));
slotSetToolTipFromHistory();
connect( m_klipper, SIGNAL(passivePopup(QString,QString)), SLOT(slotPassivePopup(QString,QString)));
}
void KlipperTray::slotSetToolTipFromHistory()
{
const int TOOLTIP_LENGTH_LIMIT = 200;
if (m_klipper->history()->empty()) {
setToolTipSubTitle( i18n("Clipboard is empty"));
} else {
const HistoryItem* top = m_klipper->history()->first();
if (top->text().length() <= TOOLTIP_LENGTH_LIMIT) {
setToolTipSubTitle(top->text());
} else {
setToolTipSubTitle(top->text().left(TOOLTIP_LENGTH_LIMIT - 3) + "..." );
}
}
}
void KlipperTray::slotPassivePopup(const QString& caption, const QString& text)
{
if (!m_notification) {
m_notification = new KNotification(this);
m_notification->setEventID("kde/notification");
m_notification->setIcon("klipper");
}
m_notification->setTitle(caption);
m_notification->setText(text);
m_notification->send();
}
#include "moc_tray.cpp"

View file

@ -1,46 +0,0 @@
/* This file is part of the KDE project
Copyright (C) by Andrew Stanley-Jones <asj@cban.com>
Copyright (C) 2004 Esben Mose Hansen <kde@mosehansen.dk>
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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef TRAY_H
#define TRAY_H
#include <QtCore/QPointer>
#include <KStatusNotifierItem>
class KNotification;
class Klipper;
class KlipperTray : public KStatusNotifierItem
{
Q_OBJECT
public:
KlipperTray();
public slots:
void slotSetToolTipFromHistory();
void slotPassivePopup(const QString& caption, const QString& text);
private:
Klipper* m_klipper;
QPointer<KNotification> m_notification;
};
#endif

View file

@ -1,524 +0,0 @@
/* This file is part of the KDE project
Copyright (C) (C) 2000,2001,2002 by Carsten Pfeiffer <pfeiffer@kde.org>
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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "urlgrabber.h"
#include <netwm.h>
#include <QtCore/QHash>
#include <QtCore/QTimer>
#include <QtCore/QFile>
#include <QtGui/qx11info_x11.h>
#include <KDialog>
#include <KLocale>
#include <KMenu>
#include <KService>
#include <KDebug>
#include <KStringHandler>
#include <KGlobal>
#include <KMimeTypeTrader>
#include <KMimeType>
#include <KCharMacroExpander>
#include "klippersettings.h"
#include "clipcommandprocess.h"
// TODO: script-interface?
#include "history.h"
#include "historystringitem.h"
URLGrabber::URLGrabber(History* history):
m_myMenu(0L),
m_myPopupKillTimer(new QTimer( this )),
m_myPopupKillTimeout(8),
m_stripWhiteSpace(true),
m_history(history)
{
m_myPopupKillTimer->setSingleShot( true );
connect( m_myPopupKillTimer, SIGNAL(timeout()),
SLOT(slotKillPopupMenu()));
// testing
/*
ClipAction *action;
action = new ClipAction( "^http:\\/\\/", "Web-URL" );
action->addCommand("kioclient exec %s", "Open with Browser", true);
action->addCommand("netscape -no-about-splash -remote \"openURL(%s, new-window)\"", "Open with Netscape", true);
m_myActions->append( action );
action = new ClipAction( "^mailto:", "Mail-URL" );
action->addCommand("kmail --composer %s", "Launch kmail", true);
m_myActions->append( action );
action = new ClipAction( "^\\/.+\\.jpg$", "Jpeg-Image" );
action->addCommand("kuickshow %s", "Launch KuickShow", true);
action->addCommand("kview %s", "Launch KView", true);
m_myActions->append( action );
*/
}
URLGrabber::~URLGrabber()
{
qDeleteAll(m_myActions);
m_myActions.clear();
delete m_myMenu;
}
//
// Called from Klipper::slotRepeatAction, i.e. by pressing Ctrl-Alt-R
// shortcut. I.e. never from clipboard monitoring
//
void URLGrabber::invokeAction( const HistoryItem* item )
{
m_myClipItem = item;
actionMenu( item, false );
}
void URLGrabber::setActionList( const ActionList& list )
{
qDeleteAll(m_myActions);
m_myActions.clear();
m_myActions = list;
}
void URLGrabber::matchingMimeActions(const QString& clipData)
{
KUrl url(clipData);
KConfigGroup cg(KGlobal::config(), "Actions");
if(!cg.readEntry("EnableMagicMimeActions",true)) {
//kDebug() << "skipping mime magic due to configuration";
return;
}
if(!url.isValid()) {
//kDebug() << "skipping mime magic due to invalid url";
return;
}
if(url.isRelative()) { //openinng a relative path will just not work. what path should be used?
//kDebug() << "skipping mime magic due to relative url";
return;
}
if(url.isLocalFile()) {
if ( clipData == "//") {
//kDebug() << "skipping mime magic due to C++ comment //";
return;
}
if(!QFile::exists(url.toLocalFile())) {
//kDebug() << "skipping mime magic due to nonexistent localfile";
return;
}
}
// try to figure out if clipData contains a filename
KMimeType::Ptr mimetype = KMimeType::findByUrl( url, 0,
false,
true /*fast mode*/ );
// let's see if we found some reasonable mimetype.
// If we do we'll populate menu with actions for apps
// that can handle that mimetype
// first: if clipboard contents starts with http, let's assume it's "text/html".
// That is even if we've url like "http://www.kde.org/somescript.pl", we'll
// still treat that as html page, because determining a mimetype using kio
// might take a long time, and i want this function to be quick!
if ( ( clipData.startsWith( QLatin1String("http://") ) || clipData.startsWith( QLatin1String("https://") ) )
&& mimetype->name() != "text/html" )
{
// use a fake path to create a mimetype that corresponds to "text/html"
mimetype = KMimeType::findByPath( "/tmp/klipper.html", 0, true /*fast mode*/ );
}
if ( !mimetype->isDefault() ) {
ClipAction* action = new ClipAction( QString(), mimetype->comment() );
KService::List lst = KMimeTypeTrader::self()->query( mimetype->name(), "Application" );
foreach( const KService::Ptr &service, lst ) {
QHash<QChar,QString> map;
map.insert( 'i', "--icon " + service->icon() );
map.insert( 'c', service->name() );
QString exec = service->exec();
exec = KMacroExpander::expandMacros( exec, map ).trimmed();
action->addCommand( ClipCommand( exec, service->name(), true, service->icon() ) );
}
if ( !lst.isEmpty() )
m_myMatches.append( action );
}
}
const ActionList& URLGrabber::matchingActions( const QString& clipData, bool automatically_invoked )
{
m_myMatches.clear();
matchingMimeActions(clipData);
// now look for matches in custom user actions
foreach (ClipAction* action, m_myActions) {
if ( action->matches( clipData ) && (action->automatic() || !automatically_invoked) ) {
m_myMatches.append( action );
}
}
return m_myMatches;
}
void URLGrabber::checkNewData( const HistoryItem* item )
{
// kDebug() << "** checking new data: " << clipData;
actionMenu( item, true ); // also creates m_myMatches
}
void URLGrabber::actionMenu( const HistoryItem* item, bool automatically_invoked )
{
if (!item) {
qWarning("Attempt to invoke URLGrabber without an item");
return;
}
QString text(item->text());
if (m_stripWhiteSpace) {
text = text.trimmed();
}
ActionList matchingActionsList = matchingActions( text, automatically_invoked );
if (!matchingActionsList.isEmpty()) {
// don't react on blacklisted (e.g. konqi's/netscape's urls) unless the user explicitly asked for it
if ( automatically_invoked && isAvoidedWindow() ) {
return;
}
m_myCommandMapper.clear();
m_myPopupKillTimer->stop();
m_myMenu = new KMenu;
connect(m_myMenu, SIGNAL(triggered(QAction*)), SLOT(slotItemSelected(QAction*)));
foreach (ClipAction* clipAct, matchingActionsList) {
m_myMenu->addTitle(KIcon( "klipper" ),
i18n("%1 - Actions For: %2", clipAct->description(), KStringHandler::csqueeze(text, 45)));
QList<ClipCommand> cmdList = clipAct->commands();
int listSize = cmdList.count();
for (int i=0; i<listSize;++i) {
ClipCommand command = cmdList.at(i);
QString item = command.description;
if ( item.isEmpty() )
item = command.command;
QByteArray id = qRandomUuid();
QAction * action = new QAction(this);
action->setData(id);
action->setText(item);
if (!command.icon.isEmpty())
action->setIcon(KIcon(command.icon));
m_myCommandMapper.insert(id, qMakePair(clipAct,i));
m_myMenu->addAction(action);
}
}
// only insert this when invoked via clipboard monitoring, not from an
// explicit Ctrl-Alt-R
if ( automatically_invoked )
{
m_myMenu->addSeparator();
QAction *disableAction = new QAction(i18n("Disable This Popup"), this);
connect(disableAction, SIGNAL(triggered()), SIGNAL(sigDisablePopup()));
m_myMenu->addAction(disableAction);
}
m_myMenu->addSeparator();
QAction *cancelAction = new QAction(KIcon("dialog-cancel"), i18n("&Cancel"), this);
connect(cancelAction, SIGNAL(triggered()), m_myMenu, SLOT(hide()));
m_myMenu->addAction(cancelAction);
m_myClipItem = item;
if ( m_myPopupKillTimeout > 0 )
m_myPopupKillTimer->start( 1000 * m_myPopupKillTimeout );
emit sigPopup( m_myMenu );
}
}
void URLGrabber::slotItemSelected(QAction* action)
{
if (m_myMenu)
m_myMenu->hide(); // deleted by the timer or the next action
QByteArray id = action->data().toByteArray();
if (id.isEmpty()) {
kDebug() << "Klipper: no command associated";
return;
}
// first is action ptr, second is command index
QPair<ClipAction*, int> actionCommand = m_myCommandMapper.value(id);
if (actionCommand.first)
execute(actionCommand.first, actionCommand.second);
else
kDebug() << "Klipper: cannot find associated action";
}
void URLGrabber::execute( const ClipAction* action, int cmdIdx ) const
{
if (!action) {
kDebug() << "Action object is null";
return;
}
ClipCommand command = action->command(cmdIdx);
if ( command.isEnabled ) {
QString text(m_myClipItem->text());
if (m_stripWhiteSpace) {
text = text.trimmed();
}
ClipCommandProcess* proc = new ClipCommandProcess(*action, command, text, m_history, m_myClipItem);
if (proc->program().isEmpty()) {
delete proc;
proc = 0L;
} else {
proc->start();
}
}
}
void URLGrabber::loadSettings()
{
m_stripWhiteSpace = KlipperSettings::stripWhiteSpace();
m_myAvoidWindows = KlipperSettings::noActionsForWM_CLASS();
m_myPopupKillTimeout = KlipperSettings::timeoutForActionPopups();
qDeleteAll(m_myActions);
m_myActions.clear();
KConfigGroup cg(KGlobal::config(), "General");
int num = cg.readEntry("Number of Actions", 0);
QString group;
for ( int i = 0; i < num; i++ ) {
group = QString("Action_%1").arg( i );
m_myActions.append( new ClipAction( KGlobal::config(), group ) );
}
}
void URLGrabber::saveSettings() const
{
KConfigGroup cg(KGlobal::config(), "General");
cg.writeEntry( "Number of Actions", m_myActions.count() );
int i = 0;
QString group;
foreach (ClipAction* action, m_myActions) {
group = QString("Action_%1").arg( i );
action->save( KGlobal::config(), group );
++i;
}
KlipperSettings::setNoActionsForWM_CLASS(m_myAvoidWindows);
}
// find out whether the active window's WM_CLASS is in our avoid-list
// digged a little bit in netwm.cpp
bool URLGrabber::isAvoidedWindow() const
{
#ifdef Q_WS_X11
Display *d = QX11Info::display();
static Atom wm_class = XInternAtom( d, "WM_CLASS", true );
static Atom active_window = XInternAtom( d, "_NET_ACTIVE_WINDOW", true );
Atom type_ret;
int format_ret;
unsigned long nitems_ret, unused;
unsigned char *data_ret;
long BUFSIZE = 2048;
bool ret = false;
Window active = 0L;
QString wmClass;
// get the active window
if (XGetWindowProperty(d, DefaultRootWindow( d ), active_window, 0l, 1l,
False, XA_WINDOW, &type_ret, &format_ret,
&nitems_ret, &unused, &data_ret)
== Success) {
if (type_ret == XA_WINDOW && format_ret == 32 && nitems_ret == 1) {
active = *((Window *) data_ret);
}
XFree(data_ret);
}
if ( !active )
return false;
// get the class of the active window
if ( XGetWindowProperty(d, active, wm_class, 0L, BUFSIZE, False, XA_STRING,
&type_ret, &format_ret, &nitems_ret,
&unused, &data_ret ) == Success) {
if ( type_ret == XA_STRING && format_ret == 8 && nitems_ret > 0 ) {
wmClass = QString::fromUtf8( (const char *) data_ret );
ret = (m_myAvoidWindows.indexOf( wmClass ) != -1);
}
XFree( data_ret );
}
return ret;
#else
return false;
#endif
}
void URLGrabber::slotKillPopupMenu()
{
if ( m_myMenu && m_myMenu->isVisible() )
{
if ( m_myMenu->geometry().contains( QCursor::pos() ) &&
m_myPopupKillTimeout > 0 )
{
m_myPopupKillTimer->start( 1000 * m_myPopupKillTimeout );
return;
}
}
if ( m_myMenu ) {
m_myMenu->deleteLater();
m_myMenu = 0;
}
}
///////////////////////////////////////////////////////////////////////////
////////
ClipCommand::ClipCommand(const QString&_command, const QString& _description,
bool _isEnabled, const QString& _icon, Output _output)
: command(_command),
description(_description),
isEnabled(_isEnabled),
output(_output)
{
if (!_icon.isEmpty())
icon = _icon;
else
{
// try to find suitable icon
QString appName = command.section( ' ', 0, 0 );
if ( !appName.isEmpty() )
{
QPixmap iconPix = KIconLoader::global()->loadIcon(
appName, KIconLoader::Small, 0,
KIconLoader::DefaultState,
QStringList(), 0, true /* canReturnNull */ );
if ( !iconPix.isNull() )
icon = appName;
else
icon.clear();
}
}
}
ClipAction::ClipAction( const QString& regExp, const QString& description, bool automatic )
: m_myRegExp( regExp ), m_myDescription( description ), m_automatic(automatic)
{
}
ClipAction::ClipAction( KSharedConfigPtr kc, const QString& group )
: m_myRegExp( kc->group(group).readEntry("Regexp") ),
m_myDescription (kc->group(group).readEntry("Description") ),
m_automatic(kc->group(group).readEntry("Automatic", QVariant(true)).toBool() )
{
KConfigGroup cg(kc, group);
int num = cg.readEntry( "Number of commands", 0 );
// read the commands
for ( int i = 0; i < num; i++ ) {
QString _group = group + "/Command_%1";
KConfigGroup _cg(kc, _group.arg(i));
addCommand( ClipCommand(_cg.readPathEntry( "Commandline", QString() ),
_cg.readEntry( "Description" ), // i18n'ed
_cg.readEntry( "Enabled" , false),
_cg.readEntry( "Icon"),
static_cast<ClipCommand::Output>(_cg.readEntry( "Output", QVariant(ClipCommand::IGNORE)).toInt())));
}
}
ClipAction::~ClipAction()
{
m_myCommands.clear();
}
void ClipAction::addCommand( const ClipCommand& cmd )
{
if ( cmd.command.isEmpty() )
return;
m_myCommands.append( cmd );
}
void ClipAction::replaceCommand( int idx, const ClipCommand& cmd )
{
if ( idx < 0 || idx >= m_myCommands.count() ) {
kDebug() << "wrong command index given";
return;
}
m_myCommands.replace(idx, cmd);
}
// precondition: we're in the correct action's group of the KConfig object
void ClipAction::save( KSharedConfigPtr kc, const QString& group ) const
{
KConfigGroup cg(kc, group);
cg.writeEntry( "Description", description() );
cg.writeEntry( "Regexp", regExp() );
cg.writeEntry( "Number of commands", m_myCommands.count() );
cg.writeEntry( "Automatic", automatic() );
int i=0;
// now iterate over all commands of this action
foreach (const ClipCommand& cmd, m_myCommands) {
QString _group = group + "/Command_%1";
KConfigGroup cg(kc, _group.arg(i));
cg.writePathEntry( "Commandline", cmd.command );
cg.writeEntry( "Description", cmd.description );
cg.writeEntry( "Enabled", cmd.isEnabled );
cg.writeEntry( "Icon", cmd.icon );
cg.writeEntry( "Output", static_cast<int>(cmd.output) );
++i;
}
}
#include "moc_urlgrabber.cpp"

View file

@ -1,193 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2000 by Carsten Pfeiffer <pfeiffer@kde.org>
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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef URLGRABBER_H
#define URLGRABBER_H
#include <QtCore/QHash>
#include <QtCore/QRegExp>
#include <QtCore/QStringList>
#include <KSharedConfig>
class History;
class HistoryItem;
#include <QTimer>
class KConfig;
class KMenu;
#include <QMenu>
#include <QAction>
class ClipAction;
class ClipCommand;
typedef QList<ClipAction*> ActionList;
class URLGrabber : public QObject
{
Q_OBJECT
public:
URLGrabber(History* history);
~URLGrabber();
/**
* Checks a given string whether it matches any of the user-defined criteria.
* If it does, the configured action will be executed.
* @returns false if the string should be put into the popupmenu or not,
* otherwise true.
*/
void checkNewData( const HistoryItem* item );
void invokeAction( const HistoryItem* item );
ActionList actionList() const { return m_myActions; }
void setActionList( const ActionList& );
void loadSettings();
void saveSettings() const;
int popupTimeout() const { return m_myPopupKillTimeout; }
void setPopupTimeout( int timeout ) { m_myPopupKillTimeout = timeout; }
QStringList excludedWMClasses() const { return m_myAvoidWindows; }
void setExcludedWMClasses( const QStringList& list ) { m_myAvoidWindows = list; }
bool stripWhiteSpace() const { return m_stripWhiteSpace; }
void setStripWhiteSpace( bool enable ) { m_stripWhiteSpace = enable; }
private:
const ActionList& matchingActions( const QString&, bool automatically_invoked );
void execute( const ClipAction *action, int commandIdx ) const;
bool isAvoidedWindow() const;
void actionMenu( const HistoryItem* item, bool automatically_invoked );
void matchingMimeActions(const QString& clipData);
ActionList m_myActions;
ActionList m_myMatches;
QStringList m_myAvoidWindows;
const HistoryItem* m_myClipItem;
// holds mappings of menu action IDs to action commands (action+cmd index in it)
QHash<QByteArray, QPair<ClipAction*, int> > m_myCommandMapper;
KMenu* m_myMenu;
QTimer* m_myPopupKillTimer;
int m_myPopupKillTimeout;
bool m_stripWhiteSpace;
History* m_history;
private Q_SLOTS:
void slotItemSelected(QAction* action);
void slotKillPopupMenu();
Q_SIGNALS:
void sigPopup( QMenu * );
void sigDisablePopup();
};
class ClipCommand
{
public:
/**
* What to do with output of command
*/
enum Output {
IGNORE, // Discard output
REPLACE, // Replace clipboard entry with output
ADD // Add output as new clipboard element
};
ClipCommand( const QString& _command,
const QString& _description,
bool enabled=true,
const QString& _icon=QString(),
Output _output=IGNORE);
QString command;
QString description;
bool isEnabled;
QString icon;
Output output;
};
Q_DECLARE_METATYPE(ClipCommand::Output)
/**
* Represents one configured action. An action consists of one regular
* expression, an (optional) description and a list of ClipCommands
* (a command to be executed, a description and an enabled/disabled flag).
*/
class ClipAction
{
public:
explicit ClipAction( const QString& regExp = QString(),
const QString& description = QString(),
bool automagic = true);
ClipAction( KSharedConfigPtr kc, const QString& );
~ClipAction();
void setRegExp( const QString& r) { m_myRegExp = QRegExp( r ); }
QString regExp() const { return m_myRegExp.pattern(); }
bool matches( const QString& string ) const { return ( m_myRegExp.indexIn( string ) != -1 ); }
QStringList regExpMatches() const { return m_myRegExp.capturedTexts(); }
void setDescription( const QString& d) { m_myDescription = d; }
QString description() const { return m_myDescription; }
void setAutomatic( bool automatic ) { m_automatic = automatic; }
bool automatic() const { return m_automatic; }
/**
* Removes all ClipCommands associated with this ClipAction.
*/
void clearCommands() { m_myCommands.clear(); }
void addCommand(const ClipCommand& cmd);
/**
* Replaces command at index @p idx with command @p newCmd
*/
void replaceCommand( int idx, const ClipCommand& newCmd );
/**
* Returns command by its index in command list
*/
ClipCommand command(int idx) const { return m_myCommands.at(idx); }
QList<ClipCommand> commands() const { return m_myCommands; }
/**
* Saves this action to a a given KConfig object
*/
void save( KSharedConfigPtr, const QString& ) const;
private:
QRegExp m_myRegExp;
QString m_myDescription;
QList<ClipCommand> m_myCommands;
bool m_automatic;
};
#endif // URLGRABBER_H

View file

@ -1,25 +0,0 @@
/* This file is part of the KDE project
Copyright (C) Andrew Stanley-Jones <asj@cban.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; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef VERSION_H
#define VERSION_H
static const char * const klipper_version = "0.9.7";
static const qint8 klipper_version_int = 97;
#endif

View file

@ -10,4 +10,3 @@ Categories=Qt;KDE;AudioVideo;Audio;Video;Player;TV;
MimeType=application/ogg;application/x-ogg;application/sdp;application/smil;application/x-smil;application/streamingmedia;application/x-streamingmedia;application/vnd.rn-realmedia;application/vnd.rn-realmedia-vbr;audio/aac;audio/x-aac;audio/m4a;audio/x-m4a;audio/mp1;audio/x-mp1;audio/mp2;audio/x-mp2;audio/mp3;audio/x-mp3;audio/mpeg;audio/x-mpeg;audio/mpegurl;audio/x-mpegurl;audio/mpg;audio/x-mpg;audio/rn-mpeg;audio/ogg;audio/scpls;audio/x-scpls;audio/vnd.rn-realaudio;audio/wav;audio/x-pn-windows-pcm;audio/x-realaudio;audio/x-pn-realaudio;audio/x-ms-wma;audio/x-pls;audio/x-wav;video/mpeg;video/x-mpeg;video/x-mpeg2;video/mp4;video/msvideo;video/x-msvideo;video/ogg;video/quicktime;video/vnd.rn-realvideo;video/x-ms-afs;video/x-ms-asf;video/x-ms-wmv;video/x-ms-wmx;video/x-ms-wvxvideo;video/x-avi;video/x-fli;video/x-flv;video/x-theora;video/x-matroska;video/webm;audio/x-flac;audio/x-vorbis+ogg;video/x-ogm+ogg;audio/x-shorten;audio/x-ape;audio/x-wavpack;audio/x-tta;audio/AMR;audio/ac3;video/mp2t;audio/flac;audio/mp4;
StartupNotify=true
X-KDE-MediaPlayer=kmediaplayer
X-KDE-HasTrayOption=true

View file

@ -78,7 +78,6 @@ BasicTab::BasicTab( QWidget *parent )
"%c - the caption"));
_launchCB = new QCheckBox(i18n("Enable &launch feedback"), general_group);
_systrayCB = new QCheckBox(i18n("&Place in system tray"), general_group);
_onlyShowInKdeCB = new QCheckBox( i18n( "Only show in KDE" ), general_group );
_hiddenEntryCB = new QCheckBox( i18n( "Hidden entry" ), general_group );
_hiddenEntryCB->hide();
@ -109,7 +108,6 @@ BasicTab::BasicTab( QWidget *parent )
connect(_execEdit, SIGNAL(urlSelected(KUrl)),
SLOT(slotExecSelected()));
connect(_launchCB, SIGNAL(clicked()), SLOT(launchcb_clicked()));
connect(_systrayCB, SIGNAL(clicked()), SLOT(systraycb_clicked()));
connect(_onlyShowInKdeCB, SIGNAL(clicked()), SLOT(onlyshowcb_clicked()) );
connect( _hiddenEntryCB, SIGNAL(clicked()), SLOT(hiddenentrycb_clicked()) );
// add line inputs to the grid
@ -118,9 +116,8 @@ BasicTab::BasicTab( QWidget *parent )
grid->addWidget(_commentEdit, 2, 1, 1, 2);
grid->addWidget(_execEdit, 3, 1, 1, 2);
grid->addWidget(_launchCB, 4, 0, 1, 3 );
grid->addWidget(_systrayCB, 5, 0, 1, 3 );
grid->addWidget(_onlyShowInKdeCB, 6, 0, 1, 3 );
grid->addWidget(_hiddenEntryCB, 7, 0, 1, 3 );
grid->addWidget(_onlyShowInKdeCB, 5, 0, 1, 3 );
grid->addWidget(_hiddenEntryCB, 6, 0, 1, 3 );
// setup icon button
_iconButton = new KIconButton(general_group);
@ -226,7 +223,6 @@ void BasicTab::slotDisableAction()
_commentEdit->setEnabled(false);
_execEdit->setEnabled(false);
_launchCB->setEnabled(false);
_systrayCB->setEnabled(false);
_onlyShowInKdeCB->setEnabled( false );
_hiddenEntryCB->setEnabled( false );
_nameLabel->setEnabled(false);
@ -248,7 +244,6 @@ void BasicTab::enableWidgets(bool isDF, bool isDeleted)
_iconButton->setEnabled(!isDeleted);
_execEdit->setEnabled(isDF && !isDeleted);
_launchCB->setEnabled(isDF && !isDeleted);
// _systrayCB->setEnabled(isDF && !isDeleted);
_onlyShowInKdeCB->setEnabled(isDF && !isDeleted);
_hiddenEntryCB->setEnabled(isDF && !isDeleted);
_nameLabel->setEnabled(!isDeleted);
@ -286,7 +281,6 @@ void BasicTab::setFolderInfo(MenuFolderInfo *folderInfo)
_termOptEdit->clear();
_uidEdit->clear();
_launchCB->setChecked(false);
_systrayCB->setChecked(false);
_terminalCB->setChecked(false);
_onlyShowInKdeCB->setChecked( false );
_hiddenEntryCB->setChecked( false );
@ -310,7 +304,6 @@ void BasicTab::setEntryInfo(MenuEntryInfo *entryInfo)
_iconButton->setIcon( QString() );
_execEdit->lineEdit()->clear();
_systrayCB->setChecked(false);
_onlyShowInKdeCB->setChecked( false );
_hiddenEntryCB->setChecked( false );
@ -335,18 +328,7 @@ void BasicTab::setEntryInfo(MenuEntryInfo *entryInfo)
_commentEdit->setCursorPosition(0);
_iconButton->setIcon(df->readIcon());
QString temp = df->desktopGroup().readEntry("Exec");
if (temp.endsWith(QLatin1String(" -tray")))
{
_execEdit->lineEdit()->setText(temp.left(temp.length()-6));
_systrayCB->setChecked(true);
}
else
{
_execEdit->lineEdit()->setText(temp);
_systrayCB->setChecked(false);
}
_systrayCB->setEnabled(df->desktopGroup().readEntry("X-KDE-HasTrayOption", false));
_execEdit->lineEdit()->setText(df->desktopGroup().readEntry("Exec"));
_pathEdit->lineEdit()->setText(df->readPath());
_termOptEdit->setText(df->desktopGroup().readEntry("TerminalOptions"));
@ -385,10 +367,7 @@ void BasicTab::apply()
KDesktopFile *df = _menuEntryInfo->desktopFile();
KConfigGroup dg = df->desktopGroup();
dg.writeEntry("Comment", _commentEdit->text());
if (_systrayCB->isEnabled() && _systrayCB->isChecked())
dg.writeEntry("Exec", _execEdit->lineEdit()->text().append(" -tray"));
else
dg.writeEntry("Exec", _execEdit->lineEdit()->text());
dg.writeEntry("Exec", _execEdit->lineEdit()->text());
dg.writePathEntry("Path", _pathEdit->lineEdit()->text());
@ -442,11 +421,6 @@ void BasicTab::launchcb_clicked()
slotChanged();
}
void BasicTab::systraycb_clicked()
{
slotChanged();
}
void BasicTab::onlyshowcb_clicked()
{
slotChanged();

View file

@ -58,7 +58,6 @@ public Q_SLOTS:
protected Q_SLOTS:
void slotChanged();
void launchcb_clicked();
void systraycb_clicked();
void termcb_clicked();
void uidcb_clicked();
void slotExecSelected();
@ -74,7 +73,7 @@ protected:
KLineEdit *_descriptionEdit;
KUrlRequester *_execEdit, *_pathEdit;
KLineEdit *_termOptEdit, *_uidEdit;
QCheckBox *_terminalCB, *_uidCB, *_launchCB, *_systrayCB, *_onlyShowInKdeCB, *_hiddenEntryCB;
QCheckBox *_terminalCB, *_uidCB, *_launchCB, *_onlyShowInKdeCB, *_hiddenEntryCB;
KIconButton *_iconButton;
QGroupBox *_path_group, *_term_group, *_uid_group;
QLabel *_termOptLabel, *_uidLabel, *_pathLabel, *_nameLabel, *_commentLabel, *_execLabel;

View file

@ -8,7 +8,6 @@ Categories=Qt;KDE;System;TerminalEmulator;
Actions=NewWindow;
X-DocPath=konsole/index.html
StartupNotify=true
X-KDE-HasTrayOption=true
Name=Konsole
Name[af]=Konsole

View file

@ -359,29 +359,11 @@ namespace Oxygen
in most cases all 4 paddings are identical, since offsets are handled when generating the pixmaps.
There is one extra pixel needed with respect to actual shadow size, to deal with how
menu backgrounds are rendered.
Some special care is needed for QBalloonTip, since the later have an arrow
*/
if( isToolTip( widget ) )
{
if( widget->inherits( "QBalloonTip" ) )
{
// balloon tip needs special margins to deal with the arrow
int top = 0;
int bottom = 0;
widget->getContentsMargins(NULL, &top, NULL, &bottom );
// also need to decrement default size further due to extra hard coded round corner
const int size = _size - 2;
// it seems arrow can be either to the top or the bottom. Adjust margins accordingly
if( top > bottom ) data << size - (top - bottom) << size << size << size;
else data << size << size << size - (bottom - top) << size;
} else {
data << _size << _size << _size << _size;
}
data << _size << _size << _size << _size;
} else if( isToolBar( widget ) ) {

View file

@ -175,4 +175,3 @@ X-DocPath=ksysguard/index.html
Terminal=false
StartupNotify=true
Categories=Qt;KDE;System;
X-KDE-HasTrayOption=true

View file

@ -1,8 +1,6 @@
########### configure tests ###############
option(KWIN_BUILD_OXYGEN "Enable building of default decoration Oxygen" ON)
option(KWIN_BUILD_KCMS "Enable building of KWin configuration modules." ON)
option(KWIN_BUILD_TABBOX "Enable building of KWin Tabbox functionality" ON)
option(KWIN_BUILD_SCREENEDGES "Enable building of KWin with screen edge support" ON)
option(KWIN_BUILD_COMPOSITE "Enable building of KWin with XRender Compositing support" ON)
@ -23,7 +21,6 @@ include_directories(BEFORE
${CMAKE_CURRENT_SOURCE_DIR}/libkwineffects
${CMAKE_CURRENT_SOURCE_DIR}/libkdecorations
${CMAKE_CURRENT_SOURCE_DIR}/effects
${CMAKE_CURRENT_SOURCE_DIR}/tabbox
)
add_subdirectory( libkdecorations )
@ -34,7 +31,6 @@ if(KWIN_BUILD_KCMS)
endif()
add_subdirectory( clients )
add_subdirectory( tabbox )
# Install the KWin/Effect service type
@ -113,7 +109,6 @@ set(kwin_SRCS
unmanaged.cpp
scene.cpp
scene_xrender.cpp
thumbnailitem.cpp
deleted.cpp
effects.cpp
compositingprefs.cpp
@ -122,19 +117,6 @@ set(kwin_SRCS
xcbutils.cpp
)
if(KWIN_BUILD_TABBOX)
set(kwin_SRCS
${kwin_SRCS}
tabbox/tabbox.cpp
tabbox/clientmodel.cpp
tabbox/declarative.cpp
tabbox/desktopchain.cpp
tabbox/desktopmodel.cpp
tabbox/tabboxconfig.cpp
tabbox/tabboxhandler.cpp
)
endif()
if(KWIN_BUILD_SCREENEDGES)
set(kwin_SRCS
${kwin_SRCS}
@ -167,7 +149,6 @@ add_executable(kwin ${kwin_SRCS} ${kwin4_effect_builtins_sources})
target_link_libraries(kwin
KDE4::kdeui
KDE4::kdeclarative
${X11_X11_LIB}
${X11_Xext_LIB}
${X11_ICE_LIB}

View file

@ -233,7 +233,6 @@ _KDE_NET_WM_USER_CREATION_TIME window property
_KDE_NET_WM_BLOCK_COMPOSITING window property
_KDE_NET_WM_SHADOW window property
_KDE_NET_WM_TAB_GROUP window property
_KDE_FIRST_IN_WINDOWLIST window property
_KDE_NET_WM_TEMPORARY_RULES window property
_NET_WM_CONTEXT_HELP
- Katie extension

View file

@ -1,3 +1,3 @@
#!/bin/bash
$EXTRACTRC *.kcfg >> rc.cpp
$XGETTEXT *.h *.cpp killer/*.cpp tabbox/*.cpp -o $podir/kwin.pot
$XGETTEXT *.h *.cpp killer/*.cpp -o $podir/kwin.pot

View file

@ -118,9 +118,6 @@ Atoms::Atoms()
atoms[n] = &kde_net_wm_tab_group;
names[n++] = (char*) "_KDE_NET_WM_TAB_GROUP";
atoms[n] = &kde_first_in_window_list;
names[n++] = (char*) "_KDE_FIRST_IN_WINDOWLIST";
atoms[n] = &kde_skip_close_animation;
names[n++] = (char*) "_KDE_NET_WM_SKIP_CLOSE_ANIMATION";

View file

@ -61,7 +61,6 @@ public:
Atom kde_net_wm_shadow;
Atom net_wm_opaque_region;
Atom kde_net_wm_tab_group;
Atom kde_first_in_window_list;
Atom kde_skip_close_animation;
};

View file

@ -32,9 +32,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "group.h"
#include "paintredirector.h"
#include "shadow.h"
#ifdef KWIN_BUILD_TABBOX
#include "tabbox.h"
#endif
#include "workspace.h"
// KDE
#include <KIconLoader>
@ -119,7 +116,6 @@ Client::Client()
, padding_bottom(0)
, sm_stacking_order(-1)
, paintRedirector(0)
, m_firstInTabBox(false)
, electricMaximizing(false)
, needsSessionInteract(false)
, needsXWindowMove(false)
@ -178,11 +174,6 @@ Client::Client()
//Client to workspace connections require that each
//client constructed be connected to the workspace wrapper
#ifdef KWIN_BUILD_TABBOX
// TabBoxClient
m_tabBoxClient = QSharedPointer<TabBox::TabBoxClientImpl>(new TabBox::TabBoxClientImpl(this));
#endif
geom = QRect(0, 0, 100, 100); // So that decorations don't start with size being (0,0)
client_size = QSize(100, 100);
ready_for_painting = false; // wait for first damage or sync reply
@ -2201,24 +2192,6 @@ KDecorationDefines::Position Client::titlebarPosition() const
return titlePos;
}
void Client::updateFirstInTabBox()
{
// TODO: move into KWindowInfo
Atom type;
int format, status;
unsigned long nitems = 0;
unsigned long extra = 0;
unsigned char *data = 0;
status = XGetWindowProperty(display(), window(), atoms->kde_first_in_window_list, 0, 1, false, atoms->kde_first_in_window_list, &type, &format, &nitems, &extra, &data);
if (status == Success && format == 32 && nitems == 1) {
setFirstInTabBox(true);
} else {
setFirstInTabBox(false);
}
if (data)
XFree(data);
}
bool Client::isClient() const
{
return true;

View file

@ -50,11 +50,6 @@ class KStartupInfoId;
namespace KWin
{
namespace TabBox
{
class TabBoxClientImpl;
}
class Bridge;
class PaintRedirector;
@ -609,17 +604,6 @@ public:
};
void layoutDecorationRects(QRect &left, QRect &top, QRect &right, QRect &bottom, CoordinateMode mode) const;
QWeakPointer<TabBox::TabBoxClientImpl> tabBoxClient() const {
return m_tabBoxClient.toWeakRef();
}
bool isFirstInTabBox() const {
return m_firstInTabBox;
}
void setFirstInTabBox(bool enable) {
m_firstInTabBox = enable;
}
void updateFirstInTabBox();
//sets whether the client should be treated as a SessionInteract window
void setSessionInteract(bool needed);
virtual bool isClient() const;
@ -935,8 +919,6 @@ private:
friend struct ResetupRulesProcedure;
friend class GeometryUpdatesBlocker;
PaintRedirector* paintRedirector;
QSharedPointer<TabBox::TabBoxClientImpl> m_tabBoxClient;
bool m_firstInTabBox;
bool electricMaximizing;
QuickTileMode electricMode;

View file

@ -1,4 +1 @@
add_subdirectory( aurorae )
if(KWIN_BUILD_OXYGEN)
add_subdirectory( oxygen )
endif()
add_subdirectory( oxygen )

View file

@ -1,6 +0,0 @@
project(aurorae)
add_subdirectory(src)
#add_subdirectory(themes/example-deco)
add_subdirectory(themes)

View file

@ -1,6 +0,0 @@
Aurorae is a themeable window decoration for KWin.
It supports theme files consisting of several SVG files for decoration and buttons. Themes can be
installed and selected directly in the configuration module of KWin decorations.
Please have a look at theme-description on how to write a theme file.

View file

@ -1,49 +0,0 @@
########### decoration ###############
include_directories(
./lib
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
set(kwin3_aurorae_PART_SRCS
aurorae.cpp
lib/auroraetheme.cpp
lib/themeconfig.cpp
)
kde4_add_plugin(kwin3_aurorae ${kwin3_aurorae_PART_SRCS})
target_link_libraries(kwin3_aurorae KDE4::kdeui ${QT_QTDECLARATIVE_LIBRARY} kdecorations)
install(TARGETS kwin3_aurorae DESTINATION ${KDE4_PLUGIN_INSTALL_DIR} )
set(decoration_plugin_SRCS
decorationplugin.cpp
decorationoptions.cpp
colorhelper.cpp
)
add_library(decorationplugin SHARED ${decoration_plugin_SRCS})
target_link_libraries(decorationplugin ${QT_QTCORE_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY} KDE4::kdeui kdecorations)
install(TARGETS decorationplugin DESTINATION ${KDE4_IMPORTS_INSTALL_DIR}/org/kde/kwin/decoration)
########### install files ###############
install( FILES aurorae.desktop DESTINATION ${KDE4_DATA_INSTALL_DIR}/kwin )
install( FILES
qml/aurorae.qml
qml/AuroraeButton.qml
qml/AuroraeButtonGroup.qml
qml/AuroraeMaximizeButton.qml
qml/Decoration.qml
qml/DecorationButton.qml
qml/MenuButton.qml
DESTINATION ${KDE4_DATA_INSTALL_DIR}/kwin/aurorae )
install( FILES
qml/Decoration.qml
qml/DecorationButton.qml
qml/MenuButton.qml
qml/ButtonGroup.qml
qml/qmldir
DESTINATION ${KDE4_IMPORTS_INSTALL_DIR}/org/kde/kwin/decoration )
install( FILES kwindecoration.desktop DESTINATION ${KDE4_SERVICETYPES_INSTALL_DIR} )

View file

@ -1,646 +0,0 @@
/********************************************************************
Copyright (C) 2009, 2010, 2012 Martin Gräßlin <mgraesslin@kde.org>
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, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "aurorae.h"
#include "auroraetheme.h"
#include "config-kwin.h"
#include <QApplication>
#include <QDeclarativeComponent>
#include <QDeclarativeContext>
#include <QDeclarativeEngine>
#include <QDeclarativeItem>
#include <QGraphicsView>
#include <QPaintEngine>
#include <KConfig>
#include <KConfigGroup>
#include <KDebug>
#include <KPluginInfo>
#include <KServiceTypeTrader>
#include <KStandardDirs>
namespace Aurorae
{
AuroraeFactory::AuroraeFactory()
: QObject()
, KDecorationFactory()
, m_theme(new AuroraeTheme(this))
, m_engine(new QDeclarativeEngine(this))
, m_component(new QDeclarativeComponent(m_engine, this))
, m_engineType(AuroraeEngine)
{
init();
}
void AuroraeFactory::init()
{
qRegisterMetaType<uint>("Qt::MouseButtons");
KConfig conf("auroraerc");
KConfigGroup group(&conf, "Engine");
if (!group.hasKey("EngineType") && !group.hasKey("ThemeName")) {
// neither engine type and theme name are configured, use the only available theme
initQML(group);
} else if (group.hasKey("EngineType")) {
const QString engineType = group.readEntry("EngineType", "aurorae").toLower();
if (engineType == "qml") {
initQML(group);
} else {
// fallback to classic Aurorae Themes
initAurorae(conf, group);
}
} else {
// fallback to classic Aurorae Themes
initAurorae(conf, group);
}
}
void AuroraeFactory::initAurorae(KConfig &conf, KConfigGroup &group)
{
m_engineType = AuroraeEngine;
const QString themeName = group.readEntry("ThemeName");
if (themeName.isEmpty()) {
// no theme configured, fall back to Plastik QML theme
initQML(group);
return;
}
KConfig config("aurorae/themes/" + themeName + '/' + themeName + "rc", KConfig::FullConfig, "data");
KConfigGroup themeGroup(&conf, themeName);
m_theme->loadTheme(themeName, config);
m_theme->setBorderSize((KDecorationDefines::BorderSize)themeGroup.readEntry<int>("BorderSize", KDecorationDefines::BorderNormal));
m_theme->setButtonSize((KDecorationDefines::BorderSize)themeGroup.readEntry<int>("ButtonSize", KDecorationDefines::BorderNormal));
m_theme->setTabDragMimeType(tabDragMimeType());
// setup the QML engine
/* use logic from KDeclarative::setupBindings():
"addImportPath adds the path at the beginning, so to honour user's
paths we need to traverse the list in reverse order" */
QStringListIterator paths(KGlobal::dirs()->findDirs("module", "imports"));
paths.toBack();
while (paths.hasPrevious()) {
m_engine->addImportPath(paths.previous());
}
m_component->loadUrl(QUrl(KStandardDirs::locate("data", "kwin/aurorae/aurorae.qml")));
m_engine->rootContext()->setContextProperty("auroraeTheme", m_theme);
m_themeName = themeName;
}
void AuroraeFactory::initQML(const KConfigGroup &group)
{
// try finding the QML package
const QString themeName = group.readEntry("ThemeName", "kwin4_decoration_qml_plastik");
kDebug(1212) << "Trying to load QML Decoration " << themeName;
const QString internalname = themeName.toLower();
QString constraint = QString("[X-KDE-PluginInfo-Name] == '%1'").arg(internalname);
KService::List offers = KServiceTypeTrader::self()->query("KWin/Decoration", constraint);
if (offers.isEmpty()) {
kError(1212) << "Couldn't find QML Decoration " << themeName;
// TODO: what to do in error case?
return;
}
KService::Ptr service = offers.first();
KPluginInfo plugininfo(service);
const QString pluginName = service->property("X-KDE-PluginInfo-Name").toString();
const QString scriptName = service->property("X-Plasma-MainScript").toString();
const QString file = KStandardDirs::locate("data", "kwin/decorations/" + pluginName + "/contents/" + scriptName);
if (file.isNull()) {
kDebug(1212) << "Could not find script file for " << pluginName;
// TODO: what to do in error case?
return;
}
m_engineType = QMLEngine;
// setup the QML engine
/* use logic from KDeclarative::setupBindings():
"addImportPath adds the path at the beginning, so to honour user's
paths we need to traverse the list in reverse order" */
QStringListIterator paths(KGlobal::dirs()->findDirs("module", "imports"));
paths.toBack();
while (paths.hasPrevious()) {
m_engine->addImportPath(paths.previous());
}
m_component->loadUrl(QUrl::fromLocalFile(file));
m_themeName = themeName;
}
AuroraeFactory::~AuroraeFactory()
{
s_instance = NULL;
}
AuroraeFactory *AuroraeFactory::instance()
{
if (!s_instance) {
s_instance = new AuroraeFactory;
}
return s_instance;
}
bool AuroraeFactory::reset(unsigned long changed)
{
if (changed & SettingButtons) {
emit buttonsChanged();
}
if (changed & SettingFont){
emit titleFontChanged();
}
if (changed == SettingCompositing) {
return false;
}
const KConfig conf("auroraerc");
const KConfigGroup group(&conf, "Engine");
const QString themeName = group.readEntry("ThemeName", "example-deco");
const KConfig config("aurorae/themes/" + themeName + '/' + themeName + "rc", KConfig::FullConfig, "data");
const KConfigGroup themeGroup(&conf, themeName);
if (themeName != m_themeName) {
m_engine->clearComponentCache();
init();
// recreate all decorations
return true;
}
if (m_engineType == AuroraeEngine) {
m_theme->setBorderSize((KDecorationDefines::BorderSize)themeGroup.readEntry<int>("BorderSize", KDecorationDefines::BorderNormal));
m_theme->setButtonSize((KDecorationDefines::BorderSize)themeGroup.readEntry<int>("ButtonSize", KDecorationDefines::BorderNormal));
}
emit configChanged();
return changed & (SettingDecoration | SettingButtons | SettingBorder); // need hard reset
}
bool AuroraeFactory::supports(Ability ability) const
{
switch (ability) {
case AbilityUsesAlphaChannel:
case AbilityAnnounceAlphaChannel:
case AbilityButtonMenu:
case AbilityButtonSpacer:
case AbilityExtendIntoClientArea:
case AbilityButtonMinimize:
case AbilityButtonMaximize:
case AbilityButtonClose:
case AbilityButtonAboveOthers:
case AbilityButtonBelowOthers:
case AbilityButtonShade:
case AbilityButtonOnAllDesktops:
case AbilityButtonHelp:
case AbilityProvidesShadow:
return true; // TODO: correct value from theme
case AbilityTabbing:
return false;
default:
return false;
}
}
KDecoration *AuroraeFactory::createDecoration(KDecorationBridge *bridge)
{
AuroraeClient *client = new AuroraeClient(bridge, this);
return client;
}
QList< KDecorationDefines::BorderSize > AuroraeFactory::borderSizes() const
{
return QList< BorderSize >() << BorderTiny << BorderNormal <<
BorderLarge << BorderVeryLarge << BorderHuge <<
BorderVeryHuge << BorderOversized;
}
QDeclarativeItem *AuroraeFactory::createQmlDecoration(Aurorae::AuroraeClient *client)
{
QDeclarativeContext *context = new QDeclarativeContext(m_engine->rootContext(), this);
context->setContextProperty("decoration", client);
return qobject_cast< QDeclarativeItem* >(m_component->create(context));
}
AuroraeFactory *AuroraeFactory::s_instance = NULL;
/*******************************************************
* Client
*******************************************************/
AuroraeClient::AuroraeClient(KDecorationBridge *bridge, KDecorationFactory *factory)
: KDecoration(bridge, factory)
, m_view(NULL)
, m_scene(new QGraphicsScene(this))
, m_item(AuroraeFactory::instance()->createQmlDecoration(this))
{
connect(this, SIGNAL(keepAboveChanged(bool)), SIGNAL(keepAboveChangedWrapper()));
connect(this, SIGNAL(keepBelowChanged(bool)), SIGNAL(keepBelowChangedWrapper()));
connect(AuroraeFactory::instance(), SIGNAL(buttonsChanged()), SIGNAL(buttonsChanged()));
connect(AuroraeFactory::instance(), SIGNAL(configChanged()), SIGNAL(configChanged()));
connect(AuroraeFactory::instance(), SIGNAL(titleFontChanged()), SIGNAL(fontChanged()));
connect(m_item, SIGNAL(alphaChanged()), SLOT(slotAlphaChanged()));
}
AuroraeClient::~AuroraeClient()
{
if (m_item) {
m_item->setParent(NULL);
m_item->deleteLater();
}
m_scene->setParent(NULL);
m_scene->deleteLater();
m_view->setParent(NULL);
m_view->deleteLater();
}
void AuroraeClient::init()
{
m_scene->setItemIndexMethod(QGraphicsScene::NoIndex);
// HACK: we need to add the GraphicsView as a child widget to a normal widget
// the GraphicsView eats the mouse release event and by that kwin core starts to move
// the decoration each time the decoration is clicked
// therefore we use two widgets and inject an own mouse release event to the parent widget
// when the graphics view eats a mouse event
createMainWidget();
widget()->setAttribute(Qt::WA_TranslucentBackground);
widget()->setAttribute(Qt::WA_NoSystemBackground);
widget()->installEventFilter(this);
m_view = new QGraphicsView(m_scene, widget());
m_view->setAttribute(Qt::WA_TranslucentBackground);
m_view->setWindowFlags(Qt::X11BypassWindowManagerHint);
m_view->setFrameShape(QFrame::NoFrame);
m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_view->setOptimizationFlags(QGraphicsView::DontSavePainterState);
m_view->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
QPalette pal = m_view->palette();
pal.setColor(m_view->backgroundRole(), Qt::transparent);
m_view->setPalette(pal);
QPalette pal2 = widget()->palette();
pal2.setColor(widget()->backgroundRole(), Qt::transparent);
widget()->setPalette(pal2);
if (m_item)
m_scene->addItem(m_item);
slotAlphaChanged();
AuroraeFactory::instance()->theme()->setCompositingActive(compositingActive());
}
bool AuroraeClient::eventFilter(QObject *object, QEvent *event)
{
// we need to filter the wheel events on the decoration
// QML does not yet provide a way to accept wheel events, this will change with Qt 5
// TODO: remove in KDE5
// see BUG: 304248
if (object != widget() || event->type() != QEvent::Wheel) {
return KDecoration::eventFilter(object, event);
}
QWheelEvent *wheel = static_cast<QWheelEvent*>(event);
if (mousePosition(wheel->pos()) == PositionCenter) {
titlebarMouseWheelOperation(wheel->delta());
return true;
}
return false;
}
void AuroraeClient::activeChange()
{
emit activeChanged();
}
void AuroraeClient::captionChange()
{
emit captionChanged();
}
void AuroraeClient::iconChange()
{
emit iconChanged();
}
void AuroraeClient::desktopChange()
{
emit desktopChanged();
}
void AuroraeClient::maximizeChange()
{
emit maximizeChanged();
}
void AuroraeClient::resize(const QSize &s)
{
if (m_item) {
m_item->setWidth(s.width());
m_item->setHeight(s.height());
}
m_scene->setSceneRect(QRectF(QPoint(0, 0), s));
m_view->resize(s);
widget()->resize(s);
}
void AuroraeClient::shadeChange()
{
emit shadeChanged();
}
void AuroraeClient::borders(int &left, int &right, int &top, int &bottom) const
{
if (!m_item) {
left = right = top = bottom = 0;
return;
}
const bool maximized = maximizeMode() == MaximizeFull;
QObject *borders = NULL;
if (maximized) {
borders = m_item->findChild<QObject*>("maximizedBorders");
} else {
borders = m_item->findChild<QObject*>("borders");
}
sizesFromBorders(borders, left, right, top, bottom);
}
void AuroraeClient::padding(int &left, int &right, int &top, int &bottom) const
{
if (!m_item || maximizeMode() == MaximizeFull) {
left = right = top = bottom = 0;
return;
}
sizesFromBorders(m_item->findChild<QObject*>("padding"), left, right, top, bottom);
}
void AuroraeClient::sizesFromBorders(const QObject *borders, int &left, int &right, int &top, int &bottom) const
{
if (!borders) {
return;
}
left = borders->property("left").toInt();
right = borders->property("right").toInt();
top = borders->property("top").toInt();
bottom = borders->property("bottom").toInt();
}
QSize AuroraeClient::minimumSize() const
{
return widget()->minimumSize();
}
KDecorationDefines::Position AuroraeClient::mousePosition(const QPoint &point) const
{
// based on the code from deKorator
int pos = PositionCenter;
if (isShade() || isMaximized()) {
return Position(pos);
}
int borderLeft, borderTop, borderRight, borderBottom;
borders(borderLeft, borderRight, borderTop, borderBottom);
int paddingLeft, paddingTop, paddingRight, paddingBottom;
padding(paddingLeft, paddingRight, paddingTop, paddingBottom);
int titleEdgeLeft, titleEdgeRight, titleEdgeTop, titleEdgeBottom;
AuroraeFactory::instance()->theme()->titleEdges(titleEdgeLeft, titleEdgeTop, titleEdgeRight, titleEdgeBottom, false);
switch (AuroraeFactory::instance()->theme()->decorationPosition()) {
case DecorationTop:
borderTop = titleEdgeTop;
break;
case DecorationLeft:
borderLeft = titleEdgeLeft;
break;
case DecorationRight:
borderRight = titleEdgeRight;
break;
case DecorationBottom:
borderBottom = titleEdgeBottom;
break;
default:
break; // nothing
}
if (point.x() >= (m_view->width() - borderRight - paddingRight)) {
pos |= PositionRight;
} else if (point.x() <= borderLeft + paddingLeft) {
pos |= PositionLeft;
}
if (point.y() >= m_view->height() - borderBottom - paddingBottom) {
pos |= PositionBottom;
} else if (point.y() <= borderTop + paddingTop ) {
pos |= PositionTop;
}
return Position(pos);
}
void AuroraeClient::reset(long unsigned int changed)
{
KDecoration::reset(changed);
}
void AuroraeClient::menuClicked()
{
showWindowMenu(QCursor::pos());
}
void AuroraeClient::toggleShade()
{
setShade(!isShade());
}
void AuroraeClient::toggleKeepAbove()
{
setKeepAbove(!keepAbove());
}
void AuroraeClient::toggleKeepBelow()
{
setKeepBelow(!keepBelow());
}
bool AuroraeClient::isMaximized() const
{
return maximizeMode()==KDecorationDefines::MaximizeFull;
}
void AuroraeClient::titlePressed(int button, int buttons)
{
titlePressed(static_cast<Qt::MouseButton>(button), static_cast<Qt::MouseButtons>(buttons));
}
void AuroraeClient::titleReleased(int button, int buttons)
{
titleReleased(static_cast<Qt::MouseButton>(button), static_cast<Qt::MouseButtons>(buttons));
}
void AuroraeClient::titleMouseMoved(int button, int buttons)
{
titleMouseMoved(static_cast<Qt::MouseButton>(button), static_cast<Qt::MouseButtons>(buttons));
}
void AuroraeClient::titlePressed(Qt::MouseButton button, Qt::MouseButtons buttons)
{
const QPoint cursor = QCursor::pos();
QMouseEvent *event = new QMouseEvent(QEvent::MouseButtonPress, widget()->mapFromGlobal(cursor),
cursor, button, buttons, Qt::NoModifier);
processMousePressEvent(event);
delete event;
event = 0;
}
void AuroraeClient::titleReleased(Qt::MouseButton button, Qt::MouseButtons buttons)
{
const QPoint cursor = QCursor::pos();
QMouseEvent *event = new QMouseEvent(QEvent::MouseButtonRelease, widget()->mapFromGlobal(cursor),
cursor, button, buttons, Qt::NoModifier);
QApplication::sendEvent(widget(), event);
delete event;
event = 0;
}
void AuroraeClient::titleMouseMoved(Qt::MouseButton button, Qt::MouseButtons buttons)
{
const QPoint cursor = QCursor::pos();
QMouseEvent *event = new QMouseEvent(QEvent::MouseMove, widget()->mapFromGlobal(cursor),
cursor, button, buttons, Qt::NoModifier);
QApplication::sendEvent(widget(), event);
delete event;
event = 0;
}
void AuroraeClient::themeChanged()
{
m_scene->clear();
m_item = AuroraeFactory::instance()->createQmlDecoration(this);
if (!m_item) {
return;
}
m_item->setWidth(m_scene->sceneRect().width());
m_item->setHeight(m_scene->sceneRect().height());
m_scene->addItem(m_item);
connect(m_item, SIGNAL(alphaChanged()), SLOT(slotAlphaChanged()));
slotAlphaChanged();
}
int AuroraeClient::doubleClickInterval() const
{
return QApplication::doubleClickInterval();
}
void AuroraeClient::closeWindow()
{
QMetaObject::invokeMethod(qobject_cast< KDecoration* >(this), "doCloseWindow", Qt::QueuedConnection);
}
void AuroraeClient::doCloseWindow()
{
KDecoration::closeWindow();
}
void AuroraeClient::maximize(int button)
{
// a maximized window does not need to have a window decoration
// in that case we need to delay handling by one cycle
// BUG: 304870
QMetaObject::invokeMethod(qobject_cast< KDecoration* >(this),
"doMaximzie",
Qt::QueuedConnection,
Q_ARG(int, button));
}
void AuroraeClient::doMaximzie(int button)
{
KDecoration::maximize(static_cast<Qt::MouseButton>(button));
}
void AuroraeClient::titlebarDblClickOperation()
{
// the double click operation can result in a window being maximized
// see maximize
QMetaObject::invokeMethod(qobject_cast< KDecoration* >(this), "doTitlebarDblClickOperation", Qt::QueuedConnection);
}
void AuroraeClient::doTitlebarDblClickOperation()
{
KDecoration::titlebarDblClickOperation();
}
QVariant AuroraeClient::readConfig(const QString &key, const QVariant &defaultValue)
{
KSharedConfigPtr config = KSharedConfig::openConfig("auroraerc");
return config->group(AuroraeFactory::instance()->currentThemeName()).readEntry(key, defaultValue);
}
void AuroraeClient::slotAlphaChanged()
{
if (!m_item) {
setAlphaEnabled(false);
return;
}
QVariant alphaProperty = m_item->property("alpha");
if (alphaProperty.isValid() && alphaProperty.canConvert<bool>()) {
setAlphaEnabled(alphaProperty.toBool());
} else {
// by default all Aurorae themes use the alpha channel
setAlphaEnabled(true);
}
}
QRegion AuroraeClient::region(KDecorationDefines::Region r)
{
if (r != ExtendedBorderRegion) {
return QRegion();
}
if (!m_item) {
return QRegion();
}
if (isMaximized()) {
// empty region for maximized windows
return QRegion();
}
int left, right, top, bottom;
left = right = top = bottom = 0;
sizesFromBorders(m_item->findChild<QObject*>("extendedBorders"), left, right, top, bottom);
if (top == 0 && right == 0 && bottom == 0 && left == 0) {
// no extended borders
return QRegion();
}
int paddingLeft, paddingRight, paddingTop, paddingBottom;
paddingLeft = paddingRight = paddingTop = paddingBottom = 0;
padding(paddingLeft, paddingRight, paddingTop, paddingBottom);
QRect rect = widget()->rect().adjusted(paddingLeft, paddingTop, -paddingRight, -paddingBottom);
rect.translate(-paddingLeft, -paddingTop);
return QRegion(rect.adjusted(-left, -top, right, bottom)).subtract(rect);
}
bool AuroraeClient::animationsSupported() const
{
if (!compositingActive()) {
return false;
}
QPixmap pix(1,1);
QPainter p(&pix);
const bool raster = p.paintEngine()->type() == QPaintEngine::Raster;
p.end();
return raster;
}
} // namespace Aurorae
extern "C"
{
KDE_EXPORT KDecorationFactory *create_factory() {
return Aurorae::AuroraeFactory::instance();
}
KWIN_EXPORT int decoration_version() {
return KWIN_DECORATION_API_VERSION;
}
}
#include "moc_aurorae.cpp"

View file

@ -1,68 +0,0 @@
[Desktop Entry]
Name=Aurorae Decoration Theme Engine
Name[ar]=محرك شفق لسمات التزيين
Name[ast]=Motor de temes de decoración Aurorae
Name[bg]=Теми за декорация на прозорци Aurorae
Name[bs]=Aurore, tematski motor dekoracija
Name[ca]=Motor del tema de decoració Aurorae
Name[ca@valencia]=Motor del tema de decoració Aurorae
Name[cs]=Stroj motivů dekorace Aurorae
Name[csb]=Mòtór dekòracëji wëzdrzatkù Aurorae
Name[da]=Temamotor til Aurorae-dekorationen
Name[de]=Aurorae-Dekorationsdesign-Engine
Name[el]=Μηχανισμός διακόσμησης θεμάτων Aurorae
Name[en_GB]=Auroræ Decoration Theme Engine
Name[eo]=Aurorae Ornamaĵ-etosa Modulo
Name[es]=Motor de temas de decoración Aurorae
Name[et]=Aurorae dekoratsioonide teema mootor
Name[eu]=Aurorae apainketa-gaiaren motorra
Name[fi]=Kehysten teemamoottori Aurorae
Name[fr]=Moteur de thèmes pour la décoration « Aurorae »
Name[fy]=Aurorae dekoraasje tema motor
Name[ga]=Inneall Téama Maisiúcháin Aurorae
Name[gl]=Motor de temas de decoración Aurorae
Name[he]=מנוע ערכת התצוגה Aurorae Decoration
Name[hr]=Tematski mehanizam za ukrase Aurorae
Name[hu]=Aurorae ablakdekorációs témamodul
Name[ia]=Motor de thema de decoration Aurorae
Name[id]=Mesin Tema Dekorasi Aurorae
Name[is]=Aurorae skjáskreytiþemavél
Name[it]=Motore dei temi decorativi Aurorae
Name[ja]=
Name[kk]=Aurorae безендіру нақыш теігі
Name[km]= Aurorae
Name[kn]= ಿ ಿ() ಿ
Name[ko]=Aurorae
Name[lt]=Aurorae dekoracijos temos variklis
Name[lv]=Aurorae dekorācijas tēmu dzinējs
Name[ml]= ിി ി
Name[mr]= ि
Name[nb]=Aurorae motor for dekorasjonstema
Name[nds]=Aurorae Dekoratschonen-Musterkarn
Name[nl]=Aurorae decoratiethema-engine
Name[nn]=Motor for pynting med temaet Aurorae
Name[pa]=
Name[pl]=Silnik zestawu ozdób Aurora
Name[pt]=Motor do Tema de Decoração Aurorae
Name[pt_BR]=Mecanismo do tema de decoração Aurorae
Name[ro]=Motor pentru tematici de decorare Aurorae
Name[ru]=Движок оформлений окон Aurorae
Name[si]=Aurorae
Name[sk]=Aurorae témy dekorácie
Name[sl]=Pogon Aurorae za teme okraskov
Name[sr]=Ауроре, тематски мотор декорација
Name[sr@ijekavian]=Ауроре, тематски мотор декорација
Name[sr@ijekavianlatin]=Aurore, tematski motor dekoracija
Name[sr@latin]=Aurore, tematski motor dekoracija
Name[sv]=Aurora dekorationstemagränssnitt
Name[tg]=Системаи мавзӯъҳои аврора
Name[th]= Aurorae
Name[tr]=Aurorae Dekorasyon Teması Motoru
Name[ug]=Aurorae زىننەتلەش ئۆرنەك ماتورى
Name[uk]=Рушій декорації тем Aurorae
Name[vi]=Cơ chế sc thái trang trí Aurorae
Name[wa]=Moteur di tinme di gåyotaedje Aurorae
Name[x-test]=xxAurorae Decoration Theme Enginexx
Name[zh_CN]=Aurorae
Name[zh_TW]=Aurorae
X-KDE-Library=kwin3_aurorae

View file

@ -1,190 +0,0 @@
/********************************************************************
Copyright (C) 2009, 2010, 2012 Martin Gräßlin <mgraesslin@kde.org>
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, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef AURORAE_H
#define AURORAE_H
#include "themeconfig.h"
#include <kdecoration.h>
#include <kdecorationfactory.h>
#include <QDeclarativeComponent>
#include <QDeclarativeEngine>
#include <QDeclarativeItem>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsScene>
#include <QGraphicsView>
class KConfig;
class KConfigGroup;
namespace Aurorae
{
class AuroraeTheme;
class AuroraeClient;
class AuroraeFactory : public QObject, public KDecorationFactory
{
Q_OBJECT
public:
~AuroraeFactory();
static AuroraeFactory* instance();
bool reset(unsigned long changed);
KDecoration *createDecoration(KDecorationBridge*);
bool supports(Ability ability) const;
virtual QList< BorderSize > borderSizes() const;
AuroraeTheme *theme() const {
return m_theme;
}
QDeclarativeItem *createQmlDecoration(AuroraeClient *client);
const QString &currentThemeName() const {
return m_themeName;
}
private:
enum EngineType {
AuroraeEngine,
QMLEngine
};
AuroraeFactory();
void init();
void initAurorae(KConfig &conf, KConfigGroup &group);
void initQML(const KConfigGroup& group);
Q_SIGNALS:
void buttonsChanged();
void titleFontChanged();
void configChanged();
private:
static AuroraeFactory *s_instance;
AuroraeTheme *m_theme;
QDeclarativeEngine *m_engine;
QDeclarativeComponent *m_component;
EngineType m_engineType;
QString m_themeName;
};
class AuroraeClient : public KDecoration
{
Q_OBJECT
Q_PROPERTY(bool active READ isActive NOTIFY activeChanged)
Q_PROPERTY(QString caption READ caption NOTIFY captionChanged)
Q_PROPERTY(int desktop READ desktop WRITE setDesktop NOTIFY desktopChanged)
Q_PROPERTY(QRect geometry READ geometry)
Q_PROPERTY(int height READ height)
Q_PROPERTY(QIcon icon READ icon NOTIFY iconChanged)
Q_PROPERTY(bool closeable READ isCloseable CONSTANT)
Q_PROPERTY(bool maximizeable READ isMaximizable CONSTANT)
Q_PROPERTY(bool minimizeable READ isMinimizable CONSTANT)
Q_PROPERTY(bool modal READ isModal)
Q_PROPERTY(bool moveable READ isMovable CONSTANT)
Q_PROPERTY(bool onAllDesktops READ isOnAllDesktops NOTIFY desktopChanged)
Q_PROPERTY(bool preview READ isPreview CONSTANT)
Q_PROPERTY(bool resizeable READ isResizable CONSTANT)
Q_PROPERTY(bool setShade READ isSetShade NOTIFY shadeChanged)
Q_PROPERTY(bool shade READ isShade WRITE setShade NOTIFY shadeChanged)
Q_PROPERTY(bool shadeable READ isShadeable)
Q_PROPERTY(bool keepAbove READ keepAbove WRITE setKeepAbove NOTIFY keepAboveChangedWrapper)
Q_PROPERTY(bool keepBelow READ keepBelow WRITE setKeepBelow NOTIFY keepBelowChangedWrapper)
Q_PROPERTY(bool maximized READ isMaximized NOTIFY maximizeChanged)
Q_PROPERTY(bool providesContextHelp READ providesContextHelp)
Q_PROPERTY(QRect transparentRect READ transparentRect)
Q_PROPERTY(int width READ width)
Q_PROPERTY(qulonglong windowId READ windowId CONSTANT)
Q_PROPERTY(int doubleClickInterval READ doubleClickInterval)
Q_PROPERTY(bool animationsSupported READ animationsSupported CONSTANT)
// TODO: window tabs - they suck for dynamic features
public:
AuroraeClient(KDecorationBridge* bridge, KDecorationFactory* factory);
virtual ~AuroraeClient();
virtual bool eventFilter(QObject *object, QEvent *event);
virtual void activeChange();
virtual void borders(int& left, int& right, int& top, int& bottom) const;
virtual void captionChange();
virtual void desktopChange();
virtual void iconChange();
virtual void init();
virtual void maximizeChange();
virtual QSize minimumSize() const;
virtual Position mousePosition(const QPoint& p) const;
virtual void resize(const QSize& s);
virtual void shadeChange();
// optional overrides
virtual void padding(int &left, int &right, int &top, int &bottom) const;
virtual void reset(long unsigned int changed);
bool isMaximized() const;
int doubleClickInterval() const;
bool animationsSupported() const;
Q_INVOKABLE QVariant readConfig(const QString &key, const QVariant &defaultValue = QVariant());
Q_SIGNALS:
void activeChanged();
void captionChanged();
void desktopChanged();
void iconChanged();
void maximizeChanged();
void shadeChanged();
void keepAboveChangedWrapper();
void keepBelowChangedWrapper();
void buttonsChanged();
/**
* Signal emitted when the decoration's configuration might have changed.
* A decoration could reload it's configuration when this signal is emitted.
**/
void configChanged();
void fontChanged();
public slots:
void menuClicked();
void toggleShade();
void toggleKeepAbove();
void toggleKeepBelow();
void titlePressed(int button, int buttons);
void titleReleased(int button, int buttons);
void titleMouseMoved(int button, int buttons);
void titlePressed(Qt::MouseButton button, Qt::MouseButtons buttons);
void titleReleased(Qt::MouseButton button, Qt::MouseButtons buttons);
void titleMouseMoved(Qt::MouseButton button, Qt::MouseButtons buttons);
void closeWindow();
void titlebarDblClickOperation();
void maximize(int button);
QRegion region(KDecorationDefines::Region r);
private slots:
void themeChanged();
void doCloseWindow();
void doTitlebarDblClickOperation();
void doMaximzie(int button);
void slotAlphaChanged();
private:
void sizesFromBorders(const QObject *borders, int &left, int &right, int &top, int &bottom) const;
QGraphicsView *m_view;
QGraphicsScene *m_scene;
QDeclarativeItem *m_item;
};
}
#endif

View file

@ -1,65 +0,0 @@
/********************************************************************
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
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, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "colorhelper.h"
#include <KGlobalSettings>
#include <KColorScheme>
ColorHelper::ColorHelper(QObject *parent)
: QObject(parent)
{
}
ColorHelper::~ColorHelper()
{
}
QColor ColorHelper::shade(const QColor &color, ColorHelper::ShadeRole role)
{
return KColorScheme::shade(color, static_cast<KColorScheme::ShadeRole>(role));
}
QColor ColorHelper::shade(const QColor &color, ColorHelper::ShadeRole role, qreal contrast)
{
return KColorScheme::shade(color, static_cast<KColorScheme::ShadeRole>(role), contrast);
}
qreal ColorHelper::contrast() const
{
return KGlobalSettings::contrastF();
}
QColor ColorHelper::multiplyAlpha(const QColor &color, qreal alpha)
{
QColor retCol(color);
retCol.setAlphaF(color.alphaF() * alpha);
return retCol;
}
QColor ColorHelper::background(bool active, ColorHelper::BackgroundRole role) const
{
KColorScheme kcs(active ? QPalette::Active : QPalette::Inactive, KColorScheme::Button);
return kcs.background(static_cast<KColorScheme::BackgroundRole>(role)).color();
}
QColor ColorHelper::foreground(bool active, ColorHelper::ForegroundRole role) const
{
KColorScheme kcs(active ? QPalette::Active : QPalette::Inactive, KColorScheme::Button);
return kcs.foreground(static_cast<KColorScheme::ForegroundRole>(role)).color();
}
#include "moc_colorhelper.cpp"

View file

@ -1,240 +0,0 @@
/********************************************************************
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
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, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef COLOR_HELPER_H
#define COLOR_HELPER_H
#include <QObject>
#include <QColor>
/**
* @short Helper to manipulate colors.
*
* Exports a few functions from KColorScheme.
**/
class ColorHelper : public QObject
{
Q_OBJECT
Q_ENUMS(ShadeRole)
Q_ENUMS(ForegroundRole)
Q_ENUMS(BackgroundRole)
/**
* Same as KGlobalSettings::contrastF.
**/
Q_PROPERTY(qreal contrast READ contrast CONSTANT)
public:
explicit ColorHelper(QObject *parent = 0);
~ColorHelper();
/**
* This enumeration describes the color shade being selected from the given
* set.
*
* Color shades are used to draw "3d" elements, such as frames and bevels.
* They are neither foreground nor background colors. Text should not be
* painted over a shade, and shades should not be used to draw text.
*/
enum ShadeRole {
/**
* The light color is lighter than dark() or shadow() and contrasts
* with the base color.
*/
LightShade,
/**
* The midlight color is in between base() and light().
*/
MidlightShade,
/**
* The mid color is in between base() and dark().
*/
MidShade,
/**
* The dark color is in between mid() and shadow().
*/
DarkShade,
/**
* The shadow color is darker than light() or midlight() and contrasts
* the base color.
*/
ShadowShade
};
/**
* This enumeration describes the background color being selected from the
* given set.
*
* Background colors are suitable for drawing under text, and should never
* be used to draw text. In combination with one of the overloads of
* KColorScheme::shade, they may be used to generate colors for drawing
* frames, bevels, and similar decorations.
*/
enum BackgroundRole {
/**
* Normal background.
*/
NormalBackground = 0,
/**
* Alternate background; for example, for use in lists.
*
* This color may be the same as BackgroundNormal, especially in sets
* other than View and Window.
*/
AlternateBackground = 1,
/**
* Third color; for example, items which are new, active, requesting
* attention, etc.
*
* Alerting the user that a certain field must be filled out would be a
* good usage (although NegativeBackground could be used to the same
* effect, depending on what you are trying to achieve). Unlike
* ActiveText, this should not be used for mouseover effects.
*/
ActiveBackground = 2,
/**
* Fourth color; corresponds to (unvisited) links.
*
* Exactly what this might be used for is somewhat harder to qualify;
* it might be used for bookmarks, as a 'you can click here' indicator,
* or to highlight recent content (i.e. in a most-recently-accessed
* list).
*/
LinkBackground = 3,
/**
* Fifth color; corresponds to visited links.
*
* This can also be used to indicate "not recent" content, especially
* when a color is needed to denote content which is "old" or
* "archival".
*/
VisitedBackground = 4,
/**
* Sixth color; for example, errors, untrusted content, etc.
*/
NegativeBackground = 5,
/**
* Seventh color; for example, warnings, secure/encrypted content.
*/
NeutralBackground = 6,
/**
* Eigth color; for example, success messages, trusted content.
*/
PositiveBackground = 7
};
/**
* This enumeration describes the foreground color being selected from the
* given set.
*
* Foreground colors are suitable for drawing text or glyphs (such as the
* symbols on window decoration buttons, assuming a suitable background
* brush is used), and should never be used to draw backgrounds.
*
* For window decorations, the following is suggested, but not set in
* stone:
* @li Maximize - PositiveText
* @li Minimize - NeutralText
* @li Close - NegativeText
* @li WhatsThis - LinkText
* @li Sticky - ActiveText
*/
enum ForegroundRole {
/**
* Normal foreground.
*/
NormalText = 0,
/**
* Second color; for example, comments, items which are old, inactive
* or disabled. Generally used for things that are meant to be "less
* important". InactiveText is not the same role as NormalText in the
* inactive state.
*/
InactiveText = 1,
/**
* Third color; for example items which are new, active, requesting
* attention, etc. May be used as a hover color for clickable items.
*/
ActiveText = 2,
/**
* Fourth color; use for (unvisited) links. May also be used for other
* clickable items or content that indicates relationships, items that
* indicate somewhere the user can visit, etc.
*/
LinkText = 3,
/**
* Fifth color; used for (visited) links. As with LinkText, may be used
* for items that have already been "visited" or accessed. May also be
* used to indicate "historical" (i.e. "old") items or information,
* especially if InactiveText is being used in the same context to
* express something different.
*/
VisitedText = 4,
/**
* Sixth color; for example, errors, untrusted content, deletions,
* etc.
*/
NegativeText = 5,
/**
* Seventh color; for example, warnings, secure/encrypted content.
*/
NeutralText = 6,
/**
* Eigth color; for example, additions, success messages, trusted
* content.
*/
PositiveText = 7
};
/**
* Retrieve the requested shade color, using the specified color as the
* base color and the system contrast setting.
*
* @note Shades are chosen such that all shades would contrast with the
* base color. This means that if base is very dark, the 'dark' shades will
* be lighter than the base color, with midlight() == shadow().
* Conversely, if the base color is very light, the 'light' shades will be
* darker than the base color, with light() == mid().
*/
Q_INVOKABLE QColor shade(const QColor& color, ShadeRole role);
Q_INVOKABLE QColor shade(const QColor& color, ShadeRole role, qreal contrast); /**
* Retrieve the requested shade color, using the specified color as the
* base color and the specified contrast.
*
* @param contrast Amount roughly specifying the contrast by which to
* adjust the base color, between -1.0 and 1.0 (values between 0.0 and 1.0
* correspond to the value from KGlobalSettings::contrastF)
*
* @note Shades are chosen such that all shades would contrast with the
* base color. This means that if base is very dark, the 'dark' shades will
* be lighter than the base color, with midlight() == shadow().
* Conversely, if the base color is very light, the 'light' shades will be
* darker than the base color, with light() == mid().
*
* @see KColorUtils::shade
*/
Q_INVOKABLE QColor multiplyAlpha(const QColor& color, qreal alpha);
/**
* Retrieve the requested background brush's color for the @p active button.
* @param active Whether the active or inactive palette should be used.
*/
Q_INVOKABLE QColor background(bool active, BackgroundRole role = NormalBackground) const;
/**
* Retrieve the requested foreground brush's color for the @p active button.
* @param active Whether the active or inactive palette should be used.
*/
Q_INVOKABLE QColor foreground(bool active, ForegroundRole role = NormalText) const;
qreal contrast() const;
};
#endif

View file

@ -1,181 +0,0 @@
/********************************************************************
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
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, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "decorationoptions.h"
#include <kdecoration.h>
namespace KWin
{
DecorationOptions::DecorationOptions(QObject *parent)
: QObject(parent)
, m_active(true)
, m_decoration(NULL)
{
connect(this, SIGNAL(decorationChanged()), SLOT(slotActiveChanged()));
connect(this, SIGNAL(decorationChanged()), SIGNAL(colorsChanged()));
connect(this, SIGNAL(decorationChanged()), SIGNAL(fontChanged()));
}
DecorationOptions::~DecorationOptions()
{
}
QColor DecorationOptions::borderColor() const
{
return KDecoration::options()->color(KDecorationDefines::ColorFrame, m_active);
}
QColor DecorationOptions::buttonColor() const
{
return KDecoration::options()->color(KDecorationDefines::ColorButtonBg, m_active);
}
QColor DecorationOptions::fontColor() const
{
return KDecoration::options()->color(KDecorationDefines::ColorFont, m_active);
}
QColor DecorationOptions::resizeHandleColor() const
{
return KDecoration::options()->color(KDecorationDefines::ColorHandle, m_active);
}
QColor DecorationOptions::titleBarBlendColor() const
{
return KDecoration::options()->color(KDecorationDefines::ColorTitleBlend, m_active);
}
QColor DecorationOptions::titleBarColor() const
{
return KDecoration::options()->color(KDecorationDefines::ColorTitleBar, m_active);
}
QFont DecorationOptions::titleFont() const
{
return KDecoration::options()->font(m_active);
}
QString DecorationOptions::titleButtonsLeft() const
{
if (KDecoration::options()->customButtonPositions()) {
return KDecoration::options()->titleButtonsLeft();
} else {
return KDecorationOptions::defaultTitleButtonsLeft();
}
}
QString DecorationOptions::titleButtonsRight() const
{
if (KDecoration::options()->customButtonPositions()) {
return KDecoration::options()->titleButtonsRight();
} else {
return KDecorationOptions::defaultTitleButtonsRight();
}
}
QObject *DecorationOptions::decoration() const
{
return m_decoration;
}
void DecorationOptions::setDecoration(QObject *decoration)
{
if (m_decoration == decoration) {
return;
}
if (m_decoration) {
// disconnect from existing decoration
disconnect(m_decoration, SIGNAL(activeChanged()), this, SLOT(slotActiveChanged()));
disconnect(m_decoration, SIGNAL(buttonsChanged()), this, SIGNAL(titleButtonsChanged()));
disconnect(m_decoration, SIGNAL(fontChanged()), this, SIGNAL(fontChanged()));
}
m_decoration = decoration;
connect(m_decoration, SIGNAL(activeChanged()), SLOT(slotActiveChanged()));
connect(m_decoration, SIGNAL(buttonsChanged()), SIGNAL(titleButtonsChanged()));
connect(m_decoration, SIGNAL(fontChanged()), SIGNAL(fontChanged()));
emit decorationChanged();
}
void DecorationOptions::slotActiveChanged()
{
if (!m_decoration) {
return;
}
if (m_active == m_decoration->property("active").toBool()) {
return;
}
m_active = m_decoration->property("active").toBool();
emit colorsChanged();
emit fontChanged();
}
Borders::Borders(QObject *parent)
: QObject(parent)
, m_left(0)
, m_right(0)
, m_top(0)
, m_bottom(0)
{
}
Borders::~Borders()
{
}
#define SETTER( methodName, name ) \
void Borders::methodName(int name) \
{ \
if (m_##name == name) { \
return; \
} \
m_##name = name; \
emit name##Changed(); \
}
SETTER(setLeft, left)
SETTER(setRight, right)
SETTER(setTop, top)
SETTER(setBottom, bottom)
#undef SETTER
void Borders::setAllBorders(int border)
{
setBorders(border);
setTitle(border);
}
void Borders::setBorders(int border)
{
setSideBorders(border);
setBottom(border);
}
void Borders::setSideBorders(int border)
{
setLeft(border);
setRight(border);
}
void Borders::setTitle(int value)
{
setTop(value);
}
} // namespace
#include "moc_decorationoptions.cpp"

View file

@ -1,222 +0,0 @@
/********************************************************************
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
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, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_DECORATION_OPTIONS_H
#define KWIN_DECORATION_OPTIONS_H
#include <QObject>
#include <QColor>
#include <QFont>
namespace KWin
{
/**
* @short Common Window Decoration Options.
*
* This Class provides common window decoration options which can be used, but do not have to
* be used by a window decoration. The class provides properties for global settings such as
* color, font and decoration button position.
*
* If a window decoration wants to follow the global color scheme it should honor the values
* provided by the properties.
*
* In any case it makes sense to respect the font settings for the decoration as this is also
* an accessibility feature.
*
* In order to use the options in a QML based window decoration an instance of this object needs
* to be created and the as a context property available "decoration" needs to be passed to the
* DecorationOptions instance:
*
* @code
* DecorationOptions {
* id: options
* deco: decoration
* }
* @endcode
**/
class DecorationOptions : public QObject
{
Q_OBJECT
Q_ENUMS(BorderSize)
/**
* The decoration Object for which this set of options should be used. The decoration is
* required to get the correct colors and fonts depending on whether the decoration represents
* an active or inactive window.
*
* Best pass the decoration object available as a context property to this property.
**/
Q_PROPERTY(QObject *deco READ decoration WRITE setDecoration NOTIFY decorationChanged)
/**
* The color for the titlebar depending on the decoration's active state.
**/
Q_PROPERTY(QColor titleBarColor READ titleBarColor NOTIFY colorsChanged)
/**
* The blend color for the titlebar depending on the decoration's active state.
**/
Q_PROPERTY(QColor titleBarBlendColor READ titleBarBlendColor NOTIFY colorsChanged)
/**
* The titlebar text color depending on the decoration's active state.
**/
Q_PROPERTY(QColor fontColor READ fontColor NOTIFY colorsChanged)
/**
* The color to use for titlebar buttons depending on the decoration's active state.
**/
Q_PROPERTY(QColor buttonColor READ buttonColor NOTIFY colorsChanged)
/**
* The color for the window frame (border) depending on the decoration's active state.
**/
Q_PROPERTY(QColor borderColor READ borderColor NOTIFY colorsChanged)
/**
* The color for the resize handle depending on the decoration's active state.
**/
Q_PROPERTY(QColor resizeHandleColor READ resizeHandleColor NOTIFY colorsChanged)
/**
* The font to be used for the decoration caption depending on the decoration's active state.
**/
Q_PROPERTY(QFont titleFont READ titleFont NOTIFY fontChanged)
/**
* The buttons to be positioned on the left side of the titlebar from left to right.
*
* Characters in the returned string have the following meaning:
* <ul>
* <li>'M' menu button</li>
* <li>'S' on all desktops button</li>
* <li>'H' quickhelp button</li>
* <li>'I' minimize button</li>
* <li>'A' maximize button</li>
* <li>'X' close button</li>
* <li>'F' keep above button</li>
* <li>'B' keep below button</li>
* <li>'L' shade button</li>
* <li>'_' explicit spacer</li>
* </ul>
* @todo: make this a list of enum values
**/
Q_PROPERTY(QString titleButtonsLeft READ titleButtonsLeft NOTIFY titleButtonsChanged)
/**
* The buttons to be positioned on the right side of the titlebar from left to right.
* @see titleButtonsRight
**/
Q_PROPERTY(QString titleButtonsRight READ titleButtonsRight NOTIFY titleButtonsChanged)
public:
enum BorderSize {
BorderTiny, ///< Minimal borders
BorderNormal, ///< Standard size borders, the default setting
BorderLarge, ///< Larger borders
BorderVeryLarge, ///< Very large borders
BorderHuge, ///< Huge borders
BorderVeryHuge, ///< Very huge borders
BorderOversized, ///< Oversized borders
BorderNoSides, ///< No borders on sides
BorderNone ///< No borders except title
};
explicit DecorationOptions(QObject *parent = 0);
virtual ~DecorationOptions();
QColor titleBarColor() const;
QColor titleBarBlendColor() const;
QColor fontColor() const;
QColor buttonColor() const;
QColor borderColor() const;
QColor resizeHandleColor() const;
QFont titleFont() const;
QString titleButtonsLeft() const;
QString titleButtonsRight() const;
QObject *decoration() const;
void setDecoration(QObject *decoration);
signals:
void colorsChanged();
void fontChanged();
void decorationChanged();
void titleButtonsChanged();
private slots:
void slotActiveChanged();
private:
bool m_active;
QObject *m_decoration;
};
class Borders : public QObject
{
Q_OBJECT
Q_PROPERTY(int left READ left WRITE setLeft NOTIFY leftChanged)
Q_PROPERTY(int right READ right WRITE setRight NOTIFY rightChanged)
Q_PROPERTY(int top READ top WRITE setTop NOTIFY topChanged)
Q_PROPERTY(int bottom READ bottom WRITE setBottom NOTIFY bottomChanged)
public:
Borders(QObject *parent = NULL);
virtual ~Borders();
int left() const;
int right() const;
int top() const;
int bottom() const;
void setLeft(int left);
void setRight(int right);
void setTop(int top);
void setBottom(int bottom);
public Q_SLOTS:
/**
* Sets all four borders to @p value.
**/
void setAllBorders(int value);
/**
* Sets all borders except the title border to @p value.
**/
void setBorders(int value);
/**
* Sets the side borders (e.g. if title is on top, the left and right borders)
* to @p value.
**/
void setSideBorders(int value);
/**
* Sets the title border to @p value.
**/
void setTitle(int value);
Q_SIGNALS:
void leftChanged();
void rightChanged();
void topChanged();
void bottomChanged();
private:
int m_left;
int m_right;
int m_top;
int m_bottom;
};
#define GETTER( name ) \
inline int Borders::name() const \
{ \
return m_##name;\
}\
GETTER(left)
GETTER(right)
GETTER(top)
GETTER(bottom)
#undef GETTER
} // namespace
#endif // KWIN_DECORATION_OPTIONS_H

View file

@ -1,32 +0,0 @@
/********************************************************************
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
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, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "decorationplugin.h"
#include "colorhelper.h"
#include "decorationoptions.h"
#include <qdeclarative.h>
Q_EXPORT_PLUGIN(DecorationPlugin)
void DecorationPlugin::registerTypes(const char *uri)
{
Q_ASSERT(uri == QLatin1String("org.kde.kwin.decoration"));
qmlRegisterType<ColorHelper>(uri, 0, 1, "ColorHelper");
qmlRegisterType<KWin::DecorationOptions>(uri, 0, 1, "DecorationOptions");
qmlRegisterType<KWin::Borders>(uri, 0, 1, "Borders");
}
#include "moc_decorationplugin.cpp"

View file

@ -1,28 +0,0 @@
/********************************************************************
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
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, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef DECORATION_PLUGIN_H
#define DECORATION_PLUGIN_H
#include <QDeclarativeExtensionPlugin>
class DecorationPlugin : public QDeclarativeExtensionPlugin
{
Q_OBJECT
public:
void registerTypes(const char *uri);
};
#endif

View file

@ -1,53 +0,0 @@
[Desktop Entry]
Type=ServiceType
X-KDE-ServiceType=KWin/Decoration
Comment=KWin Window Decoration
Comment[bs]=KWin Dekoracije prozora
Comment[ca]=Decoració de finestres del KWin
Comment[ca@valencia]=Decoració de finestres del KWin
Comment[cs]=Dekorace oken KWin
Comment[da]=KWin vinduesdekoration
Comment[de]=KWin-Fensterdekoration
Comment[el]=Διακοσμήσεις παραθύρου KWin
Comment[en_GB]=KWin Window Decoration
Comment[es]=Decoración de ventanas de KWin
Comment[et]=KWini akna dekoratsioon
Comment[eu]=KWin leihoen apainketa
Comment[fi]=KWin-ikkunan kehys
Comment[fr]=Décorations de fenêtres KWin
Comment[ga]=Maisiúchán Fuinneog KWin
Comment[gl]=Decoración de xanela de Kwin
Comment[he]=קישוטי חלון
Comment[hu]=KWin ablakdekoráció
Comment[ia]=Decorationes de fenestra de KWin
Comment[is]=KWin gluggaskreytingar
Comment[it]=Decorazione delle finestre di KWin
Comment[kk]=KWin терезе безендіруі
Comment[ko]=KWin
Comment[lt]=KWin lango dekoracija
Comment[mr]=-ि
Comment[nb]=KWin Vinduspynt
Comment[nds]=KWin-Finsterdekoratschoon
Comment[nl]=KWin vensterdecoratie
Comment[pa]=ਿ ਿ
Comment[pl]=Wystrój okien KWin
Comment[pt]=Decoração das Janelas do KWin
Comment[pt_BR]=Decorações de janelas do KWin
Comment[ro]=Decorații de fereastră KWin
Comment[ru]=Оформление окон KWin
Comment[sk]=Dekorácie okien KWin
Comment[sl]=Okraski oken KWin
Comment[sr]=Квинова декорација прозора
Comment[sr@ijekavian]=Квинова декорација прозора
Comment[sr@ijekavianlatin]=KWinova dekoracija prozora
Comment[sr@latin]=KWinova dekoracija prozora
Comment[sv]=Kwin-fönsterdekorationer
Comment[tr]=KWin Pencere Dekorasyonu
Comment[uk]=Обрамлення вікон KWin
Comment[x-test]=xxKWin Window Decorationxx
Comment[zh_CN]=KWin
Comment[zh_TW]=KWin
[PropertyDef::X-Plasma-MainScript]
Type=QString

View file

@ -1,512 +0,0 @@
/*
Library for Aurorae window decoration themes.
Copyright (C) 2009, 2010, 2012 Martin Gräßlin <mgraesslin@kde.org>
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 "auroraetheme.h"
#include "themeconfig.h"
// Qt
#include <QHash>
// KDE
#include <KConfig>
#include <KConfigGroup>
#include <KDebug>
#include <KStandardDirs>
#include <KGlobal>
namespace Aurorae {
/************************************************
* AuroraeThemePrivate
************************************************/
class AuroraeThemePrivate
{
public:
AuroraeThemePrivate();
~AuroraeThemePrivate();
void initButtonFrame(AuroraeButtonType type);
QString themeName;
Aurorae::ThemeConfig themeConfig;
QHash< AuroraeButtonType, QString > pathes;
bool activeCompositing;
KDecorationDefines::BorderSize borderSize;
KDecorationDefines::BorderSize buttonSize;
QString dragMimeType;
QString decorationPath;
};
AuroraeThemePrivate::AuroraeThemePrivate()
:activeCompositing(true)
, borderSize(KDecoration::BorderNormal)
, buttonSize(KDecoration::BorderNormal)
{
}
AuroraeThemePrivate::~AuroraeThemePrivate()
{
}
void AuroraeThemePrivate::initButtonFrame(AuroraeButtonType type)
{
QString file("aurorae/themes/" + themeName + '/' + AuroraeTheme::mapButtonToName(type) + ".svg");
QString path = KGlobal::dirs()->findResource("data", file);
if (path.isEmpty()) {
// let's look for svgz
file.append("z");
path = KGlobal::dirs()->findResource("data", file);
}
if (!path.isEmpty()) {
pathes[ type ] = path;
} else {
kDebug(1216) << "No button for: " << AuroraeTheme::mapButtonToName(type);
}
}
/************************************************
* AuroraeTheme
************************************************/
AuroraeTheme::AuroraeTheme(QObject* parent)
: QObject(parent)
, d(new AuroraeThemePrivate)
{
connect(this, SIGNAL(themeChanged()), SIGNAL(borderSizesChanged()));
connect(this, SIGNAL(buttonSizesChanged()), SIGNAL(borderSizesChanged()));
}
AuroraeTheme::~AuroraeTheme()
{
delete d;
}
bool AuroraeTheme::isValid() const
{
return !d->themeName.isNull();
}
void AuroraeTheme::loadTheme(const QString &name)
{
KConfig conf("auroraerc");
KConfig config("aurorae/themes/" + name + '/' + name + "rc", KConfig::FullConfig, "data");
KConfigGroup themeGroup(&conf, name);
loadTheme(name, config);
setBorderSize((KDecorationDefines::BorderSize)themeGroup.readEntry<int>("BorderSize", KDecorationDefines::BorderNormal));
setButtonSize((KDecorationDefines::BorderSize)themeGroup.readEntry<int>("ButtonSize", KDecorationDefines::BorderNormal));
}
void AuroraeTheme::loadTheme(const QString &name, const KConfig &config)
{
d->themeName = name;
QString file("aurorae/themes/" + d->themeName + "/decoration.svg");
QString path = KGlobal::dirs()->findResource("data", file);
if (path.isEmpty()) {
file += 'z';
path = KGlobal::dirs()->findResource("data", file);
}
if (path.isEmpty()) {
kDebug(1216) << "Could not find decoration svg: aborting";
d->themeName.clear();
return;
}
d->decorationPath = path;
// load the buttons
d->initButtonFrame(MinimizeButton);
d->initButtonFrame(MaximizeButton);
d->initButtonFrame(RestoreButton);
d->initButtonFrame(CloseButton);
d->initButtonFrame(AllDesktopsButton);
d->initButtonFrame(KeepAboveButton);
d->initButtonFrame(KeepBelowButton);
d->initButtonFrame(ShadeButton);
d->initButtonFrame(HelpButton);
d->themeConfig.load(config);
emit themeChanged();
}
bool AuroraeTheme::hasButton(AuroraeButtonType button) const
{
return d->pathes.contains(button);
}
QLatin1String AuroraeTheme::mapButtonToName(AuroraeButtonType type)
{
switch(type) {
case MinimizeButton:
return QLatin1String("minimize");
case MaximizeButton:
return QLatin1String("maximize");
case RestoreButton:
return QLatin1String("restore");
case CloseButton:
return QLatin1String("close");
case AllDesktopsButton:
return QLatin1String("alldesktops");
case KeepAboveButton:
return QLatin1String("keepabove");
case KeepBelowButton:
return QLatin1String("keepbelow");
case ShadeButton:
return QLatin1String("shade");
case HelpButton:
return QLatin1String("help");
case MenuButton:
return QLatin1String("menu");
default:
return QLatin1String("");
}
}
const QString &AuroraeTheme::themeName() const
{
return d->themeName;
}
void AuroraeTheme::borders(int& left, int& top, int& right, int& bottom, bool maximized) const
{
const qreal titleHeight = qMax((qreal)d->themeConfig.titleHeight(),
d->themeConfig.buttonHeight()*buttonSizeFactor() +
d->themeConfig.buttonMarginTop());
if (maximized) {
const qreal title = titleHeight + d->themeConfig.titleEdgeTopMaximized() + d->themeConfig.titleEdgeBottomMaximized();
switch ((DecorationPosition)d->themeConfig.decorationPosition()) {
case DecorationTop:
left = right = bottom = 0;
top = title;
break;
case DecorationBottom:
left = right = top = 0;
bottom = title;
break;
case DecorationLeft:
top = right = bottom = 0;
left = title;
break;
case DecorationRight:
left = top = bottom = 0;
right = title;
break;
default:
left = right = bottom = top = 0;
break;
}
} else {
switch (d->borderSize) {
case KDecoration::BorderTiny:
// TODO: this looks wrong
if (isCompositingActive()) {
left = qMin(0, (int)left - d->themeConfig.borderLeft() - d->themeConfig.paddingLeft());
right = qMin(0, (int)right - d->themeConfig.borderRight() - d->themeConfig.paddingRight());
bottom = qMin(0, (int)bottom - d->themeConfig.borderBottom() - d->themeConfig.paddingBottom());
} else {
left = qMin(0, (int)left - d->themeConfig.borderLeft());
right = qMin(0, (int)right - d->themeConfig.borderRight());
bottom = qMin(0, (int)bottom - d->themeConfig.borderBottom());
}
break;
case KDecoration::BorderLarge:
left = right = bottom = top = 4;
break;
case KDecoration::BorderVeryLarge:
left = right = bottom = top = 8;
break;
case KDecoration::BorderHuge:
left = right = bottom = top = 12;
break;
case KDecoration::BorderVeryHuge:
left = right = bottom = top = 23;
break;
case KDecoration::BorderOversized:
left = right = bottom = top = 36;
break;
case KDecoration::BorderNormal:
default:
left = right = bottom = top = 0;
}
const qreal title = titleHeight + d->themeConfig.titleEdgeTop() + d->themeConfig.titleEdgeBottom();
switch ((DecorationPosition)d->themeConfig.decorationPosition()) {
case DecorationTop:
left += d->themeConfig.borderLeft();
right += d->themeConfig.borderRight();
bottom += d->themeConfig.borderBottom();
top = title;
break;
case DecorationBottom:
left += d->themeConfig.borderLeft();
right += d->themeConfig.borderRight();
bottom = title;
top += d->themeConfig.borderTop();
break;
case DecorationLeft:
left = title;
right += d->themeConfig.borderRight();
bottom += d->themeConfig.borderBottom();
top += d->themeConfig.borderTop();
break;
case DecorationRight:
left += d->themeConfig.borderLeft();
right = title;
bottom += d->themeConfig.borderBottom();
top += d->themeConfig.borderTop();
break;
default:
left = right = bottom = top = 0;
break;
}
}
}
int AuroraeTheme::bottomBorder() const
{
int left, top, right, bottom;
left = top = right = bottom = 0;
borders(left, top, right, bottom, false);
return bottom;
}
int AuroraeTheme::leftBorder() const
{
int left, top, right, bottom;
left = top = right = bottom = 0;
borders(left, top, right, bottom, false);
return left;
}
int AuroraeTheme::rightBorder() const
{
int left, top, right, bottom;
left = top = right = bottom = 0;
borders(left, top, right, bottom, false);
return right;
}
int AuroraeTheme::topBorder() const
{
int left, top, right, bottom;
left = top = right = bottom = 0;
borders(left, top, right, bottom, false);
return top;
}
int AuroraeTheme::bottomBorderMaximized() const
{
int left, top, right, bottom;
left = top = right = bottom = 0;
borders(left, top, right, bottom, true);
return bottom;
}
int AuroraeTheme::leftBorderMaximized() const
{
int left, top, right, bottom;
left = top = right = bottom = 0;
borders(left, top, right, bottom, true);
return left;
}
int AuroraeTheme::rightBorderMaximized() const
{
int left, top, right, bottom;
left = top = right = bottom = 0;
borders(left, top, right, bottom, true);
return right;
}
int AuroraeTheme::topBorderMaximized() const
{
int left, top, right, bottom;
left = top = right = bottom = 0;
borders(left, top, right, bottom, true);
return top;
}
void AuroraeTheme::padding(int& left, int& top, int& right, int& bottom) const
{
left = d->themeConfig.paddingLeft();
top = d->themeConfig.paddingTop();
right = d->themeConfig.paddingRight();
bottom = d->themeConfig.paddingBottom();
}
#define THEME_CONFIG( prototype ) \
int AuroraeTheme::prototype ( ) const \
{ \
return d->themeConfig.prototype( ); \
}
THEME_CONFIG(paddingBottom)
THEME_CONFIG(paddingLeft)
THEME_CONFIG(paddingRight)
THEME_CONFIG(paddingTop)
THEME_CONFIG(buttonWidth)
THEME_CONFIG(buttonWidthMinimize)
THEME_CONFIG(buttonWidthMaximizeRestore)
THEME_CONFIG(buttonWidthClose)
THEME_CONFIG(buttonWidthAllDesktops)
THEME_CONFIG(buttonWidthKeepAbove)
THEME_CONFIG(buttonWidthKeepBelow)
THEME_CONFIG(buttonWidthShade)
THEME_CONFIG(buttonWidthHelp)
THEME_CONFIG(buttonWidthMenu)
THEME_CONFIG(buttonHeight)
THEME_CONFIG(buttonSpacing)
THEME_CONFIG(buttonMarginTop)
THEME_CONFIG(explicitButtonSpacer)
THEME_CONFIG(animationTime)
THEME_CONFIG(titleEdgeLeft)
THEME_CONFIG(titleEdgeRight)
THEME_CONFIG(titleEdgeTop)
THEME_CONFIG(titleEdgeLeftMaximized)
THEME_CONFIG(titleEdgeRightMaximized)
THEME_CONFIG(titleEdgeTopMaximized)
THEME_CONFIG(titleBorderLeft)
THEME_CONFIG(titleBorderRight)
THEME_CONFIG(titleHeight)
#undef THEME_CONFIG
#define THEME_CONFIG_TYPE( rettype, prototype ) \
rettype AuroraeTheme::prototype ( ) const \
{\
return d->themeConfig.prototype(); \
}
THEME_CONFIG_TYPE(QColor, activeTextColor)
THEME_CONFIG_TYPE(QColor, inactiveTextColor)
THEME_CONFIG_TYPE(Qt::Alignment, alignment)
THEME_CONFIG_TYPE(Qt::Alignment, verticalAlignment)
#undef THEME_CONFIG_TYPE
QString AuroraeTheme::decorationPath() const
{
return d->decorationPath;
}
#define BUTTON_PATH( prototype, buttonType ) \
QString AuroraeTheme::prototype ( ) const \
{ \
if (hasButton( buttonType )) { \
return d->pathes[ buttonType ]; \
} else { \
return ""; \
} \
}\
BUTTON_PATH(minimizeButtonPath, MinimizeButton)
BUTTON_PATH(maximizeButtonPath, MaximizeButton)
BUTTON_PATH(restoreButtonPath, RestoreButton)
BUTTON_PATH(closeButtonPath, CloseButton)
BUTTON_PATH(allDesktopsButtonPath, AllDesktopsButton)
BUTTON_PATH(keepAboveButtonPath, KeepAboveButton)
BUTTON_PATH(keepBelowButtonPath, KeepBelowButton)
BUTTON_PATH(shadeButtonPath, ShadeButton)
BUTTON_PATH(helpButtonPath, HelpButton)
#undef BUTTON_PATH
void AuroraeTheme::titleEdges(int &left, int &top, int &right, int &bottom, bool maximized) const
{
if (maximized) {
left = d->themeConfig.titleEdgeLeftMaximized();
top = d->themeConfig.titleEdgeTopMaximized();
right = d->themeConfig.titleEdgeRightMaximized();
bottom = d->themeConfig.titleEdgeBottomMaximized();
} else {
left = d->themeConfig.titleEdgeLeft();
top = d->themeConfig.titleEdgeTop();
right = d->themeConfig.titleEdgeRight();
bottom = d->themeConfig.titleEdgeBottom();
}
}
bool AuroraeTheme::isCompositingActive() const
{
return d->activeCompositing;
}
void AuroraeTheme::setCompositingActive(bool active)
{
d->activeCompositing = active;
}
QString AuroraeTheme::defaultButtonsLeft() const
{
return d->themeConfig.defaultButtonsLeft();
}
QString AuroraeTheme::defaultButtonsRight() const
{
return d->themeConfig.defaultButtonsRight();
}
void AuroraeTheme::setBorderSize(KDecorationDefines::BorderSize size)
{
if (d->borderSize == size) {
return;
}
d->borderSize = size;
emit borderSizesChanged();
}
void AuroraeTheme::setButtonSize(KDecorationDefines::BorderSize size)
{
if (d->buttonSize == size) {
return;
}
d->buttonSize = size;
emit buttonSizesChanged();
}
void AuroraeTheme::setTabDragMimeType(const QString &mime)
{
d->dragMimeType = mime;
}
const QString &AuroraeTheme::tabDragMimeType() const
{
return d->dragMimeType;
}
qreal AuroraeTheme::buttonSizeFactor() const
{
switch (d->buttonSize) {
case KDecorationDefines::BorderTiny:
return 0.8;
case KDecorationDefines::BorderLarge:
return 1.2;
case KDecorationDefines::BorderVeryLarge:
return 1.4;
case KDecorationDefines::BorderHuge:
return 1.6;
case KDecorationDefines::BorderVeryHuge:
return 1.8;
case KDecorationDefines::BorderOversized:
return 2.0;
case KDecorationDefines::BorderNormal: // fall through
default:
return 1.0;
}
}
DecorationPosition AuroraeTheme::decorationPosition() const
{
return (DecorationPosition)d->themeConfig.decorationPosition();
}
} // namespace

View file

@ -1,225 +0,0 @@
/*
Library for Aurorae window decoration themes.
Copyright (C) 2009, 2010, 2012 Martin Gräßlin <mgraesslin@kde.org>
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 AURORAETHEME_H
#define AURORAETHEME_H
// #include "libaurorae_export.h"
#include <QObject>
#include <kdecoration.h>
class KConfig;
namespace Aurorae {
class AuroraeThemePrivate;
class ThemeConfig;
enum AuroraeButtonType {
MinimizeButton = 0,
MaximizeButton,
RestoreButton,
CloseButton,
AllDesktopsButton,
KeepAboveButton,
KeepBelowButton,
ShadeButton,
HelpButton,
MenuButton
};
enum DecorationPosition {
DecorationTop = 0,
DecorationLeft,
DecorationRight,
DecorationBottom
};
class /*LIBAURORAE_EXPORT*/ AuroraeTheme : public QObject
{
Q_OBJECT
Q_PROPERTY(int borderLeft READ leftBorder NOTIFY borderSizesChanged)
Q_PROPERTY(int borderRight READ rightBorder NOTIFY borderSizesChanged)
Q_PROPERTY(int borderTop READ topBorder NOTIFY borderSizesChanged)
Q_PROPERTY(int borderBottom READ bottomBorder NOTIFY borderSizesChanged)
Q_PROPERTY(int borderLeftMaximized READ leftBorderMaximized NOTIFY borderSizesChanged)
Q_PROPERTY(int borderRightMaximized READ rightBorderMaximized NOTIFY borderSizesChanged)
Q_PROPERTY(int borderTopMaximized READ topBorderMaximized NOTIFY borderSizesChanged)
Q_PROPERTY(int borderBottomMaximized READ bottomBorderMaximized NOTIFY borderSizesChanged)
Q_PROPERTY(int paddingLeft READ paddingLeft NOTIFY themeChanged)
Q_PROPERTY(int paddingRight READ paddingRight NOTIFY themeChanged)
Q_PROPERTY(int paddingTop READ paddingTop NOTIFY themeChanged)
Q_PROPERTY(int paddingBottom READ paddingBottom NOTIFY themeChanged)
Q_PROPERTY(QString themeName READ themeName NOTIFY themeChanged)
Q_PROPERTY(int buttonHeight READ buttonHeight NOTIFY themeChanged)
Q_PROPERTY(int buttonWidth READ buttonWidth NOTIFY themeChanged)
Q_PROPERTY(int buttonWidthMinimize READ buttonWidthMinimize NOTIFY themeChanged)
Q_PROPERTY(int buttonWidthMaximizeRestore READ buttonWidthMaximizeRestore NOTIFY themeChanged)
Q_PROPERTY(int buttonWidthClose READ buttonWidthClose NOTIFY themeChanged)
Q_PROPERTY(int buttonWidthAllDesktops READ buttonWidthAllDesktops NOTIFY themeChanged)
Q_PROPERTY(int buttonWidthKeepAbove READ buttonWidthKeepAbove NOTIFY themeChanged)
Q_PROPERTY(int buttonWidthKeepBelow READ buttonWidthKeepBelow NOTIFY themeChanged)
Q_PROPERTY(int buttonWidthShade READ buttonWidthShade NOTIFY themeChanged)
Q_PROPERTY(int buttonWidthHelp READ buttonWidthHelp NOTIFY themeChanged)
Q_PROPERTY(int buttonWidthMenu READ buttonWidthMenu NOTIFY themeChanged)
Q_PROPERTY(int buttonSpacing READ buttonSpacing NOTIFY themeChanged)
Q_PROPERTY(int buttonMarginTop READ buttonMarginTop NOTIFY themeChanged)
Q_PROPERTY(int explicitButtonSpacer READ explicitButtonSpacer NOTIFY themeChanged)
Q_PROPERTY(qreal buttonSizeFactor READ buttonSizeFactor NOTIFY buttonSizesChanged)
Q_PROPERTY(int animationTime READ animationTime NOTIFY themeChanged)
Q_PROPERTY(int titleEdgeLeft READ titleEdgeLeft NOTIFY themeChanged)
Q_PROPERTY(int titleEdgeRight READ titleEdgeRight NOTIFY themeChanged)
Q_PROPERTY(int titleEdgeTop READ titleEdgeTop NOTIFY themeChanged)
Q_PROPERTY(int titleEdgeLeftMaximized READ titleEdgeLeftMaximized NOTIFY themeChanged)
Q_PROPERTY(int titleEdgeRightMaximized READ titleEdgeRightMaximized NOTIFY themeChanged)
Q_PROPERTY(int titleEdgeTopMaximized READ titleEdgeTopMaximized NOTIFY themeChanged)
Q_PROPERTY(int titleBorderRight READ titleBorderRight NOTIFY themeChanged)
Q_PROPERTY(int titleBorderLeft READ titleBorderLeft NOTIFY themeChanged)
Q_PROPERTY(int titleHeight READ titleHeight NOTIFY themeChanged)
Q_PROPERTY(QString decorationPath READ decorationPath NOTIFY themeChanged)
Q_PROPERTY(QString minimizeButtonPath READ minimizeButtonPath NOTIFY themeChanged)
Q_PROPERTY(QString maximizeButtonPath READ maximizeButtonPath NOTIFY themeChanged)
Q_PROPERTY(QString restoreButtonPath READ restoreButtonPath NOTIFY themeChanged)
Q_PROPERTY(QString closeButtonPath READ closeButtonPath NOTIFY themeChanged)
Q_PROPERTY(QString allDesktopsButtonPath READ allDesktopsButtonPath NOTIFY themeChanged)
Q_PROPERTY(QString keepAboveButtonPath READ keepAboveButtonPath NOTIFY themeChanged)
Q_PROPERTY(QString keepBelowButtonPath READ keepBelowButtonPath NOTIFY themeChanged)
Q_PROPERTY(QString shadeButtonPath READ shadeButtonPath NOTIFY themeChanged)
Q_PROPERTY(QString helpButtonPath READ helpButtonPath NOTIFY themeChanged)
Q_PROPERTY(QColor activeTextColor READ activeTextColor NOTIFY themeChanged)
Q_PROPERTY(QColor inactiveTextColor READ inactiveTextColor NOTIFY themeChanged)
Q_PROPERTY(Qt::Alignment horizontalAlignment READ alignment NOTIFY themeChanged)
Q_PROPERTY(Qt::Alignment verticalAlignment READ verticalAlignment NOTIFY themeChanged)
Q_PROPERTY(QString defaultButtonsLeft READ defaultButtonsLeft NOTIFY themeChanged)
Q_PROPERTY(QString defaultButtonsRight READ defaultButtonsRight NOTIFY themeChanged)
public:
explicit AuroraeTheme(QObject* parent = 0);
virtual ~AuroraeTheme();
// TODO: KSharedConfigPtr
void loadTheme(const QString &name, const KConfig &config);
bool isValid() const;
const QString &themeName() const;
int leftBorder() const;
int rightBorder() const;
int topBorder() const;
int bottomBorder() const;
int leftBorderMaximized() const;
int rightBorderMaximized() const;
int topBorderMaximized() const;
int bottomBorderMaximized() const;
int paddingLeft() const;
int paddingRight() const;
int paddingTop() const;
int paddingBottom() const;
int buttonWidth() const;
int buttonWidthMinimize() const;
int buttonWidthMaximizeRestore() const;
int buttonWidthClose() const;
int buttonWidthAllDesktops() const;
int buttonWidthKeepAbove() const;
int buttonWidthKeepBelow() const;
int buttonWidthShade() const;
int buttonWidthHelp() const;
int buttonWidthMenu() const;
int buttonHeight() const;
int buttonSpacing() const;
int buttonMarginTop() const;
int explicitButtonSpacer() const;
int animationTime() const;
int titleEdgeLeft() const;
int titleEdgeRight() const;
int titleEdgeTop() const;
int titleEdgeLeftMaximized() const;
int titleEdgeRightMaximized() const;
int titleEdgeTopMaximized() const;
int titleBorderLeft() const;
int titleBorderRight() const;
int titleHeight() const;
QString decorationPath() const;
QString minimizeButtonPath() const;
QString maximizeButtonPath() const;
QString restoreButtonPath() const;
QString closeButtonPath() const;
QString allDesktopsButtonPath() const;
QString keepAboveButtonPath() const;
QString keepBelowButtonPath() const;
QString shadeButtonPath() const;
QString helpButtonPath() const;
QColor activeTextColor() const;
QColor inactiveTextColor() const;
Qt::Alignment alignment() const;
Qt::Alignment verticalAlignment() const;
/**
* Sets the title edges according to maximized state.
* Title edges are global to all windows.
*/
void titleEdges(int &left, int &top, int &right, int &bottom, bool maximized) const;
void setCompositingActive(bool active);
bool isCompositingActive() const;
/**
* @returns true if the theme contains a FrameSvg for specified button.
*/
bool hasButton(AuroraeButtonType button) const;
QString defaultButtonsLeft() const;
QString defaultButtonsRight() const;
void setBorderSize(KDecorationDefines::BorderSize size);
/**
* Sets the size of the buttons.
* The available sizes are identical to border sizes, therefore BorderSize is used.
* @param size The buttons size
*/
void setButtonSize(KDecorationDefines::BorderSize size);
qreal buttonSizeFactor() const;
DecorationPosition decorationPosition() const;
void setTabDragMimeType(const QString &mime);
const QString &tabDragMimeType() const;
// TODO: move to namespace
static QLatin1String mapButtonToName(AuroraeButtonType type);
public Q_SLOTS:
void loadTheme(const QString &name);
Q_SIGNALS:
void themeChanged();
void buttonSizesChanged();
void borderSizesChanged();
private:
/**
* Sets the borders according to maximized state.
* Borders are global to all windows.
*/
void borders(int &left, int &top, int &right, int &bottom, bool maximized) const;
/**
* Sets the padding according.
* Padding is global to all windows.
*/
void padding(int &left, int &top, int &right, int &bottom) const;
AuroraeThemePrivate* const d;
};
} // namespace
#endif // AURORAETHEME_H

View file

@ -1,193 +0,0 @@
/********************************************************************
Copyright (C) 2009 Martin Gräßlin <mgraesslin@kde.org>
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, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "themeconfig.h"
#include <kdecoration.h>
#include <KConfig>
#include <KConfigGroup>
namespace Aurorae
{
ThemeConfig::ThemeConfig()
: m_activeTextColor(defaultActiveTextColor())
, m_activeFocusedTextColor(defaultActiveFocusedTextColor())
, m_activeUnfocusedTextColor(defaultActiveUnfocusedTextColor())
, m_inactiveTextColor(defaultInactiveTextColor())
, m_inactiveFocusedTextColor(defaultInactiveFocusedTextColor())
, m_inactiveUnfocusedTextColor(defaultInactiveUnfocusedTextColor())
, m_activeTextShadowColor(defaultActiveTextShadowColor())
, m_inactiveTextShadowColor(defaultInactiveTextShadowColor())
, m_textShadowOffsetX(defaultTextShadowOffsetX())
, m_textShadowOffsetY(defaultTextShadowOffsetY())
, m_useTextShadow(defaultUseTextShadow())
, m_haloActive(defaultHaloActive())
, m_haloInactive(defaultHaloInactive())
, m_alignment(defaultAlignment())
, m_verticalAlignment(defaultVerticalAlignment())
// borders
, m_borderLeft(defaultBorderLeft())
, m_borderRight(defaultBorderRight())
, m_borderBottom(defaultBorderBottom())
, m_borderTop(defaultBorderTop())
// title
, m_titleEdgeTop(defaultTitleEdgeTop())
, m_titleEdgeBottom(defaultTitleEdgeBottom())
, m_titleEdgeLeft(defaultTitleEdgeLeft())
, m_titleEdgeRight(defaultTitleEdgeRight())
, m_titleEdgeTopMaximized(defaultTitleEdgeTopMaximized())
, m_titleEdgeBottomMaximized(defaultTitleEdgeBottomMaximized())
, m_titleEdgeLeftMaximized(defaultTitleEdgeLeftMaximized())
, m_titleEdgeRightMaximized(defaultTitleEdgeRightMaximized())
, m_titleBorderLeft(defaultTitleBorderLeft())
, m_titleBorderRight(defaultTitleBorderRight())
, m_titleHeight(defaultTitleHeight())
// buttons
, m_buttonWidth(defaultButtonWidth())
, m_buttonWidthMinimize(defaultButtonWidthMinimize())
, m_buttonWidthMaximizeRestore(defaultButtonWidthMaximizeRestore())
, m_buttonWidthClose(defaultButtonWidthClose())
, m_buttonWidthAllDesktops(defaultButtonWidthAllDesktops())
, m_buttonWidthKeepAbove(defaultButtonWidthKeepAbove())
, m_buttonWidthKeepBelow(defaultButtonWidthKeepBelow())
, m_buttonWidthShade(defaultButtonWidthShade())
, m_buttonWidthHelp(defaultButtonWidthHelp())
, m_buttonWidthMenu(defaultButtonWidthMenu())
, m_buttonHeight(defaultButtonHeight())
, m_buttonSpacing(defaultButtonSpacing())
, m_buttonMarginTop(defaultButtonMarginTop())
, m_explicitButtonSpacer(defaultExplicitButtonSpacer())
// padding
, m_paddingLeft(defaultPaddingLeft())
, m_paddingRight(defaultPaddingRight())
, m_paddingTop(defaultPaddingTop())
, m_paddingBottom(defaultPaddingBottom())
, m_animationTime(defaultAnimationTime())
, m_defaultButtonsLeft(KDecorationOptions::defaultTitleButtonsLeft())
, m_defaultButtonsRight(KDecorationOptions::defaultTitleButtonsRight())
, m_shadow(defaultShadow())
, m_decorationPosition(defaultDecorationPosition())
{
}
void ThemeConfig::load(const KConfig &conf)
{
KConfigGroup general(&conf, "General");
m_activeTextColor = general.readEntry("ActiveTextColor", defaultActiveTextColor());
m_inactiveTextColor = general.readEntry("InactiveTextColor", defaultInactiveTextColor());
m_activeFocusedTextColor = general.readEntry("ActiveFocusedTabColor", m_activeTextColor);
m_activeUnfocusedTextColor = general.readEntry("ActiveUnfocusedTabColor", m_inactiveTextColor);
m_inactiveFocusedTextColor = general.readEntry("InactiveFocusedTabColor", m_inactiveTextColor);
m_inactiveUnfocusedTextColor = general.readEntry("InactiveUnfocusedTabColor", m_inactiveTextColor);
m_useTextShadow = general.readEntry("UseTextShadow", defaultUseTextShadow());
m_activeTextShadowColor = general.readEntry("ActiveTextShadowColor", defaultActiveTextColor());
m_inactiveTextShadowColor = general.readEntry("InactiveTextShadowColor", defaultInactiveTextColor());
m_textShadowOffsetX = general.readEntry("TextShadowOffsetX", defaultTextShadowOffsetX());
m_textShadowOffsetY = general.readEntry("TextShadowOffsetY", defaultTextShadowOffsetY());
m_haloActive = general.readEntry("HaloActive", defaultHaloActive());
m_haloInactive = general.readEntry("HaloInactive", defaultHaloInactive());
QString alignment = (general.readEntry("TitleAlignment", "Left")).toLower();
if (alignment == "left") {
m_alignment = Qt::AlignLeft;
}
else if (alignment == "center") {
m_alignment = Qt::AlignCenter;
}
else {
m_alignment = Qt::AlignRight;
}
alignment = (general.readEntry("TitleVerticalAlignment", "Center")).toLower();
if (alignment == "top") {
m_verticalAlignment = Qt::AlignTop;
}
else if (alignment == "center") {
m_verticalAlignment = Qt::AlignVCenter;
}
else {
m_verticalAlignment = Qt::AlignBottom;
}
m_animationTime = general.readEntry("Animation", defaultAnimationTime());
m_defaultButtonsLeft = general.readEntry("LeftButtons", KDecorationOptions::defaultTitleButtonsLeft());
m_defaultButtonsRight = general.readEntry("RightButtons", KDecorationOptions::defaultTitleButtonsRight());
m_shadow = general.readEntry("Shadow", defaultShadow());
m_decorationPosition = general.readEntry("DecorationPosition", defaultDecorationPosition());
KConfigGroup border(&conf, "Layout");
// default values taken from KCommonDecoration::layoutMetric() in kcommondecoration.cpp
m_borderLeft = border.readEntry("BorderLeft", defaultBorderLeft());
m_borderRight = border.readEntry("BorderRight", defaultBorderRight());
m_borderBottom = border.readEntry("BorderBottom", defaultBorderBottom());
m_borderTop = border.readEntry("BorderTop", defaultBorderTop());
m_titleEdgeTop = border.readEntry("TitleEdgeTop", defaultTitleEdgeTop());
m_titleEdgeBottom = border.readEntry("TitleEdgeBottom", defaultTitleEdgeBottom());
m_titleEdgeLeft = border.readEntry("TitleEdgeLeft", defaultTitleEdgeLeft());
m_titleEdgeRight = border.readEntry("TitleEdgeRight", defaultTitleEdgeRight());
m_titleEdgeTopMaximized = border.readEntry("TitleEdgeTopMaximized", defaultTitleEdgeTopMaximized());
m_titleEdgeBottomMaximized = border.readEntry("TitleEdgeBottomMaximized", defaultTitleEdgeBottomMaximized());
m_titleEdgeLeftMaximized = border.readEntry("TitleEdgeLeftMaximized", defaultTitleEdgeLeftMaximized());
m_titleEdgeRightMaximized = border.readEntry("TitleEdgeRightMaximized", defaultTitleEdgeRightMaximized());
m_titleBorderLeft = border.readEntry("TitleBorderLeft", defaultTitleBorderLeft());
m_titleBorderRight = border.readEntry("TitleBorderRight", defaultTitleBorderRight());
m_titleHeight = border.readEntry("TitleHeight", defaultTitleHeight());
m_buttonWidth = border.readEntry("ButtonWidth", defaultButtonWidth());
m_buttonWidthMinimize = border.readEntry("ButtonWidthMinimize", m_buttonWidth);
m_buttonWidthMaximizeRestore = border.readEntry("ButtonWidthMaximizeRestore", m_buttonWidth);
m_buttonWidthClose = border.readEntry("ButtonWidthClose", m_buttonWidth);
m_buttonWidthAllDesktops = border.readEntry("ButtonWidthAlldesktops", m_buttonWidth);
m_buttonWidthKeepAbove = border.readEntry("ButtonWidthKeepabove", m_buttonWidth);
m_buttonWidthKeepBelow = border.readEntry("ButtonWidthKeepbelow", m_buttonWidth);
m_buttonWidthShade = border.readEntry("ButtonWidthShade", m_buttonWidth);
m_buttonWidthHelp = border.readEntry("ButtonWidthHelp", m_buttonWidth);
m_buttonWidthMenu = border.readEntry("ButtonWidthMenu", m_buttonWidth);
m_buttonHeight = border.readEntry("ButtonHeight", defaultButtonHeight());
m_buttonSpacing = border.readEntry("ButtonSpacing", defaultButtonSpacing());
m_buttonMarginTop = border.readEntry("ButtonMarginTop", defaultButtonMarginTop());
m_explicitButtonSpacer = border.readEntry("ExplicitButtonSpacer", defaultExplicitButtonSpacer());
m_paddingLeft = border.readEntry("PaddingLeft", defaultPaddingLeft());
m_paddingRight = border.readEntry("PaddingRight", defaultPaddingRight());
m_paddingTop = border.readEntry("PaddingTop", defaultPaddingTop());
m_paddingBottom = border.readEntry("PaddingBottom", defaultPaddingBottom());
}
QColor ThemeConfig::activeTextColor(bool useTabs, bool focused) const
{
if (!useTabs) {
return m_activeTextColor;
}
if (focused) {
return m_activeFocusedTextColor;
} else {
return m_activeUnfocusedTextColor;
}
}
QColor ThemeConfig::inactiveTextColor(bool useTabs, bool focused) const
{
if (!useTabs) {
return m_inactiveTextColor;
}
if (focused) {
return m_inactiveFocusedTextColor;
} else {
return m_inactiveUnfocusedTextColor;
}
}
} //namespace

View file

@ -1,414 +0,0 @@
/********************************************************************
Copyright (C) 2009 Martin Gräßlin <mgraesslin@kde.org>
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, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef THEMECONFIG_H
#define THEMECONFIG_H
// This class encapsulates all theme config values
// it's a separate class as it's needed by both deco and config dialog
#include <QString>
#include <QColor>
class KConfig;
namespace Aurorae
{
class ThemeConfig
{
public:
ThemeConfig();
void load(const KConfig &conf);
~ThemeConfig() {};
// active window
QColor activeTextColor(bool useTabs = false, bool focused = true) const;
// inactive window
QColor inactiveTextColor(bool useTabs = false, bool focused = true) const;
QColor activeTextShadowColor() const {
return m_activeTextShadowColor;
}
QColor inactiveTextShadowColor() const {
return m_inactiveTextShadowColor;
}
int textShadowOffsetX() const {
return m_textShadowOffsetX;
}
int textShadowOffsetY() const {
return m_textShadowOffsetY;
}
bool useTextShadow() const {
return m_useTextShadow;
}
bool haloActive() const {
return m_haloActive;
}
bool haloInactive() const {
return m_haloInactive;
}
// Alignment
Qt::Alignment alignment() const {
return m_alignment;
};
Qt::Alignment verticalAlignment() const {
return m_verticalAlignment;
}
int animationTime() const {
return m_animationTime;
}
// Borders
int borderLeft() const {
return m_borderLeft;
}
int borderRight() const {
return m_borderRight;
}
int borderBottom() const {
return m_borderBottom;
}
int borderTop() const {
return m_borderTop;
}
int titleEdgeTop() const {
return m_titleEdgeTop;
}
int titleEdgeBottom() const {
return m_titleEdgeBottom;
}
int titleEdgeLeft() const {
return m_titleEdgeLeft;
}
int titleEdgeRight() const {
return m_titleEdgeRight;
}
int titleEdgeTopMaximized() const {
return m_titleEdgeTopMaximized;
}
int titleEdgeBottomMaximized() const {
return m_titleEdgeBottomMaximized;
}
int titleEdgeLeftMaximized() const {
return m_titleEdgeLeftMaximized;
}
int titleEdgeRightMaximized() const {
return m_titleEdgeRightMaximized;
}
int titleBorderLeft() const {
return m_titleBorderLeft;
}
int titleBorderRight() const {
return m_titleBorderRight;
}
int titleHeight() const {
return m_titleHeight;
}
int buttonWidth() const {
return m_buttonWidth;
}
int buttonWidthMinimize() const {
return m_buttonWidthMinimize;
}
int buttonWidthMaximizeRestore() const {
return m_buttonWidthMaximizeRestore;
}
int buttonWidthClose() const {
return m_buttonWidthClose;
}
int buttonWidthAllDesktops() const {
return m_buttonWidthAllDesktops;
}
int buttonWidthKeepAbove() const {
return m_buttonWidthKeepAbove;
}
int buttonWidthKeepBelow() const {
return m_buttonWidthKeepBelow;
}
int buttonWidthShade() const {
return m_buttonWidthShade;
}
int buttonWidthHelp() const {
return m_buttonWidthHelp;
}
int buttonWidthMenu() const {
return m_buttonWidthMenu;
}
int buttonHeight() const {
return m_buttonHeight;
}
int buttonSpacing() const {
return m_buttonSpacing;
}
int buttonMarginTop() const {
return m_buttonMarginTop;
}
int explicitButtonSpacer() const {
return m_explicitButtonSpacer;
}
int paddingLeft() const {
return m_paddingLeft;
}
int paddingRight() const {
return m_paddingRight;
}
int paddingTop() const {
return m_paddingTop;
}
int paddingBottom() const {
return m_paddingBottom;
}
QString defaultButtonsLeft() const {
return m_defaultButtonsLeft;
}
QString defaultButtonsRight() const {
return m_defaultButtonsRight;
}
bool shadow() const {
return m_shadow;
}
int decorationPosition() const {
return m_decorationPosition;
}
static QColor defaultActiveTextColor() {
return QColor(Qt::black);
}
static QColor defaultActiveFocusedTextColor() {
return QColor(Qt::black);
}
static QColor defaultActiveUnfocusedTextColor() {
return QColor(Qt::black);
}
static QColor defaultInactiveTextColor() {
return QColor(Qt::black);
}
static QColor defaultInactiveFocusedTextColor() {
return QColor(Qt::black);
}
static QColor defaultInactiveUnfocusedTextColor() {
return QColor(Qt::black);
}
static QColor defaultActiveTextShadowColor() {
return QColor(Qt::white);
}
static QColor defaultInactiveTextShadowColor() {
return QColor(Qt::white);
}
static int defaultTextShadowOffsetX() {
return 0;
}
static int defaultTextShadowOffsetY() {
return 0;
}
static bool defaultUseTextShadow() {
return false;
}
static bool defaultHaloActive() {
return false;
}
static bool defaultHaloInactive() {
return false;
}
static Qt::Alignment defaultAlignment() {
return Qt::AlignLeft;
}
static Qt::Alignment defaultVerticalAlignment() {
return Qt::AlignVCenter;
}
// borders
static int defaultBorderLeft() {
return 5;
}
static int defaultBorderRight() {
return 5;
}
static int defaultBorderBottom() {
return 5;
}
static int defaultBorderTop() {
return 0;
}
// title
static int defaultTitleEdgeTop() {
return 5;
}
static int defaultTitleEdgeBottom() {
return 5;
}
static int defaultTitleEdgeLeft() {
return 5;
}
static int defaultTitleEdgeRight() {
return 5;
}
static int defaultTitleEdgeTopMaximized() {
return 0;
}
static int defaultTitleEdgeBottomMaximized() {
return 0;
}
static int defaultTitleEdgeLeftMaximized() {
return 0;
}
static int defaultTitleEdgeRightMaximized() {
return 0;
}
static int defaultTitleBorderLeft() {
return 5;
}
static int defaultTitleBorderRight() {
return 5;
}
static int defaultTitleHeight() {
return 20;
}
// buttons
static int defaultButtonWidth() {
return 20;
}
static int defaultButtonWidthMinimize() {
return defaultButtonWidth();
}
static int defaultButtonWidthMaximizeRestore() {
return defaultButtonWidth();
}
static int defaultButtonWidthClose() {
return defaultButtonWidth();
}
static int defaultButtonWidthAllDesktops() {
return defaultButtonWidth();
}
static int defaultButtonWidthKeepAbove() {
return defaultButtonWidth();
}
static int defaultButtonWidthKeepBelow() {
return defaultButtonWidth();
}
static int defaultButtonWidthShade() {
return defaultButtonWidth();
}
static int defaultButtonWidthHelp() {
return defaultButtonWidth();
}
static int defaultButtonWidthMenu() {
return defaultButtonWidth();
}
static int defaultButtonHeight() {
return 20;
}
static int defaultButtonSpacing() {
return 5;
}
static int defaultButtonMarginTop() {
return 0;
}
static int defaultExplicitButtonSpacer() {
return 10;
}
// padding
static int defaultPaddingLeft() {
return 0;
}
static int defaultPaddingRight() {
return 0;
}
static int defaultPaddingTop() {
return 0;
}
static int defaultPaddingBottom() {
return 0;
}
static int defaultAnimationTime() {
return 0;
}
static bool defaultShadow() {
return true;
}
static int defaultDecorationPosition() {
return 0;
}
private:
QColor m_activeTextColor;
QColor m_activeFocusedTextColor;
QColor m_activeUnfocusedTextColor;
QColor m_inactiveTextColor;
QColor m_inactiveFocusedTextColor;
QColor m_inactiveUnfocusedTextColor;
QColor m_activeTextShadowColor;
QColor m_inactiveTextShadowColor;
int m_textShadowOffsetX;
int m_textShadowOffsetY;
bool m_useTextShadow;
bool m_haloActive;
bool m_haloInactive;
Qt::Alignment m_alignment;
Qt::Alignment m_verticalAlignment;
// borders
int m_borderLeft;
int m_borderRight;
int m_borderBottom;
int m_borderTop;
// title
int m_titleEdgeTop;
int m_titleEdgeBottom;
int m_titleEdgeLeft;
int m_titleEdgeRight;
int m_titleEdgeTopMaximized;
int m_titleEdgeBottomMaximized;
int m_titleEdgeLeftMaximized;
int m_titleEdgeRightMaximized;
int m_titleBorderLeft;
int m_titleBorderRight;
int m_titleHeight;
// buttons
int m_buttonWidth;
int m_buttonWidthMinimize;
int m_buttonWidthMaximizeRestore;
int m_buttonWidthClose;
int m_buttonWidthAllDesktops;
int m_buttonWidthKeepAbove;
int m_buttonWidthKeepBelow;
int m_buttonWidthShade;
int m_buttonWidthHelp;
int m_buttonWidthMenu;
int m_buttonHeight;
int m_buttonSpacing;
int m_buttonMarginTop;
int m_explicitButtonSpacer;
// padding
int m_paddingLeft;
int m_paddingRight;
int m_paddingTop;
int m_paddingBottom;
int m_animationTime;
QString m_defaultButtonsLeft;
QString m_defaultButtonsRight;
bool m_shadow;
int m_decorationPosition;
};
}
#endif

View file

@ -1,211 +0,0 @@
/********************************************************************
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
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, see <http://www.gnu.org/licenses/>.
*********************************************************************/
import QtQuick 1.1
import org.kde.plasma.core 0.1 as PlasmaCore
DecorationButton {
function widthForButton() {
switch (buttonType) {
case "M":
// menu
return auroraeTheme.buttonWidthMenu;
case "S":
// all desktops
return auroraeTheme.buttonWidthAllDesktops;
case "H":
// help
return auroraeTheme.buttonWidthHelp;
case "I":
// minimize
return auroraeTheme.buttonWidthMinimize;
case "A":
// maximize
return auroraeTheme.buttonWidthMaximizeRestore;
case "X":
// close
return auroraeTheme.buttonWidthClose;
case "F":
// keep above
return auroraeTheme.buttonWidthKeepAbove;
case "B":
// keep below
return auroraeTheme.buttonWidthKeepBelow;
case "L":
// shade
return auroraeTheme.buttonWidthShade;
default:
return auroraeTheme.buttonWidth;
}
}
function pathForButton() {
switch (buttonType) {
case "S":
// all desktops
return auroraeTheme.allDesktopsButtonPath;
case "H":
// help
return auroraeTheme.helpButtonPath;
case "I":
// minimize
return auroraeTheme.minimizeButtonPath;
case "A":
// maximize
return auroraeTheme.maximizeButtonPath;
case "R":
// maximize
return auroraeTheme.restoreButtonPath;
case "X":
// close
return auroraeTheme.closeButtonPath;
case "F":
// keep above
return auroraeTheme.keepAboveButtonPath;
case "B":
// keep below
return auroraeTheme.keepBelowButtonPath;
case "L":
// shade
return auroraeTheme.shadeButtonPath;
default:
return "";
}
}
width: widthForButton() * auroraeTheme.buttonSizeFactor
height: auroraeTheme.buttonHeight * auroraeTheme.buttonSizeFactor
PlasmaCore.FrameSvg {
property bool supportsHover: hasElementPrefix("hover")
property bool supportsPressed: hasElementPrefix("pressed")
property bool supportsDeactivated: hasElementPrefix("deactivated")
property bool supportsInactive: hasElementPrefix("inactive")
property bool supportsInactiveHover: hasElementPrefix("hover-inactive")
property bool supportsInactivePressed: hasElementPrefix("pressed-inactive")
property bool supportsInactiveDeactivated: hasElementPrefix("deactivated-inactive")
id: buttonSvg
imagePath: pathForButton()
}
PlasmaCore.FrameSvgItem {
id: buttonActive
property bool shown: (decoration.active || !buttonSvg.supportsInactive) && ((!pressed && !toggled) || !buttonSvg.supportsPressed) && (!hovered || !buttonSvg.supportsHover) && (enabled || !buttonSvg.supportsDeactivated)
anchors.fill: parent
imagePath: buttonSvg.imagePath
prefix: "active"
opacity: shown ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: auroraeTheme.animationTime
}
}
}
PlasmaCore.FrameSvgItem {
id: buttonActiveHover
property bool shown: hovered && !pressed && !toggled && buttonSvg.supportsHover && (decoration.active || !buttonSvg.supportsInactiveHover)
anchors.fill: parent
imagePath: buttonSvg.imagePath
prefix: "hover"
opacity: shown ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: auroraeTheme.animationTime
}
}
}
PlasmaCore.FrameSvgItem {
id: buttonActivePressed
property bool shown: (toggled || pressed) && buttonSvg.supportsPressed && (decoration.active || !buttonSvg.supportsInactivePressed)
anchors.fill: parent
imagePath: buttonSvg.imagePath
prefix: "pressed"
opacity: shown ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: auroraeTheme.animationTime
}
}
}
PlasmaCore.FrameSvgItem {
id: buttonActiveDeactivated
property bool shown: !enabled && buttonSvg.supportsDeactivated && (decoration.active || !buttonSvg.supportsInactiveDeactivated)
anchors.fill: parent
imagePath: buttonSvg.imagePath
prefix: "deactivated"
opacity: shown ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: auroraeTheme.animationTime
}
}
}
PlasmaCore.FrameSvgItem {
id: buttonInactive
property bool shown: !decoration.active && buttonSvg.supportsInactive && !hovered && !pressed && !toggled && enabled
anchors.fill: parent
imagePath: buttonSvg.imagePath
prefix: "inactive"
opacity: shown ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: auroraeTheme.animationTime
}
}
}
PlasmaCore.FrameSvgItem {
id: buttonInactiveHover
property bool shown: !decoration.active && hovered && !pressed && !toggled && buttonSvg.supportsInactiveHover
anchors.fill: parent
imagePath: buttonSvg.imagePath
prefix: "hover-inactive"
opacity: shown ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: auroraeTheme.animationTime
}
}
}
PlasmaCore.FrameSvgItem {
id: buttonInactivePressed
property bool shown: !decoration.active && (toggled || pressed) && buttonSvg.supportsInactivePressed
anchors.fill: parent
imagePath: buttonSvg.imagePath
prefix: "pressed-inactive"
opacity: shown ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: auroraeTheme.animationTime
}
}
}
PlasmaCore.FrameSvgItem {
id: buttonInactiveDeactivated
property bool shown: !decoration.active && !enabled && buttonSvg.supportsInactiveDeactivated
anchors.fill: parent
imagePath: buttonSvg.imagePath
prefix: "deactivated-inactive"
opacity: shown ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: auroraeTheme.animationTime
}
}
}
Component.onCompleted: {
if (buttonType == "H" && !decoration.providesContextHelp) {
visible = false;
} else {
visible = buttonSvg.imagePath != "";
}
}
}

View file

@ -1,62 +0,0 @@
/********************************************************************
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
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, see <http://www.gnu.org/licenses/>.
*********************************************************************/
import QtQuick 1.1
import org.kde.plasma.core 0.1 as PlasmaCore
Item {
function createButtons() {
var component = Qt.createComponent("AuroraeButton.qml");
for (var i=0; i<buttons.length; i++) {
if (buttons.charAt(i) == "_") {
Qt.createQmlObject("import QtQuick 1.1; Item { width: auroraeTheme.explicitButtonSpacer * auroraeTheme.buttonSizeFactor; height: auroraeTheme.buttonHeight * auroraeTheme.buttonSizeFactor }",
groupRow, "explicitSpacer" + buttons + i);
} else if (buttons.charAt(i) == "M") {
Qt.createQmlObject("import QtQuick 1.1; MenuButton { width: auroraeTheme.buttonWidthMenu * auroraeTheme.buttonSizeFactor; height: auroraeTheme.buttonHeight * auroraeTheme.buttonSizeFactor }",
groupRow, "menuButton" + buttons + i);
} else if (buttons.charAt(i) == "A") {
var maximizeComponent = Qt.createComponent("AuroraeMaximizeButton.qml");
maximizeComponent.createObject(groupRow);
} else {
component.createObject(groupRow, {buttonType: buttons.charAt(i)});
}
}
}
id: group
property string buttons
property bool animate: false
Row {
id: groupRow
spacing: auroraeTheme.buttonSpacing * auroraeTheme.buttonSizeFactor
}
onButtonsChanged: {
for (i = 0; i < groupRow.children.length; i++) {
groupRow.children[i].destroy();
}
createButtons();
}
anchors {
top: parent.top
topMargin: (decoration.maximized ? auroraeTheme.titleEdgeTopMaximized : auroraeTheme.titleEdgeTop + root.padding.top) + auroraeTheme.buttonMarginTop
}
Behavior on anchors.topMargin {
enabled: group.animate
NumberAnimation {
duration: auroraeTheme.animationTime
}
}
}

View file

@ -1,45 +0,0 @@
/********************************************************************
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
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, see <http://www.gnu.org/licenses/>.
*********************************************************************/
import QtQuick 1.1
Item {
id: button
width: auroraeTheme.buttonWidthMaximizeRestore * auroraeTheme.buttonSizeFactor
height: auroraeTheme.buttonHeight * auroraeTheme.buttonSizeFactor
AuroraeButton {
id: maximizeButton
anchors.fill: parent
buttonType: "A"
opacity: (!decoration.maximized || auroraeTheme.restoreButtonPath == "") ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: auroraeTheme.animationTime
}
}
}
AuroraeButton {
id: restoreButton
anchors.fill: parent
buttonType: "R"
opacity: (decoration.maximized && auroraeTheme.restoreButtonPath != "") ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: auroraeTheme.animationTime
}
}
}
}

View file

@ -1,96 +0,0 @@
/********************************************************************
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
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, see <http://www.gnu.org/licenses/>.
*********************************************************************/
import QtQuick 1.1
Item {
function createButtons() {
for (var i=0; i<buttons.length; i++) {
var component = undefined;
switch (buttons.charAt(i)) {
case "_":
component = explicitSpacerComponent;
break;
case "A":
component = group.maximizeButton;
break;
case "B":
component = group.keepBelowButton;
break;
case "F":
component = group.keepAboveButton;
break;
case "H":
component = group.helpButton;
break;
case "I":
component = group.minimizeButton;
break;
case "L":
component = group.shadeButton;
break;
case "M":
component = group.menuButton;
break;
case "S":
component = group.allDesktopsButton;
break;
case "X":
component = group.closeButton;
break;
}
if (!component) {
continue;
}
var button = Qt.createQmlObject("import QtQuick 1.1; Loader{}", groupRow, "dynamicGroup_" + buttons + i);
button.sourceComponent = component;
}
}
id: group
property string buttons
property int explicitSpacer
property alias spacing: groupRow.spacing
property variant closeButton
property variant helpButton
property variant keepAboveButton
property variant keepBelowButton
property variant maximizeButton
property variant menuButton
property variant minimizeButton
property variant allDesktopsButton
property variant shadeButton
width: childrenRect.width
Row {
id: groupRow
}
onButtonsChanged: {
for (var i = 0; i < groupRow.children.length; i++) {
groupRow.children[i].destroy();
}
createButtons();
}
Component {
id: explicitSpacerComponent
Item {
width: group.explicitSpacer
height: groupRow.height
}
}
}

View file

@ -1,43 +0,0 @@
/********************************************************************
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
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, see <http://www.gnu.org/licenses/>.
*********************************************************************/
import QtQuick 1.1
Item {
signal alphaChanged()
property QtObject borders: Borders {
objectName: "borders"
}
property QtObject maximizedBorders: Borders {
objectName: "maximizedBorders"
}
property QtObject extendedBorders: Borders {
objectName: "extendedBorders"
}
property QtObject padding: Borders {
objectName: "padding"
}
property bool alpha: true
onAlphaChanged: alphaChanged()
MouseArea {
anchors.fill: parent
hoverEnabled: true
onPositionChanged: decoration.titleMouseMoved(mouse.button, mouse.buttons)
onPressed: decoration.titlePressed(mouse.button, mouse.buttons)
onReleased: decoration.titleReleased(mouse.button, mouse.buttons)
}
}

View file

@ -1,150 +0,0 @@
/********************************************************************
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
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, see <http://www.gnu.org/licenses/>.
*********************************************************************/
import QtQuick 1.1
Item {
id: button
property string buttonType : ""
property bool hovered: false
property bool pressed: false
property bool toggled: false
enabled: {
switch (button.buttonType) {
case "X":
return decoration.closeable;
case "A":
case "R":
return decoration.maximizeable;
case "I":
return decoration.minimizeable;
case "_":
return false;
default:
return true;
}
}
MouseArea {
anchors.fill: parent
acceptedButtons: {
switch (button.buttonType) {
case "M":
return Qt.LeftButton | Qt.RightButton;
case "A":
case "R":
return Qt.LeftButton | Qt.RightButton | Qt.MiddleButton;
default:
return Qt.LeftButton;
}
}
hoverEnabled: true
onEntered: button.hovered = true
onPositionChanged: decoration.titleMouseMoved(mouse.button, mouse.buttons)
onExited: button.hovered = false
onPressed: button.pressed = true
onReleased: button.pressed = false
onClicked: {
switch (button.buttonType) {
case "M":
// menu
decoration.menuClicked();
break;
case "S":
// all desktops
decoration.toggleOnAllDesktops();
break;
case "H":
// help
decoration.showContextHelp();
break;
case "I":
// minimize
decoration.minimize();
break;
case "A":
case "R":
// maximize
decoration.maximize(mouse.button);
break;
case "X":
// close
decoration.closeWindow();
break;
case "F":
// keep above
decoration.toggleKeepAbove();
break;
case "B":
// keep below
decoration.toggleKeepBelow();
break;
case "L":
// shade
decoration.toggleShade();
break;
}
}
onDoubleClicked: {
if (button.buttonType == "M") {
decoration.closeWindow();
}
}
Component.onCompleted: {
switch (button.buttonType) {
case "S":
// all desktops
button.toggled = decoration.onAllDesktops;
break;
case "F":
button.toggled = decoration.keepAbove;
break;
case "B":
button.toggled = decoration.keepBelow;
break;
case "L":
button.toggled = decoration.shade;
break;
}
}
Connections {
target: decoration
onShadeChanged: {
if (button.buttonType != "L") {
return;
}
button.toggled = decoration.shade;
}
onKeepBelowChanged: {
if (button.buttonType != "B") {
return;
}
button.toggled = decoration.keepBelow;
}
onKeepAboveChanged: {
if (button.buttonType != "F") {
return;
}
button.toggled = decoration.keepAbove;
}
onDesktopChanged: {
if (button.buttonType != "S") {
return;
}
button.toggled = decoration.onAllDesktops;
}
}
}
}

View file

@ -1,85 +0,0 @@
/********************************************************************
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
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, see <http://www.gnu.org/licenses/>.
*********************************************************************/
import QtQuick 1.1
import org.kde.qtextracomponents 0.1 as QtExtra
DecorationButton {
property bool closeOnDoubleClick: true
id: menuButton
buttonType: "M"
QtExtra.QIconItem {
icon: decoration.icon
anchors.fill: parent
}
Timer {
id: timer
interval: 150
repeat: false
onTriggered: decoration.menuClicked()
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onPressed: {
parent.pressed = true;
// we need a timer to figure out whether there is a double click in progress or not
// if we have a "normal" click we want to open the context menu. This would eat our
// second click of the double click. To properly get the double click we have to wait
// the double click delay to ensure that it was only a single click.
if (timer.running) {
timer.stop();
} else if (menuButton.closeOnDoubleClick) {
timer.start();
}
}
onReleased: {
parent.pressed = false;
timer.stop();
}
onExited: {
if (!parent.pressed) {
return;
}
if (timer.running) {
timer.stop();
}
parent.pressed = false;
}
onClicked: {
// for right clicks we show the menu instantly
// and if the option is disabled we always show menu directly
if (!menuButton.closeOnDoubleClick || mouse.button == Qt.RightButton) {
decoration.menuClicked();
timer.stop();
}
}
onDoubleClicked: {
if (menuButton.closeOnDoubleClick) {
decoration.closeWindow();
}
}
}
Component.onCompleted: {
menuButton.closeOnDoubleClick = decoration.readConfig("CloseOnDoubleClickMenuButton", true);
}
Connections {
target: decoration
onConfigChanged: {
menuButton.closeOnDoubleClick = decoration.readConfig("CloseOnDoubleClickMenuButton", true);
}
}
}

Some files were not shown because too many files have changed in this diff Show more