diff options
Diffstat (limited to 'kicker/extensions')
55 files changed, 11347 insertions, 0 deletions
diff --git a/kicker/extensions/Makefile.am b/kicker/extensions/Makefile.am new file mode 100644 index 000000000..bf9475c3f --- /dev/null +++ b/kicker/extensions/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = dockbar taskbar kasbar sidebar diff --git a/kicker/extensions/dockbar/Makefile.am b/kicker/extensions/dockbar/Makefile.am new file mode 100644 index 000000000..6d2f20546 --- /dev/null +++ b/kicker/extensions/dockbar/Makefile.am @@ -0,0 +1,18 @@ +INCLUDES = $(all_includes) + +kde_module_LTLIBRARIES = dockbar_panelextension.la + +dockbar_panelextension_la_SOURCES = dockcontainer.cpp dockbarextension.cpp +dockbar_panelextension_la_METASOURCES = AUTO +dockbar_panelextension_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) +dockbar_panelextension_la_LIBADD = $(LIB_KDEUI) + +noinst_HEADERS = dockcontainer.h dockbarextension.h + +lnkdir = $(kde_datadir)/kicker/extensions +lnk_DATA = dockbarextension.desktop + +EXTRA_DIST = $(lnk_DATA) + +messages: + $(XGETTEXT) *.cpp *.h -o $(podir)/dockbarextension.pot diff --git a/kicker/extensions/dockbar/dockbarextension.cpp b/kicker/extensions/dockbar/dockbarextension.cpp new file mode 100644 index 000000000..71b583f35 --- /dev/null +++ b/kicker/extensions/dockbar/dockbarextension.cpp @@ -0,0 +1,423 @@ +/***************************************************************** + +Copyright (c) 2000 Matthias Elter + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + +#undef Bool // For enable-final +#include <klocale.h> +#include <kwinmodule.h> +#include <kdebug.h> +#include <kconfig.h> +#include <kprocess.h> +#include <kshell.h> +#include <kwin.h> +#include <kstandarddirs.h> +#include <kmessagebox.h> +#include <kapplication.h> +#include <dcopclient.h> +#include <kglobal.h> + +#include "dockbarextension.h" +#include "dockbarextension.moc" + +#include <X11/X.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +extern "C" +{ + KDE_EXPORT KPanelExtension* init(QWidget *parent, const QString& configFile) + { + KGlobal::locale()->insertCatalogue("dockbarextension"); + return new DockBarExtension(configFile, KPanelExtension::Normal, + 0, parent, "dockbarextension"); + } +} + +DockBarExtension::DockBarExtension(const QString& configFile, Type type, + int actions, QWidget *parent, const char *name) + : KPanelExtension(configFile, type, actions, parent, name) +{ + dragging_container = 0; + kwin_module = new KWinModule(this); + connect( kwin_module, SIGNAL( windowAdded(WId) ), SLOT( windowAdded(WId) ) ); + setMinimumSize(DockContainer::sz(), DockContainer::sz()); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + loadContainerConfig(); +} + +DockBarExtension::~DockBarExtension() +{ + // kill nicely the applets + for (DockContainer::Vector::const_iterator it = containers.constBegin(); + it != containers.constEnd(); + ++it) + { + (*it)->kill(); + } + + if (dragging_container) delete dragging_container; +} + +QSize DockBarExtension::sizeHint(Position p, QSize) const +{ + if (p == Left || p == Right) + return QSize(DockContainer::sz(), DockContainer::sz() * containers.count()); + else + return QSize(DockContainer::sz() * containers.count(), DockContainer::sz()); +} + +void DockBarExtension::resizeEvent(QResizeEvent*) +{ + layoutContainers(); +} + + +void DockBarExtension::windowAdded(WId win) +{ + // try to read WM_COMMAND + int argc; + char **argv; + QString command; + if (XGetCommand(qt_xdisplay(), win, &argv, &argc)) { + command = KShell::joinArgs(argv, argc); + XFreeStringList(argv); + } + + // try to read wm hints + WId resIconwin = 0; + XWMHints *wmhints = XGetWMHints(qt_xdisplay(), win); + if (0 != wmhints) { // we managed to read wm hints + // read IconWindowHint + bool is_valid = false; + /* a good dockapp set the icon hint and the state hint, + if it uses its icon, the window initial state must be "withdrawn" + if not, then the initial state must be "normal" + this filters the problematic Eterm whose initial state is "normal" + and which has an iconwin. + */ + if ((wmhints->flags & IconWindowHint) && + (wmhints->flags & StateHint)) { + resIconwin = wmhints->icon_window; + is_valid = (resIconwin && wmhints->initial_state == 0) || + (resIconwin == 0 && wmhints->initial_state == 1); + + /* an alternative is a window who does not have an icon, + but whose initial state is set to "withdrawn". This has been + added for wmxmms... I hope it won't swallow to much windows :-/ + */ + } else if ((wmhints->flags & IconWindowHint) == 0 && + (wmhints->flags & StateHint)) { + is_valid = (wmhints->initial_state == 0); + } + XFree(wmhints); + if (!is_valid) + return; // we won't swallow this one + } + else + return; + + // The following if statement was at one point commented out, + // without a comment as to why. This caused problems like + // Eterm windows getting swallowed whole. So, perhaps now I'll + // get bug reports about whatever commenting it out was supposed + // to fix. + if (resIconwin == 0) + resIconwin = win; + + // try to read class hint + XClassHint hint; + QString resClass, resName; + if (XGetClassHint(qt_xdisplay(), win, &hint)) { + resName = hint.res_name; + resClass = hint.res_class; + } + else { + kdDebug() << "Could not read XClassHint of window " << win << endl; + return; + } + /* withdrawing the window prevents kwin from managing the window, + which causes the double-launch bug (one instance from the kwin + session, and one from the dockbar) bug when kde is restarted */ + if (resIconwin != win) { + XWithdrawWindow( qt_xdisplay(), win, qt_xscreen() ); + while( KWin::windowInfo(win, NET::XAWMState).mappingState() != NET::Withdrawn ); + } + + // add a container + embedWindow(resIconwin, command, resName, resClass); + saveContainerConfig(); +} + +void DockBarExtension::layoutContainers() +{ + int i = 0; + for (DockContainer::Vector::const_iterator it = containers.constBegin(); + it != containers.constEnd(); + ++it) + { + if (orientation() == Horizontal) + (*it)->move(DockContainer::sz() * i, 0); + else + (*it)->move(0, DockContainer::sz() * i); + i++; + } +} + +void DockBarExtension::embedWindow(WId win, QString command, QString resName, QString resClass) +{ + if (win == 0) return; + DockContainer* container = 0; + bool ncmd = false; + + for (DockContainer::Vector::const_iterator it = containers.constBegin(); + it != containers.constEnd(); + ++it) + { + DockContainer* c = *it; + if (c->embeddedWinId() == 0 && + c->resName() == resName && + c->resClass() == resClass && + (command.isNull() || c->command() == command)) + { + container = c; + break; + } + } + + if (container == 0) { + QString cmd = command.isNull() ? resClass : command; + if (KStandardDirs::findExe(KShell::splitArgs(cmd).front()).isEmpty()) + ncmd = true; + container = new DockContainer(cmd, this, resName, resClass); + addContainer(container); + } + + container->embed(win); + layoutContainers(); + emit updateLayout(); + if (ncmd) + container->askNewCommand(); + } + +void DockBarExtension::addContainer(DockContainer* c, int pos) +{ + if (pos == -1) + { + containers.append(c); + } + else + { + DockContainer::Vector::iterator it = containers.begin(); + + for (int i = 0; i < pos && it != containers.end(); ++i) + { + ++it; + } + ++it; + + containers.insert(it, c); + } + connect(c, SIGNAL(embeddedWindowDestroyed(DockContainer*)), + SLOT(embeddedWindowDestroyed(DockContainer*))); + connect(c, SIGNAL(settingsChanged(DockContainer*)), + SLOT(settingsChanged(DockContainer*))); + c->resize(DockContainer::sz(), DockContainer::sz()); + c->show(); +} + +void DockBarExtension::removeContainer(DockContainer* c) +{ + DockContainer::Vector::iterator it = qFind(containers.begin(), containers.end(), c); + + if (it == containers.end()) + { + return; + } + + containers.erase(it); + delete c; + layoutContainers(); +} + +void DockBarExtension::embeddedWindowDestroyed(DockContainer* c) +{ + removeContainer(c); + saveContainerConfig(); + emit updateLayout(); +} + +void DockBarExtension::settingsChanged(DockContainer *) +{ + saveContainerConfig(); +} + +void DockBarExtension::saveContainerConfig() +{ + QStringList applet_list; + KConfig *conf = config(); + unsigned count = 0; + + for (DockContainer::Vector::const_iterator it = containers.constBegin(); + it != containers.constEnd(); + ++it) + { + DockContainer* c = *it; + if (!c->command().isEmpty()) + { + QString applet_gid = QString("Applet_%1").arg(QString::number(count)); + applet_list.append(applet_gid); + conf->setGroup(applet_gid); + conf->writePathEntry("Command", c->command()); + conf->writePathEntry("resName", c->resName()); + conf->writeEntry("resClass", c->resClass()); + ++count; + } + } + conf->setGroup("General"); + conf->writeEntry("Applets", applet_list); + conf->deleteEntry("Commands"); // cleanup old config + conf->sync(); +} + +void DockBarExtension::loadContainerConfig() +{ + KConfig *conf = config(); + conf->setGroup("General"); + QStringList applets = conf->readListEntry("Applets"); + + QStringList fail_list; + for (QStringList::Iterator it = applets.begin(); it != applets.end(); ++it) { + if (!conf->hasGroup(*it)) continue; + conf->setGroup(*it); + QString cmd = conf->readPathEntry("Command"); + QString resName = conf->readPathEntry("resName"); + QString resClass = conf->readEntry("resClass"); + if (cmd.isEmpty() || resName.isEmpty() || resClass.isEmpty()) continue; + + DockContainer* c = new DockContainer(cmd, this, resName, resClass ); + addContainer(c); + + KProcess proc; + proc << KShell::splitArgs( cmd ); + if (!proc.start(KProcess::DontCare)) { + fail_list.append(cmd); + removeContainer(c); + } + } + if (!fail_list.isEmpty()) + KMessageBox::queuedMessageBox(0, KMessageBox::Information, i18n("The following dockbar applets could not be started: %1").arg(fail_list.join(", ")), i18n("kicker: information"), 0); + saveContainerConfig(); +} + +int DockBarExtension::findContainerAtPoint(const QPoint& p) +{ + int i = 0; + for (DockContainer::Vector::const_iterator it = containers.constBegin(); + it != containers.constEnd(); + ++it, ++i) + { + if ((*it)->geometry().contains(p)) + { + return i; + } + } + + return -1; +} + +void DockBarExtension::mousePressEvent(QMouseEvent *e ) { + if (e->button() == LeftButton) { + // Store the position of the mouse clic. + mclic_pos = e->pos(); + } else if (e->button() == RightButton) { + int pos = findContainerAtPoint(e->pos()); + if (pos != -1) containers.at(pos)->popupMenu(e->globalPos()); + } +} + +void DockBarExtension::mouseReleaseEvent(QMouseEvent *e ) { + if (e->button() != LeftButton) return; + if (dragging_container) { + releaseMouse(); + original_container->embed(dragging_container->embeddedWinId()); + delete dragging_container; dragging_container = 0; + layoutContainers(); + saveContainerConfig(); + } +} + +void DockBarExtension::mouseMoveEvent(QMouseEvent *e) { + if (! (e->state() & LeftButton) ) return; + if (dragging_container == 0) { + // Check whether the user has moved far enough. + int delay = QApplication::startDragDistance(); + if ( (mclic_pos - e->pos()).manhattanLength() > delay ) { + int pos = findContainerAtPoint(e->pos()); + original_container = 0; + if (pos > -1) { + original_container = containers.at(pos); + mclic_dock_pos = e->pos() - original_container->pos(); + dragged_container_original_pos = pos; + dragging_container = new DockContainer(original_container->command(), 0, original_container->resName(), original_container->resClass(), true); + dragging_container->show(); + dragging_container->embed(original_container->embeddedWinId()); + grabMouse(); + } + } + } + if (dragging_container) { + dragging_container->move(e->globalPos() - mclic_dock_pos); + + // change layout of other containers + QPoint dragpos(dragging_container->pos()), + barpos(mapToGlobal(pos())); + int pdrag1,pdrag2,psz; + pdrag1 = dragpos.x() - barpos.x() + DockContainer::sz()/2; + pdrag2 = dragpos.y() - barpos.y() + DockContainer::sz()/2; + if (orientation() == Vertical) { + int tmp = pdrag1; pdrag1 = pdrag2; pdrag2 = tmp; + psz = height(); + } else psz = width(); + if (pdrag2 >= 0 && pdrag2 < DockContainer::sz() && pdrag1 >= 0 && pdrag1 < psz) + pdrag1 /= DockContainer::sz(); + else + pdrag1 = dragged_container_original_pos; + + + DockContainer::Vector::iterator it = qFind(containers.begin(), containers.end(), original_container); + + if (it == containers.end()) + { + return; + } + + DockContainer::Vector::iterator target = containers.begin(); + for (int i = 0; i < pdrag1 && target != containers.end(); ++i) + { + ++target; + } + + containers.erase(it); + containers.insert(target, original_container); + layoutContainers(); + } +} diff --git a/kicker/extensions/dockbar/dockbarextension.desktop b/kicker/extensions/dockbar/dockbarextension.desktop new file mode 100644 index 000000000..53dff4bb0 --- /dev/null +++ b/kicker/extensions/dockbar/dockbarextension.desktop @@ -0,0 +1,148 @@ +[Desktop Entry] +Name=Dock Application Bar +Name[af]=Vasmeer Program Balk +Name[az]=Proqram Çubuğunu Yapışdır +Name[be]=Аплет убудоўвання праграмаў +Name[bg]=Допълнителен панел +Name[bn]=ডক অ্যাপলিকেশন বার +Name[bs]=Traka za dokiranje aplikacija +Name[ca]=Barra per ancorar aplicacions +Name[cs]=Lišta pro dokování aplikací +Name[csb]=Lëstew przërzeszaniô programów +Name[cy]=Docio'r Bar Cymhwysiad +Name[da]=Dok programlinje +Name[de]=Programm-Andockleiste +Name[el]=Γραμμή προσαρτημένων εφαρμογών +Name[eo]=Aplikaĵostrio +Name[es]=Barra para anclar aplicaciones +Name[et]=Dokitavate rakenduste riba +Name[eu]=Aplikazioak ainguratzeko barra +Name[fa]=میله کاربرد پیوند +Name[fi]=Upotettava ohjelmapalkki +Name[fr]=Barre de stockage des applications +Name[fy]=Ekstra systeemfak +Name[gl]=Acoplar Barra de Aplicación +Name[he]=מעגן יישומים +Name[hi]=अनुप्रयोग पट्टी डॉक करें +Name[hr]=Usidravanje trake aplikacija +Name[hu]=Alkalmazásdokkoló +Name[id]=Aplikasi Dock bar +Name[is]=Kví fyrir forrit +Name[it]=Barra per le applicazioni Dock +Name[ja]=ドックアプリケーションバー +Name[kk]=Қолданбаларды тіркеу панелі +Name[km]=របារកម្មវិធីចូលផែ +Name[ko]=KDE 응용 프로그램 +Name[lo]=ແຖບພັກແອບພີເຄຊັ້ນ +Name[lt]=Pritvirtintų programų juosta +Name[lv]=Dokot Aplikāciju Joslu +Name[mk]=Лента за вкотвување на апликации +Name[mn]=Програм-шигтгэх самбар +Name[ms]=Bar Aplikasi Dok +Name[mt]=Waħħal il-bar tal-programmi +Name[nb]=Festet programlinje +Name[nds]=Andockbalken +Name[ne]=डक अनुप्रयोगपट्टी +Name[nl]=Extra systeemvak +Name[nn]=Dokka programlinje +Name[nso]=Bar ya Tshomiso ya Dock +Name[pa]=ਡੋਕ ਕਾਰਜ ਪੱਟੀ +Name[pl]=Pasek dokowania programów +Name[pt]=Barra de Aplicações Acopláveis +Name[pt_BR]=Barra de aplicativos integrados +Name[ro]=Bară de docare aplicații +Name[ru]=Панель для встраивания приложений +Name[rw]=Umurongo Porogaramu Bikomatanye +Name[se]=Vuojuhuvvon prográmmaid holga +Name[sk]=Panel na dokovanie aplikácií +Name[sl]=Vrstica za zasidranje programov +Name[sr]=Трака за пристајање програма +Name[sr@Latn]=Traka za pristajanje programa +Name[sv]=Programdocka +Name[ta]=டாக் பயன்பாட்டு பட்டி +Name[tg]=Навори барномаи обзор +Name[th]=แถบพักแอพพลิเคชัน +Name[tr]=Uygulama çubuğunu gizle +Name[tt]=Yazılım Utırtu Taqtası +Name[uk]=Док-панель для програм +Name[vi]=Bến đỗ Thanh Chương trình +Name[wa]=Bår di wårdaedje des programes +Name[xh]=Ibar Yesicelo ye Dock +Name[zh_CN]=停靠应用程序栏 +Name[zh_TW]=嵌入程式工具列 +Name[zu]=Ibha Yomyaleli we-Dock +Comment=Dock application bar extension. +Comment[af]=Vasmeer program balk uitbreidings +Comment[az]=Proqram çubuğu uzantısını gizlət. +Comment[be]=Пашырэнне для ўбудавання праграмаў у панэль. +Comment[bg]=Разширение на системния панел +Comment[bn]=ডক অ্যাপলিকেশন বার এক্সটেনশন +Comment[bs]=Proširenje za dokiranje aplikacija +Comment[ca]=Una extensió de la barra per ancorar aplicacions. +Comment[cs]=Rozšíření lišty pro dokování aplikací. +Comment[csb]=Rozszérzenié do przërzeszaniô programów. +Comment[cy]=Docio estyniad y bar cymhwysiad +Comment[da]=Udvidelse - dok programlinje. +Comment[de]=Eine Andockleiste für Programme +Comment[el]=Επέκταση γραμμής προσαρτημένων εφαρμογών. +Comment[eo]=Aplikaĵostria aldono +Comment[es]=Extensión Barra para anclar aplicaciones. +Comment[et]=Paneeli laiendus dokitavate rakenduste hoidmiseks +Comment[eu]=Aplikazioak ainguratzeko barraren hedapena +Comment[fa]=پسوند میله کاربرد پیوند. +Comment[fi]=Upota ohjelmapalkkilaajennus +Comment[fr]=Stockage des applications dans une barre. +Comment[fy]=In balke wêryn tapassingen hun byldkaike kinne pleatse +Comment[gl]=Extensión de acoplamento de barras de aplicación +Comment[he]=הרחבת מעגן יישומים +Comment[hi]=अनुप्रयोग पट्टी विस्तार डॉक करें +Comment[hr]=Proširenje za usidravanje aplikacija +Comment[hu]=Alkalmazásdokkoló kiterjesztés. +Comment[id]=Panel dock ektensi untuk aplikasi +Comment[is]=Útvíkkun kvíar fyrir ísett forrit. +Comment[it]=Estensione per la barra delle applicazioni Dock. +Comment[ja]=アプリケーション用のドックパネル +Comment[kk]=Қолданбаларды тіркеу үшін панель. +Comment[km]=ផ្នែកបន្ថែមរបារកម្មវិធីចូលផែ ។ +Comment[lo]=ສ່ວນຂະຫຍາຍເພີ້ນຕື່ມພາເນລແຖລພັກແອລພີເຄຊັ້ນ +Comment[lt]=Pritvirtintų programų juostos plėtinys. +Comment[lv]=Doko aplikāciju joslas paplašinājumu. +Comment[mk]=Екстензија за вкотвување на апликации. +Comment[mn]=Програмын шигтгээ самбар өргөтгөл +Comment[ms]=Lanjutan bar aplikasi dok. +Comment[mt]=Estensjoni biex twaħħal il-bar tal-programmi. +Comment[nb]=Festepanel for programmer +Comment[nds]=Andockbalken för Programmen +Comment[ne]=डक अनुप्रयोगपट्टी विस्तार +Comment[nl]=Een balk waarin toepassingen hun pictogram kunnen plaatsen +Comment[nn]=Dokkingspanel for program +Comment[nso]=Koketso ya bar ya tshomiso ya dock. +Comment[pa]=ਡੋਕ ਕਾਰਜ ਪੱਟੀ ਵਧਾਰਾ ਹੈ। +Comment[pl]=Rozszerzenie do dokowania programów. +Comment[pt]=Uma extensão de barra de aplicações acopláveis. +Comment[pt_BR]=Extensão da barra de aplicativos embutidos. +Comment[ro]=Extensie bară de docare aplicații. +Comment[ru]=Расширение панели для встраивания приложений. +Comment[rw]=Iyagura ry'umurongo w'ikomatanya porogaramu +Comment[se]=Prográmmaid vuojuhanpanela +Comment[sk]=Rozšírenie pre dokovací panel aplikácií +Comment[sl]=Razširitev za sidrišče programov. +Comment[sr]=Проширење траке за пристајање програма. +Comment[sr@Latn]=Proširenje trake za pristajanje programa. +Comment[sv]=Bygger ut med en programdocka +Comment[ta]=டாக் பயன்பாடு பட்டி விரிவாக்கம் +Comment[tg]=Кушодкунии панел барои бино кунӣ. +Comment[th]=ส่วนขยายเพิ่มเติมพาเนล แถบพักแอพพลิเคชัน +Comment[tr]=Uygulama çubuğu uzantısını gizle. +Comment[tt]=Yazılım utırtuçı taqta östämäse. +Comment[uk]=Розширення док-панелі для програм. +Comment[vi]=Bến đỗ các thanh chương trình mở rộng +Comment[wa]=Module di bår di wårdaedje des programes +Comment[xh]=Ulwandiso lwe bar yesicelo se Dock. +Comment[zh_CN]=停靠应用程序栏扩展。 +Comment[zh_TW]=嵌入延伸程式工具列 +Comment[zu]=Isandiso sebha Yomyaleli we-Dock + +Icon=dockbar +X-KDE-Library=dockbar_panelextension +X-KDE-UniqueApplet=true diff --git a/kicker/extensions/dockbar/dockbarextension.h b/kicker/extensions/dockbar/dockbarextension.h new file mode 100644 index 000000000..0003ec6fa --- /dev/null +++ b/kicker/extensions/dockbar/dockbarextension.h @@ -0,0 +1,73 @@ +/***************************************************************** + +Copyright (c) 2000 Matthias Elter + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + +#ifndef __dockbarextension_h__ +#define __dockbarextension_h__ + +#include <qvaluevector.h> +#include <kpanelextension.h> +#include "dockcontainer.h" + +class KWinModule; + +class DockBarExtension : public KPanelExtension +{ + Q_OBJECT + +public: + DockBarExtension(const QString& configFile, Type t = Normal, + int actions = 0, QWidget *parent = 0, const char *name = 0); + + virtual ~DockBarExtension(); + + QSize sizeHint(Position, QSize maxSize) const; + Position preferedPosition() const { return Right; } + +protected slots: + void windowAdded(WId); + void embeddedWindowDestroyed(DockContainer*); + void settingsChanged(DockContainer*); + +protected: + void resizeEvent(QResizeEvent*); + void embedWindow(WId win, QString command, QString resName, QString resClass); + void addContainer(DockContainer*, int pos=-1); + void removeContainer(DockContainer*); + void saveContainerConfig(); + void loadContainerConfig(); + void layoutContainers(); + int findContainerAtPoint(const QPoint&); + void mousePressEvent(QMouseEvent *); + void mouseReleaseEvent(QMouseEvent *); + void mouseMoveEvent(QMouseEvent *); +private: + KWinModule* kwin_module; + DockContainer::Vector containers; + + // handle the dragging of applets + DockContainer *dragging_container, *original_container; + QPoint mclic_pos, mclic_dock_pos; + int dragged_container_original_pos; +}; + +#endif diff --git a/kicker/extensions/dockbar/dockcontainer.cpp b/kicker/extensions/dockbar/dockcontainer.cpp new file mode 100644 index 000000000..f2117346d --- /dev/null +++ b/kicker/extensions/dockbar/dockcontainer.cpp @@ -0,0 +1,198 @@ +/***************************************************************** + +Copyright (c) 2000 Matthias Elter <elter@kde.org> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + +#include <qwidget.h> +#include <qtooltip.h> +#include <kwin.h> +#include <qvalidator.h> +#include <kinputdialog.h> +#include <klocale.h> +#include <kpopupmenu.h> +#include <kdebug.h> + +#include "dockcontainer.h" +#include "dockcontainer.moc" + +#include <X11/X.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> + + +DockContainer::DockContainer( QString command, QWidget *parent, + QString resname, QString resclass, bool undocked_style ) + : QFrame( parent, resname.ascii(), + undocked_style ? WStyle_Customize | + WStyle_StaysOnTop | WStyle_Tool | + WStyle_NoBorder | WX11BypassWM : 0 ), + _embeddedWinId(0), + _command(command), + _resName(resname), + _resClass(resclass) +{ + XSelectInput( qt_xdisplay(), winId(), + KeyPressMask | KeyReleaseMask | + ButtonPressMask | ButtonReleaseMask | + KeymapStateMask | + ButtonMotionMask | + PointerMotionMask | + EnterWindowMask | LeaveWindowMask | + FocusChangeMask | + ExposureMask | + StructureNotifyMask | + SubstructureRedirectMask | + SubstructureNotifyMask ); + if (!undocked_style) { + setFrameStyle(StyledPanel | Raised); + setLineWidth(border()); + QToolTip::add(this, command); + } else { + setFrameStyle(StyledPanel | Plain); + setLineWidth(1); + } + resize(sz(),sz()); +} + +void DockContainer::embed( WId id ) +{ + if( id == _embeddedWinId || id == 0) + return; + QRect geom = KWin::windowInfo(id,NET::WMKDEFrameStrut).frameGeometry(); + + // does the same as KWM::prepareForSwallowing() + XWithdrawWindow( qt_xdisplay(), id, qt_xscreen() ); + while( KWin::windowInfo(id, NET::XAWMState).mappingState() != NET::Withdrawn ); + + XReparentWindow( qt_xdisplay(), id, winId(), 0, 0 ); + + // resize if window is bigger than frame + if( (geom.width() > width()) || + (geom.height() > height()) ) + XResizeWindow( qt_xdisplay(), id, width(), height() ); + else + XMoveWindow(qt_xdisplay(), id, + (sz() - geom.width())/2 - border(), + (sz() - geom.height())/2 - border()); + XMapWindow( qt_xdisplay(), id ); + XUngrabButton( qt_xdisplay(), AnyButton, AnyModifier, winId() ); + + _embeddedWinId = id; +} + +void DockContainer::unembed() +{ + if( _embeddedWinId ) + XReparentWindow( qt_xdisplay(), _embeddedWinId, qt_xrootwin(), 0, 0 ); +} + +void DockContainer::kill() +{ + if ( _embeddedWinId ) { + XKillClient( qt_xdisplay(), _embeddedWinId ); + _embeddedWinId = 0; // in case the window does not exist anymore.. + } + else emit embeddedWindowDestroyed(this); /* enable killing of empty windows.. */ +} + +bool DockContainer::x11Event( XEvent *e ) +{ + switch( e->type ) { + case DestroyNotify: + if( e->xdestroywindow.window == _embeddedWinId || _embeddedWinId == 0) { + _embeddedWinId = 0; + emit embeddedWindowDestroyed(this); + } + break; + case UnmapNotify: + if ( e->xunmap.window == _embeddedWinId ) { + kdDebug() << "Unmap Notify !!! I hate smart dockapps as wmpinboard " << command() << endl; + _embeddedWinId = 0; + } + break; + case ReparentNotify: + if( _embeddedWinId && + (e->xreparent.window == _embeddedWinId) && + (e->xreparent.parent != winId()) ) { + _embeddedWinId = 0; + } + else if( e->xreparent.parent == winId() ) { + _embeddedWinId = e->xreparent.window; + embed( _embeddedWinId ); + } + break; + } + + return false; +} + +void DockContainer::askNewCommand(bool bad_command) +{ + bool ok; + QString title( i18n("Enter Command Line for Applet %1.%2").arg(resName()).arg(resClass()) ); + QString description( i18n("This applet does not behave correctly and the dockbar was unable to " + "find the command line necessary to launch it the next time KDE starts up") ); + QString cmd; + + /* + I was not able to figure out why valgrind complains inside the getText call.. + (invalid read of size 1 in Xmb.. functions) + */ + if (bad_command) { + cmd = KInputDialog::getText( title, description, + command(), &ok, this ); + } else { + cmd = KInputDialog::getText( title, QString::null, + command(), &ok, this ); + } + if (ok) { _command = cmd; emit settingsChanged(this); } +} + +void DockContainer::popupMenu(QPoint p) +{ + int r; + { + KPopupMenu pm(this); + pm.insertItem( i18n("Kill This Applet"), 0); + pm.insertItem( i18n("Change Command"), 1); + r = pm.exec(p); + /* pm is destroyed now .. if it is destroyed later, + there is a risk that kill() double-frees it */ + } + switch (r) { + case 0: { + kill(); + } break; + case 1: { + askNewCommand(false); + } break; + } +} + +int& DockContainer::sz() { + static int _sz = 66; + return _sz; +} + +int& DockContainer::border() { + static int _border = 1; + return _border; +} diff --git a/kicker/extensions/dockbar/dockcontainer.h b/kicker/extensions/dockbar/dockcontainer.h new file mode 100644 index 000000000..bc9962290 --- /dev/null +++ b/kicker/extensions/dockbar/dockcontainer.h @@ -0,0 +1,90 @@ +/***************************************************************** + +Copyright (c) 2000 Matthias Elter <elter@kde.org> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + +#ifndef __dockcontainer_h__ +#define __dockcontainer_h__ + +#include <qframe.h> +#include <qvaluevector.h> + +class DockContainer : public QFrame +{ + Q_OBJECT + +public: + typedef QValueVector<DockContainer*> Vector; + + DockContainer( QString command, QWidget *parent, + QString resname, + QString resclass, + bool undocked_style=false); + + void embed(WId); + void unembed(); + void kill(); + + WId embeddedWinId() const; + QString command() const; + QString resClass() const; + QString resName() const; + void askNewCommand(bool bad_command=true); + void popupMenu(QPoint p); + static int& sz(); + static int& border(); +signals: + void embeddedWindowDestroyed(DockContainer*); + void settingsChanged(DockContainer*); + +protected: + bool x11Event( XEvent * ); + +private: + WId _embeddedWinId; + QString _command; + QString _resName, _resClass; +}; + + +inline WId DockContainer::embeddedWinId() const +{ + return _embeddedWinId; +} + +inline QString DockContainer::command() const +{ + return _command; +} + +inline QString DockContainer::resClass() const +{ + return _resClass; +} + +inline QString DockContainer::resName() const +{ + return _resName; +} + + +#endif + diff --git a/kicker/extensions/kasbar/ChangeLog b/kicker/extensions/kasbar/ChangeLog new file mode 100644 index 000000000..09408fc4a --- /dev/null +++ b/kicker/extensions/kasbar/ChangeLog @@ -0,0 +1,954 @@ +2004-11-20 Saturday 23:27 rich + + * - Ensure the LCD used by the clock is deleted in a timely manner. + + - Lazy creation of the data picker popup of the clock item. + + - Save orientation and direction between sessions properly (the + direction is now the primary record). + +2004-11-20 Saturday 21:18 rich + + * - Update changelog + +2004-11-20 Saturday 21:17 rich + + * - Fixed a warning from KImageEffect about the image being invalid + when we draw the load gradient and the load is 0. + +2004-11-20 Saturday 20:05 rich + + * - Added support for filling the bar from either end. + +2004-11-20 Saturday 02:34 rich + + * - Middle click now rotates the bar. + + - Improved the about dialog. + + - Made masking of the containing toplevel optional. + + - Fixed positioning of the clock display in small mode. + +2004-11-19 Friday 23:21 rich + + * - The standalone app now remembers its position properly. + +2004-11-19 Friday 22:30 rich + + * - Increase version and update changelog. + +2004-11-19 Friday 22:29 rich + + * - Moved item bg gradients into KasResources. + + - More work on improving the painting. This is currently a bit + broken as it is waiting for me to abandon using KRootPixmap. + +2004-11-17 Wednesday 17:56 mueller + + * fix export's + +2004-11-14 Sunday 20:52 binner + + * CVS_SILENT i18n style guide fixes + +2004-11-13 Saturday 02:37 rich + + * - Totally reworked the way showing and hiding popups works. + + - Added a command line tool that provides a standalone kasbar. + + - Added a system load meter item. + + - Improved config dialog. + +2004-10-23 Saturday 19:04 wgreven + + * Fix for unsermake. + +2004-10-23 Saturday 13:42 wgreven + + * Sync with HEAD. + +2004-10-23 Saturday 04:19 rich + + * + - Totally reworked the way showing and hiding of popups works. + Things should be a lot more sane now as the popups are reused. + + - Added a command line tool that provides a standalone kasbar. + + - Improved the demo in the about dialog. + +2004-10-03 Sunday 01:26 rich + + * - Move the startup animation frames into KasResources so they are + shared by all items. Changed the QPtrList to a QValueVector for + more efficient lookups and implicit sharing. + + - Improved the way animations are triggered to support custom + animations. + + - Added a new clock item type. + +2004-09-13 Monday 12:08 coles + + * + + CVS_SILENT + + behaviour -> behavior. + +2004-09-12 Sunday 02:43 rich + + * - Items store their position. This allows much more efficient + painting. + +2004-09-12 Sunday 01:21 rich + + * - Remove floating bars if the extension that they are supposed to + live in is removed. + +2004-09-12 Sunday 00:24 rich + + * - Update changelog + +2004-09-12 Sunday 00:24 rich + + * - Support for only showing minimized applications like the old + OLWM. + + - Improvements to the context menu. + + - Optionally don't show the frames for inactive items (great if + you want the floating mode to blend into your desktop). + + - Refactored code for drawing state icons. + +2004-09-05 Sunday 00:47 rich + + * - Moved most of the config writing code into KasTasker. + +2004-09-04 Saturday 02:57 rich + + * - Update changelog + +2004-09-04 Saturday 02:56 rich + + * - Began making startup items work like other types of item. + + - Fixed a regression that broke all the grouping code. + +2004-09-04 Saturday 01:42 rich + + * - You can now disable the frame around inactive boxes. + + - Startup items now spin around their own center. + +2004-09-03 Friday 22:32 rich + + * - Added support for the XShape extension, the unused space is now + masked so that when you have a non-rectangular bar (by using + the 'Boxes per line' setting) the unused space is truly unused. + To make this better, I need to make it so that the box is + always populated from the screen edge outwards. + +2004-08-29 Sunday 00:27 rich + + * Update changelog + +2004-08-29 Sunday 00:27 rich + + * - Added ability to rotate the bar when it is floating. + + - Added a context menu item to attach and detach the bar. + + - Improved repaint performance. + + - Increased version number. + +2004-08-21 Saturday 02:22 rich + + * - Completed support for embedding the thumbnails of tasks in the + icon boxes instead of only showing them in the tooltip. If the + app changes its WM icon then this is overlayed on the box as + before. + + - Fixed popup display. + +2004-08-20 Friday 23:18 rich + + * - Merge the kasbar3 code into head: + + - Better grouping facilities + - Cleaner code + - More efficient + - Send any window to the system tray + - Attention required indicator + - Partial support for more sizes: huge, enourmous and custom + sizes + - Better organisation of the preferences dialog + - More control over the appearance of the bar + - 'Floating' mode + - Group windows on inactive desktops + +2004-08-07 Saturday 04:10 rich + + * - Moved almost all of the functionality of KasGroupPopup into + KasPopup in preparation for the removal of the custom class for + group popups. + + - Removed the KasGroupPopup class. The functionality it contained + is now all supported by the KasPopup base-class. + +2004-08-07 Saturday 03:39 rich + + * - Ensure the test program reads the current config file properly. + +2004-08-07 Saturday 03:34 rich + + * - Improved the handling of inactive desktop grouping. + + - Fixed a problem with popups not being deleted when their + associated item was invalidated. + +2004-08-07 Saturday 03:00 rich + + * - Ensure that grouping windows on inactive desktops updates + correctly when the current desktop changes. + +2004-08-07 Saturday 02:35 rich + + * - Added kasgrouper class and updated changelog. + +2004-08-07 Saturday 02:34 rich + + * - Reworked the configuration dialog to move the 'insanely + detailed' options into an advanced page. I also added a + graphical way to configure some of the color options that + previously required hacking the config file to access. + + - Made the color of the 'attention required' state icon + configurable. + +2004-08-07 Saturday 00:00 rich + + * - Emit signals for mouse handling and use them for controlling + the popup. + + - Split grouping out into a separate class. + +2004-08-06 Friday 00:51 rich + + * - Fix breakage of the preferences dialog. + +2004-08-06 Friday 00:19 rich + + * - Added an 'ungroup' action to the context menu for group items. + + - Added a 'Refresh' action to kasbar menu. + +2004-08-05 Thursday 23:30 rich + + * - Updated copyrights and added info about the features to docs.h. + +2004-08-05 Thursday 23:26 rich + + * - Reworked the popup handling code to massively improve control + over the lifetime of the popup. This has simplified a bunch of + things and made more advanced popup handling possible. + +2004-08-01 Sunday 02:55 rich + + * - KasItem is now responsible for drawing the main icon of the + boxes. + + - KasItem now provides a demo childbar as the default + implementation of createPopup(). This means that you now get a + nice popup when you move the mouse over the item in the about + dialog. + +2004-08-01 Sunday 01:45 rich + + * - Began moving support for child bars to the kasbar base class + rather than confining it to KasTasker. + + - New constructor for childbars in KasBar. + - Reworked code for updating child to match parents resources. + - Moved child bar creation to a factory method in KasBar. + +2004-08-01 Sunday 00:24 rich + + * - Added support for the 'demands attention' task property. + + - Centralised the code that creates the kasbar menu. + + - Modified icon is now accessed via the resource object. + + - Singleton icons are no longer stored as pointers. + +2004-07-25 Sunday 01:15 rich + + * - Fix a problem with the usage of the RMB menu from taskmanger, + passing a widget as an argument to a bool variable is not + what's supposed to happen. + + - Fixed menu for group items. + + CCMAIL: 48825-done@bugs.kde.org + +2004-07-25 Sunday 00:58 rich + + * - Fixed menu handling to support the show all flag properly, and + added group menus. + +2004-07-25 Sunday 00:20 rich + + * - Started pulling ui resources into a standalone class + KasResources. Child bars inherit their parents resources by + default. + + - Added a hack to prototype the idea of embedding the thumbnails + in the icon box. + + - Support for custom sizes (incomplete). + + - Improvements to the configuration dialog. + + - Ability to group windows on inactive desktops (still buggy). + +2004-07-24 Saturday 00:10 rich + + * - Added the ability to send a window to the system tray. + + - Broke transparency in preparation for the new implementation. + + - Started the 'group windows on inactive desktops' option. + +2004-07-18 Sunday 00:31 rich + + * The work I've been doing to get kasbar ready for the 3.3 release + has encouraged me to add few new features and do a bit of + redesign. This code is not ready to be released, so I'm keeping + it the newly created kasbar3_branch. + +2004-07-10 Saturday 20:38 binner + + * CVS_SILENT i18n style guide fixes + +2004-07-10 Saturday 01:57 rich + + * - Fixed the progress indicator code. You can now get a progress + bar in the label of a task (replacing the broken pie chart + code). + +2004-06-29 Tuesday 01:19 wheeler + + * CVS_SILENT Oops. Didn't mean for this to go in. + +2004-06-29 Tuesday 01:16 wheeler + + * Disable the tint color and amount boxes if tinting is disabled. + +2004-06-27 Sunday 17:18 binner + + * CVS_SILENT i18n style guide fixes + +2004-06-27 Sunday 01:10 rich + + * - Added the ability to choose the colors used for the item + labels. + + CCMAIL: 60520-done@bugs.kde.org + +2004-06-26 Saturday 23:49 rich + + * - Don't show the desktop number if there's only one desktop. + + CCMAIL: 60520@bugs.kde.org + +2004-06-26 Saturday 02:12 rich + + * - Fixed clearing of unused space when the used part of the bar is + not rectangular. The fix could be improved, but it removes the + essential problem. + + CCMAIL: 47078-done@bugs.kde.org + +2004-06-26 Saturday 01:48 rich + + * - Fix popup handling. + + CCMAIL: 68305-done@kde.org + +2004-06-26 Saturday 00:28 rich + + * - Fix test program for kwin changes. + +2004-06-26 Saturday 00:10 rich + + * - Fix task properties dialog to use the new name of the + visibleiconname Task property. + +2004-06-25 Friday 23:43 rich + + * - Fixed about dialog to take account of the fact the cvs id was + removed. + + - Fixed the size and wrapping of the license text in the about + dialog. + +2004-06-25 Friday 23:10 rich + + * Updated the changelog, it was 2 years out of date + +2004-02-24 Tuesday 19:14 mcamen + + * Fix compilation. The remove-id-tag-commit was not correct for + these files. + +2004-02-24 Tuesday 11:30 englich + + * + Remove all CVS Id tags from kdebase, if I haven't missed one. + + Of course, this will multifold break compile as well as a dozen + of people will now object that they actually wanted the Id tags. + +2004-01-05 Monday 21:38 adridg + + * Add dual-license GPL/BSD to files as instructed by Rich Moore. + +2003-12-20 Saturday 15:14 kossebau + + * hiding a few symbols :) + +2003-11-20 Thursday 16:12 mlaurent + + * Clean commit as requested by David. When we use + K_EXPORT_KICKER_MENUEXT it's automatic => don't use + removeCatalogue otherwise use removeCatalogue. + +2003-10-27 Monday 19:12 bwalter + + * CVS_SILENT Changed the "check popup" delay. + +2003-10-23 Thursday 21:41 bwalter + + * Use topLevelWidget() instead of parent()->parent()... + +2003-10-22 Wednesday 22:15 bwalter + + * Better than a singleShot timer to make popups disappear but not + always enough. + +2003-10-21 Tuesday 10:45 bwalter + + * Fix the annoying problem of tooltips which sometimes never + disappear. + +2003-10-06 Monday 23:27 rich + + * Fix vertical mode + +2003-10-06 Monday 20:11 rich + + * Fix problem with maxBoxes fix. + +2003-10-04 Saturday 21:36 rich + + * - Split the 'max boxes' concept into two so we can handle things + properly. The original max boxes remains, and refers to the + user specified limit on the number of boxes per line. In + addition there is now a 'boxes per line' concept which stores + the number of boxes that will actually fit. This change cleans + up the configuration handling and also means that kasbar can obey + the size limits placed on it. + + - Take notice of the size limits passed to the widget. This means + the size limits for extension that were added in 3.1 will now + work properly. + + - Disable updates when refreshing the entire task list. This + removes lots of flicker when changing desktops when you don't + show all the tasks. + + - Improved the resize handling code so that can handle changes in + the item size cleanly. + + - Updated copyright dates. + +2003-09-30 Tuesday 22:25 rich + + * - More improvements to bg repainting (much more efficient). + + - Fixed startup animation problem #39582 + + - Fixed erase problem introduced by the repaint changes in my + last commit. + + CCMAIL: 39582-done@bugs.kde.org + +2003-09-30 Tuesday 19:18 rich + + * - Removed duplicated config loading code from the extension + class. + + - Removed redundant reload of configuration info. + + - Reworked painting - Double buffering is now handled by KasBar + not the items. - Items now longer force an immediate repaint, + they use update instead. - Fixes #53735 + + CCMAIL: 53735-done@bugs.kde.org + +2003-09-29 Monday 12:24 lunakl + + * Another attempt to get (_NET_)WM_(ICON_)NAME right. + +2003-08-07 Thursday 19:51 lunakl + + * Rewrite handling of _NET_WM_ICON_NAME. This together with the + recent KApplication change should hopefully make taskbar again + display what it's supposed to display. Please yell if something + is still wrong. + +2003-07-31 Thursday 10:31 lunakl + + * Proper handling of _NET_WM_ICON_NAME - it has nothing to do with + what's usually meant by icons in KDE, but it's the text to be + shown in iconic representations of a window, such as taskbar + entries. + +2003-07-19 Saturday 22:35 deller + + * do not use hardcoded fontnames + +2003-05-17 Saturday 10:20 coolo + + * fixing quite some compiler warnings + +2003-03-29 Saturday 20:29 binner + + * Fixed a layout problem and solution for "only drawing last icon + from a group". + +2003-02-09 Sunday 09:51 mfranz + + * fix typo + +2002-12-29 Sunday 17:10 mueller + + * use $(KDE_PLUGIN) + +2002-10-27 Sunday 16:05 mlaurent + + * Fix a part of crash. But kastaskbar crash again when we call + "show preference" or "about" when we call it into taskbarpopup. + Because taskitem was deleted when we hide popup => so when we + close dialogbox, kicker crash. I don't know how to fix it. But + it crashs again... + +2002-10-27 Sunday 15:50 mlaurent + + * Remove some if( blabla) delete blabla => delete blabla; + +2002-10-27 Sunday 14:46 mlaurent + + * Fix display properties dialogbox when we call it from + kasgroupitem + +2002-10-27 Sunday 13:53 mlaurent + + * Fix crash when we call showPreference on item in kasgroupgroup => + config pointer was null. + +2002-10-27 Sunday 12:48 mlaurent + + * Fix crash when we taskbar was re-create after change config. + +2002-09-18 Wednesday 17:13 binner + + * CVS_SILENT Style guide fix, use "cvslastchange" or X-WebCVS + header line to view + +2002-09-03 Tuesday 16:42 ettrich + + * patch from Benoit Walter <benoit.walter@esstin.uhp-nancy.fr> as + discussed on kde-core-devel + +2002-08-31 Saturday 10:44 pfeiffer + + * another font-patch from CCMAIL: Luciano Montanaro + <mikelima@virgilio.it> + +2002-08-30 Friday 11:45 mkretz + + * This took me 2 hours to find... + + - KConfigGroupSaver( conf, "Appearance" ); + + KConfigGroupSaver saver( conf, "Appearance" ); + + Finally the size is restored correctly. + +2002-08-30 Friday 10:37 pfeiffer + + * use KGlobal::taskbarFont(), patch by CCMAIL: Luciano Montanaro + <mikelima@virgilio.it> + +2002-08-29 Thursday 17:38 mueller + + * remove outdated #ifdef's + +2002-08-13 Tuesday 09:05 binner + + * CVS_SILENT Style guide fix, use "cvslastchange" or X-WebCVS + header line to view + +2002-08-09 Friday 23:57 rich + + * - Fixed repaint problem with startup items + +2002-07-29 Monday 22:03 coolo + + * this fixes compilation for me +void KasTasker::readConfig() +{ + + readConfig(this->conf); +} + +2002-07-27 Saturday 04:26 rich + + * Added kasbar actions to item menus to fix reported ui bug + +2002-07-03 Wednesday 11:03 binner + + * CVS_SILENT Style guide fixes + +2002-06-10 Monday 03:29 rich + + * - Simplify drawing code - Ensure popup doesn't obscure menu - Fix + bug when window changes desktop - Task properties dialog + +2002-05-25 Saturday 14:18 coolo + + * CVS_SILENT ignoring unsermake generated files + +2002-05-14 Tuesday 10:31 gioele + + * kapp.h -> kapplication.h + +2002-04-23 Tuesday 14:02 binner + + * CVS_SILENT Capitalisation fixes. + +2002-04-12 Friday 22:36 rich + + * - kdoc fixes + +2002-03-11 Monday 00:23 rich + + * Use all the frames in the startup animation (cleaner fix) + +2002-03-11 Monday 00:10 rich + + * Use all the frames in the statup animation + +2002-03-08 Friday 15:08 lukas + + * grrr, I fixed that before 2.2.2 and it's back :( + + + KGlobal::locale()->insertCatalogue("kasbarextension"); + +2002-02-26 Tuesday 17:04 elter + + * - install extensions into kde's module subdir + +2002-02-24 Sunday 21:44 rich + + * Added change log file + +2002-02-24 Sunday 21:41 rich + + * - Version++ - Fixed redraw errors when there are no tasks - Now + makes use of the KRootPixmap improvements in KDE 3. - All + drawing is now double buffered, so the flicker problems of the + past should be solved. - Changed many methods to remove + coordinate params. - KasItems are now given a translated + qpainter. - Added a change log (generated from the cvs log by + cvs2cl). - Removed old RMB menu code (we use the more reliable + stuff in the taskmanager lib instead). + + ---------------------------------------------------------------------- + +2002-01-20 Sunday 18:15 wgreven + + * Initialize dragTimer to null. + +2001-12-29 Saturday 17:18 mueller + + * CVSSILENT: fixincludes + +2001-12-11 Tuesday 02:09 firebaugh + + * Clean up task menu code. Kill memory leaks. Add new items to RMB + menu for grouped tasks. + +2001-11-29 Thursday 19:34 rich + + * version++, update homepage + +2001-11-29 Thursday 19:23 rich + + * Switch to taskmanager task popup menu instead of kwin (avoids + some problems) + +2001-11-25 Sunday 02:03 rich + + * - Updated todo list - Only showing the group popups for 4 ms was + a bit daft - Moved config load code + +2001-11-25 Sunday 01:43 rich + + * - Reduced flicker - kasbar widget now supports widget flags - + Version++ - Task grouping popups now auto-hide - Added standalone + version for testing (maybe a user-level feature in future). + +2001-11-11 Sunday 17:26 rich + + * Work the same way as the std taskbar + +2001-10-07 Sunday 01:46 mueller + + * whoopsie + +2001-09-26 Wednesday 18:37 mueller + + * fixes for QT_NO_COMPAT + +2001-09-01 Saturday 22:31 rich + + * Fix popup window for Qt 3 widget flags better + +2001-09-01 Saturday 22:23 rich + + * Fix popup window for Qt 3 widget flags + +2001-09-01 Saturday 00:55 rich + + * - QList->QPtrList - Improved classdocs build target + +2001-08-27 Monday 18:41 lukas + + * make it show translated + +2001-07-17 Tuesday 19:59 rich + + * Added some extra guards around KRootPixmap calls and readded the + repaint I removed earlier + +2001-07-17 Tuesday 17:03 rich + + * Remove redundant repaint + +2001-07-17 Tuesday 16:47 rich + + * Get rid of the warning reported by Dirk + +2001-06-04 Monday 22:09 rich + + * Minor fixes + +2001-06-04 Monday 19:55 rich + + * Do not refresh on desktop switch if we show all tasks + +2001-05-24 Thursday 02:01 rich + + * UI fix for small mode + +2001-05-22 Tuesday 05:03 waba + + * Get rid of compiler warnings. Make it compile with + --enable-final. + +2001-05-22 Tuesday 02:22 rich + + * Use shared idmatching code + transparency fix + +2001-05-21 Monday 21:59 rich + + * Added support for task grouping (optional) + +2001-05-21 Monday 02:09 mhunter + + * Spelling and grammar corrections + +2001-05-15 Tuesday 04:37 rich + + * Moved the icon handling code out of Kasbar and into the Task + class. Task now provides an API for icon loading that allows + access to different icon sizes and uses KIconLoader where needed. + +2001-05-15 Tuesday 01:19 rich + + * Improved icon support in task manager api Fixed flicker in kasbar + startup items Kasbar large mode handles dynamically changing + icons nicely + +2001-05-14 Monday 21:37 rich + + * Still standardising the method names + +2001-05-14 Monday 17:56 rich + + * Changed taskmanager api to follow standard naming conventions + +2001-05-14 Monday 16:38 rich + + * Better icon handling in Large mode Fixed config handling of + MaxBoxes + +2001-05-14 Monday 03:26 rich + + * Minor tweaks + +2001-05-14 Monday 02:52 rich + + * More thumbnail improvements + +2001-05-14 Monday 00:40 rich + + * Added new about dialog Fixed some flicker problems Improved + thumbnail heuristics Improved transparent mode repaints + +2001-04-27 Friday 19:07 rich + + * Fixed modified indicator + +2001-04-27 Friday 18:00 rich + + * You can vary the size of Kasbar! + +2001-04-26 Thursday 22:50 rich + + * Fix transparency bug + +2001-04-26 Thursday 22:15 rich + + * UI fixes + +2001-04-26 Thursday 21:08 rich + + * Improvements to extension support + +2001-04-26 Thursday 00:05 rich + + * Fixed whatsthis + +2001-04-25 Wednesday 23:56 rich + + * Added whatsthis help + +2001-04-25 Wednesday 20:23 rich + + * Nicer config dialog + +2001-04-25 Wednesday 19:38 rich + + * Version number++ + +2001-04-25 Wednesday 18:35 rich + + * Now you turn off thumbnails and a minor memory leak was fixed + +2001-04-19 Thursday 01:27 rich + + * All the preferences are now working except for disabling + thumbnails. + +2001-04-18 Wednesday 00:01 rich + + * More work on the config dialog + +2001-04-16 Monday 14:07 rich + + * Forgot to commit this + +2001-04-16 Monday 14:05 rich + + * Added config handling (partial so far) Changed + X-KDE-UniqueExtension to X-KDE-UniqueApplet (the former is + correct according to the docs but doesn't work). + +2001-04-10 Tuesday 21:13 rich + + * Fixed startup crash + +2001-03-31 Saturday 11:50 elter + + * - fixed extension size hint - fixed compiler warning + +2001-03-20 Tuesday 02:15 rich + + * * About dialog now shows a version number. * Changed modified + icon from blue to black. * Much improved thumbnailing - now + feels nice and responsive. + +2001-03-18 Sunday 17:43 rich + + * Added about dlg and publish icon geometries + +2001-03-18 Sunday 16:20 rich + + * Fixed crash in mouse move event + +2001-03-16 Friday 03:37 rich + + * - Added task switch on drag over - Tidied up access to TasTasker + - Made gradient code more efficient - Added window menu support + +2001-03-06 Tuesday 23:34 rich + + * More efficient startup items + +2001-03-06 Tuesday 22:29 porten + + * friend class + +2001-03-06 Tuesday 12:32 faure + + * ran includemocs to get this to compile (am_edit was trying to + compile a .moc.cpp into a .moc ... there's still something fishy + in am_edit...) + +2001-03-06 Tuesday 02:05 rich + + * First public release of the Kasbar TNG code + + Kasbar now: - Use the new taskmanager API - Supports the startup + notifier - Supports thumbnails - Supports transparency ... + +2000-12-17 Sunday 12:00 elter + + * Fixed totally broken kasbar sizeHint. + +2000-12-17 Sunday 11:53 elter + + * - correct initial positioning of extensions - bugfixes + +2000-11-14 Tuesday 21:46 rich + + * Added: - Transparency support - Show this-desktop-only mode + + Fixed: - Icon sizing issue caused by the move to 34x34 icons - + Unique flag in .desktop file + +2000-11-12 Sunday 20:21 rich + + * - Tidied up the code - Steps towards startup notifier - Better + left click behaviour - Window menu support using DCOP (needs KWin + update I am committing in a moment) - Minor bug fixes + +2000-11-12 Sunday 01:14 rich + + * Ported kasbar to kicker entensions framework + diff --git a/kicker/extensions/kasbar/DESIGN b/kicker/extensions/kasbar/DESIGN new file mode 100644 index 000000000..6d2de25e6 --- /dev/null +++ b/kicker/extensions/kasbar/DESIGN @@ -0,0 +1,42 @@ +KasBar TNG Design +================= + +In order to support both the various features people asked for when I +discussed Kasbar on dot.kde.org without ending up with a completely +unmaintainable application, I've decided to rewrite the code. It's a +fairly small application, so this isn't a big deal. The task management +side of things (interacting with the window manager etc.) is now handled +via the standard TaskManager API provided by kicker. + +The division of labour between the classes is like this: + +* KasBar, KasItem, KasPopup + + These classes implement the KasBar widget. KasBar provides the + layout and smart redraws while the KasItem class is an abstract + interface for the items forming the bars contents. The KasPopup + class provides a self positioning widget that should be subclassed + to provide useful information. + + These classes are usable standalone. + +* KasTasker, KasTaskItem, KasTaskPopup + + These classes provide the glue linking the task management and + karbar modules together. + +* KasGroupItem, KasGroupPopup + + These class provide a container item for a group of tasks, and popup + window that shows them in a KasTasker widget. + +* KasBarExtension + + This class handles integration with kicker and configuration info. + +* KasPrefsDlg + + This is the configuration dialog. It acts directly on the kastasker + widget to provide immediate feedback of the effects of configuration + changes. Any changes being previewed are reverted if the user cancels + the dialog because the configuration is reloaded. diff --git a/kicker/extensions/kasbar/Doxyfile b/kicker/extensions/kasbar/Doxyfile new file mode 100644 index 000000000..8c82cae8b --- /dev/null +++ b/kicker/extensions/kasbar/Doxyfile @@ -0,0 +1,1101 @@ +# Doxyfile 1.3.2 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = classdocs + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, +# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en +# (Japanese with English messages), Korean, Norwegian, Polish, Portuguese, +# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = NO + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. It is allowed to use relative paths in the argument list. + +STRIP_FROM_PATH = + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explict @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# reimplements. + +INHERIT_DOCS = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = . ../../taskmanager + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl *.cs + +FILE_PATTERNS = *.h *.cpp + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = *moc* + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output dir. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimised for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assigments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superceded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# colloborations diagrams in a style similiar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes that +# lay further from the root node will be omitted. Note that setting this option to +# 1 or 2 may greatly reduce the computation time needed for large code bases. Also +# note that a graph may be further truncated if the graph's image dimensions are +# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). +# If 0 is used for the depth value (the default), the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO + +# The CGI_NAME tag should be the name of the CGI script that +# starts the search engine (doxysearch) with the correct parameters. +# A script with this name will be generated by doxygen. + +CGI_NAME = search.cgi + +# The CGI_URL tag should be the absolute URL to the directory where the +# cgi binaries are located. See the documentation of your http daemon for +# details. + +CGI_URL = + +# The DOC_URL tag should be the absolute URL to the directory where the +# documentation is located. If left blank the absolute path to the +# documentation, with file:// prepended to it, will be used. + +DOC_URL = + +# The DOC_ABSPATH tag should be the absolute path to the directory where the +# documentation is located. If left blank the directory on the local machine +# will be used. + +DOC_ABSPATH = + +# The BIN_ABSPATH tag must point to the directory where the doxysearch binary +# is installed. + +BIN_ABSPATH = /usr/local/bin/ + +# The EXT_DOC_PATHS tag can be used to specify one or more paths to +# documentation generated for other projects. This allows doxysearch to search +# the documentation for these projects as well. + +EXT_DOC_PATHS = diff --git a/kicker/extensions/kasbar/Makefile.am b/kicker/extensions/kasbar/Makefile.am new file mode 100644 index 000000000..f7e4ce14c --- /dev/null +++ b/kicker/extensions/kasbar/Makefile.am @@ -0,0 +1,55 @@ +INCLUDES = -I$(srcdir)/../../taskmanager $(all_includes) +METASOURCES = AUTO + +# +# Library implementing the core functionality +# +lib_LTLIBRARIES = libkasbar.la + +libkasbar_la_SOURCES = kasbar.cpp kasitem.cpp \ + kastaskitem.cpp kastasker.cpp kaspopup.cpp \ + kastaskpopup.cpp kasstartupitem.cpp \ + kasaboutdlg.cpp kasprefsdlg.cpp kasclockitem.cpp \ + kasgroupitem.cpp kasresources.cpp kasgrouper.cpp \ + kasloaditem.cpp + +libkasbar_la_LDFLAGS = $(all_libraries) -version-info 1:0:0 -no-undefined +libkasbar_la_LIBADD = $(LIB_KDEUI) ../../taskmanager/libtaskmanager.la + +# +# Panel Extension +# +kde_module_LTLIBRARIES = kasbar_panelextension.la + +kasbar_panelextension_la_SOURCES = kasbarextension.cpp +kasbar_panelextension_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) +kasbar_panelextension_la_LIBADD = libkasbar.la + +noinst_HEADERS = kasbar.h kasitem.h kasbarextension.h \ + kastaskitem.h kastasker.h kaspopup.h kasstartupitem.h \ + kasaboutdlg.h kasprefsdlg.h version.h kasclockitem.cpp \ + kasgroupitem.h kasresources.h kasgrouper.h kasloaditem.cpp + +lnkdir = $(kde_datadir)/kicker/extensions +lnk_DATA = kasbarextension.desktop + +EXTRA_DIST = $(lnk_DATA) + +bin_PROGRAMS = kasbar +kasbar_SOURCES = kasbarapp.cpp +kasbar_LDFLAGS = $(all_libraries) $(KDE_RPATH) +kasbar_LDADD = libkasbar.la \ + $(LIB_QT) $(LIB_KDECORE) $(LIB_KDEUI) + + +messages: + $(XGETTEXT) *.cpp *.h -o $(podir)/kasbarextension.pot + +srcdoc: + $(kde_bindir)/kdoc -a -p -d classdocs -n 'Kasbar2' ../../taskmanager/*.h *.h -lqt -lkdecore -lkdeui + +.PHONY: changes +changes: + cvs2cl.pl --window 3600 -w --hide-filenames -I '.desktop' + +KDE_OPTIONS = nofinal diff --git a/kicker/extensions/kasbar/TODO b/kicker/extensions/kasbar/TODO new file mode 100644 index 000000000..3b35b775f --- /dev/null +++ b/kicker/extensions/kasbar/TODO @@ -0,0 +1,29 @@ +- Don't show systray option if already has one +- Close detached bar when container dies + + +Bug Fixes +========= + +- Turn the rest of the 'magic numbers' into named constants + +- Ensure the boxes load from the screen edges outwards (not done + currently correctly right now) + +New Features +============ + +- Task listing profiles + +- Add double buffered updates + +- Allow more control over task grouping + +Mostly Done +=========== + +- Move the generic code from Kasbar and the default taskbar to + libtaskmanager + + + diff --git a/kicker/extensions/kasbar/configure.in.in b/kicker/extensions/kasbar/configure.in.in new file mode 100644 index 000000000..9d5ec223c --- /dev/null +++ b/kicker/extensions/kasbar/configure.in.in @@ -0,0 +1 @@ +AC_CHECK_HEADERS(sys/loadavg.h) diff --git a/kicker/extensions/kasbar/docs.h b/kicker/extensions/kasbar/docs.h new file mode 100644 index 000000000..6a9aa5849 --- /dev/null +++ b/kicker/extensions/kasbar/docs.h @@ -0,0 +1,69 @@ +/** + * @mainpage Kasbar 3NG + * + * @section intro Introduction + * + * This is the 3rd generation of kasbar. + * + * @section completed Completed Features + * + * <ul> + * <li>Added the ability to detach the bar from the screen edge and drag it around. + * <li>Added support for the 'demands attention' NET WM property. + * <li>Many internal code clean-ups. + * <li>Centralised the drawing code and graphical resource management. + * <li>Added a 'Send To System Tray' command to the window menu. + * <li>Added the ability to group windows on inactive desktops. + * <li>Improved the painting code. + * <li>Added an 'ungroup' action to the context menu for group items. + * <li>Added a 'Refresh' action to kasbar menu. + * <li>Added a 'Quit' action to kasbar menu when running as a standalone app. + * <li>Support for embedding the preview in the box instead of an icon. + * </ul> + * + * @section inprogress In Progress + * + * <ul> + * <li>Support for new size modes. + * </ul> + * + * @section todo Todo + * + * <ul> + * <li>Support for custom grouping. + * </ul> + */ + + + +class QObject +{ +}; + +class QWidget : public QObject +{ +}; + +class QDialog : public QWidget +{ +}; + +class QFrame : public QWidget +{ +}; + +class QHBox : public QFrame +{ +}; + +class QLCDNumber : public QFrame +{ +}; + +class KDialogBase : public QDialog +{ +}; + +class KPanelExtension : public QWidget +{ +}; diff --git a/kicker/extensions/kasbar/kasaboutdlg.cpp b/kicker/extensions/kasbar/kasaboutdlg.cpp new file mode 100644 index 000000000..73d20d94b --- /dev/null +++ b/kicker/extensions/kasbar/kasaboutdlg.cpp @@ -0,0 +1,264 @@ +/* kasaboutdlg.cpp +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ + +#include <qcheckbox.h> +#include <qgrid.h> +#include <qvbox.h> +#include <qlabel.h> +#include <qfile.h> +#include <qtextstream.h> + +#include <kdeversion.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <ktextbrowser.h> + +#ifdef USE_KSPY +#include <kspy.h> +#endif + +#include "kasbar.h" +#include "kasitem.h" +#include "kaspopup.h" + +#include "kasclockitem.h" +#include "kasloaditem.h" + +#include "kasaboutdlg.h" +#include "version.h" + +#define Icon(x) KGlobal::iconLoader()->loadIcon( x, KIcon::NoGroup, KIcon::SizeMedium ) +#define LargeIcon(x) KGlobal::iconLoader()->loadIcon( x, KIcon::NoGroup, KIcon::SizeLarge ) + +KasAboutDialog::KasAboutDialog( QWidget *parent ) + : KDialogBase( KDialogBase::IconList, i18n("About Kasbar"), + KDialogBase::Ok, + KDialogBase::Ok, + parent, "kasbarAboutDialog", false ) +{ +#ifdef USE_KSPY + KSpy::invoke(); +#endif + + addInfoPage(); + addAuthorsPage(); + addBSDPage(); + addGPLPage(); + + addDemoBar(); + + resize( 760, 450 ); +} + +KasAboutDialog::~KasAboutDialog() +{ + +} + +void KasAboutDialog::addDemoBar() +{ + QHBox *box = new QHBox( this ); + + box->setLineWidth(2); + box->setFrameStyle( QFrame::Panel | QFrame::Sunken ); + + box->setSpacing( spacingHint() ); + box->setMargin( marginHint() ); + + KasBar *bar = new KasBar( Horizontal, box ); + bar->setItemSize( KasBar::Large ); + bar->setMasked( false ); + + KasItem *ci = new KasItem( bar ); + ci->setIcon( LargeIcon( "icons" ) ); + bar->append( ci ); + + KasPopup *pop = new KasPopup( ci ); + ci->setPopup( pop ); + ci->setCustomPopup( true ); + connect( ci, SIGNAL(leftButtonClicked(QMouseEvent *)), ci, SLOT(togglePopup()) ); + + KasBar *groupbar = bar->createChildBar( ( bar->orientation() == Horizontal ) ? Vertical : Horizontal, pop ); + KasItem *i = 0; + + KasClockItem *clk = new KasClockItem( groupbar ); + groupbar->append( clk ); + + i = new KasLoadItem( groupbar ); + groupbar->append( i ); + + groupbar->addTestItems(); + + pop->resize( groupbar->size() ); + + bar->setFixedSize( bar->itemExtent(), bar->itemExtent() ); + addWidgetBelowList( box ); +} + +void KasAboutDialog::addInfoPage() +{ + QVBox *aboutPage = addVBoxPage( i18n("About"), i18n("About Kasbar"), Icon( "appearance" ) ); + aboutPage->setSpacing( spacingHint() ); + + new QLabel( i18n( "<qt><body>" + "<h2>Kasbar Version: %1</h2>" + "<b>KDE Version:</b> %2" + "</body></qt>" ) + .arg( VERSION_STRING ).arg( KDE_VERSION_STRING ), + aboutPage ); + + KTextBrowser *text5 = new KTextBrowser( aboutPage ); + text5->setText( i18n( "<html><body>" + "<p>Kasbar TNG began as a port of the original Kasbar applet to " + "the (then new) extension API, but ended up as a complete " + "rewrite because of the range of features needed by different " + "groups of users. In the process of the rewrite all the standard " + "features provided by the default taskbar were added, along with " + "some more original ones such as thumbnails." + "</p>" + "<p>" + "You can find information about the latest developments in Kasbar at " + "<a href=\"%3\">%4</a>, the Kasbar homepage." + "</p>" + "</body></html>" ) + .arg( HOMEPAGE_URL ).arg( HOMEPAGE_URL ) ); + + text5->setWordWrap( QTextEdit::WidgetWidth ); +} + +void KasAboutDialog::addAuthorsPage() +{ + QVBox *authorsPage = addVBoxPage( i18n("Authors"), + i18n("Kasbar Authors"), + Icon( "kuser" ) ); + + KTextBrowser *text = new KTextBrowser( authorsPage ); + text->setText( i18n( + "<html>" + + "<b>Richard Moore</b> <a href=\"mailto:rich@kde.org\">rich@kde.org</a><br>" + "<b>Homepage:</b> <a href=\"http://xmelegance.org/\">http://xmelegance.org/</a>" + + "<p>Developer and maintainer of the Kasbar TNG code.</p>" + + "<hr/>" + + "<b>Daniel M. Duley (Mosfet)</b> <a href=\"mailto:mosfet@kde.org\">mosfet@kde.org</a><br>" + "<b>Homepage:</b> <a href=\"http://www.mosfet.org/\">http://www.mosfet.org/</a>" + + "<p>Mosfet wrote the original Kasbar applet on which this " + "extension is based. There is little of the original code " + "remaining, but the basic look in opaque mode is almost " + "identical to this first implementation.</p>" + + "</html>" ) ); + + text->setWordWrap( QTextEdit::WidgetWidth ); +} + +void KasAboutDialog::addBSDPage() +{ + QVBox *bsdLicense = addVBoxPage( i18n("BSD License"), QString::null, Icon( "filefind" ) ); + + new QLabel( i18n( "Kasbar may be used under the terms of either the BSD license, " + "or the GNU Public License." ), bsdLicense ); + + KTextBrowser *text2 = new KTextBrowser( bsdLicense ); + text2->setText( "Some text of unsurpassed tediousness goes here." ); + text2->setWordWrap( QTextEdit::NoWrap ); + + QString bsdFile = locate("data", "LICENSES/BSD"); + if ( !bsdFile.isEmpty() ) { + QString result; + QFile file( bsdFile ); + + if ( file.open( IO_ReadOnly ) ) + { + QTextStream str(&file); + result += str.read(); + } + + text2->setText( result ); + } +} + +void KasAboutDialog::addGPLPage() +{ + QVBox *gplPage = addVBoxPage( i18n("GPL License"), QString::null, Icon( "filefind" ) ); + + new QLabel( i18n( "Kasbar may be used under the terms of either the BSD license, " + "or the GNU Public License." ), gplPage ); + + KTextBrowser *text3 = new KTextBrowser( gplPage ); + text3->setText( "Some more text of unsurpassed tediousness goes here." ); + text3->setWordWrap( QTextEdit::NoWrap ); + + QString gplFile = locate("data", "LICENSES/GPL_V2"); + if ( !gplFile.isEmpty() ) { + QString result; + QFile file( gplFile ); + + if ( file.open( IO_ReadOnly ) ) + { + QTextStream str(&file); + result += str.read(); + } + + text3->setText( result ); + } +} + +#include "kasaboutdlg.moc" diff --git a/kicker/extensions/kasbar/kasaboutdlg.h b/kicker/extensions/kasbar/kasaboutdlg.h new file mode 100644 index 000000000..c217ead79 --- /dev/null +++ b/kicker/extensions/kasbar/kasaboutdlg.h @@ -0,0 +1,86 @@ +/* kasaboutdlg.h +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +// -*- c++ -*- + +#ifndef KASABOUTDLG_H +#define KASABOUTDLG_H + +#include <kdialogbase.h> + +class KasBar; + +/** + * About dialog for KasBar + */ +class KasAboutDialog : public KDialogBase +{ + Q_OBJECT + +public: + KasAboutDialog( QWidget *parent=0 ); + ~KasAboutDialog(); + + void addAuthorsPage(); + void addAdvancedPage(); + void addInfoPage(); + void addBSDPage(); + void addGPLPage(); + void addDemoBar(); + +private: + KasBar *bar; +}; + +#endif // KASABOUTDLG_H + diff --git a/kicker/extensions/kasbar/kasbar.cpp b/kicker/extensions/kasbar/kasbar.cpp new file mode 100644 index 000000000..8210190c8 --- /dev/null +++ b/kicker/extensions/kasbar/kasbar.cpp @@ -0,0 +1,728 @@ +/* kasbar.cpp +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +#include <math.h> + +#include <qbitmap.h> +#include <qcursor.h> +#include <qpainter.h> +#include <qmemarray.h> +#include <qtimer.h> + +#include <kapplication.h> +#include <kdebug.h> +#include <krootpixmap.h> +#include <kpixmapio.h> +#include <kiconloader.h> + +#include "kasitem.h" + +#include "kasbar.h" +#include "kasbar.moc" + +static const int SMALL_EXTENT = 36; +static const int MEDIUM_EXTENT = 52; +static const int LARGE_EXTENT = 68; +static const int HUGE_EXTENT = 84; +static const int ENORMOUS_EXTENT = 148; + +KasBar::KasBar( Orientation o, QWidget *parent, const char *name, WFlags f ) + : QWidget( parent, name, f ), + master_(0), + orient( o ), + direction_( o == Horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom ), + itemUnderMouse_( 0 ), + boxesPerLine_(10), // Temp value + inDrag( false ), + detached( false ), + maxBoxes_( 100 ), // Temp value + itemSize_( Medium ), + itemExtent_( MEDIUM_EXTENT ), + paintInactiveFrame_( true ), + transparent_( false ), + rootPix( 0 ), + enableTint_( false ), + tintAmount_( 0.1 ), + tintColour_( colorGroup().mid() ), + useMask_( true ), + res(0) +{ + setBackgroundMode( NoBackground ); + items.setAutoDelete( true ); + setMouseTracking( true ); + setMaxBoxes( 0 ); + + connect( this, SIGNAL( configChanged() ), SLOT( repaint() ) ); +} + +KasBar::KasBar( Orientation o, KasBar *master, QWidget *parent, const char *name, WFlags f ) + : QWidget( parent, name, f ), + master_(master), + orient( o ), + direction_( o == Horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom ), + itemUnderMouse_( 0 ), + boxesPerLine_(10), // Temp value + inDrag( false ), + detached( false ), + maxBoxes_( 100 ), // Temp value + itemSize_( Medium ), + itemExtent_( MEDIUM_EXTENT ), + paintInactiveFrame_( true ), + transparent_( false ), + rootPix( 0 ), + enableTint_( false ), + tintAmount_( 0.1 ), + tintColour_( colorGroup().mid() ), + useMask_( true ), + res(0) +{ + setBackgroundMode( NoBackground ); + items.setAutoDelete( true ); + setMouseTracking( true ); + setMaxBoxes( 0 ); + connect( master_, SIGNAL( configChanged() ), SLOT( repaint() ) ); +} + +KasBar::~KasBar() +{ + delete res; +} + +KasResources *KasBar::resources() +{ + if ( res ) + return res; + + if ( isTopLevel() ) { + res = new KasResources( this ); + connect( res, SIGNAL( changed() ), SIGNAL( configChanged() ) ); + connect( this, SIGNAL( itemSizeChanged(int) ), res, SLOT( itemSizeChanged() ) ); + return res; + } + + return master_->resources(); +} + +KasBar *KasBar::createChildBar( Orientation o, QWidget *parent, const char *name ) +{ + KasBar *child = new KasBar( o, this, parent, name ); + child->rereadMaster(); + return child; +} + +void KasBar::setItemSize( int size ) +{ + switch( size ) { + case Small: + setItemExtent( SMALL_EXTENT ); + break; + case Medium: + setItemExtent( MEDIUM_EXTENT ); + break; + case Large: + setItemExtent( LARGE_EXTENT ); + break; + case Huge: + setItemExtent( HUGE_EXTENT ); + break; + case Enormous: + setItemExtent( ENORMOUS_EXTENT ); + break; + default: + break; + } +} + +void KasBar::setItemExtent( int size ) +{ + if ( size == itemExtent_ ) + return; + + itemExtent_ = size; + + if ( size < MEDIUM_EXTENT ) + itemSize_ = Small; + else if ( size < LARGE_EXTENT ) + itemSize_ = Medium; + else if ( size < HUGE_EXTENT ) + itemSize_ = Large; + else if ( size < ENORMOUS_EXTENT ) + itemSize_ = Huge; + else + itemSize_ = Enormous; + + emit itemSizeChanged( itemSize_ ); + emit configChanged(); + + updateLayout(); +} + +void KasBar::setTransparent( bool enable ) +{ + if ( transparent_ == enable ) + return; + + transparent_ = enable; + + if ( transparent_ ) { + kdDebug(1345) << "KasBar: Enabling transparency" << endl; + + rootPix = new KRootPixmap( this ); + connect( rootPix, SIGNAL( backgroundUpdated(const QPixmap &) ), + this, SLOT( setBackground(const QPixmap &) ) ); + + rootPix->setCustomPainting( true ); + + if ( enableTint_ ) + rootPix->setFadeEffect( tintAmount_, tintColour_ ); + + rootPix->start(); + } + else { + kdDebug(1345) << "KasBar: Disabling transparency" << endl; + + rootPix->stop(); + delete rootPix; + rootPix = 0; + } + + emit configChanged(); +} + +void KasBar::setTint( bool enable ) +{ + if ( enableTint_ == enable ) + return; + + enableTint_ = enable; + + if ( transparent_ && rootPix ) { + if ( enableTint_ ) { + rootPix->setFadeEffect( tintAmount_, tintColour_ ); + } + else { + rootPix->setFadeEffect( 0.0, tintColour_ ); + } + + emit configChanged(); + repaint( true ); + } +} + +void KasBar::setTint( double amount, QColor color ) +{ + tintAmount_ = amount; + tintColour_ = color; + + if ( transparent_ && enableTint_ ) { + rootPix->setFadeEffect( tintAmount_, tintColour_ ); + emit configChanged(); + + if ( rootPix->isAvailable() ) + rootPix->repaint( true ); + } +} + +void KasBar::setTintColor( const QColor &c ) +{ + setTint( tintAmount_, c ); +} + +void KasBar::setTintAmount( int percent ) +{ + double amt = (double) percent / 100.0; + setTint( amt, tintColour_ ); +} + +void KasBar::setMaxBoxes( int count ) +{ + if ( count == maxBoxes_ ) + return; + + if ( count == 0 ) + count = 15; // XXX Hacked + + maxBoxes_ = count; + emit configChanged(); + setBoxesPerLine( count ); +} + +void KasBar::setBoxesPerLine( int count ) +{ + boxesPerLine_ = QMIN( count, maxBoxes_ ); + updateLayout(); +} + +void KasBar::setDetachedPosition( const QPoint &pos ) +{ + if ( detachedPos == pos ) + return; + + detachedPos = pos; + emit detachedPositionChanged( pos ); +} + +void KasBar::setDirection( Direction dir ) +{ + if ( direction_ == dir ) + return; + + if ( ( dir == QBoxLayout::LeftToRight ) || ( dir == QBoxLayout::RightToLeft ) ) + orient = Horizontal; + else + orient = Vertical; + + direction_ = dir; + emit directionChanged(); + updateLayout(); +} + +void KasBar::setOrientation( Orientation o ) +{ + if ( orient == o ) + return; + + if ( o == Horizontal ) + setDirection( QBoxLayout::LeftToRight ); + else + setDirection( QBoxLayout::TopToBottom ); +} + +void KasBar::toggleOrientation() +{ + switch( direction_ ) { + case QBoxLayout::LeftToRight: + setDirection( QBoxLayout::RightToLeft ); + break; + case QBoxLayout::RightToLeft: + setDirection( QBoxLayout::TopToBottom ); + break; + case QBoxLayout::TopToBottom: + setDirection( QBoxLayout::BottomToTop ); + break; + case QBoxLayout::BottomToTop: + setDirection( QBoxLayout::LeftToRight ); + break; + default: + kdWarning() << "toggleOrientation got an odd direction: " << (uint) direction_ << endl; + setDirection( QBoxLayout::LeftToRight ); + break; + } +} + +void KasBar::toggleDetached() +{ + setDetached( !detached ); +} + +void KasBar::setDetached( bool detach ) +{ + if ( detached == detach ) + return; + + detached = detach; + updateLayout(); + emit detachedChanged( detached ); +} + +QSize KasBar::sizeHint( Orientation o, QSize sz ) +{ + if ( o == Horizontal ) + setBoxesPerLine( sz.width() / itemExtent() ); + else + setBoxesPerLine( sz.height() / itemExtent() ); + + unsigned int r=0, c=0; + if( items.count() > (unsigned int) boxesPerLine_ ) { + r = items.count()/boxesPerLine_; + c = boxesPerLine_; + } + else { + r = 1; + c = items.count(); + } + + if( r*c < items.count() ) // remainders + ++r; + + QSize s; + if( o == Horizontal ) { + s.setWidth( c*itemExtent() ); + s.setHeight( r*itemExtent() ); + } + else { + s.setWidth( r*itemExtent() ); + s.setHeight( c*itemExtent() ); + } + + return s; +} + +void KasBar::updateLayout() +{ +// kdDebug(1345) << "KasBar: updateLayout(), count is " << items.count() << endl; + if ( !isUpdatesEnabled() ) + return; + bool updates = isUpdatesEnabled(); + setUpdatesEnabled( false ); + +// This is for testing a rectangular layout +// boxesPerLine_ = (uint) ceil(sqrt( items.count() )); + + // Work out the number of rows and columns + unsigned int r=0, c=0; + if( items.count() > (unsigned int) boxesPerLine_ ) { + r = items.count()/boxesPerLine_; + c = boxesPerLine_; + } + else{ + r = 1; + c = items.count(); + } + + if( r*c < items.count() ) // remainders + ++r; + + QSize sz; + if ( orient == Horizontal ) + sz = QSize( c * itemExtent(), r * itemExtent() ); + else + sz = QSize( r * itemExtent(), c * itemExtent() ); + + if ( sz != size() ) { + resize( sz ); + } + + setUpdatesEnabled( updates ); + + QWidget *top = topLevelWidget(); + QRegion mask; + + KasItem *i; + if ( orient == Horizontal ) { + for ( i = items.first(); i; i = items.next() ) { + int x = (items.at() % c) * itemExtent(); + + if ( direction_ == QBoxLayout::RightToLeft ) + x = width() - x - itemExtent(); + + i->setPos( x, (items.at() / c) * itemExtent() ); + i->update(); + mask = mask.unite( QRegion( QRect( i->pos(), QSize(itemExtent(),itemExtent()) ) ) ); + } + } + else { + for ( i = items.first(); i; i = items.next() ) { + int y = (items.at() / r) * itemExtent(); + + if ( direction_ == QBoxLayout::BottomToTop ) + y = height() - y - itemExtent(); + + i->setPos( (items.at() % r) * itemExtent(), y ); + i->update(); + mask = mask.unite( QRegion( QRect( i->pos(), QSize(itemExtent(),itemExtent()) ) ) ); + } + } + + if ( useMask_ ) + top->setMask( mask ); + else + top->clearMask(); + update(); +} + +void KasBar::rereadMaster() +{ + if ( !master_ ) + return; + + setItemSize( master_->itemSize() ); + setTint( master_->hasTint() ); + setTintColor( master_->tintColor() ); + setTintAmount( master_->tintAmount() ); +} + +void KasBar::append( KasItem *i ) +{ + if ( !i ) + return; + + items.append( i ); + updateLayout(); +} + +void KasBar::insert( int index, KasItem *i ) +{ + if ( (!i) || (index < 0) ) + return; + + items.insert( index, i ); + updateLayout(); +} + +void KasBar::remove( KasItem *i ) +{ + items.remove( i ); + + if ( i == itemUnderMouse_ ) + itemUnderMouse_ = 0; + updateLayout(); +} + +void KasBar::clear() +{ + items.clear(); + itemUnderMouse_ = 0; + updateLayout(); +} + +void KasBar::mousePressEvent(QMouseEvent *ev) +{ + KasItem *i = itemAt( ev->pos() ); + if ( i ) + i->mousePressEvent( ev ); + + pressPos = ev->globalPos(); +} + +void KasBar::mouseReleaseEvent(QMouseEvent *ev) +{ + if ( !inDrag ) { + KasItem *i = itemAt( ev->pos() ); + if ( i ) + i->mouseReleaseEvent( ev ); + } + else if ( detached ) { + setDetachedPosition( pos() ); + emit configChanged(); + } + + pressPos = QPoint(); + inDrag = false; +} + +void KasBar::updateMouseOver() +{ + updateMouseOver( mapFromGlobal( QCursor::pos() ) ); +} + +void KasBar::updateMouseOver( QPoint pos ) +{ + KasItem *i = itemAt(pos); + + if ( i == itemUnderMouse_ ) + return; + + if ( itemUnderMouse_ ) + itemUnderMouse_->mouseLeave(); + if ( i ) + i->mouseEnter(); + if ( i && itemUnderMouse_ ) + itemUnderMouse_->hidePopup(); + + itemUnderMouse_ = i; +} + +void KasBar::mouseMoveEvent(QMouseEvent *ev) +{ + if ( detached && (!pressPos.isNull()) ) { + QPoint moved = ev->globalPos() - pressPos; + + if ( !inDrag ) { + if ( moved.manhattanLength() > 6 ) { + inDrag = true; + emit dragStarted(); + } + } + + if ( inDrag ) { + if ( itemUnderMouse_ ) + itemUnderMouse_->hidePopup(); + + move( pos() + moved ); + pressPos = ev->globalPos(); + } + } + else { + updateMouseOver( ev->pos() ); + } +} + +void KasBar::dragMoveEvent ( QDragMoveEvent *ev ) +{ + KasItem *i = itemAt( ev->pos() ); + if ( itemUnderMouse_ != i ) { + if ( itemUnderMouse_ ) + itemUnderMouse_->dragLeave(); + if ( i ) + i->dragEnter(); + itemUnderMouse_ = i; + } +} + +void KasBar::paintEvent(QPaintEvent *ev) +{ + QPainter q( this ); + q.drawPixmap( ev->rect().topLeft(), offscreen, ev->rect() ); +} + +void KasBar::resizeEvent(QResizeEvent *ev) +{ + offscreen.resize( ev->size() ); + QPainter p( &offscreen ); + paintBackground( &p, QRect(QPoint(0,0),size()) ); + QWidget::resizeEvent(ev); + emit layoutChanged(); +} + + +QPoint KasBar::itemPos( KasItem *i ) +{ + return i->pos(); +} + +void KasBar::updateItem( KasItem *i ) +{ + if ( !i ) + return; + if ( !isShown() ) + return; + + QPainter p( &offscreen ); + QPoint pos = i->pos(); + + paintBackground( &p, QRect( pos, QSize( itemExtent(), itemExtent() ) ) ); + i->paint( &p, pos.x(), pos.y() ); + update( QRect( pos, QSize( itemExtent(), itemExtent() ) ) ); +} + +void KasBar::repaintItem(KasItem *i, bool erase ) +{ + if ( !i ) + return; + if ( !isShown() ) + return; + + QPainter p( &offscreen ); + QPoint pos = i->pos(); + + paintBackground( &p, QRect( pos, QSize( itemExtent(), itemExtent() ) ) ); + i->paint( &p, pos.x(), pos.y() ); + repaint( QRect( pos, QSize( itemExtent(), itemExtent() ) ), transparent_ || erase ); +} + +KasItem* KasBar::itemAt(const QPoint &p) +{ + KasItem *i; + QRect cr; + + for (i = items.first(); i; i = items.next()) { + cr.setTopLeft( i->pos() ); + cr.setSize( QSize( itemExtent(), itemExtent() ) ); + + if(cr.contains(p)) + return i; + } + + return 0; +} + +void KasBar::setBackground( const QPixmap &newBg ) +{ + bg = newBg; + + QPainter p( &offscreen ); + paintBackground( &p, QRect(QPoint(0,0),size()) ); + + updateLayout(); +} + +void KasBar::setMasked( bool mask ) +{ + if ( useMask_ == mask ) + return; + + useMask_ = mask; +} + +void KasBar::setPaintInactiveFrames( bool enable ) +{ + paintInactiveFrame_ = enable; + update(); +} + +void KasBar::paintBackground( QPainter *p, const QRect &r ) +{ + // If we're transparent + if ( transparent_ ) { + if ( !bg.isNull() ) { + p->drawPixmap( r.topLeft(), bg, r ); + return; + } + } +} + +void KasBar::addTestItems() +{ + KasItem *i = new KasItem( this ); + insert( 0, i ); + i->setText( "Animated" ); + i->setIcon( KGlobal::iconLoader()->loadIcon( "icons", KIcon::NoGroup, KIcon::SizeMedium ) ); + i->setAnimation( resources()->startupAnimation() ); + QTimer *aniTimer = new QTimer( i ); + connect( aniTimer, SIGNAL( timeout() ), i, SLOT( advanceAnimation() ) ); + aniTimer->start( 100 ); + i->setShowAnimation( true ); + + updateLayout(); +} diff --git a/kicker/extensions/kasbar/kasbar.h b/kicker/extensions/kasbar/kasbar.h new file mode 100644 index 000000000..297291d4f --- /dev/null +++ b/kicker/extensions/kasbar/kasbar.h @@ -0,0 +1,318 @@ +// -*- c++ -*- + +/* kasbar.h +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +// -*- c++ -*- + + +#ifndef __KASBAR_H +#define __KASBAR_H + +#include <qwidget.h> +#include <qpoint.h> +#include <qptrlist.h> +#include <qlayout.h> + +#include "kasresources.h" + +class KRootPixmap; + +class KasItem; +class KasResources; + +typedef QPtrList<KasItem> KasItemList; + + +/** + * The main view for KasBar. + */ +class KDE_EXPORT KasBar : public QWidget +{ + Q_OBJECT + Q_PROPERTY( int maxBoxes READ maxBoxes ) + Q_PROPERTY( uint boxesPerLine READ boxesPerLine ) + Q_PROPERTY( Direction direction READ direction ) + Q_PROPERTY( Orientation orientation READ orientation ) + Q_PROPERTY( bool masked READ isMasked ) + Q_ENUMS( Direction ) + + friend class KasItem; +public: + KasBar( Orientation o, QWidget *parent=0, const char *name=0, WFlags f=0 ); + KasBar( Orientation o, KasBar *master, + QWidget* parent=0, const char* name=0, WFlags f=0 ); + + virtual ~KasBar(); + + typedef QBoxLayout::Direction Direction; + + /** Returns true iff this is a top-level bar. This is unrelated to it being a top-level widget. */ + bool isTopLevel() const { return !master_; } + + /** Returns the bar from which this bar inherits its settings (or 0 if this is the top-level bar). */ + KasBar *master() const { return master_; } + + /** Creates a child bar of the kasbar. The child will inherit the appearance options. */ + virtual KasBar *createChildBar( Orientation o, QWidget *parent, const char *name=0 ); + + /** Factory method that returns the singleton resources object. */ + virtual KasResources *resources(); + + /** Returns true iff we have a resources object. */ + bool hasResources() const { return (res ? true : false); } + + // + // Item management + // + void append( KasItem *i ); + void insert( int index, KasItem *i ); + void remove( KasItem *i ); + void clear(); + KasItem *take( KasItem *i ) { return items.take( indexOf(i) ); } + KasItem *itemAt( uint i ) { return items.at( i ); } + int indexOf( KasItem *i ) { return items.find( i ); } + + KasItemList *itemList() { return &items; } + + // + // Layout options. + // + + /** The possible item sizes. */ + enum ItemSize { Enormous, Huge, Large, Medium, Small, Custom }; + + int itemSize() const { return itemSize_; } + int itemExtent() const { return itemExtent_; } + + /** The number of items in the bar. */ + unsigned int itemCount() const { return items.count(); } + + int maxBoxes() const { return maxBoxes_; } + uint boxesPerLine() const { return boxesPerLine_; } + + void setOrientation( Orientation o ); + Orientation orientation() const { return orient; } + + void setDirection( Direction dir ); + Direction direction() const { return direction_; } + + bool isDetached() const { return detached; } + QPoint detachedPosition() const { return detachedPos; } + + bool isDrag() const { return inDrag; } + + QSize sizeHint( Orientation, QSize max ); + + // + // Look and feel options + // + + bool isMasked() const { return useMask_; } + + /** Is transparency enabled? */ + bool isTransparent() const { return transparent_; } + + /** Is tinting enabled? */ + bool hasTint() const { return enableTint_; } + + /** Sets the amount and color of the tint. */ + void setTint( double amount, QColor color ); + + /** Sets the amount of tinting. */ + void setTintAmount( double amount ) { setTint( amount, tintColour_ ); } + + /** Get the amount of tinting. */ + double tintAmount() const { return tintAmount_; } + + /** Get the color of the tint. */ + QColor tintColor() const { return tintColour_; } + + /** Returns true iff we will paint frames around inactive items. */ + bool paintInactiveFrames() const { return paintInactiveFrame_; } + + // + // Utilities + // + + void updateItem( KasItem *i ); + + /** Redraws the specified item. */ + void repaintItem(KasItem *i, bool erase = true ); + + /** Returns the item at p or 0. */ + KasItem* itemAt(const QPoint &p); + + /** Get the position of the specified item. */ + QPoint itemPos( KasItem *i ); + + /** The item under the mouse pointer (or 0). */ + KasItem *itemUnderMouse() const { return itemUnderMouse_; } + +public slots: + // + // Layout slots + // + void setMaxBoxes( int count ); + void setBoxesPerLine( int count ); + + void setItemSize( int size ); + void setItemExtent( int size ); + void setDetachedPosition( const QPoint &pos ); + + virtual void updateLayout(); + + void updateMouseOver(); + void updateMouseOver( QPoint pos ); + + /** Enable or disable tinting. */ + void setTint( bool enable ); + + /** Enable or disable transparency. */ + void setTransparent( bool enable ); + + /** Set the color of the tint. */ + void setTintColor( const QColor &c ); + + /** Set the strength of the tint (as a percentage). */ + void setTintAmount( int percent ); + + void setBackground( const QPixmap &pix ); + + void setMasked( bool mask ); + + void setPaintInactiveFrames( bool enable ); + + void toggleOrientation(); + void toggleDetached(); + void setDetached( bool detach ); + + /** Rereads the configuration of the master Kasbar. */ + virtual void rereadMaster(); + + virtual void addTestItems(); + +signals: + + void detachedChanged( bool ); + void detachedPositionChanged( const QPoint & ); + void dragStarted(); + + void directionChanged(); + + /** Emitted when kasbar wants to resize. This happens when a new window is added. */ + void layoutChanged(); + + /** Emitted when the item size is changed. */ + void itemSizeChanged( int ); + + void configChanged(); + +protected: + KRootPixmap *rootPixmap() const { return rootPix; } + + /** Displays the popup menus, hides/shows windows. */ + void mousePressEvent(QMouseEvent *ev); + + /** Displays the popup menus, hides/shows windows. */ + void mouseReleaseEvent(QMouseEvent *ev); + + /** Overridden to implement the mouse-over highlight effect. */ + void mouseMoveEvent(QMouseEvent *ev); + + /** Overridden to implement the drag-over task switching. */ + void dragMoveEvent(QDragMoveEvent *ev); + + /** Paints the background of the item to the painter. */ + void paintBackground( QPainter *p, const QRect &r ); + + /** Calls the paint methods for the items in the rectangle specified by the event. */ + void paintEvent(QPaintEvent *ev); + + /** Forces the widget to re-layout it's contents. */ + void resizeEvent(QResizeEvent *ev); + +private: + // Core data + QPixmap offscreen; + KasBar *master_; + KasItemList items; + Orientation orient; + Direction direction_; + KasItem *itemUnderMouse_; + uint boxesPerLine_; + QPoint pressPos; + bool inDrag; + bool detached; + int maxBoxes_; + int itemSize_; + int itemExtent_; + QPoint detachedPos; + bool paintInactiveFrame_; + + // Implements pseudo-transparency + bool transparent_; + KPixmap bg; + KRootPixmap *rootPix; + bool enableTint_; + double tintAmount_; + QColor tintColour_; + bool useMask_; + + // Look and feel resources + KasResources *res; +}; + + + +#endif diff --git a/kicker/extensions/kasbar/kasbarapp.cpp b/kicker/extensions/kasbar/kasbarapp.cpp new file mode 100644 index 000000000..6c006af16 --- /dev/null +++ b/kicker/extensions/kasbar/kasbarapp.cpp @@ -0,0 +1,125 @@ +/* test_kasbar.cpp +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +#include <kapplication.h> +#include <kcmdlineargs.h> +#include <kconfig.h> +#include <kdebug.h> +#include <dcopclient.h> +#include <kwin.h> +#include <kglobal.h> +#include <klocale.h> + +#include "kasitem.h" +#include "kastasker.h" +#include "kasclockitem.h" +#include "kasloaditem.h" + +#include "version.h" + +static KCmdLineOptions options[] = +{ + { "test", "Test the basic kasbar code", 0 }, + KCmdLineLastOption +}; + +int main( int argc, char **argv ) +{ + KCmdLineArgs::init( argc, argv, "kasbar", "KasBar", I18N_NOOP( "An alternative task manager" ), VERSION_STRING ); + KCmdLineArgs::addCmdLineOptions( options ); + KGlobal::locale()->setMainCatalogue( "kasbarextension" ); + KApplication app; + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + kdDebug(1345) << "Kasbar starting..." << endl; + + int wflags = Qt::WStyle_Customize | Qt::WX11BypassWM | Qt::WStyle_DialogBorder | Qt::WStyle_StaysOnTop; + KasBar *kasbar; + KConfig conf( "kasbarrc" ); + + if ( args->isSet("test") ) { + kasbar = new KasBar( Qt::Vertical, 0, "testkas", wflags ); + kasbar->setItemSize( KasBar::Large ); + kasbar->append( new KasClockItem(kasbar) ); + kasbar->append( new KasItem(kasbar) ); + kasbar->append( new KasLoadItem(kasbar) ); + kasbar->append( new KasItem(kasbar) ); + kasbar->addTestItems(); + } + else { + KasTasker *kastasker = new KasTasker( Qt::Vertical, 0, "testkas", wflags ); + kastasker->setConfig( &conf ); + kastasker->setStandAlone( true ); + kasbar = kastasker; + + kastasker->readConfig(); + kastasker->move( kastasker->detachedPosition() ); + kastasker->connect( kastasker->resources(), SIGNAL(changed()), SLOT(readConfig()) ); + kastasker->refreshAll(); + } + + kdDebug(1345) << "Kasbar about to show" << endl; + app.setMainWidget( kasbar ); + kasbar->show(); + + kasbar->setDetached( true ); + KWin::setOnAllDesktops( kasbar->winId(), true ); + kdDebug() << "kasbar: Window id is " << kasbar->winId() << endl; + + KApplication::kApplication()->dcopClient()->registerAs( "kasbar" ); + + app.connect( &app, SIGNAL( lastWindowClosed() ), SLOT(quit()) ); + + return app.exec(); +} + diff --git a/kicker/extensions/kasbar/kasbarextension.cpp b/kicker/extensions/kasbar/kasbarextension.cpp new file mode 100644 index 000000000..9b1e2435e --- /dev/null +++ b/kicker/extensions/kasbar/kasbarextension.cpp @@ -0,0 +1,189 @@ +/* kasbarextension.cpp +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +#include <qlayout.h> + +#include <dcopclient.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kconfig.h> + +#include <kmessagebox.h> + +#include "kastasker.h" +#include "kasprefsdlg.h" +#include "kasaboutdlg.h" + +#include "version.h" + +#include "kasbarextension.h" +#include "kasbarextension.moc" + +extern "C" +{ + KDE_EXPORT KPanelExtension *init( QWidget *parent, const QString& configFile ) + { + KGlobal::locale()->insertCatalogue("kasbarextension"); + return new KasBarExtension( configFile, + KPanelExtension::Normal, + KPanelExtension::About | KPanelExtension::Preferences, + parent, "kasbarextension"); + } +} + +KasBarExtension::KasBarExtension( const QString& configFile, + Type type, + int actions, + QWidget *parent, const char *name ) + : KPanelExtension( configFile, type, actions, parent, name ), + detached_( false ) +{ + kdDebug(1345) << "KasBarExtension: Created '" << name << "', '" << configFile << "'" << endl; +// KApplication::kApplication()->dcopClient()->registerAs( "kasbar" ); + +// setBackgroundMode( NoBackground ); + kasbar = new KasTasker( orientation(), this, name ); + + connect( kasbar, SIGNAL( layoutChanged() ), this, SIGNAL( updateLayout() ) ); + connect( kasbar, SIGNAL( detachedChanged(bool) ), this, SLOT( setDetached(bool) ) ); + + kasbar->setConfig( config() ); + kasbar->readConfig(); + kasbar->refreshAll(); +} + +KasBarExtension::~KasBarExtension() +{ + if ( detached_ && (!kasbar.isNull()) ) + kasbar->deleteLater(); + KGlobal::locale()->removeCatalogue("kasbarextension"); +} + +void KasBarExtension::setDetached( bool detach ) +{ + if ( detach == detached_ ) + return; + + detached_ = detach; + + if ( detach ) { + + int wflags = Qt::WStyle_Customize | Qt::WX11BypassWM | Qt::WStyle_DialogBorder | Qt::WStyle_StaysOnTop; + kasbar->reparent( 0, wflags, kasbar->detachedPosition(), true ); + updateGeometry(); + resize( detachedSize() ); + } + else { + kasbar->reparent( this, QPoint(0,0), true ); + kasbar->setOrientation( orientation() ); + + updateGeometry(); + resize( kasbar->size() ); + } + + emit updateLayout(); +} + +void KasBarExtension::showEvent( QShowEvent */*se*/ ) +{ + updateGeometry(); + resize( kasbar->size() ); + repaint( true ); +} + +QSize KasBarExtension::detachedSize() +{ + if ( orientation() == Vertical ) + return QSize( kasbar->itemExtent()/2, 0 ); + else + return QSize( 0, kasbar->itemExtent()/2 ); + +} + +QSize KasBarExtension::sizeHint(Position p, QSize maxSize ) const +{ + Orientation o = Horizontal; + + if ( p == Left || p == Right ) + o = Vertical; + + if ( detached_ ) { + if ( o == Vertical ) + return QSize( kasbar->itemExtent()/2, 0 ); + else + return QSize( 0, kasbar->itemExtent()/2 ); + } + + return kasbar->sizeHint( o, maxSize ); +} + +void KasBarExtension::positionChange( Position /* position */) +{ + kasbar->setOrientation( orientation() ); + kasbar->updateLayout(); + kasbar->refreshIconGeometry(); +} + +void KasBarExtension::about() +{ + kasbar->showAbout(); +} + +void KasBarExtension::preferences() +{ + kasbar->showPreferences(); +} + diff --git a/kicker/extensions/kasbar/kasbarextension.desktop b/kicker/extensions/kasbar/kasbarextension.desktop new file mode 100644 index 000000000..59497c00b --- /dev/null +++ b/kicker/extensions/kasbar/kasbarextension.desktop @@ -0,0 +1,109 @@ +[Desktop Entry] +Name=KasBar +Name[af]=Kasbar +Name[bg]=Алтернативен панел +Name[cs]=Kasbar +Name[csb]=Lëstew dzejaniów (Kasbar) +Name[de]=Kasbar +Name[eo]=Kasbaro +Name[fy]=Kasbar +Name[he]=שורת משימות חלופית +Name[hi]=कास-बार +Name[is]=Kasbar +Name[it]=Kasbar +Name[lo]=ຄາສບາຣ - K +Name[lv]=KasJosla +Name[mn]=Kasbar +Name[nb]=Kasbar +Name[ne]=कासबार +Name[nl]=Kasbar +Name[nso]=Bar ya Kas +Name[pa]=ਕਸ-ਬਾਰ +Name[pl]=Pasek zadań (Kasbar) +Name[sv]=Kasbar +Name[te]=కాస్ బార్ +Name[tg]=Навори Kas +Name[th]=คาสบาร์ +Name[zu]=I-KasBar + +Comment=An alternative taskbar panel applet. +Comment[af]='n Alternatiewe taakbalk paneel miniprogram. +Comment[az]=Alternatif bir vəzifə çubuğu programcığı. +Comment[be]=Альтэрнатыўная панэль заданняў. +Comment[bg]=Алтернативен аплет за лентата със задачите +Comment[bn]=টাস্কবার প্যানেল অ্যাপলেট-এর একটি বিকল্প +Comment[br]=Arloadig barrenn poelladoù dazeilat evit ar bannell. +Comment[bs]=Panelski applet - alternativni taskbar +Comment[ca]=Un applet per al plafó alternatiu a la barra de tasques. +Comment[cs]=Applet s alternativním pruhem úloh +Comment[csb]=Alternatiwnô lëstew dzejaniów dlô panelu. +Comment[cy]=Rhaglennig bar tasgau arall i'r panel +Comment[da]=Et alternativt opgavelinjepanelprogram. +Comment[de]=Eine alternative Fensterleiste +Comment[el]=Μία εναλλακτική μικροεφαρμογή γραμμής εργασιών για τον πίνακα. +Comment[eo]=Alternativa taskostria panelaplikaĵeto +Comment[es]=Barra de tareas alternativa (miniaplicación del panel). +Comment[et]=Teistsugune paneelil töötav tegumiriba aplett +Comment[eu]=Ataza-barra alternatiboa (paneleko appleta) +Comment[fa]=یک برنامک تابلوی میله تکلیف متفاوت. +Comment[fi]=Vaihtoehtoinen ohjelmalistasovelma. +Comment[fr]=Une autre applet de barre des tâches +Comment[fy]=In alternative taakbalke panielapplet. +Comment[gl]=Unha applet de barra de tarefas alternativa para o painel +Comment[he]=יישומון שורת משימות חלופי עבור הלוח +Comment[hi]=एक वैकल्पिक कार्यपट्टी फलक ऐपलेट +Comment[hr]=Alternativni aplet trake zadataka +Comment[hu]=Egy feladatlista-alternatíva panel-kisalkalmazásként. +Comment[id]=Aplet panel taskbar alternatif +Comment[is]=Annað verkspjald en það sjálfgefna. +Comment[it]=Applet alternativa per la barra delle applicazioni +Comment[ja]=代替のタスクバーパネルアプレット +Comment[ka]=ალტერნატიული ამოცანათა პანელის აპლეტი +Comment[kk]=Қосымша тапсырмалар панель апплеті. +Comment[km]=អាប់ភ្លេតបន្ទះរបារភារកិច្ចជំនួស ។ +Comment[lo]=ແອລແພັດຖາດຫນ້າຕ່າງງານແບບອື່ນ +Comment[lt]=Alternatyvi užduočių pulto priemonė. +Comment[lv]=Alternatīvs uzdevumjoslas paneļa aplets. +Comment[mk]=Аплет од панелот - алтернативна лента со програми. +Comment[mn]=Хоёрдогч цонхны самбар +Comment[ms]=Aplet panel 'taskbar' alternatif. +Comment[mt]=Applet alternattiva għall-panel tat-taskbar +Comment[nb]=En alternativ oppgavelinje som panelprogram. +Comment[nds]=En anner Lüttprogramm för den Paneel-Programmbalken +Comment[ne]=वैकल्पिक कार्यपट्टी प्यानल एप्लेट +Comment[nl]=Een alternatieve taakbalk paneelapplet. +Comment[nn]=Ei alternativ oppgåvelinje til panelet. +Comment[nso]=Applet yenngwe ya panel ya bar ya mosongwana. +Comment[oc]=Un aplet dèu plafon alternatiu de la barra de tasques. +Comment[pa]=ਇੱਕ ਬਦਲਵੀਂ ਕੰਮ-ਪੱਟੀ ਐਪਲਿਟ +Comment[pl]=Alternatywny pasek zadań dla panelu. +Comment[pt]=Uma barra de tarefas alternativa. +Comment[pt_BR]=Um mini-aplicativo de painel alternativo para a barra de tarefas. +Comment[ro]=O alternativă la miniaplicația bară de procese. +Comment[ru]=Аплет альтернативной панели задач. +Comment[rw]=Apuleti y'umwanya w'umurongoibikorwa usimbura +Comment[se]=Eavttolaš bargoholga panelii +Comment[sk]=Alternatívny panel úloh +Comment[sl]=Vstavek za alternativno opravilno vrstico na pultu +Comment[sr]=Алтернативни аплет траке задатака за панел. +Comment[sr@Latn]=Alternativni aplet trake zadataka za panel. +Comment[sv]=Alternativt miniprogram till aktivitetsfältet +Comment[ta]=மாற்றுவழி பணிபட்டி பலக சிறுநிரல் +Comment[tg]=Барномаи сафҳаи масъалаҳои алтернативӣ +Comment[th]=แอพเพล็ตถาดหน้าต่างงานแบบอื่น +Comment[tr]=Alternatif bir görev çubuğu programcığı. +Comment[tt]=Almaş yöktirä taqtasınıñ applete. +Comment[uk]=Альтернативний аплет смужки задач. +Comment[ven]=Apulete phanele ine nanga shumisa yone ya bara ya mushumo. +Comment[vi]=Một tiểu ứng dụng khác cũng có bảng điểu khiển chứa thanh tác vụ. +Comment[wa]=Ene ôte aplikete di bår des bouyes do scriftôr +Comment[xh]=I applet yeqela lenjongo ethile yebar yomsebenzi olandelelanayo. +Comment[zh_CN]=备选的任务栏面板小程序。 +Comment[zh_TW]=可供選擇的另外一個工作列面板小程式。 +Comment[zu]=Enye i-applet yewindi lemininingwane yebha yemisebenzi + +Icon=kasbar + +X-KDE-Library=kasbar_panelextension +X-KDE-UniqueApplet=true +X-KDE-PanelExt-Positions=Right,Left,Top,Bottom diff --git a/kicker/extensions/kasbar/kasbarextension.h b/kicker/extensions/kasbar/kasbarextension.h new file mode 100644 index 000000000..e85750d40 --- /dev/null +++ b/kicker/extensions/kasbar/kasbarextension.h @@ -0,0 +1,101 @@ +/* kasbarextension.h +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +// -*- c++ -*- + +#ifndef KASBAREXTENSION_H +#define KASBAREXTENSION_H + +#include <qguardedptr.h> +#include <kpanelextension.h> + +class KasTasker; + +/** + * A KPanelExtension that displays a KasTasker widget. + */ +class KasBarExtension : public KPanelExtension +{ + Q_OBJECT + +public: + KasBarExtension( const QString& configFile, + Type t = Normal, + int actions = 0, + QWidget *parent = 0, const char *name = 0 ); + + virtual ~KasBarExtension(); + + QSize sizeHint( Position, QSize maxSize ) const; + Position preferedPosition() const { return Right; } + + virtual void positionChange( Position position ); + + bool isDetached() const { return detached_; } + QSize detachedSize(); + +public slots: + void setDetached( bool detach ); + +protected: + void showEvent( QShowEvent *se ); + virtual void about(); + virtual void preferences(); + +private: + QGuardedPtr<KasTasker> kasbar; + bool detached_; +}; + +#endif // KASBAREXTENSION_H + diff --git a/kicker/extensions/kasbar/kasclockitem.cpp b/kicker/extensions/kasbar/kasclockitem.cpp new file mode 100644 index 000000000..0292a93cb --- /dev/null +++ b/kicker/extensions/kasbar/kasclockitem.cpp @@ -0,0 +1,120 @@ +#include <qpainter.h> +#include <qbitmap.h> +#include <qdatetime.h> +#include <qdrawutil.h> +#include <qlcdnumber.h> +#include <qtimer.h> + +#include <kdatepicker.h> +#include <kglobal.h> +#include <kwin.h> +#include <kiconloader.h> +#include <kpixmap.h> +#include <kpixmapeffect.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kpopupmenu.h> + +#include <taskmanager.h> + +#include "kaspopup.h" +#include "kastasker.h" + +#include "kasclockitem.h" +#include "kasclockitem.moc" + +class LCD : public QLCDNumber +{ +public: + LCD( QWidget *parent, const char *name=0 ) + : QLCDNumber(parent,name) {} + ~LCD() {} + + void draw( QPainter *p ) { drawContents(p); } +}; + +KasClockItem::KasClockItem( KasBar *parent ) + : KasItem( parent ) +{ + setCustomPopup( true ); + + QTimer *t = new QTimer( this ); + connect( t, SIGNAL( timeout() ), SLOT( updateTime() ) ); + t->start( 1000 ); + + lcd = new LCD( parent ); + lcd->hide(); + + lcd->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ); + lcd->setBackgroundMode( NoBackground ); + lcd->setFrameStyle( QFrame::NoFrame ); + lcd->setSegmentStyle( QLCDNumber::Flat ); + lcd->setNumDigits( 5 ); + lcd->setAutoMask( true ); + updateTime(); + + connect( this, SIGNAL(leftButtonClicked(QMouseEvent *)), SLOT(togglePopup()) ); + connect( this, SIGNAL(rightButtonClicked(QMouseEvent *)), SLOT(showMenuAt(QMouseEvent *) ) ); +} + +KasClockItem::~KasClockItem() +{ + delete lcd; +} + +KasPopup *KasClockItem::createPopup() +{ + KasPopup *pop = new KasPopup( this ); + setPopup( pop ); + + (void) new KDatePicker( pop ); + pop->adjustSize(); + + return pop; +} + +void KasClockItem::updateTime() +{ + setText( KGlobal::locale()->formatDate( QDate::currentDate(), true /* shortFormat */ ) ); + lcd->display( KGlobal::locale()->formatTime( QTime::currentTime(), false /* includeSecs */, false /* isDuration */) ); + + update(); +} + +void KasClockItem::paint( QPainter *p ) +{ + KasItem::paint( p ); + + lcd->setGeometry( QRect( 0, 0, extent(), extent()-15 ) ); + + p->save(); + p->translate( 3, 15 ); + lcd->setPaletteForegroundColor( kasbar()->colorGroup().mid() ); + lcd->draw( p ); + p->restore(); + + p->save(); + p->translate( 1, 13 ); + lcd->setPaletteForegroundColor( resources()->activePenColor() ); + lcd->draw( p ); + p->restore(); +} + +void KasClockItem::showMenuAt( QMouseEvent *ev ) +{ + hidePopup(); + showMenuAt( ev->globalPos() ); +} + +void KasClockItem::showMenuAt( QPoint p ) +{ + mouseLeave(); + kasbar()->updateMouseOver(); + + KasTasker *bar = dynamic_cast<KasTasker *> (KasItem::kasbar()); + if ( !bar ) + return; + + KPopupMenu *menu = bar->contextMenu(); + menu->exec( p ); +} diff --git a/kicker/extensions/kasbar/kasclockitem.h b/kicker/extensions/kasbar/kasclockitem.h new file mode 100644 index 000000000..380901765 --- /dev/null +++ b/kicker/extensions/kasbar/kasclockitem.h @@ -0,0 +1,37 @@ +// -*- c++ -*- + + +#ifndef KASCLOCKITEM_H +#define KASCLOCKITEM_H + +#include "kasitem.h" + +/** + * An item that displays a clock. + */ +class KDE_EXPORT KasClockItem : public KasItem +{ + Q_OBJECT + +public: + KasClockItem( KasBar *parent ); + virtual ~KasClockItem(); + + void paint( QPainter *p ); + +public slots: + void updateTime(); + + void showMenuAt( QMouseEvent *ev ); + void showMenuAt( QPoint p ); + +protected: + /** Reimplemented from KasItem to create a date picker. */ + virtual KasPopup *createPopup(); + +private: + class LCD *lcd; +}; + +#endif // KASCLOCKITEM_H + diff --git a/kicker/extensions/kasbar/kasgrouper.cpp b/kicker/extensions/kasbar/kasgrouper.cpp new file mode 100644 index 000000000..44dcc57b5 --- /dev/null +++ b/kicker/extensions/kasbar/kasgrouper.cpp @@ -0,0 +1,156 @@ +/* kasgrouper.cpp +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +#include <taskmanager.h> + +#include "kastasker.h" +#include "kasgroupitem.h" +#include "kastaskitem.h" + +#include "kasgrouper.h" + +KasGrouper::KasGrouper( KasTasker *bar ) + : kasbar( bar ) +{ +} + +KasGrouper::~KasGrouper() +{ +} + +KasItem *KasGrouper::maybeGroup( Task::Ptr t ) +{ + KasItem *item = 0; + + if ( kasbar->groupInactiveDesktops() ) + item = maybeAddToDesktopGroup( t ); + if ( item ) + return item; + + if ( kasbar->groupWindows() ) + item = maybeAddToGroup( t ); + if ( item ) + return item; + + return item; +} + +KasItem *KasGrouper::maybeAddToDesktopGroup( Task::Ptr t ) +{ + if ( t->isOnCurrentDesktop() ) + return 0; + + KasItem *item = 0; + for ( uint i = 0; i < kasbar->itemCount(); i++ ) { + KasItem *ei = kasbar->itemAt( i ); + + if ( ei->inherits( "KasTaskItem" ) ) { + KasTaskItem *eti = static_cast<KasTaskItem *> (ei); + if ( eti->task()->desktop() == t->desktop() ) { + KasGroupItem *egi = kasbar->convertToGroup( eti->task() ); + egi->setGroupType( KasGroupItem::GroupDesktop ); + egi->addTask( t ); + item = egi; + } + } + else if ( ei->inherits( "KasGroupItem" ) ) { + KasGroupItem *egi = static_cast<KasGroupItem *> (ei); + if ( egi->groupType() == KasGroupItem::GroupDesktop ) { + if ( egi->task(0)->desktop() == t->desktop() ) { + egi->addTask( t ); + item = egi; + } + } + } + } + + return item; +} + +KasItem *KasGrouper::maybeAddToGroup( Task::Ptr t ) +{ + KasItem *item = 0; + + QString taskClass = t->className().lower(); + + for ( uint i = 0; (!item) && (i < kasbar->itemCount()); i++ ) { + KasItem *ei = kasbar->itemAt( i ); + + if ( ei->inherits( "KasTaskItem" ) ) { + + KasTaskItem *eti = static_cast<KasTaskItem *> (ei); + + // NB This calls Task::className() not QObject::className() + QString currClass = eti->task()->className().lower(); + + if ( Task::idMatch( currClass, taskClass ) ) { + KasGroupItem *egi = kasbar->convertToGroup( eti->task() ); + egi->addTask( t ); + item = egi; + break; + } + } + else if ( ei->inherits( "KasGroupItem" ) ) { + KasGroupItem *egi = static_cast<KasGroupItem *> (ei); + + for ( int i = 0; i < egi->taskCount(); i++ ) { + + // NB This calls Task::className() not QObject::className() + QString currClass = egi->task( i )->className().lower(); + + if ( Task::idMatch( currClass, taskClass ) ) { + egi->addTask( t ); + item = egi; + break; + } + } + } + } + + return item; +} diff --git a/kicker/extensions/kasbar/kasgrouper.h b/kicker/extensions/kasbar/kasgrouper.h new file mode 100644 index 000000000..c5beab3a6 --- /dev/null +++ b/kicker/extensions/kasbar/kasgrouper.h @@ -0,0 +1,85 @@ +// -*- c++ -*- + +/* kasgrouper.h +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +#ifndef KASGROUPER_H +#define KASGROUPER_H + +class KasTasker; +class KasItem; +class Task; + +/** + * Assigns items in the Kasbar to groups. + * + * @author Richard Moore, rich@kde.org + */ +class KasGrouper +{ +public: + KasGrouper( KasTasker *bar ); + virtual ~KasGrouper(); + + KasItem *maybeGroup( Task::Ptr t ); + + /** If the task should be part of an inactive desktop group then make it so. */ + KasItem *maybeAddToDesktopGroup( Task::Ptr t ); + + /** If the task should be part of a group then make it so. */ + KasItem *maybeAddToGroup( Task::Ptr t ); + +private: + KasTasker *kasbar; +}; + + +#endif // KASGROUPER_H + + diff --git a/kicker/extensions/kasbar/kasgroupitem.cpp b/kicker/extensions/kasbar/kasgroupitem.cpp new file mode 100644 index 000000000..a4435f7c2 --- /dev/null +++ b/kicker/extensions/kasbar/kasgroupitem.cpp @@ -0,0 +1,305 @@ +/* kasgroupitem.cpp +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +#include <qpainter.h> +#include <qbitmap.h> +#include <qtimer.h> +#include <qwmatrix.h> + +#include <kdebug.h> +#include <kglobal.h> +#include <kwin.h> +#include <kiconloader.h> +#include <kpixmap.h> +#include <kpixmapeffect.h> +#include <kpopupmenu.h> +#include <klocale.h> + +#include <taskmanager.h> +#include <taskrmbmenu.h> + +#include "kastasker.h" +#include "kaspopup.h" + +#include "kasgroupitem.h" +#include "kasgroupitem.moc" + + +KasGroupItem::KasGroupItem( KasTasker *parent ) + : KasItem( parent ), items(), groupType_( GroupRelated ) + +{ + setCustomPopup( true ); + setGroupItem( true ); + setText( i18n("Group") ); + + connect( parent, SIGNAL( layoutChanged() ), this, SLOT( hidePopup() ) ); + connect( parent, SIGNAL( layoutChanged() ), this, SLOT( update() ) ); + connect( this, SIGNAL(leftButtonClicked(QMouseEvent *)), SLOT(togglePopup()) ); + connect( this, SIGNAL(rightButtonClicked(QMouseEvent *)), SLOT(showGroupMenuAt(QMouseEvent *) ) ); +} + +KasGroupItem::~KasGroupItem() +{ +} + +KasTasker *KasGroupItem::kasbar() const +{ + return static_cast<KasTasker *> (KasItem::kasbar()); +} + +void KasGroupItem::addTask( Task::Ptr t ) +{ + if (!t) + return; + + items.append( t ); + if ( items.count() == 1 ) { + setText( t->visibleName() ); + updateIcon(); + } + + connect( t, SIGNAL( changed(bool) ), this, SLOT( update() ) ); + update(); +} + +void KasGroupItem::removeTask( Task::Ptr t ) +{ + if ( !t ) + return; + + hidePopup(); + + for (Task::List::iterator it = items.begin(); it != items.end();) + { + if ((*it) == t) + { + it = items.erase(it); + } + else + { + ++it; + } + } + + updateIcon(); + + if ( items.count() == 1 ) + kasbar()->moveToMain( this, items.first() ); +} + +void KasGroupItem::updateIcon() +{ + QPixmap p; + bool usedIconLoader = false; + Task::Ptr t = items.first(); + if (!t) + p = KGlobal::iconLoader()->loadIcon( "kicker", + KIcon::NoGroup, + KIcon::SizeSmall ); + + int sizes[] = { KIcon::SizeEnormous, + KIcon::SizeHuge, + KIcon::SizeLarge, + KIcon::SizeMedium, + KIcon::SizeSmall }; + + p = t->bestIcon( sizes[kasbar()->itemSize()], usedIconLoader ); + + if ( p.isNull() ) + p = KGlobal::iconLoader()->loadIcon( "error", KIcon::NoGroup, KIcon::SizeSmall ); + + setIcon( p ); +} + +void KasGroupItem::paint( QPainter *p ) +{ + KasItem::paint( p ); + + // + // Item summary info + // + int modCount = 0; + for ( Task::List::iterator it = items.begin(); it != items.end() ; ++it ) { + if ( (*it)->isModified() ) + modCount++; + } + + KasResources *res = resources(); + + p->setPen( isShowingPopup() ? res->activePenColor() : res->inactivePenColor() ); + + if ( modCount ) { + QString modCountStr; + modCountStr.setNum( modCount ); + p->drawText( extent()-fontMetrics().width( modCountStr )-3, + 15+fontMetrics().ascent(), + modCountStr ); + + p->drawPixmap( extent()-12, 29, res->modifiedIcon() ); + } + + int microsPerCol; + switch( kasbar()->itemSize() ) { + default: + case KasBar::Small: + microsPerCol = 2; + break; + case KasBar::Medium: + microsPerCol = 4; + break; + case KasBar::Large: + microsPerCol = 7; + break; + case KasBar::Huge: + microsPerCol = 9; + break; + case KasBar::Enormous: + microsPerCol = 16; + break; + } + + int xpos = 3; + int ypos = 16; + + for ( int i = 0; ( i < (int) items.count() ) && ( i < microsPerCol ); i++ ) { + Task::Ptr t = items.at( i ); + + if( t->isIconified() ) + p->drawPixmap( xpos, ypos, res->microMinIcon() ); + else if ( t->isShaded() ) + p->drawPixmap( xpos, ypos, res->microShadeIcon() ); + else + p->drawPixmap( xpos, ypos, res->microMaxIcon() ); + + ypos += 7; + } + + if ( ((int) items.count() > microsPerCol) && ( kasbar()->itemSize() != KasBar::Small ) ) { + QString countStr; + countStr.setNum( items.count() ); + p->drawText( extent()-fontMetrics().width( countStr )-3, + extent()+fontMetrics().ascent()-16, + countStr ); + } +} + +void KasGroupItem::updatePopup() +{ + if ( bar ) { + bar->rereadMaster(); + + bar->clear(); + if ( items.count() ) { + for ( Task::List::iterator t = items.begin(); t != items.end(); ++t ) { + bar->addTask( *t ); + } + } + + bar->updateLayout(); + if ( popup() ) + popup()->resize( bar->size() ); + } +} + +KasPopup *KasGroupItem::createPopup() +{ + KasPopup *pop = new KasPopup( this ); + bar = kasbar()->createChildBar( ( kasbar()->orientation() == Horizontal ) ? Vertical : Horizontal, pop ); + + connect( pop, SIGNAL(shown()), SLOT(updatePopup()) ); + + return pop; + +// // Test code +// // +// // This generates cool looking fractal-like patterns if you keep unfolding the +// // groups! +// int pos = (int) this; +// if ( pos % 2 ) +// bar->append( new KasItem( bar ) ); +// if ( pos % 5 ) +// bar->append( new KasItem( bar ) ); +// bar->append( new KasGroupItem( bar ) ); +// if ( pos % 3 ) +// bar->append( new KasItem( bar ) ); +// if ( pos % 7 ) +// bar->append( new KasItem( bar ) ); +// //////////// +} + +void KasGroupItem::ungroup() +{ + kasbar()->moveToMain( this ); +} + +void KasGroupItem::showGroupMenuAt( QMouseEvent *ev ) +{ + showGroupMenuAt( ev->globalPos() ); +} + +void KasGroupItem::showGroupMenuAt( const QPoint &p ) +{ + TaskRMBMenu *tm = new TaskRMBMenu(items, true, kasbar()); + tm->insertItem( i18n("&Ungroup" ), this, SLOT( ungroup() ) ); + tm->insertSeparator(); + tm->insertItem( i18n("&Kasbar"), kasbar()->contextMenu() ); + + setLockPopup( true ); + tm->exec( p ); + delete tm; + setLockPopup( false ); +} + + + diff --git a/kicker/extensions/kasbar/kasgroupitem.h b/kicker/extensions/kasbar/kasgroupitem.h new file mode 100644 index 000000000..348fb2839 --- /dev/null +++ b/kicker/extensions/kasbar/kasgroupitem.h @@ -0,0 +1,124 @@ +// -*- c++ -*- + +/* kasgroupitem.h +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +// -*- c++ -*- + + +#ifndef KASGROUPITEM_H +#define KASGROUPITEM_H + +#include <qpixmap.h> +#include <taskmanager.h> +#include "kasitem.h" + +class KasPopup; +class KasTasker; +class KPixmap; +class Task; + +/** + * A KasItem that holds a list of Tasks. + */ +class KasGroupItem : public KasItem +{ + Q_OBJECT + +public: + enum GroupType { + GroupRelated, GroupDesktop + }; + + KasGroupItem( KasTasker *parent/*, Group *group*/ ); + virtual ~KasGroupItem(); + + uint groupType() const { return groupType_; } + void setGroupType( uint type ) { groupType_ = type; } + + /** Reimplemented to paint the item. */ + virtual void paint( QPainter *p ); + + KasTasker *kasbar() const; + + Task::Ptr task( uint i ) { return items.at( i ); } + int taskCount() const { return items.count(); } + + QPixmap icon(); + +public slots: + void addTask( Task::Ptr t ); + void removeTask( Task::Ptr t ); + + void ungroup(); + + void showGroupMenuAt( QMouseEvent *ev ); + void showGroupMenuAt( const QPoint &p ); + + void updateIcon(); + + void updatePopup(); + +protected: + /** Reimplemented to create a KasGroupPopup. */ + virtual KasPopup *createPopup(); + +private: + QString title_; + Task::List items; + uint groupType_; + KasTasker *bar; +}; + +#endif // KASGROUPITEM_H + diff --git a/kicker/extensions/kasbar/kasitem.cpp b/kicker/extensions/kasbar/kasitem.cpp new file mode 100644 index 000000000..5cd8ef7f0 --- /dev/null +++ b/kicker/extensions/kasbar/kasitem.cpp @@ -0,0 +1,566 @@ +/* kasitem.cpp +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +#include <qcursor.h> +#include <qpainter.h> +#include <qdrawutil.h> +#include <qregexp.h> +#include <qtimer.h> + +#include <kdebug.h> +#include <kglobal.h> +#include <kglobalsettings.h> +#include <kiconloader.h> +#include <klocale.h> + +#include "kasitem.h" + +#include "kaspopup.h" +#include "kasitem.moc" + +/* XPM */ +static const char *tiny_arrow[]={ +"5 9 2 1", +". c None", +"# c #ffffff", +"....#", +"...##", +"..###", +".####", +"#####", +".####", +"..###", +"...##", +"....#"}; + +static const int KASITEM_CHECK_POPUP_DELAY = 500; + +KasItem::KasItem( KasBar *parent ) + : QObject( parent ), + kas( parent ), popupTimer( 0 ), dragTimer( 0 ), + title( i18n( "Kasbar" ) ), + mouseOver( false ), activated( false ), + customPopup( false ), lockPopup(false), groupItem( false ), + frame(true), modified(false), attention_(false), prog( -1 ), + anim(), aniFrame( 0 ), drawAnim( false ) +{ + connect( parent, SIGNAL( dragStarted() ), SLOT( hidePopup() ) ); + connect( this, SIGNAL( middleButtonClicked(QMouseEvent *) ), parent, SLOT( toggleOrientation() ) ); +} + +KasItem::~KasItem() +{ + delete (KasPopup *) pop; +} + +void KasItem::setActive( bool yesno ) +{ + if ( activated == yesno ) + return; + + activated = yesno; + update(); +} + +void KasItem::setText( const QString &text ) +{ + if ( title == text ) + return; + + title = text; + update(); +} + +void KasItem::setIcon( const QPixmap &p ) +{ + pix = p; + update(); +} + +void KasItem::setProgress( int percent ) +{ + if ( percent == prog ) + return; + + prog = percent; + update(); +} + +void KasItem::setShowFrame( bool yes ) +{ + if ( frame == yes ) + return; + + frame = yes; + update(); +} + +void KasItem::setModified( bool yes ) +{ + if ( modified == yes ) + return; + + modified = yes; + update(); +} + +void KasItem::setAttention( bool yes ) +{ + if ( attention_ == yes ) + return; + + attention_ = yes; + update(); +} + +void KasItem::mouseEnter() +{ + static const int POPUP_DELAY = 300; + + if ( (!customPopup) && (popupTimer == 0) ) { + popupTimer = new QTimer( this, "popupTimer" ); + connect( popupTimer, SIGNAL( timeout() ), SLOT( showPopup() ) ); + popupTimer->start( POPUP_DELAY, true ); + } + + mouseOver = true; + update(); +} + +void KasItem::mouseReleaseEvent( QMouseEvent *ev ) +{ + if ( ev->button() == LeftButton ) + emit leftButtonClicked( ev ); + else if ( ev->button() == RightButton ) + emit rightButtonClicked( ev ); + else if ( ev->button() == MidButton ) + emit middleButtonClicked( ev ); +} + +// Check periodically if the popup can be hidden (hack) +void KasItem::checkPopup() +{ + if ( pop.isNull() ) + return; + if ( !pop->isVisible() ) + return; + + QWidget *w = QApplication::widgetAt( QCursor::pos() ); + if ( !w ) { + if ( popupTimer ) { + delete popupTimer; + popupTimer = 0; + } + if ( (!customPopup) && (!lockPopup) ) + hidePopup(); + } + else { + QTimer::singleShot( KASITEM_CHECK_POPUP_DELAY, this, SLOT( checkPopup() ) ); + } +} + +void KasItem::dragEnter() +{ + static const int DRAG_SWITCH_DELAY = 1000; + + if ( dragTimer == 0 ) { + dragTimer = new QTimer( this, "dragTimer" ); + connect( dragTimer, SIGNAL( timeout() ), SLOT( dragOverAction() ) ); + dragTimer->start( DRAG_SWITCH_DELAY, true ); + } + + mouseOver = true; + update(); +} + +void KasItem::mouseLeave() +{ + if ( popupTimer ) { + delete popupTimer; + popupTimer = 0; + } + + mouseOver = false; + update(); +} + +void KasItem::dragLeave() +{ + if ( dragTimer ) { + delete dragTimer; + dragTimer = 0; + } + + mouseOver = false; + update(); +} + +bool KasItem::isShowingPopup() const +{ + if ( pop.isNull() ) + return false; + return pop->isVisible(); +} + +KasPopup *KasItem::createPopup() +{ + return 0; +} + +void KasItem::showPopup() +{ + if ( pop.isNull() ) + pop = createPopup(); + + if ( pop.isNull() ) + return; + + pop->show(); + update(); + + QTimer::singleShot( KASITEM_CHECK_POPUP_DELAY, this, SLOT( checkPopup() ) ); +} + +void KasItem::hidePopup() +{ + if ( pop.isNull() ) + return; + + pop->hide(); + activated = false; + update(); +} + +void KasItem::togglePopup() +{ + if ( activated ) + hidePopup(); + else + showPopup(); +} + +void KasItem::setPopup( KasPopup *popup ) +{ + if ( pop ) + pop->deleteLater(); + pop = popup; +} + +void KasItem::paintFrame( QPainter *p ) +{ + if ( !frame ) + return; + + qDrawShadePanel(p, 0, 0, extent(), extent(), colorGroup(), false, 2); + + QPen pen; + + if ( mouseOver ) { + if ( attention_ ) { + pen = QPen( resources()->attentionColor(), 2 ); + p->setPen( pen ); + p->drawRect( 0, 0, extent(), extent()); + } + else { + pen = QPen( Qt::white ); + p->setPen( pen ); + p->drawRect(0, 0, extent(), extent()); + } + } + else if ( kas->paintInactiveFrames() ) { + p->setPen( attention_ ? resources()->attentionColor() : Qt::black ); + p->drawRect(0, 0, extent(), extent()); + } +} + +void KasItem::paintLabel( QPainter *p ) +{ + QString text = title; + + if ( !groupItem ) { + p->fillRect( 2, 2, extent()-4, 13, QBrush( resources()->labelBgColor() ) ); + + if ( isProgressItem() ) { + QRegExp reg( "(1?[0-9]?[0-9])%" ); + if ( -1 != reg.search( text ) ) { + prog = reg.cap(1).toInt(); + paintProgress( p, prog ); + } + else { + prog = 0; + } + } + + p->setFont( KGlobalSettings::taskbarFont() ); + p->setPen( resources()->labelPenColor() ); + + if ( fontMetrics().width( text ) > extent()-4 ) + p->drawText( 2, 2, extent()-4, 12, AlignLeft | AlignVCenter, text ); + else + p->drawText( 2, 2, extent()-4, 12, AlignCenter, text ); + + return; + } + else { + QPixmap arrow( tiny_arrow ); + + QPoint popupPos = KasPopup::calcPosition( this, 10, 10 ); + QPoint iPos = kas->mapToGlobal( kas->itemPos( this ) ); + QWMatrix turn; + + if ( popupPos.x() < iPos.x() ) { + paintArrowLabel( p, arrow.width(), true ); + p->drawPixmap( 3, 4, arrow ); + } + else if ( popupPos.x() == iPos.x() ) { + if ( popupPos.y() < iPos.y() ) { + turn.rotate( 90.0 ); + arrow = arrow.xForm( turn ); + paintArrowLabel( p, arrow.width(), true ); + p->drawPixmap( 3, 6, arrow ); + } + else { + turn.rotate( 270.0 ); + arrow = arrow.xForm( turn ); + paintArrowLabel( p, arrow.width(), false ); + p->drawPixmap( extent()-12, 6, arrow ); + } + } + else { + turn.rotate( 180.0 ); + arrow = arrow.xForm( turn ); + paintArrowLabel( p, arrow.width(), false ); + p->drawPixmap( extent()-8, 4, arrow ); + } + } +} + +void KasItem::paintArrowLabel( QPainter *p, int arrowSize, bool arrowOnLeft ) +{ + QString text = title; + int lx = 2; + int ly = 2; + int w = extent()-4; + int h = 13; + arrowSize+=2; // Add a space + + p->fillRect( lx, ly, w, h, QBrush( resources()->labelBgColor() ) ); + + // Adjust for arrow + if ( arrowOnLeft ) { + lx += arrowSize; + w -= arrowSize; + } + else { + w -= arrowSize; + } + + p->setFont( KGlobalSettings::taskbarFont() ); + p->setPen( resources()->labelPenColor() ); + if ( fontMetrics().width( text ) > w ) + p->drawText( lx, ly, w, h-1, AlignLeft | AlignVCenter, text ); + else + p->drawText( lx, ly, w, h-1, AlignCenter, text ); +} + +void KasItem::paintModified( QPainter *p ) +{ + if ( modified ) + p->drawPixmap(extent()-12, extent()-22, resources()->modifiedIcon() ); +} + +void KasItem::paintBackground( QPainter *p ) +{ + if ( activated ) + p->drawPixmap( 0, 0, resources()->activeBg() ); + else if ( kas->isTransparent() ) + ; + else + p->drawPixmap( 0, 0, resources()->inactiveBg() ); +} + +void KasItem::paintProgress( QPainter *p, int percent ) +{ + double amt = (extent()-4) * (percent / 100.0L); + p->fillRect( 2, 13, (int) amt, 2, QBrush( resources()->progressColor() ) ); +} + +void KasItem::paintStateIcon( QPainter *p, uint state ) +{ + if ( kas->itemSize() != KasBar::Small ) { + switch(state) { + case StateIcon: + p->drawPixmap(extent()-11, extent()-11, resources()->minIcon() ); + break; + case StateShaded: + p->drawPixmap(extent()-11, extent()-11, resources()->shadeIcon() ); + break; + case StateNormal: + p->drawPixmap(extent()-11, extent()-11, resources()->maxIcon() ); + break; + default: + break; + } + } + else { + switch(state) { + case StateIcon: + p->drawPixmap(extent()-9, extent()-9, resources()->microMinIcon() ); + break; + case StateShaded: + p->drawPixmap(extent()-9, extent()-9, resources()->microShadeIcon() ); + break; + case StateNormal: + p->drawPixmap(extent()-9, extent()-9, resources()->microMaxIcon() ); + break; + default: + break; + } + } +} + +void KasItem::paintAttention( QPainter *p ) +{ + p->setPen( resources()->attentionColor() ); + p->drawPixmap( 3, extent()-11, resources()->attentionIcon() ); +} + +void KasItem::setAnimation( const PixmapList &frames ) +{ + anim = frames; + aniFrame = 0; +} + +void KasItem::advanceAnimation() +{ + aniFrame++; + + if ( aniFrame >= anim.count() ) + aniFrame = 0; + + update(); +} + +void KasItem::setShowAnimation( bool yes ) +{ + if ( yes == drawAnim ) + return; + + drawAnim = yes; + update(); +} + +void KasItem::paintAnimation( QPainter *p ) +{ + if ( (aniFrame+1) > anim.count() ) + return; + + QPixmap pix = anim[ aniFrame ]; + if ( pix.isNull() ) + return; + + if ( kas->itemSize() == KasBar::Small ) + p->drawPixmap( 4, 16, pix ); + else + p->drawPixmap( extent()-18, 16, pix ); +} + +void KasItem::paintIcon( QPainter *p ) +{ + if ( pix.isNull() ) + return; + + int x = (extent() - 4 - pix.width()) / 2; + int y = (extent() - 15 - pix.height()) / 2; + p->drawPixmap( x-4, y+15, pix ); +} + +void KasItem::paint( QPainter *p ) +{ + paintBackground( p ); + paintFrame( p ); + paintLabel( p ); + paintIcon( p ); + + if ( drawAnim ) + paintAnimation( p ); + + if ( attention_ ) + paintAttention( p ); +} + +void KasItem::paint( QPainter *p, int x, int y ) +{ + p->save(); + p->translate( x, y ); + paint( p ); + p->restore(); +} + +void KasItem::repaint() +{ + repaint( true ); +} + +void KasItem::repaint( bool erase ) +{ + if ( kas->isVisible() ) + kas->repaintItem( this, erase ); +} + +void KasItem::update() +{ + if ( kas->isVisible() ) + kas->updateItem( this ); +} + diff --git a/kicker/extensions/kasbar/kasitem.h b/kicker/extensions/kasbar/kasitem.h new file mode 100644 index 000000000..3555d576f --- /dev/null +++ b/kicker/extensions/kasbar/kasitem.h @@ -0,0 +1,284 @@ +/* kasitem.h +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +// -*- c++ -*- + +#ifndef KASITEM_H +#define KASITEM_H + +class QPainter; +class QMouseEvent; +class KasPopup; + +#include <qobject.h> +#include <qguardedptr.h> +#include <qpoint.h> +#include <qvaluevector.h> + +#include <kdemacros.h> + +#include "kasbar.h" + +/** + * Abstract base class for items that can be in a KasBar. + * + * @author Richard Moore, rich@kde.org + */ +class KDE_EXPORT KasItem : public QObject +{ + Q_OBJECT + +public: + friend class KasBar; + + typedef QValueVector<QPixmap> PixmapList; + + /** The states that a window can be in. */ + enum WindowState { + StateIcon, StateShaded, StateNormal + }; + + KasItem( KasBar *parent ); + virtual ~KasItem(); + + /** Returns the parent KasBar of this item. */ + KasBar *kasbar() const { return kas; } + + /** Returns the size of the item in pixels. */ + int extent() const { return kas->itemExtent(); } + + /** Returns the text that will be displayed in the title. */ + QString text() const { return title; } + + /** Returns the position of this item. */ + QPoint pos() const { return pos_; } + void setPos( const QPoint &p ) { pos_ = p; } + void setPos( int x, int y ) { pos_ = QPoint( x, y ); } + + /** Returns the progress so far. This will -1 if the item is not displaying progress info. */ + int progress() const { return prog; } + + /** Returns true iff this item is displaying progress info. */ + bool isProgressItem() const { return prog != -1; } + + /** Returns true iff this item will display the modified indicator. */ + bool isModified() const { return modified; } + + /** + * Returns true if this is a group item. Group items display an arrow + * showing where the popup containing their children will appear. + */ + void setGroupItem( bool enable = true ) { groupItem = enable; } + + // + // Popup + // + + /** Returns true iff this item is showing a popup. */ + bool isShowingPopup() const; + + /** Returns the active popup or 0. */ + KasPopup *popup() const { return pop; } + + /** Sets the popup to be used by this item. */ + void setPopup( KasPopup *popup ); + + /** + * Returns true iff this item uses a custom popup policy. If this flag is + * set, the default popup behaviour is disabled. This means you must call + * show/hide/toggle yourself if you want the popup to be shown. + */ + bool hasCustomPopup() const { return customPopup; } + + /** Enables or disables custom popup handling. */ + void setCustomPopup( bool enable = true ) { customPopup = enable; } + + // + // Drawing Methods + // + + /** Translates the QPainter then calls paintItem(). */ + void paint( QPainter *p, int x, int y ); + + /** + * Subclasses should reimplement this method to paint themselves. The painter is setup so + * that the item is always at 0, 0. + */ + virtual void paint( QPainter *p ); + + /** Draw a standard frame for the item. */ + void paintFrame( QPainter *p ); + + /** Paint the background. */ + void paintBackground( QPainter *p ); + + /** Draw the label for the item. */ + void paintLabel( QPainter *p ); + + void paintIcon( QPainter *p ); + + void paintModified( QPainter *p ); + +public slots: + void repaint(); + void repaint( bool erase ); + void update(); + + void setActive( bool yes ); + void setText( const QString &title ); + void setIcon( const QPixmap &icon ); + void setProgress( int percent ); + void setShowFrame( bool yes ); + void setModified( bool yes ); + void setAttention( bool yes ); + void setAnimation( const PixmapList &frames ); + void setShowAnimation( bool yes ); + + void advanceAnimation(); + + void setLockPopup( bool yes ) { lockPopup = yes; } + + /** Shows the items popup. */ + void showPopup(); + + /** Hides the items popup. */ + void hidePopup(); + + /** Check if the popup should be visible. */ + void checkPopup(); + + /** Hides or shows the popup. */ + void togglePopup(); + + /** + * Called when something being dragged is held over the item for a while. + */ + virtual void dragOverAction() {} + +signals: + void leftButtonClicked( QMouseEvent *ev ); + void middleButtonClicked( QMouseEvent *ev ); + void rightButtonClicked( QMouseEvent *ev ); + +protected: + KasResources *resources() { return kas->resources(); } + + /** Gets the font metrics from the parent. */ + QFontMetrics fontMetrics() const { return kas->fontMetrics(); } + + /** Gets the color group from the parent. */ + const QColorGroup &colorGroup() const { return kas->colorGroup(); } + + /** Factory method that creates a popup widget for the item. */ + virtual KasPopup *createPopup(); + + /** Draw a label with an arrow, the parameters specify the position and size of the arrow. */ + void paintArrowLabel( QPainter *p, int arrowSize, bool arrowOnLeft ); + + /** Paints a progress graph. */ + void paintProgress( QPainter *p, int percent ); + + void paintStateIcon( QPainter *p, uint state ); + + void paintAttention( QPainter *p ); + + void paintAnimation( QPainter *p ); + + // + // Event Handlers + // + + /** Called when the item receives a mouse event. */ + virtual void mousePressEvent( QMouseEvent * ) {} + + /** Called when the item receives a mouse event. */ + virtual void mouseReleaseEvent( QMouseEvent * ); + + /** Called when the mouse enters the item. */ + virtual void mouseEnter(); + + /** Called when the mouse leaves the item. */ + virtual void mouseLeave(); + + /** Called when a drag enters the item. */ + virtual void dragEnter(); + + /** Called when a drag leaves the item. */ + virtual void dragLeave(); + +private: + KasBar *kas; + QGuardedPtr<KasPopup> pop; + QTimer *popupTimer; + QTimer *dragTimer; + + QPoint pos_; + QString title; + QPixmap pix; + bool mouseOver; + bool activated; + bool customPopup; + bool lockPopup; + bool groupItem; + bool frame; + bool modified; + bool attention_; + int prog; + + PixmapList anim; + uint aniFrame; + bool drawAnim; +}; + +#endif // KASITEM_H + diff --git a/kicker/extensions/kasbar/kasloaditem.cpp b/kicker/extensions/kasbar/kasloaditem.cpp new file mode 100644 index 000000000..b0f9c23e3 --- /dev/null +++ b/kicker/extensions/kasbar/kasloaditem.cpp @@ -0,0 +1,130 @@ +#include <math.h> +#include <stdlib.h> + +#include <config.h> +#ifdef HAVE_SYS_LOADAVG_H +#include <sys/loadavg.h> // e.g. Solaris +#endif + +#include <qpainter.h> +#include <qbitmap.h> +#include <qdatetime.h> +#include <qdrawutil.h> +#include <qtimer.h> + +#include <kdebug.h> +#include <kglobal.h> +#include <kwin.h> +#include <kiconloader.h> +#include <kpixmap.h> +#include <kpixmapeffect.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kpopupmenu.h> + +#include <taskmanager.h> + +#include "kaspopup.h" +#include "kastasker.h" + +#include "kasloaditem.h" +#include "kasloaditem.moc" + +KasLoadItem::KasLoadItem( KasBar *parent ) + : KasItem( parent ) +{ + QTimer *t = new QTimer( this ); + connect( t, SIGNAL( timeout() ), SLOT( updateDisplay() ) ); + t->start( 1000 ); + updateDisplay(); + + connect( this, SIGNAL(rightButtonClicked(QMouseEvent *)), SLOT(showMenuAt(QMouseEvent *) ) ); +} + +KasLoadItem::~KasLoadItem() +{ +} + +void KasLoadItem::updateDisplay() +{ + double load[3]; + + int ret = getloadavg( load, 3 ); + if ( ret == -1 ) + return; + + valuesOne.append( load[0] ); + valuesFive.append( load[1] ); + valuesFifteen.append( load[2] ); + + if ( valuesOne.count() > 2/*(extent()-2)*/ ) { + valuesOne.pop_front(); + valuesFive.pop_front(); + valuesFifteen.pop_front(); + } + + setText( QString("%1").arg( valuesOne.last(), 3, 'f', 2 ) ); +} + +void KasLoadItem::paint( QPainter *p ) +{ + double val = valuesOne.last(); + double maxValue = 1.0; + double scaleVal = QMAX( val, valuesFive.last() ); + + if ( scaleVal >= maxValue ) + maxValue = 2.0; + if ( scaleVal >= maxValue ) + maxValue = 5.0; + if ( scaleVal >= maxValue ) + maxValue = 10.0; + if ( scaleVal >= maxValue ) + maxValue = 20.0; + if ( scaleVal >= maxValue ) + maxValue = 50.0; + if ( scaleVal >= maxValue ) + maxValue = 100.0; + + double dh = extent()-16; + dh = dh / maxValue; + + int h = (int) floor( dh * val ); + int w = extent()-4; + h = (h > 0) ? h : 1; + w = (w > 0) ? w : 1; + + KasItem::paint( p ); + + QColor light = kasbar()->colorGroup().highlight(); + QColor dark = light.dark(); + + KPixmap pix; + pix.resize( w, h ); + KPixmapEffect::gradient( pix, light, dark, KPixmapEffect::DiagonalGradient ); + p->drawPixmap( 2, extent()-2-h, pix ); + + p->setPen( kasbar()->colorGroup().mid() ); + for ( double pos = 0.2 ; pos < 1.0 ; pos += 0.2 ) { + int ypos = (int) floor((extent()-2) - (dh*maxValue*pos)); + p->drawLine( 2, ypos, extent()-3, ypos ); + } +} + +void KasLoadItem::showMenuAt( QMouseEvent *ev ) +{ + hidePopup(); + showMenuAt( ev->globalPos() ); +} + +void KasLoadItem::showMenuAt( QPoint p ) +{ + mouseLeave(); + kasbar()->updateMouseOver(); + + KasTasker *bar = dynamic_cast<KasTasker *> (KasItem::kasbar()); + if ( !bar ) + return; + + KPopupMenu *menu = bar->contextMenu(); + menu->exec( p ); +} diff --git a/kicker/extensions/kasbar/kasloaditem.h b/kicker/extensions/kasbar/kasloaditem.h new file mode 100644 index 000000000..527a85abc --- /dev/null +++ b/kicker/extensions/kasbar/kasloaditem.h @@ -0,0 +1,36 @@ +// -*- c++ -*- + + +#ifndef KASLOADITEM_H +#define KASLOADITEM_H + +#include "kasitem.h" + +#include <kdemacros.h> + +/** + * An item that displays the system load. + */ +class KDE_EXPORT KasLoadItem : public KasItem +{ + Q_OBJECT + +public: + KasLoadItem( KasBar *parent ); + virtual ~KasLoadItem(); + + void paint( QPainter *p ); + +public slots: + void updateDisplay(); + void showMenuAt( QMouseEvent *ev ); + void showMenuAt( QPoint p ); + +private: + QValueList<double> valuesOne; + QValueList<double> valuesFive; + QValueList<double> valuesFifteen; +}; + +#endif // KASLOADITEM_H + diff --git a/kicker/extensions/kasbar/kaspopup.cpp b/kicker/extensions/kasbar/kaspopup.cpp new file mode 100644 index 000000000..4407f2f48 --- /dev/null +++ b/kicker/extensions/kasbar/kaspopup.cpp @@ -0,0 +1,121 @@ +/* kaspopup.cpp +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +#include <qapplication.h> + +#include "kasitem.h" +#include "kasbar.h" + +#include "kaspopup.h" +#include "kaspopup.moc" + +KasPopup::KasPopup( KasItem *item, const char *name ) + : QHBox( 0, name, WStyle_Customize | WStyle_StaysOnTop | WStyle_Tool | WStyle_NoBorder | WX11BypassWM ), + item_( item ), + kasbar_( item->kasbar() ) +{ +} + +KasPopup::~KasPopup() +{ +} + +void KasPopup::positionSelf() +{ + move( calcPosition( item_, width(), height() ) ); +} + +void KasPopup::show() +{ + emit aboutToShow(); + positionSelf(); + QWidget::show(); + emit shown(); +} + +QPoint KasPopup::calcPosition( KasItem *item, int w, int h ) +{ + KasBar *kasbar = item->kasbar(); + QPoint pos = kasbar->itemPos( item ); + + if ( ( pos.x() < 0 ) && ( pos.y() < 0 ) ) + return QPoint(); + + pos = kasbar->mapToGlobal( pos ); + int x = pos.x(); + int y = pos.y(); + + if ( kasbar->orientation() == Horizontal ) { + if ( y < ( qApp->desktop()->height() / 2 ) ) + y = y + kasbar->itemExtent(); + else + y = y - h; + + if ( (x + w) > qApp->desktop()->width() ) + x = x - w + kasbar->itemExtent(); + } + else { + if ( x < ( qApp->desktop()->width() / 2 ) ) + x = x + kasbar->itemExtent(); + else + x = x - w; + + if ( (y + h) > qApp->desktop()->height() ) + y = y - h + kasbar->itemExtent(); + } + + return QPoint( x, y ); +} + + + diff --git a/kicker/extensions/kasbar/kaspopup.h b/kicker/extensions/kasbar/kaspopup.h new file mode 100644 index 000000000..11c024782 --- /dev/null +++ b/kicker/extensions/kasbar/kaspopup.h @@ -0,0 +1,107 @@ +/* kaspopup.h +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +// -*- c++ -*- + +#ifndef KASPOPUP_H +#define KASPOPUP_H + +#include <qguardedptr.h> +#include <qhbox.h> +#include <kpixmap.h> + +#include "kasitem.h" + +class KasBar; + +/** + * Self positioning popup for KasItems. + * + * @author Richard Moore, rich@kde.org + */ +class KasPopup : public QHBox +{ + Q_OBJECT + +public: + KasPopup( KasItem *item, const char *name=0 ); + virtual ~KasPopup(); + + /** Returns the item that is the parent of this popup. */ + KasItem *item() const { return item_; } + KasBar *kasbar() const { return kasbar_; } + + static QPoint calcPosition( KasItem *item, int w, int h ); + +public slots: + /** + * Move the popup to the right position. You should not need + * to call this directly. + */ + void positionSelf(); + + /** Reimplemented for internal reasons. */ + void show(); + +signals: + void aboutToShow(); + void shown(); + +private: + QGuardedPtr<KasItem> item_; + KasBar *kasbar_; +}; + +#endif // KASPOPUP_H + + diff --git a/kicker/extensions/kasbar/kasprefsdlg.cpp b/kicker/extensions/kasbar/kasprefsdlg.cpp new file mode 100644 index 000000000..d6f0cf39f --- /dev/null +++ b/kicker/extensions/kasbar/kasprefsdlg.cpp @@ -0,0 +1,468 @@ +/* kasprefsdlg.cpp +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ + +#include <qcheckbox.h> +#include <qcombobox.h> +#include <qgrid.h> +#include <qgroupbox.h> +#include <qlabel.h> +#include <qslider.h> +#include <qspinbox.h> +#include <qvbox.h> +#include <qwhatsthis.h> + +#include <kcolorbutton.h> +#include <kconfig.h> +#include <kdialogbase.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <klocale.h> +#include <knuminput.h> + +#include "kastasker.h" + +#include "kasprefsdlg.h" +#include "kasprefsdlg.moc" + +#define Icon(x) KGlobal::iconLoader()->loadIcon( x, KIcon::NoGroup, KIcon::SizeMedium ) +#define LargeIcon(x) KGlobal::iconLoader()->loadIcon( x, KIcon::NoGroup, KIcon::SizeLarge ) + + +KasPrefsDialog::KasPrefsDialog( KasTasker *kas, QWidget *parent ) + : KDialogBase( KDialogBase::IconList, i18n("Kasbar Preferences"), + KDialogBase::Ok | KDialogBase::Cancel, + KDialogBase::Ok, + parent, "kasbarPrefsDialog", /*true*/false ), + kasbar( kas ), + res( kas->resources() ) +{ + addLookPage(); + addBackgroundPage(); + addThumbsPage(); + addBehavePage(); +// addIndicatorsPage(); + addColorsPage(); + addAdvancedPage(); + + resize( 470, 500 ); +} + +KasPrefsDialog::~KasPrefsDialog() +{ + +} + +void KasPrefsDialog::itemSizeChanged( int sz ) +{ + customSize->setEnabled( sz == KasBar::Custom ); +} + +void KasPrefsDialog::addLookPage() +{ + QVBox *lookPage = addVBoxPage( i18n("Appearance"), QString::null, Icon( "appearance" ) ); + + // + // Item size + // + + QGrid *itemSizeBox = new QGrid( 2, lookPage ); + itemSizeBox->setSpacing( spacingHint() ); + + QWhatsThis::add( itemSizeBox, + i18n( "Specifies the size of the task items." ) ); + + QLabel *itemSizeLabel = new QLabel( i18n("Si&ze:"), itemSizeBox ); + + itemSizeCombo = new QComboBox( itemSizeBox ); + itemSizeCombo->insertItem( i18n( "Enormous" ) ); + itemSizeCombo->insertItem( i18n( "Huge" ) ); + itemSizeCombo->insertItem( i18n( "Large" ) ); + itemSizeCombo->insertItem( i18n( "Medium" ) ); + itemSizeCombo->insertItem( i18n( "Small" ) ); + itemSizeCombo->insertItem( i18n( "Custom" ) ); + + itemSizeLabel->setBuddy( itemSizeCombo ); + + connect( itemSizeCombo, SIGNAL( activated( int ) ), + kasbar, SLOT( setItemSize( int ) ) ); + connect( itemSizeCombo, SIGNAL( activated( int ) ), SLOT( itemSizeChanged( int ) ) ); + + new QWidget( itemSizeBox ); + + customSize = new QSpinBox( 5, 1000, 1, itemSizeBox ); + + customSize->setValue( kasbar->itemExtent() ); + + connect( customSize, SIGNAL( valueChanged( int ) ), + kasbar, SLOT( setItemExtent( int ) ) ); + connect( customSize, SIGNAL( valueChanged( int ) ), + kasbar, SLOT( customSizeChanged( int ) ) ); + + int sz = kasbar->itemSize(); + itemSizeCombo->setCurrentItem( sz ); + customSize->setEnabled( sz == KasBar::Custom ); + + // + // Boxes per line + // + + QHBox *maxBoxesBox = new QHBox( lookPage ); + QWhatsThis::add( maxBoxesBox, + i18n( "Specifies the maximum number of items that should be placed in a line " + "before starting a new row or column. If the value is 0 then all the " + "available space will be used." ) ); + QLabel *maxBoxesLabel = new QLabel( i18n("Bo&xes per line: "), maxBoxesBox ); + + KConfig *conf = kasbar->config(); + if ( conf ) + conf->setGroup( "Layout" ); + maxBoxesSpin = new KIntSpinBox( 0, 50, 1, + conf ? conf->readNumEntry( "MaxBoxes", 0 ) : 11, + 10, + maxBoxesBox, "maxboxes" ); + connect( maxBoxesSpin, SIGNAL( valueChanged( int ) ), kasbar, SLOT( setMaxBoxes( int ) ) ); + maxBoxesLabel->setBuddy( maxBoxesSpin ); + + // + // Mode + // + + detachedCheck = new QCheckBox( i18n("&Detach from screen edge"), lookPage ); + QWhatsThis::add( detachedCheck, i18n( "Detaches the bar from the screen edge and makes it draggable." ) ); + + detachedCheck->setEnabled( !kasbar->isStandAlone() ); + detachedCheck->setChecked( kasbar->isDetached() ); + connect( detachedCheck, SIGNAL( toggled(bool) ), kasbar, SLOT( setDetached(bool) ) ); + + (void) new QWidget( lookPage, "spacer" ); + (void) new QWidget( lookPage, "spacer" ); + (void) new QWidget( lookPage, "spacer" ); +} + +void KasPrefsDialog::addBackgroundPage() +{ + QVBox *bgPage = addVBoxPage( i18n("Background"), QString::null, Icon( "background" ) ); + + transCheck = new QCheckBox( i18n("Trans&parent"), bgPage ); + QWhatsThis::add( transCheck, i18n( "Enables pseudo-transparent mode." ) ); + transCheck->setChecked( kasbar->isTransparent() ); + connect( transCheck, SIGNAL( toggled(bool) ), kasbar, SLOT( setTransparent(bool) ) ); + + tintCheck = new QCheckBox( i18n("Enable t&int"), bgPage ); + QWhatsThis::add( tintCheck, + i18n( "Enables tinting the background that shows through in transparent mode." ) ); + tintCheck->setChecked( kasbar->hasTint() ); + connect( tintCheck, SIGNAL( toggled(bool) ), kasbar, SLOT( setTint(bool) ) ); + + QHBox *tintColBox = new QHBox( bgPage ); + QWhatsThis::add( tintColBox, + i18n( "Specifies the color used for the background tint." ) ); + connect( tintCheck, SIGNAL( toggled(bool) ), tintColBox, SLOT( setEnabled(bool) ) ); + tintColBox->setEnabled( kasbar->hasTint() ); + + QLabel *tintLabel = new QLabel( i18n("Tint &color:"), tintColBox ); + + tintButton = new KColorButton( kasbar->tintColor(), tintColBox ); + connect( tintButton, SIGNAL( changed( const QColor & ) ), + kasbar, SLOT( setTintColor( const QColor & ) ) ); + tintLabel->setBuddy( tintButton ); + + QHBox *tintAmtBox = new QHBox( bgPage ); + QWhatsThis::add( tintAmtBox, + i18n( "Specifies the strength of the background tint." ) ); + connect( tintCheck, SIGNAL( toggled(bool) ), tintAmtBox, SLOT( setEnabled(bool) ) ); + tintAmtBox->setEnabled( kasbar->hasTint() ); + + QLabel *tintStrengthLabel = new QLabel( i18n("Tint &strength: "), tintAmtBox ); + + int percent = (int) (kasbar->tintAmount() * 100.0); + tintAmount = new QSlider( 0, 100, 1, percent, Horizontal, tintAmtBox ); + tintAmount->setTracking( true ); + connect( tintAmount, SIGNAL( valueChanged( int ) ), + kasbar, SLOT( setTintAmount( int ) ) ); + tintStrengthLabel->setBuddy( tintAmount ); + + (void) new QWidget( bgPage, "spacer" ); + (void) new QWidget( bgPage, "spacer" ); + (void) new QWidget( bgPage, "spacer" ); +} + +void KasPrefsDialog::addThumbsPage() +{ + QVBox *thumbsPage = addVBoxPage( i18n("Thumbnails"), QString::null, Icon( "icons" ) ); + + thumbsCheck = new QCheckBox( i18n("Enable thu&mbnails"), thumbsPage ); + QWhatsThis::add( thumbsCheck, + i18n( "Enables the display of a thumbnailed image of the window when " + "you move your mouse pointer over an item. The thumbnails are " + "approximate, and may not reflect the current window contents.\n\n" + "Using this option on a slow machine may cause performance problems." ) ); + thumbsCheck->setChecked( kasbar->thumbnailsEnabled() ); + connect( thumbsCheck, SIGNAL( toggled(bool) ), kasbar, SLOT( setThumbnailsEnabled(bool) ) ); + + embedThumbsCheck = new QCheckBox( i18n("&Embed thumbnails"), thumbsPage ); + embedThumbsCheck->setChecked( kasbar->embedThumbnails() ); + connect( embedThumbsCheck, SIGNAL( toggled(bool) ), kasbar, SLOT( setEmbedThumbnails(bool) ) ); + + QHBox *thumbSizeBox = new QHBox( thumbsPage ); + QWhatsThis::add( thumbSizeBox, + i18n( "Controls the size of the window thumbnails. Using large sizes may " + "cause performance problems." ) ); + QLabel *thumbSizeLabel = new QLabel( i18n("Thumbnail &size: "), thumbSizeBox ); + int percent = (int) (kasbar->thumbnailSize() * 100.0); + thumbSizeSlider = new QSlider( 0, 100, 1, percent, Horizontal, thumbSizeBox ); + connect( thumbSizeSlider, SIGNAL( valueChanged( int ) ), + kasbar, SLOT( setThumbnailSize( int ) ) ); + thumbSizeLabel->setBuddy( thumbSizeSlider ); + + QHBox *thumbUpdateBox = new QHBox( thumbsPage ); + thumbUpdateBox->setSpacing( spacingHint() ); + QWhatsThis::add( thumbUpdateBox, + i18n( "Controls the frequency with which the thumbnail of the active window " + "is updated. If the value is 0 then no updates will be performed.\n\n" + "Using small values may cause performance problems on slow machines." ) ); + QLabel *thumbUpdateLabel = new QLabel( i18n("&Update thumbnail every: "), thumbUpdateBox ); + thumbUpdateSpin = new QSpinBox( 0, 1000, 1, thumbUpdateBox ); + thumbUpdateSpin->setValue( kasbar->thumbnailUpdateDelay() ); + connect( thumbUpdateSpin, SIGNAL( valueChanged( int ) ), + kasbar, SLOT( setThumbnailUpdateDelay( int ) ) ); + (void) new QLabel( i18n("seconds"), thumbUpdateBox ); + thumbUpdateLabel->setBuddy( thumbUpdateSpin ); + + (void) new QWidget( thumbsPage, "spacer" ); + (void) new QWidget( thumbsPage, "spacer" ); + (void) new QWidget( thumbsPage, "spacer" ); +} + +void KasPrefsDialog::addBehavePage() +{ + QVBox *behavePage = addVBoxPage( i18n("Behavior"), QString::null, Icon( "window_list" ) ); + + groupWindowsCheck = new QCheckBox( i18n("&Group windows"), behavePage ); + QWhatsThis::add( groupWindowsCheck, + i18n( "Enables the grouping together of related windows." ) ); + groupWindowsCheck->setChecked( kasbar->groupWindows() ); + connect( groupWindowsCheck, SIGNAL( toggled(bool) ), + kasbar, SLOT( setGroupWindows(bool) ) ); + + showAllWindowsCheck = new QCheckBox( i18n("Show all &windows"), behavePage ); + QWhatsThis::add( showAllWindowsCheck, + i18n( "Enables the display of all windows, not just those on the current desktop." ) ); + showAllWindowsCheck->setChecked( kasbar->showAllWindows() ); + connect( showAllWindowsCheck, SIGNAL( toggled(bool) ), kasbar, SLOT( setShowAllWindows(bool) ) ); + + groupInactiveCheck = new QCheckBox( i18n("&Group windows on inactive desktops"), behavePage ); + QWhatsThis::add( groupInactiveCheck, + i18n( "Enables the grouping together of windows that are not on the current desktop." ) ); + groupInactiveCheck->setChecked( kasbar->groupInactiveDesktops() ); + connect( groupInactiveCheck, SIGNAL( toggled(bool) ), + kasbar, SLOT( setGroupInactiveDesktops(bool) ) ); + + onlyShowMinimizedCheck = new QCheckBox( i18n("Only show &minimized windows"), behavePage ); + QWhatsThis::add( onlyShowMinimizedCheck, + i18n( "When this option is checked only minimized windows are shown in the bar. " \ + "This gives Kasbar similar behavior to the icon handling in older environments " \ + "like CDE or OpenLook." ) ); + onlyShowMinimizedCheck->setChecked( kasbar->onlyShowMinimized() ); + connect( onlyShowMinimizedCheck, SIGNAL( toggled(bool) ), kasbar, SLOT( setOnlyShowMinimized(bool) ) ); + + (void) new QWidget( behavePage, "spacer" ); + (void) new QWidget( behavePage, "spacer" ); +} + +void KasPrefsDialog::addColorsPage() +{ + QVBox *colorsPage = addVBoxPage( i18n("Colors"), QString::null, Icon( "colors" ) ); + + // Item label colors + QGrid *group = new QGrid( 2, colorsPage ); + + QLabel *labelPenLabel = new QLabel( i18n("Label foreground:"), group ); + + labelPenButton = new KColorButton( res->labelPenColor(), group ); + connect( labelPenButton, SIGNAL( changed( const QColor & ) ), + res, SLOT( setLabelPenColor( const QColor & ) ) ); + labelPenLabel->setBuddy( labelPenButton ); + + QLabel *labelBackgroundLabel = new QLabel( i18n("Label background:"), group ); + labelBackgroundButton = new KColorButton( res->labelBgColor(), group ); + connect( labelBackgroundButton, SIGNAL( changed( const QColor & ) ), + res, SLOT( setLabelBgColor( const QColor & ) ) ); + labelBackgroundLabel->setBuddy( labelBackgroundButton ); + + // Inactive colors + group = new QGrid( 2, colorsPage ); + + QLabel *inactivePenLabel = new QLabel( i18n("Inactive foreground:"), group ); + inactivePenButton = new KColorButton( res->inactivePenColor(), group ); + connect( inactivePenButton, SIGNAL( changed( const QColor & ) ), + res, SLOT( setInactivePenColor( const QColor & ) ) ); + inactivePenLabel->setBuddy( inactivePenButton ); + + QLabel *inactiveBgLabel = new QLabel( i18n("Inactive background:"), group ); + inactiveBgButton = new KColorButton( res->inactiveBgColor(), group ); + connect( inactiveBgButton, SIGNAL( changed( const QColor & ) ), + res, SLOT( setInactiveBgColor( const QColor & ) ) ); + inactiveBgLabel->setBuddy( inactiveBgButton ); + + // Active colors + group = new QGrid( 2, colorsPage ); + + QLabel *activePenLabel = new QLabel( i18n("Active foreground:"), group ); + activePenButton = new KColorButton( res->activePenColor(), group ); + connect( activePenButton, SIGNAL( changed( const QColor & ) ), + res, SLOT( setActivePenColor( const QColor & ) ) ); + activePenLabel->setBuddy( activePenButton ); + + QLabel *activeBgLabel = new QLabel( i18n("Active background:"), group ); + activeBgButton = new KColorButton( res->activeBgColor(), group ); + connect( activeBgButton, SIGNAL( changed( const QColor & ) ), + res, SLOT( setActiveBgColor( const QColor & ) ) ); + activeBgLabel->setBuddy( activeBgButton ); + + group = new QGrid( 2, colorsPage ); + + QLabel *progressLabel = new QLabel( i18n("&Progress color:"), group ); + progressButton = new KColorButton( res->progressColor(), group ); + connect( progressButton, SIGNAL( changed( const QColor & ) ), + res, SLOT( setProgressColor( const QColor & ) ) ); + progressLabel->setBuddy( progressButton ); + + QLabel *attentionLabel = new QLabel( i18n("&Attention color:"), group ); + attentionButton = new KColorButton( res->attentionColor(), group ); + connect( attentionButton, SIGNAL( changed( const QColor & ) ), + res, SLOT( setAttentionColor( const QColor & ) ) ); + attentionLabel->setBuddy( attentionButton ); + + (void) new QWidget( colorsPage, "spacer" ); +} + +void KasPrefsDialog::addIndicatorsPage() +{ + QVBox *indicatorsPage = addVBoxPage( i18n("Indicators"), QString::null, Icon( "bell" ) ); + + (void) new QWidget( indicatorsPage, "spacer" ); + (void) new QWidget( indicatorsPage, "spacer" ); +} + +void KasPrefsDialog::addAdvancedPage() +{ + QVBox *advancedPage = addVBoxPage( i18n("Advanced"), QString::null, Icon( "misc" ) ); + + // Startup notifier + notifierCheck = new QCheckBox( i18n("Enable &startup notifier"), advancedPage ); + QWhatsThis::add( notifierCheck, + i18n( "Enables the display of tasks that are starting but have not yet " + "created a window." ) ); + notifierCheck->setChecked( kasbar->notifierEnabled() ); + connect( notifierCheck, SIGNAL( toggled(bool) ), kasbar, SLOT( setNotifierEnabled(bool) ) ); + + // Status advanced + modifiedCheck = new QCheckBox( i18n("Enable &modified indicator"), advancedPage ); + QWhatsThis::add( modifiedCheck, + i18n( "Enables the display of a floppy disk state icon for windows containing " + "a modified document." ) ); + modifiedCheck->setChecked( kasbar->showModified() ); + connect( modifiedCheck, SIGNAL( toggled(bool) ), kasbar, SLOT( setShowModified(bool) ) ); + + progressCheck = new QCheckBox( i18n("Enable &progress indicator"), advancedPage ); + QWhatsThis::add( progressCheck, + i18n( "Enables the display of a progress bar in the label of windows show " + "are progress indicators." ) ); + progressCheck->setChecked( kasbar->showProgress() ); + connect( progressCheck, SIGNAL( toggled(bool) ), kasbar, SLOT( setShowProgress(bool) ) ); + + attentionCheck = new QCheckBox( i18n("Enable &attention indicator"), advancedPage ); + QWhatsThis::add( attentionCheck, + i18n( "Enables the display of an icon that indicates a window that needs attention." ) ); + attentionCheck->setChecked( kasbar->showAttention() ); + connect( attentionCheck, SIGNAL( toggled(bool) ), kasbar, SLOT( setShowAttention(bool) ) ); + + inactiveFramesCheck = new QCheckBox( i18n("Enable frames for inactive items"), advancedPage ); + QWhatsThis::add( inactiveFramesCheck, + i18n( "Enables frames around inactive items, if you want the bar to disappear into " \ + "the background you should probably uncheck this option." ) ); + inactiveFramesCheck->setChecked( kasbar->paintInactiveFrames() ); + connect( inactiveFramesCheck, SIGNAL( toggled(bool) ), kasbar, SLOT( setPaintInactiveFrames(bool) ) ); + + (void) new QWidget( advancedPage, "spacer" ); + (void) new QWidget( advancedPage, "spacer" ); +} + +void KasPrefsDialog::customSizeChanged ( int value ) +{ + customSize->setSuffix( i18n(" pixel", " pixels", value) ); +} + +void KasPrefsDialog::accept() +{ + KConfig *conf = kasbar->config(); + if ( conf ) { + kasbar->writeConfig( conf ); + + conf->setGroup("Layout"); + // TODO: This needs to be made independent of the gui and moved to kastasker + conf->writeEntry( "MaxBoxes", maxBoxesSpin->value() ); + + conf->sync(); + } + + QDialog::accept(); +} + +void KasPrefsDialog::reject() +{ + kasbar->readConfig(); + QDialog::reject(); +} diff --git a/kicker/extensions/kasbar/kasprefsdlg.h b/kicker/extensions/kasbar/kasprefsdlg.h new file mode 100644 index 000000000..8c6bb3200 --- /dev/null +++ b/kicker/extensions/kasbar/kasprefsdlg.h @@ -0,0 +1,142 @@ +// -*- c++ -*- + +/* kasprefsdlg.h +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +// -*- c++ -*- + +#ifndef KASPREFSDLG_H +#define KASPREFSDLG_H + +#include <kdialogbase.h> + +class QComboBox; +class QCheckBox; +class QSlider; +class QSpinBox; +class KColorButton; +class KConfig; +class KIntSpinBox; + +class KasTasker; +class KasResources; + +/** + * Prefs dialog for KasBar + */ +class KasPrefsDialog : public KDialogBase +{ + Q_OBJECT + +public: + KasPrefsDialog( KasTasker *kas, QWidget *parent=0 ); + ~KasPrefsDialog(); + + void addLookPage(); + void addBackgroundPage(); + void addThumbsPage(); + void addBehavePage(); + void addIndicatorsPage(); + void addColorsPage(); + void addAdvancedPage(); + +public slots: + void itemSizeChanged( int sz ); + +protected: + virtual void accept(); + virtual void reject(); + +private slots: + void customSizeChanged ( int value ); + +private: + + QComboBox *itemSizeCombo; + QSpinBox *customSize; + QCheckBox *transCheck; + QCheckBox *tintCheck; + KColorButton *tintButton; + QSlider *tintAmount; + QCheckBox *thumbsCheck; + QCheckBox *embedThumbsCheck; + QSlider *thumbSizeSlider; + QSpinBox *thumbUpdateSpin; + QCheckBox *notifierCheck; + QCheckBox *modifiedCheck; + QCheckBox *progressCheck; + QCheckBox *showAllWindowsCheck; + QCheckBox *onlyShowMinimizedCheck; + KIntSpinBox *maxBoxesSpin; + QCheckBox *detachedCheck; + QCheckBox *groupWindowsCheck; + QCheckBox *groupInactiveCheck; + QCheckBox *attentionCheck; + QCheckBox *inactiveFramesCheck; + + KColorButton *labelPenButton; + KColorButton *labelBackgroundButton; + KColorButton *inactivePenButton; + KColorButton *inactiveBgButton; + KColorButton *activePenButton; + KColorButton *activeBgButton; + + KColorButton *progressButton; + KColorButton *attentionButton; + + KasTasker *kasbar; + KasResources *res; +}; + +#endif // KASPREFSDLG_H + diff --git a/kicker/extensions/kasbar/kasresources.cpp b/kicker/extensions/kasbar/kasresources.cpp new file mode 100644 index 000000000..0248642f4 --- /dev/null +++ b/kicker/extensions/kasbar/kasresources.cpp @@ -0,0 +1,329 @@ +/* kasbar.cpp +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +#include <kstandarddirs.h> +#include <kpixmapeffect.h> + +#include "kasbar.h" + +#include "kasresources.h" +#include "kasresources.moc" + +// +// Bitmap data used for the window state indicators +// +static unsigned char min_bits[] = { + 0x00, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00}; +static unsigned char max_bits[] = { + 0xff, 0xff, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xff}; +static unsigned char shade_bits[] = { + 0x06, 0x1e, 0x7e, 0xfe, 0xfe, 0x7e, 0x1e, 0x06}; + +static unsigned char attention_bits[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + +/* XPM */ +static const char *tiny_floppy[]={ +"10 10 4 1", +". c None", +"# c #000000", +"b c #a0a0a0", +"a c #ffffff", +".########.", +".#aaaaaa#.", +".#aaaaaa#.", +".#aaaaaa#.", +".########.", +".########.", +".##bbbb##.", +".##bbbb##.", +".##bbbb##.", +".........."}; + +static const char *micro_max[]={ +"6 6 2 1", +". c None", +"# c #000000", +"######", +"######", +"##..##", +"##..##", +"######", +"######", +}; + +static const char *micro_min[]={ +"6 6 2 1", +". c None", +"# c #000000", +"......", +"######", +"######", +".####.", +"..##..", +"......" +}; + +static const char *micro_shade[]={ +"6 6 2 1", +". c None", +"# c #000000", +".##...", +".###..", +".####.", +".####.", +".###..", +".##..." +}; + +KasResources::KasResources( KasBar *parent, const char *name ) + : QObject( parent, name ? name : "kasbar_resources" ), + kasbar( parent ), + labelPenColor_( Qt::white ), labelBgColor_( Qt::black ), + activePenColor_( Qt::black ), activeBgColor_( Qt::white ), + inactivePenColor_( Qt::black ), inactiveBgColor_( Qt::white ), + progressColor_( Qt::green ), attentionColor_( Qt::red ), + startupFrames_() +{ +} + +KasResources::~KasResources() +{ +} + +QBitmap KasResources::minIcon() +{ + if ( minPix.isNull() ) { + minPix = QBitmap(8, 8, min_bits, true); + minPix.setMask(minPix); + } + + return minPix; +} + +QBitmap KasResources::maxIcon() +{ + if ( maxPix.isNull() ) { + maxPix = QBitmap(8, 8, max_bits, true); + maxPix.setMask(maxPix); + } + + return maxPix; +} + +QBitmap KasResources::shadeIcon() +{ + if ( shadePix.isNull() ) { + shadePix = QBitmap(8, 8, shade_bits, true); + shadePix.setMask(shadePix); + } + + return shadePix; +} + +QBitmap KasResources::attentionIcon() +{ + if ( attentionPix.isNull() ) { + attentionPix = QBitmap( 8, 8, attention_bits, true ); + attentionPix.setMask( attentionPix ); + } + + return attentionPix; +} + +QPixmap KasResources::modifiedIcon() +{ + if ( modifiedPix.isNull() ) + modifiedPix = QPixmap( tiny_floppy ); + + return modifiedPix; +} + +QPixmap KasResources::microShadeIcon() +{ + if ( microShadePix.isNull() ) + microShadePix = QPixmap( micro_shade ); + + return microShadePix; +} + +QPixmap KasResources::microMaxIcon() +{ + if ( microMaxPix.isNull() ) + microMaxPix = QPixmap( micro_max ); + + return microMaxPix; +} + +QPixmap KasResources::microMinIcon() +{ + if ( microMinPix.isNull() ) + microMinPix = QPixmap( micro_min ); + + return microMinPix; +} + +static const int MAX_ANIMATION_FRAME=10; + +QValueVector<QPixmap> KasResources::startupAnimation() +{ + if ( startupFrames_.isEmpty() ) { + for ( int i = 1; i <= MAX_ANIMATION_FRAME; i++ ) { + QPixmap p( locate("data", "kicker/pics/disk" + QString::number(i) + ".png") ); + if ( !p.isNull() ) + startupFrames_.append( p ); + } + } + + return startupFrames_; +} + +void KasResources::setLabelPenColor( const QColor &color ) +{ + if ( labelPenColor_ == color ) + return; + + labelPenColor_ = color; + emit changed(); +} + +void KasResources::setLabelBgColor( const QColor &color ) +{ + if ( labelBgColor_ == color ) + return; + + labelBgColor_ = color; + emit changed(); +} + +void KasResources::setInactivePenColor( const QColor &color ) +{ + if ( inactivePenColor_ == color ) + return; + + inactivePenColor_ = color; + emit changed(); +} + +void KasResources::setInactiveBgColor( const QColor &color ) +{ + if ( inactiveBgColor_ == color ) + return; + + inactiveBgColor_ = color; + emit changed(); +} + +void KasResources::setActivePenColor( const QColor &color ) +{ + if ( activePenColor_ == color ) + return; + + activePenColor_ = color; + emit changed(); +} + +void KasResources::setActiveBgColor( const QColor &color ) +{ + if ( activeBgColor_ == color ) + return; + + activeBgColor_ = color; + emit changed(); +} + +void KasResources::setProgressColor( const QColor &color ) +{ + if ( progressColor_ == color ) + return; + + progressColor_ = color; + emit changed(); +} + +void KasResources::setAttentionColor( const QColor &color ) +{ + if ( attentionColor_ == color ) + return; + + attentionColor_ = color; + emit changed(); +} + +void KasResources::itemSizeChanged() +{ + actBg = KPixmap(); + inactBg = KPixmap(); +} + +KPixmap KasResources::activeBg() +{ + if ( actBg.isNull() ) { + actBg.resize( kasbar->itemExtent(), kasbar->itemExtent() ); + KPixmapEffect::gradient( actBg, + kasbar->colorGroup().light(), kasbar->colorGroup().mid(), + KPixmapEffect::DiagonalGradient ); + } + + return actBg; +} + +KPixmap KasResources::inactiveBg() +{ + if ( inactBg.isNull() ) { + inactBg.resize( kasbar->itemExtent(), kasbar->itemExtent() ); + KPixmapEffect::gradient( inactBg, + kasbar->colorGroup().mid(), kasbar->colorGroup().dark(), + KPixmapEffect::DiagonalGradient ); + } + + return inactBg; +} + diff --git a/kicker/extensions/kasbar/kasresources.h b/kicker/extensions/kasbar/kasresources.h new file mode 100644 index 000000000..44048bcc3 --- /dev/null +++ b/kicker/extensions/kasbar/kasresources.h @@ -0,0 +1,171 @@ +// -*- c++ -*- + +/* kasbar.h +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ + +#ifndef KASRESOURCES_H +#define KASRESOURCES_H + +#include <qbitmap.h> +#include <qcolor.h> +#include <qbrush.h> +#include <qpen.h> +#include <kpixmap.h> + +#include <qobject.h> +#include <qvaluevector.h> + +class KasBar; + +/** + * Central class that holds the graphical resources for the bar. + * + * @author Richard Moore, rich@kde.org + */ +class KasResources : public QObject +{ + Q_OBJECT + +public: + KasResources( KasBar *parent, const char *name=0 ); + virtual ~KasResources(); + + QColor labelPenColor() const { return labelPenColor_; } + QColor labelBgColor() const { return labelBgColor_; } + QColor inactivePenColor() const { return inactivePenColor_; } + QColor inactiveBgColor() const { return inactiveBgColor_; } + QColor activePenColor() const { return activePenColor_; } + QColor activeBgColor() const { return activeBgColor_; } + + QColor progressColor() const { return progressColor_; } + QColor attentionColor() const { return attentionColor_; } + + /** Accessor for the min icon (singleton). */ + QBitmap minIcon(); + + /** Accessor for the max icon (singleton). */ + QBitmap maxIcon(); + + /** Accessor for the shade icon (singleton). */ + QBitmap shadeIcon(); + + /** Accessor for the attention icon (singleton). */ + QBitmap attentionIcon(); + + /** Accessor for the modified icon (singleton). */ + QPixmap modifiedIcon(); + + /** Accessor for the micro min icon (singleton). */ + QPixmap microMinIcon(); + + /** Accessor for the micro max icon (singleton). */ + QPixmap microMaxIcon(); + + /** Accessor for the micro shade icon (singleton). */ + QPixmap microShadeIcon(); + + /** Accessor used by items to get the active bg fill. */ + KPixmap activeBg(); + + /** Accessor used by items to get the inactive bg fill. */ + KPixmap inactiveBg(); + + QValueVector<QPixmap> startupAnimation(); + +public slots: + void setLabelPenColor( const QColor &color ); + void setLabelBgColor( const QColor &color ); + void setInactivePenColor( const QColor &color ); + void setInactiveBgColor( const QColor &color ); + void setActivePenColor( const QColor &color ); + void setActiveBgColor( const QColor &color ); + + void setProgressColor( const QColor &color ); + void setAttentionColor( const QColor &color ); + + void itemSizeChanged(); + +signals: + void changed(); + +private: + KasBar *kasbar; + + QBitmap minPix; + QBitmap maxPix; + QBitmap shadePix; + QBitmap attentionPix; + QPixmap modifiedPix; + QPixmap microShadePix; + QPixmap microMaxPix; + QPixmap microMinPix; + + QColor labelPenColor_; + QColor labelBgColor_; + QColor activePenColor_; + QColor activeBgColor_; + QColor inactivePenColor_; + QColor inactiveBgColor_; + + QColor progressColor_; + QColor attentionColor_; + + KPixmap actBg; + KPixmap inactBg; + + QValueVector<QPixmap> startupFrames_; +}; + +#endif // KASRESOURCES_H + diff --git a/kicker/extensions/kasbar/kasstartupitem.cpp b/kicker/extensions/kasbar/kasstartupitem.cpp new file mode 100644 index 000000000..334edc836 --- /dev/null +++ b/kicker/extensions/kasbar/kasstartupitem.cpp @@ -0,0 +1,161 @@ +/* kasstartupitem.cpp +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +#include <qpainter.h> +#include <qbitmap.h> +#include <qdrawutil.h> +#include <qtimer.h> + +#include <kdebug.h> +#include <kglobal.h> +#include <kwin.h> +#include <kiconloader.h> +#include <kpixmap.h> +#include <kpixmapeffect.h> +#include <klocale.h> +#include <taskmanager.h> + +#include "kaspopup.h" + +#include "kasstartupitem.h" +#include "kasstartupitem.moc" + +KasStartupItem::KasStartupItem( KasBar *parent, Startup::Ptr startup ) + : KasItem( parent ), + startup_(startup), frame(0) +{ + setText( startup_->text() ); + setIcon( icon() ); + setShowFrame( false ); + setAnimation( resources()->startupAnimation() ); + + aniTimer = new QTimer( this ); + connect( aniTimer, SIGNAL( timeout() ), SLOT( aniTimerFired() ) ); + aniTimer->start( 100 ); +} + +KasStartupItem::~KasStartupItem() +{ +} + +QPixmap KasStartupItem::icon() const +{ + /** + * This icon stuff should all be handled by the task manager api, but isn't yet. + */ + QPixmap pixmap; + + switch( kasbar()->itemSize() ) { + case KasBar::Small: + /* ***** NOP ****** + pixmap = KGlobal::iconLoader()->loadIcon( startup_->icon(), + KIcon::NoGroup, + KIcon::SizeSmall ); + */ + break; + case KasBar::Medium: + pixmap = KGlobal::iconLoader()->loadIcon( startup_->icon(), + KIcon::NoGroup, + KIcon::SizeMedium ); + break; + case KasBar::Large: + pixmap = KGlobal::iconLoader()->loadIcon( startup_->icon(), + KIcon::NoGroup, + KIcon::SizeLarge ); + break; + case KasBar::Huge: + pixmap = KGlobal::iconLoader()->loadIcon( startup_->icon(), + KIcon::NoGroup, + KIcon::SizeHuge ); + break; + case KasBar::Enormous: + pixmap = KGlobal::iconLoader()->loadIcon( startup_->icon(), + KIcon::NoGroup, + KIcon::SizeEnormous ); + break; + default: + pixmap = KGlobal::iconLoader()->loadIcon( "error", + KIcon::NoGroup, + KIcon::SizeSmall ); + } + + return pixmap; +} + +void KasStartupItem::aniTimerFired() +{ + + if ( frame == 40 ) + frame = 0; + else + frame++; + + advanceAnimation(); +} + +void KasStartupItem::paint( QPainter *p ) +{ + p->save(); + + p->setClipRect( 0, 0, extent(), extent(), QPainter::CoordPainter ); + p->translate( extent()/2, extent()/2 ); + p->rotate( 9.0L * frame ); + p->scale( 0.7L, 0.7L ); + p->translate( -extent()/2, -extent()/2 ); + + KasItem::paint( p ); + + p->restore(); + paintAnimation( p ); +} + diff --git a/kicker/extensions/kasbar/kasstartupitem.h b/kicker/extensions/kasbar/kasstartupitem.h new file mode 100644 index 000000000..b8019f337 --- /dev/null +++ b/kicker/extensions/kasbar/kasstartupitem.h @@ -0,0 +1,97 @@ +/* kasstartupitem.h +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +// -*- c++ -*- + + +#ifndef KASSTARTUPITEM_H +#define KASSTARTUPITEM_H + +#include <qpixmap.h> +#include <qstring.h> +#include "kasitem.h" + +class Startup; +class KasPopup; +class QTimer; + +/** + * A KasItem that represents a single Startup. + */ +class KasStartupItem : public KasItem +{ + Q_OBJECT + +public: + KasStartupItem( KasBar *parent, Startup::Ptr startup ); + virtual ~KasStartupItem(); + + QPixmap icon() const; + Startup::Ptr startup() const { return startup_; } + + /** + * Reimplemented to paint the item. + */ + virtual void paint( QPainter *p ); + +protected slots: + void aniTimerFired(); + +private: + Startup::Ptr startup_; + QTimer *aniTimer; + int frame; +}; + +#endif // KASSTARTUPITEM_H + diff --git a/kicker/extensions/kasbar/kastasker.cpp b/kicker/extensions/kasbar/kastasker.cpp new file mode 100644 index 000000000..9c93db56c --- /dev/null +++ b/kicker/extensions/kasbar/kastasker.cpp @@ -0,0 +1,745 @@ +/* kastasker.cpp +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +#include <qapplication.h> +#include <qtimer.h> + +#include <kactionclasses.h> +#include <kconfig.h> +#include <kdebug.h> +#include <klocale.h> +#include <kpopupmenu.h> +#include <kiconloader.h> + +//#include <kconfiggroupsaver.h> + +#include <taskmanager.h> + +#include "kasaboutdlg.h" +#include "kastaskitem.h" +#include "kasprefsdlg.h" +#include "kasstartupitem.h" +#include "kasgroupitem.h" +#include "kasgrouper.h" +#include "kasclockitem.h" +#include "kasloaditem.h" + +#include "kastasker.h" +#include "kastasker.moc" + +static const int SWITCH_DESKTOPS_REGROUP_DELAY = 50; + +KasTasker::KasTasker( Orientation o, QWidget* parent, const char* name, WFlags f ) + : KasBar( o, parent, name, f ), + menu( 0 ), + conf( 0 ), + grouper( 0 ), + standalone_( false ), + enableThumbs_( true ), + embedThumbs_( false ), + thumbnailSize_( 0.2 ), + enableNotifier_( true ), + showModified_( true ), + showProgress_( false ), + showAllWindows_( true ), + thumbUpdateDelay_( 10 ), + groupWindows_( false ), + groupInactiveDesktops_( false ), + showAttention_( true ), + showClock_( false ), + clockItem(0), + showLoad_( false ), + loadItem(0) +{ + setAcceptDrops( true ); + connect(TaskManager::the(), SIGNAL(taskAdded(Task::Ptr)), SLOT(addTask(Task::Ptr))); + connect(TaskManager::the(), SIGNAL(taskRemoved(Task::Ptr)), SLOT(removeTask(Task::Ptr))); + connect(TaskManager::the(), SIGNAL(startupAdded(Startup::Ptr)), SLOT(addStartup(Startup::Ptr))); + connect(TaskManager::the(), SIGNAL(startupRemoved(Startup::Ptr)), SLOT(removeStartup(Startup::Ptr))); + connect(TaskManager::the(), SIGNAL(desktopChanged(int)), SLOT(refreshAllLater())); +// connect( manager, SIGNAL( windowChanged( Task::Ptr ) ), SLOT( refreshAllLater() ) ); + + connect( this, SIGNAL( itemSizeChanged( int ) ), SLOT( refreshAll() ) ); + + connect( this, SIGNAL( detachedPositionChanged(const QPoint &) ), SLOT( writeLayout() ) ); + connect( this, SIGNAL( directionChanged() ), SLOT( writeLayout() ) ); +} + +KasTasker::KasTasker( Orientation o, KasTasker *master, QWidget* parent, const char* name, WFlags f ) + : KasBar( o, master, parent, name, f ), + menu( 0 ), + conf( 0 ), + grouper( 0 ), + standalone_( master->standalone_ ), + enableThumbs_( master->enableThumbs_ ), + embedThumbs_( master->embedThumbs_ ), + thumbnailSize_( master->thumbnailSize_ ), + enableNotifier_( master->enableNotifier_ ), + showModified_( master->showModified_ ), + showProgress_( master->showProgress_ ), + showAllWindows_( master->showAllWindows_ ), + thumbUpdateDelay_( master->thumbUpdateDelay_ ), + groupWindows_( false ), + groupInactiveDesktops_( false ), + showAttention_( master->showAttention_ ), + showClock_( false ), + clockItem(0), + showLoad_( false ), + loadItem(0) +{ + setAcceptDrops( true ); +} + +KasTasker::~KasTasker() +{ + delete menu; + delete grouper; +} + +KPopupMenu *KasTasker::contextMenu() +{ + if ( !menu ) { + menu = new KPopupMenu; + + showAllWindowsAction = new KToggleAction( i18n("Show &All Windows"), KShortcut(), + this, "toggle_show_all_windows" ); + showAllWindowsAction->setChecked( showAllWindows() ); + showAllWindowsAction->plug( menu ); + connect( showAllWindowsAction, SIGNAL(toggled(bool)), SLOT(setShowAllWindows(bool)) ); + connect( this, SIGNAL(showAllWindowsChanged(bool)), showAllWindowsAction, SLOT(setChecked(bool)) ); + + groupWindowsAction = new KToggleAction( i18n("&Group Windows"), KShortcut(), + this, "toggle_group_windows" ); + groupWindowsAction->setChecked( groupWindows() ); + groupWindowsAction->plug( menu ); + connect( groupWindowsAction, SIGNAL(toggled(bool)), SLOT(setGroupWindows(bool)) ); + connect( this, SIGNAL(groupWindowsChanged(bool)), groupWindowsAction, SLOT(setChecked(bool)) ); + + showClockAction = new KToggleAction( i18n("Show &Clock"), KShortcut(), this, "toggle_show_clock" ); + showClockAction->setChecked( showClock() ); + showClockAction->plug( menu ); + connect( showClockAction, SIGNAL(toggled(bool)), SLOT(setShowClock(bool)) ); + connect( this, SIGNAL(showClockChanged(bool)), showClockAction, SLOT(setChecked(bool)) ); + + showLoadAction = new KToggleAction( i18n("Show &Load Meter"), KShortcut(), this, "toggle_show_load" ); + showLoadAction->setChecked( showLoad() ); + showLoadAction->plug( menu ); + connect( showLoadAction, SIGNAL(toggled(bool)), SLOT(setShowLoad(bool)) ); + connect( this, SIGNAL(showLoadChanged(bool)), showLoadAction, SLOT(setChecked(bool)) ); + + menu->insertSeparator(); + + if ( !standalone_ ) { + toggleDetachedAction = new KToggleAction( i18n("&Floating"), KShortcut(), this, "toggle_detached" ); + toggleDetachedAction->setChecked( isDetached() ); + toggleDetachedAction->plug( menu ); + connect( toggleDetachedAction, SIGNAL(toggled(bool)), SLOT(setDetached(bool)) ); + connect( this, SIGNAL(detachedChanged(bool)), toggleDetachedAction, SLOT(setChecked(bool)) ); + } + + rotateBarAction = new KAction( i18n("R&otate Bar"), QString("rotate"), KShortcut(), + this, SLOT( toggleOrientation() ), + this, "rotate_bar" ); + rotateBarAction->plug( menu ); + connect( this, SIGNAL(detachedChanged(bool)), rotateBarAction, SLOT(setEnabled(bool)) ); + connect( rotateBarAction, SIGNAL(activated()), SLOT(writeConfigLater()) ); + + menu->insertItem( SmallIcon("reload"), i18n("&Refresh"), this, SLOT( refreshAll() ) ); + + menu->insertSeparator(); + + menu->insertItem( SmallIcon("configure"), i18n("&Configure Kasbar..."), this, SLOT( showPreferences() ) ); + + // Help menu + KPopupMenu *help = new KPopupMenu; + help->insertItem( SmallIcon("about"), i18n("&About Kasbar"), this, SLOT( showAbout() ) ); + menu->insertItem( SmallIcon("help"), i18n("&Help"), help ); + + if ( standalone_ ) { + menu->insertSeparator(); + menu->insertItem( SmallIcon("exit"), i18n("&Quit"), qApp, SLOT( quit() ) ); + } + } + + return menu; +} + +KasTasker *KasTasker::createChildBar( Orientation o, QWidget *parent, const char *name ) +{ + KasTasker *child = new KasTasker( o, this, parent, name ); + child->conf = this->conf; + return child; +} + +KasTaskItem *KasTasker::findItem( Task::Ptr t ) +{ + KasTaskItem *result = 0; + for ( uint i = 0; i < itemCount(); i++ ) { + if ( itemAt(i)->inherits( "KasTaskItem" ) ) { + KasTaskItem *curr = static_cast<KasTaskItem *> (itemAt( i )); + if ( curr->task() == t ) { + result = curr; + break; + } + } + } + return result; +} + +KasStartupItem *KasTasker::findItem( Startup::Ptr s ) +{ + KasStartupItem *result = 0; + for ( uint i = 0; i < itemCount(); i++ ) { + if ( itemAt(i)->inherits( "KasStartupItem" ) ) { + KasStartupItem *curr = static_cast<KasStartupItem *> (itemAt( i )); + if ( curr->startup() == s ) { + result = curr; + break; + } + } + } + return result; +} + +void KasTasker::addTask( Task::Ptr t ) +{ + KasItem *item = 0; + + if ( onlyShowMinimized_ && !t->isMinimized() ) + return; + + if ( showAllWindows_ || t->isOnCurrentDesktop() ) { + if ( grouper ) + item = grouper->maybeGroup( t ); + if ( !item ) { + item = new KasTaskItem( this, t ); + append( item ); + } + + // + // Ensure the window manager knows where we put the icon. + // + QPoint p = mapToGlobal( itemPos( item ) ); + QSize s( itemExtent(), itemExtent() ); + t->publishIconGeometry( QRect( p, s ) ); + } +} + +void KasTasker::removeTask( Task::Ptr t ) +{ + KasTaskItem *i = findItem( t ); + if ( !i ) + return; + + remove( i ); + refreshIconGeometry(); +} + +KasGroupItem *KasTasker::convertToGroup( Task::Ptr t ) +{ + KasTaskItem *ti = findItem( t ); + int i = indexOf( ti ); + KasGroupItem *gi = new KasGroupItem( this ); + gi->addTask( t ); + removeTask( t ); + insert( i, gi ); + + connect(TaskManager::the(), SIGNAL(taskRemoved(Task::Ptr)), gi, SLOT(removeTask(Task::Ptr))); + + return gi; +} + +void KasTasker::moveToMain( KasGroupItem *gi, Task::Ptr t ) +{ + int i = indexOf( gi ); + if ( i != -1 ) { + remove( gi ); + insert( i, new KasTaskItem( this, t ) ); + } + else + append( new KasTaskItem( this, t ) ); + + refreshIconGeometry(); +} + +void KasTasker::moveToMain( KasGroupItem *gi ) +{ + bool updates = isUpdatesEnabled(); + setUpdatesEnabled( false ); + + int i = indexOf( gi ); + + for ( int ti = 0 ; ti < gi->taskCount() ; ti++ ) { + Task::Ptr t = gi->task( ti ); + insert( i, new KasTaskItem( this, t ) ); + } + + gi->hidePopup(); + remove( gi ); + + setUpdatesEnabled( updates ); + updateLayout(); +} + +void KasTasker::addStartup( Startup::Ptr s ) +{ + if ( enableNotifier_ ) + append( new KasStartupItem( this, s ) ); +} + +void KasTasker::removeStartup( Startup::Ptr s ) +{ + KasStartupItem *i = findItem( s ); + remove( i ); +} + +void KasTasker::refreshAll() +{ + bool updates = isUpdatesEnabled(); + setUpdatesEnabled( false ); + + clear(); + + if ( showClock_ ) { + showClock_ = false; + setShowClock( true ); + } + + if ( showLoad_ ) { + showLoad_ = false; + setShowLoad( true ); + } + + Task::Dict l = TaskManager::the()->tasks(); + for ( Task::Dict::iterator t = l.begin(); t != l.end(); ++t ) { + addTask( t.data() ); + } + + setUpdatesEnabled( updates ); + updateLayout(); +} + +void KasTasker::refreshAllLater() +{ + QTimer::singleShot( SWITCH_DESKTOPS_REGROUP_DELAY, this, SLOT( refreshAll() ) ); +} + +void KasTasker::refreshIconGeometry() +{ + for ( uint i = 0; i < itemCount(); i++ ) { + if ( itemAt(i)->inherits( "KasTaskItem" ) ) { + KasTaskItem *curr = static_cast<KasTaskItem *> (itemAt( i )); + + QPoint p = mapToGlobal( itemPos( curr ) ); + QSize s( itemExtent(), itemExtent() ); + curr->task()->publishIconGeometry( QRect( p, s ) ); + } + } +} + +void KasTasker::setNotifierEnabled( bool enable ) +{ + enableNotifier_ = enable; +} + +void KasTasker::setThumbnailSize( double size ) +{ + thumbnailSize_ = size; +} + +void KasTasker::setThumbnailSize( int percent ) +{ + double amt = (double) percent / 100.0; + setThumbnailSize( amt ); +} + +void KasTasker::setThumbnailsEnabled( bool enable ) +{ + enableThumbs_ = enable; +} + +void KasTasker::setShowModified( bool enable ) +{ + showModified_ = enable; + update(); +} + +void KasTasker::setShowProgress( bool enable ) +{ + showProgress_ = enable; + update(); +} + +void KasTasker::setShowAttention( bool enable ) +{ + showAttention_ = enable; + update(); +} + +void KasTasker::setShowAllWindows( bool enable ) +{ + if ( showAllWindows_ != enable ) { + showAllWindows_ = enable; + refreshAll(); + if ( !showAllWindows_ ) { + connect(TaskManager::the(), SIGNAL(desktopChanged(int)), SLOT(refreshAll())); +// connect( manager, SIGNAL( windowChanged( Task::Ptr ) ), SLOT( refreshAll() ) ); + } + else { + disconnect(TaskManager::the(), SIGNAL(desktopChanged(int)), this, SLOT(refreshAll())); +// disconnect( manager, SIGNAL( windowChanged( Task::Ptr ) ), this, SLOT( refreshAll() ) ); + } + + emit showAllWindowsChanged( enable ); + } +} + +void KasTasker::setThumbnailUpdateDelay( int secs ) +{ + thumbUpdateDelay_ = secs; +} + +void KasTasker::setEmbedThumbnails( bool enable ) +{ + if ( embedThumbs_ == enable ) + return; + + embedThumbs_ = enable; + update(); +} + +void KasTasker::setShowClock( bool enable ) +{ + if ( showClock_ == enable ) + return; + + showClock_ = enable; + + if ( enable ) { + clockItem = new KasClockItem( this ); + insert( 0, clockItem ); + } + else if ( clockItem ) { + remove( clockItem ); + clockItem = 0; + } + + + emit showClockChanged( showClock_ ); + writeConfigLater(); +} + +void KasTasker::setShowLoad( bool enable ) +{ + if ( showLoad_ == enable ) + return; + + showLoad_ = enable; + + if ( enable ) { + loadItem = new KasLoadItem( this ); + insert( showClock_ ? 1 : 0, loadItem ); + } + else if ( loadItem ) { + remove( loadItem ); + loadItem = 0; + } + + emit showLoadChanged( showLoad_ ); + writeConfigLater(); +} + +void KasTasker::setGroupWindows( bool enable ) +{ + if ( groupWindows_ != enable ) { + groupWindows_ = enable; + if ( enable && (!grouper) ) + grouper = new KasGrouper( this ); + refreshAll(); + + emit groupWindowsChanged( enable ); + } +} + +void KasTasker::setGroupInactiveDesktops( bool enable ) +{ + if ( groupInactiveDesktops_ != enable ) { + groupInactiveDesktops_ = enable; + if ( enable && (!grouper) ) + grouper = new KasGrouper( this ); + + refreshAll(); + } +} + +void KasTasker::setOnlyShowMinimized( bool enable ) +{ + if ( onlyShowMinimized_ != enable ) { + onlyShowMinimized_ = enable; + refreshAll(); + } +} + +void KasTasker::setStandAlone( bool enable ) +{ + standalone_ = enable; +} + +// +// Configuration Loader +// + +void KasTasker::setConfig( KConfig *conf ) +{ + this->conf = conf; +} + +void KasTasker::readConfig() +{ + readConfig(conf); +} + +void KasTasker::writeConfigLater() +{ + QTimer::singleShot( 10, this, SLOT( writeConfig() ) ); +} + +void KasTasker::writeConfig() +{ + writeConfig(conf); +} + +void KasTasker::readConfig( KConfig *conf ) +{ + if ( !conf ) { + kdWarning() << "KasTasker::readConfig() got a null KConfig" << endl; + return; + } + + if ( master() ) { + kdWarning() << "KasTasker::readConfig() for child bar" << endl; + return; + } + + bool updates = isUpdatesEnabled(); + setUpdatesEnabled( false ); + + + // + // Appearance Settings. + // + KConfigGroupSaver saver( conf, "Appearance" ); + + int ext = conf->readNumEntry( "ItemExtent", -1 ); + if ( ext > 0 ) + setItemExtent( ext ); + else + setItemSize( conf->readNumEntry( "ItemSize", KasBar::Medium ) ); + + setTint( conf->readBoolEntry( "EnableTint", false ) ); + setTintColor( conf->readColorEntry( "TintColor", &Qt::black ) ); + setTintAmount( conf->readDoubleNumEntry( "TintAmount", 0.1 ) ); + setTransparent( conf->readBoolEntry( "Transparent", true ) ); + setPaintInactiveFrames( conf->readBoolEntry( "PaintInactiveFrames", true ) ); + + // + // Painting colors + // + conf->setGroup("Colors"); + + KasResources *res = resources(); + res->setLabelPenColor( conf->readColorEntry( "LabelPenColor", &Qt::white ) ); + res->setLabelBgColor( conf->readColorEntry( "LabelBgColor", &Qt::black ) ); + res->setInactivePenColor( conf->readColorEntry( "InactivePenColor", &Qt::black ) ); + res->setInactiveBgColor( conf->readColorEntry( "InactiveBgColor", &Qt::white ) ); + res->setActivePenColor( conf->readColorEntry( "ActivePenColor", &Qt::black ) ); + res->setActiveBgColor( conf->readColorEntry( "ActiveBgColor", &Qt::white ) ); + res->setProgressColor( conf->readColorEntry( "ProgressColor", &Qt::green ) ); + res->setAttentionColor( conf->readColorEntry( "AttentionColor", &Qt::red ) ); + + // + // Thumbnail Settings + // + conf->setGroup("Thumbnails"); + setThumbnailsEnabled( conf->readBoolEntry( "Thumbnails", true ) ); + setThumbnailSize( conf->readDoubleNumEntry( "ThumbnailSize", 0.2 ) ); + setThumbnailUpdateDelay( conf->readNumEntry( "ThumbnailUpdateDelay", 10 ) ); + setEmbedThumbnails( conf->readBoolEntry( "EmbedThumbnails", false ) ); + + // + // Behaviour Settings + // + conf->setGroup("Behaviour"); + setNotifierEnabled( conf->readBoolEntry( "StartupNotifier", true ) ); + setShowModified( conf->readBoolEntry( "ModifiedIndicator", true ) ); + setShowProgress( conf->readBoolEntry( "ProgressIndicator", false ) ); + setShowAttention( conf->readBoolEntry( "AttentionIndicator", true ) ); + setShowAllWindows( conf->readBoolEntry( "ShowAllWindows", true ) ); + setGroupWindows( conf->readBoolEntry( "GroupWindows", true ) ); + setGroupInactiveDesktops( conf->readBoolEntry( "GroupInactiveDesktops", false ) ); + setOnlyShowMinimized( conf->readBoolEntry( "OnlyShowMinimized", false ) ); + + // + // Layout Settings + // + conf->setGroup("Layout"); + + setDirection( (Direction) conf->readNumEntry( "Direction", QBoxLayout::LeftToRight ) ); + setOrientation( (Qt::Orientation) conf->readNumEntry( "Orientation", Horizontal ) ); + setMaxBoxes( conf->readUnsignedNumEntry( "MaxBoxes", 0 ) ); + + QPoint pos(100, 100); + setDetachedPosition( conf->readPointEntry( "DetachedPosition", &pos ) ); + setDetached( conf->readBoolEntry( "Detached", false ) ); + + // + // Custom Items + // + conf->setGroup("Custom Items"); + setShowClock( conf->readBoolEntry( "ShowClock", true ) ); + setShowLoad( conf->readBoolEntry( "ShowLoad", true ) ); + + // fillBg = conf->readBoolEntry( "FillIconBackgrounds", /*true*/ false ); + // fillActiveBg = conf->readBoolEntry( "FillActiveIconBackground", true ); + // enablePopup = conf->readBoolEntry( "EnablePopup", true ); + + setUpdatesEnabled( updates ); + emit configChanged(); +} + +void KasTasker::writeConfig( KConfig *conf ) +{ + if ( !conf ) { + kdWarning() << "KasTasker::writeConfig() got a null KConfig" << endl; + return; + } + + if ( master() ) { + kdWarning() << "KasTasker::writeConfig() for child bar" << endl; + return; + } + + conf->setGroup("Appearance"); + conf->writeEntry( "ItemSize", itemSize() ); + conf->writeEntry( "ItemExtent", itemExtent() ); + conf->writeEntry( "Transparent", isTransparent() ); + conf->writeEntry( "EnableTint", hasTint() ); + conf->writeEntry( "TintColor", tintColor() ); + conf->writeEntry( "TintAmount", tintAmount() ); + conf->writeEntry( "PaintInactiveFrames", paintInactiveFrames() ); + + conf->setGroup("Colors"); + conf->writeEntry( "LabelPenColor", resources()->labelPenColor() ); + conf->writeEntry( "LabelBgColor", resources()->labelBgColor() ); + conf->writeEntry( "InactivePenColor", resources()->inactivePenColor() ); + conf->writeEntry( "InactiveBgColor", resources()->inactiveBgColor() ); + conf->writeEntry( "ActivePenColor", resources()->activePenColor() ); + conf->writeEntry( "ActiveBgColor", resources()->activeBgColor() ); + conf->writeEntry( "ProgressColor", resources()->progressColor() ); + conf->writeEntry( "AttentionColor", resources()->attentionColor() ); + + conf->setGroup("Thumbnails"); + conf->writeEntry( "Thumbnails", thumbnailsEnabled() ); + conf->writeEntry( "ThumbnailSize", thumbnailSize() ); + conf->writeEntry( "ThumbnailUpdateDelay", thumbnailUpdateDelay() ); + conf->writeEntry( "EmbedThumbnails", embedThumbnails() ); + + conf->setGroup("Behaviour"); + conf->writeEntry( "StartupNotifier", notifierEnabled() ); + conf->writeEntry( "ModifiedIndicator", showModified() ); + conf->writeEntry( "ProgressIndicator", showProgress() ); + conf->writeEntry( "AttentionIndicator", showAttention() ); + conf->writeEntry( "ShowAllWindows", showAllWindows() ); + conf->writeEntry( "GroupWindows", groupWindows() ); + conf->writeEntry( "GroupInactiveDesktops", groupInactiveDesktops() ); + conf->writeEntry( "OnlyShowMinimized", onlyShowMinimized() ); + + conf->setGroup("Layout"); + conf->writeEntry( "Orientation", orientation() ); + conf->writeEntry( "Direction", direction() ); + conf->writeEntry( "Detached", isDetached() ); + + conf->setGroup("Custom Items"); + conf->writeEntry( "ShowClock", showClock() ); + conf->writeEntry( "ShowLoad", showLoad() ); +} + +void KasTasker::writeLayout() +{ + if ( !conf ) + return; + + conf->setGroup("Layout"); + conf->writeEntry( "Orientation", orientation() ); + conf->writeEntry( "Direction", direction() ); + conf->writeEntry( "Detached", isDetached() ); + conf->writeEntry( "DetachedPosition", detachedPosition() ); + conf->sync(); +} + +void KasTasker::showPreferences() +{ + KasPrefsDialog *dlg = new KasPrefsDialog( this ); + dlg->exec(); + delete dlg; + + readConfig(); +} + +void KasTasker::showAbout() +{ + KasAboutDialog *dlg = new KasAboutDialog( 0 ); + dlg->exec(); + delete dlg; +} + diff --git a/kicker/extensions/kasbar/kastasker.h b/kicker/extensions/kasbar/kastasker.h new file mode 100644 index 000000000..1379c8d8c --- /dev/null +++ b/kicker/extensions/kasbar/kastasker.h @@ -0,0 +1,280 @@ +// -*- c++ -*- + +/* kastasker.h +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ + +#ifndef KASTASKER_H +#define KASTASKER_H + +#include "kasbar.h" + +#include <kdemacros.h> +#include <taskmanager.h> + +class KConfig; +class KPixmap; +class KPopupMenu; +class KAction; +class KToggleAction; + +class Task; +class Startup; + +class KasTaskItem; +class KasStartupItem; +class KasGroupItem; +class KasTasker; +class KasGrouper; + +/** + * A KasBar that provides a taskbar using the TaskManager API. + * + * @author Richard Moore, rich@kde.org + */ +class KDE_EXPORT KasTasker : public KasBar +{ + Q_OBJECT + Q_PROPERTY( bool isTopLevel READ isTopLevel ) + Q_PROPERTY( bool showClock READ showClock ) + Q_PROPERTY( bool showLoad READ showLoad ) + +public: + /** Create a KasTasker widget. */ + KasTasker( Orientation o, QWidget* parent = 0, const char* name = 0, WFlags f = 0 ); + + /** + * Create a KasTasker widget that is slaved to another KasTasker. The + * created widget will inherit the settings of the parent, but will + * not connect to the signals of the TaskManager. + */ + KasTasker( Orientation o, KasTasker *master, + QWidget *parent=0, const char *name=0, WFlags f=0 ); + + /** Cleans up. */ + virtual ~KasTasker(); + + /** Factory method that returns the default menu for items in the bar. */ + virtual KPopupMenu *contextMenu(); + + virtual KasTasker *createChildBar( Orientation o, QWidget *parent, const char *name=0 ); + + /** + * Returns true if this is the top KasTasker. Note that it is possible for + * the top KasTasker to be a child of another KasBar derived class, so + * this can return a different result to KasBar::isTopLevel(). + */ + bool isTopLevel() const { return dynamic_cast<KasTasker *>( KasBar::master() ) ? true : false; } + KasTasker *master() const { return dynamic_cast<KasTasker *>( KasBar::master() ); } + + /** Finds the item representing a task (if there is one). */ + KasTaskItem *findItem( Task::Ptr ); + + /** Finds the item representing a startup (if there is one). */ + KasStartupItem *findItem( Startup::Ptr s ); + + /** Returns true iff thumbnails are enabled. */ + bool thumbnailsEnabled() const { return enableThumbs_; } + + /** Returns true iff thumbnails should be shown in the boxes instead of icons. */ + bool embedThumbnails() const { return embedThumbs_; } + + bool showClock() const { return showClock_; } + bool showLoad() const { return showLoad_; } + + /** Returns the proportions of the window thumbnails. */ + double thumbnailSize() const { return thumbnailSize_; } + + /** Returns true iff the startup notifier is enabled. */ + bool notifierEnabled() const { return enableNotifier_; } + + /** Returns true iff the modified flag should be shown. */ + bool showModified() const { return showModified_; } + + /** Returns true iff a progress bar should be shown for progress windows. */ + bool showProgress() const { return showProgress_; } + + /** Returns true iff we should indicate when a window demands attention. */ + bool showAttention() const { return showAttention_; } + + /** Returns true iff windows from all desktops should be displayed. */ + bool showAllWindows() const { return showAllWindows_; } + + /** Returns the delay between thumbnail updates (in seconds). */ + int thumbnailUpdateDelay() const { return thumbUpdateDelay_; } + + /** Returns true iff windows should be grouped together. */ + bool groupWindows() const { return groupWindows_; } + + /** Returns true iff windows on inactive desktops should be grouped together. */ + bool groupInactiveDesktops() const { return groupInactiveDesktops_; } + + /** Returns true iff we should only show windows that are minimized. */ + bool onlyShowMinimized() const { return onlyShowMinimized_; } + + /** Returns true if this bar is floating. */ + bool isStandAlone() const { return standalone_; } + + // + // Internal stuff + // + + /** + * Converts the item for a task into a group item to which additional + * tasks can be added. + */ + KasGroupItem *convertToGroup( Task::Ptr t ); + + /** Moves an item from a group into the main bar. */ + void moveToMain( KasGroupItem *gi, Task::Ptr t ); + + /** Moves all the items from a group into the main bar and removes the group. */ + void moveToMain( KasGroupItem *gi ); + +public slots: + /** Adds a task to the bar. */ + void addTask( Task::Ptr ); + + /** Removes a task from the bar. */ + void removeTask( Task::Ptr ); + + /** Adds a startup item to the bar. */ + void addStartup( Startup::Ptr ); + + /** Removes a startup item from the bar. */ + void removeStartup( Startup::Ptr ); + + void refreshAll(); + void refreshAllLater(); + void refreshIconGeometry(); + + void setNotifierEnabled( bool enable ); + void setShowModified( bool enable ); + void setShowProgress( bool enable ); + void setShowAttention( bool enable ); + + void setShowAllWindows( bool enable ); + void setGroupWindows( bool enable ); + void setGroupInactiveDesktops( bool enable ); + void setOnlyShowMinimized( bool enable ); + + void setThumbnailSize( double size ); + void setThumbnailSize( int percent ); + void setThumbnailsEnabled( bool enable ); + void setThumbnailUpdateDelay( int secs ); + void setEmbedThumbnails( bool enable ); + + void setShowClock( bool enable ); + void setShowLoad( bool enable ); + + void showPreferences(); + void showAbout(); + + /** Sets the current KConfig object. */ + void setConfig( KConfig *config ); + KConfig *config() const { return conf; } + + /** Reads the settings from the current KConfig. */ + void readConfig(); + void writeConfig(); + void writeConfigLater(); + void writeLayout(); + + /** Writes the settings of this bar to the specified KConfig. */ + void writeConfig( KConfig *conf ); + + void setStandAlone( bool enable ); + +signals: + void showAllWindowsChanged( bool ); + void groupWindowsChanged( bool ); + void showClockChanged( bool ); + void showLoadChanged( bool ); + +protected slots: + /** Load settings from the specified configuration. */ + void readConfig( KConfig *conf ); + +private: + KPopupMenu *menu; + KConfig *conf; + KasGrouper *grouper; + KToggleAction *toggleDetachedAction; + KToggleAction *showAllWindowsAction; + KToggleAction *groupWindowsAction; + KToggleAction *showClockAction; + KToggleAction *showLoadAction; + KAction *rotateBarAction; + bool standalone_; + + bool passive_; + bool enableThumbs_; + bool embedThumbs_; + double thumbnailSize_; + bool enableNotifier_; + bool showModified_; + bool showProgress_; + bool showAllWindows_; + int thumbUpdateDelay_; + bool groupWindows_; + bool groupInactiveDesktops_; + bool showAttention_; + bool onlyShowMinimized_; + bool showClock_; + KasItem *clockItem; + bool showLoad_; + KasItem *loadItem; +}; + +#endif // KASTASKER_H + diff --git a/kicker/extensions/kasbar/kastaskitem.cpp b/kicker/extensions/kasbar/kastaskitem.cpp new file mode 100644 index 000000000..d21d5ccc6 --- /dev/null +++ b/kicker/extensions/kasbar/kastaskitem.cpp @@ -0,0 +1,510 @@ +/* kastaskitem.cpp +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +#include <errno.h> + +#include <qbitmap.h> +#include <qimage.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qmetaobject.h> +#include <qpainter.h> +#include <qregexp.h> +#include <qtabwidget.h> +#include <qtextview.h> +#include <qtimer.h> +#include <qvbox.h> + +#include <kdebug.h> +#include <kdialog.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <klistview.h> +#include <klocale.h> +#include <kpassivepopup.h> +#include <kpopupmenu.h> +#include <kprocess.h> +#include <dcopclient.h> +#include <kapplication.h> + +#include <taskmanager.h> +#include <taskrmbmenu.h> + +#include "kastasker.h" +#include "kastaskpopup.h" +#include "kastaskitem.h" +#include "kasbarextension.h" + +#define Icon(x) KGlobal::iconLoader()->loadIcon( x, KIcon::NoGroup, KIcon::SizeMedium ) + +static const int CHECK_ATTENTION_DELAY = 2000; + +KasTaskItem::KasTaskItem( KasTasker *parent, Task::Ptr task ) + : KasItem( parent ), + task_(task), + thumbTimer(0), + attentionTimer(0) +{ + setIcon( icon() ); + setAttention( task->demandsAttention() ); + updateTask(false); + + connect( task, SIGNAL( changed(bool) ), this, SLOT( updateTask(bool) ) ); + connect( task, SIGNAL( activated() ), this, SLOT( startAutoThumbnail() ) ); + connect( task, SIGNAL( deactivated() ), this, SLOT( stopAutoThumbnail() ) ); + connect( task, SIGNAL( iconChanged() ), this, SLOT( iconChanged() ) ); + connect( task, SIGNAL( thumbnailChanged() ), this, SLOT( iconChanged() ) ); + + connect( this, SIGNAL(leftButtonClicked(QMouseEvent *)), SLOT(toggleActivateAction()) ); + connect( this, SIGNAL(rightButtonClicked(QMouseEvent *)), SLOT(showWindowMenuAt(QMouseEvent *) ) ); + + attentionTimer = new QTimer( this, "attentionTimer" ); + connect( attentionTimer, SIGNAL( timeout() ), SLOT( checkAttention() ) ); + attentionTimer->start( CHECK_ATTENTION_DELAY ); +} + +KasTaskItem::~KasTaskItem() +{ +} + +KasTasker *KasTaskItem::kasbar() const +{ + return static_cast<KasTasker *> (KasItem::kasbar()); +} + +QPixmap KasTaskItem::icon() +{ + int sizes[] = { KIcon::SizeEnormous, + KIcon::SizeHuge, + KIcon::SizeLarge, + KIcon::SizeMedium, + KIcon::SizeSmall }; + + if ( kasbar()->embedThumbnails() && task_->hasThumbnail() ) { + usedIconLoader = true; + + QPixmap thumb = task_->thumbnail(); + QSize sz = thumb.size(); + sz.scale( sizes[kasbar()->itemSize()], sizes[kasbar()->itemSize()], QSize::ScaleMin ); + + QImage img = thumb.convertToImage(); + img = img.smoothScale( sz ); + + bool ok = thumb.convertFromImage( img ); + if ( ok ) + return thumb; + } + + usedIconLoader = false; + QPixmap p = task_->bestIcon( sizes[kasbar()->itemSize()], usedIconLoader ); + if ( !p.isNull() ) + return p; + + return task_->icon( sizes[kasbar()->itemSize()], sizes[kasbar()->itemSize()], true ); +} + +void KasTaskItem::iconChanged() +{ + iconHasChanged = true; + setIcon( icon() ); + update(); +} + +void KasTaskItem::checkAttention() +{ + setAttention( task_->demandsAttention() ); +} + +void KasTaskItem::updateTask(bool geometryChangeOnly) +{ + if (geometryChangeOnly) + { + return; + } + + bool updates = kasbar()->isUpdatesEnabled(); + kasbar()->setUpdatesEnabled( false ); + + setProgress( kasbar()->showProgress() ? 0 : -1 ); + setText( task_->visibleIconicName() ); + setModified( task_->isModified() ); + setActive( task_->isActive() ); + + kasbar()->setUpdatesEnabled( updates ); + update(); +} + +void KasTaskItem::paint( QPainter *p ) +{ + KasItem::paint( p ); + + KasResources *res = resources(); + QColor c = task_->isActive() ? res->activePenColor() : res->inactivePenColor(); + p->setPen( c ); + + // + // Overlay the small icon if the icon has changed, we have space, + // and we are using a KIconLoader icon rather than one from the NET props. + // This only exists because we are almost always using the icon loader for + // large icons. + // + KasTasker *kas = kasbar(); + bool haveSpace = ( kas->itemSize() != KasBar::Small ) + && ( kas->itemSize() != KasBar::Medium ); + + if ( usedIconLoader && iconHasChanged && haveSpace ) { + QPixmap pix = icon(); + int x = (extent() - 4 - pix.width()) / 2; + QPixmap overlay = task_->pixmap(); + p->drawPixmap( x-4+pix.width()-overlay.width(), 18, overlay ); + } + + // + // Draw window state. + // + if( task_->isIconified() ) + paintStateIcon( p, StateIcon ); + else if ( task_->isShaded() ) + paintStateIcon( p, StateShaded ); + else + paintStateIcon( p, StateNormal ); + + // + // Draw desktop number. + // + + // Check if we only have one desktop + bool oneDesktop = (TaskManager::the()->numberOfDesktops() == 1) ? true : false; + + QString deskStr; + if ( task_->isOnAllDesktops() ) + deskStr = i18n( "All" ); + else + deskStr.setNum( task_->desktop() ); + + + if ( kas->itemSize() != KasBar::Small ) { + // Medium and Large modes + if ( !oneDesktop ) + p->drawText( extent()-fontMetrics().width(deskStr)-3, 15+fontMetrics().ascent(), deskStr ); + + // Draw document state. + if ( kas->showModified() ) + paintModified( p ); + } + else { + // Small mode + if ( !oneDesktop ) + p->drawText( extent()-fontMetrics().width(deskStr)-2, 13+fontMetrics().ascent(), deskStr ); + } +} + +void KasTaskItem::toggleActivateAction() +{ + hidePopup(); + + if ( task_->isActive() && task_->isShaded() ) { + task_->setShaded( false ); + } + else { + task_->activateRaiseOrIconify(); + } +} + +void KasTaskItem::showWindowMenuAt( QMouseEvent *ev ) +{ + hidePopup(); + showWindowMenuAt( ev->globalPos() ); +} + +KasPopup *KasTaskItem::createPopup() +{ + KasPopup *pop = new KasTaskPopup( this ); + pop->adjustSize(); + return pop; +} + +void KasTaskItem::dragOverAction() +{ + if ( !task_->isOnCurrentDesktop() ) + task_->toCurrentDesktop(); + if ( task_->isShaded() ) + task_->setShaded( false ); + if ( task_->isIconified() ) + task_->restore(); + if ( !task_->isActive() ) + task_->activate(); +} + +void KasTaskItem::startAutoThumbnail() +{ + if ( thumbTimer ) + return; + if ( !kasbar()->thumbnailsEnabled() ) + return; + + if ( kasbar()->thumbnailUpdateDelay() > 0 ) { + thumbTimer = new QTimer( this, "thumbTimer" ); + connect( thumbTimer, SIGNAL( timeout() ), SLOT( refreshThumbnail() ) ); + + thumbTimer->start( kasbar()->thumbnailUpdateDelay() * 1000 ); + } + + QTimer::singleShot( 200, this, SLOT( refreshThumbnail() ) ); +} + +void KasTaskItem::stopAutoThumbnail() +{ + if ( !thumbTimer ) + return; + + delete thumbTimer; + thumbTimer = 0; +} + +void KasTaskItem::refreshThumbnail() +{ + if ( !kasbar()->thumbnailsEnabled() ) + return; + if ( !task_->isActive() ) + return; + + // TODO: Check if the popup obscures the window + KasItem *i = kasbar()->itemUnderMouse(); + if ( i && i->isShowingPopup() ) { + QTimer::singleShot( 200, this, SLOT( refreshThumbnail() ) ); + return; + } + + task_->setThumbnailSize( kasbar()->thumbnailSize() ); + task_->updateThumbnail(); +} + +void KasTaskItem::showWindowMenuAt( QPoint p ) +{ + TaskRMBMenu *tm = new TaskRMBMenu(task_, true, kasbar()); + tm->insertItem( i18n("To &Tray" ), this, SLOT( sendToTray() ) ); + tm->insertSeparator(); + tm->insertItem( i18n("&Kasbar"), kasbar()->contextMenu() ); + tm->insertSeparator(); + tm->insertItem( i18n("&Properties" ), this, SLOT( showPropertiesDialog() ) ); + + mouseLeave(); + kasbar()->updateMouseOver(); + + tm->exec( p ); +} + +void KasTaskItem::sendToTray() +{ + QString s; + s.setNum( task_->window() ); + + KProcess proc; + proc << "ksystraycmd"; + proc << "--wid" << s << "--hidden"; + + bool ok = proc.start( KProcess::DontCare ); + if ( !ok ) { + kdWarning(1345) << "Unable to launch ksystraycmd" << endl; + KPassivePopup::message( i18n("Could Not Send to Tray"), + i18n("%1").arg(strerror(errno)), + Icon("error"), + kasbar() ); + return; + } + + proc.detach(); +} + +void KasTaskItem::showPropertiesDialog() +{ + // + // Create Dialog + // + QDialog *dlg = new QDialog( /*kasbar()*/0L, "task_props", false ); + + // + // Title + // + KPopupTitle *title = new KPopupTitle( dlg, "title" ); + dlg->setCaption( i18n("Task Properties") ); + title->setText( i18n("Task Properties") ); + title->setIcon( icon() ); + + // + // Tabbed View + // + QTabWidget *tabs = new QTabWidget( dlg ); + tabs->addTab( createX11Props( tabs ), i18n("General") ); + tabs->addTab( createTaskProps( task_, tabs ), i18n("Task") ); + + tabs->addTab( createTaskProps( this, tabs ), i18n("Item") ); + tabs->addTab( createTaskProps( kasbar(), tabs, false ), i18n("Bar") ); + +#if 0 + tabs->addTab( createNETProps( tabs ), i18n("NET") ); +#endif + + // + // Layout Dialog + // + QVBoxLayout *vbl = new QVBoxLayout( dlg, KDialog::marginHint(), KDialog::spacingHint() ); + vbl->addWidget( title ); + vbl->addWidget( tabs ); + + dlg->resize( 470, 500 ); + dlg->show(); + +} + +QWidget *KasTaskItem::createTaskProps( QObject *target, QWidget *parent, bool recursive ) +{ + QVBox *vb = new QVBox( parent ); + vb->setSpacing( KDialog::spacingHint() ); + vb->setMargin( KDialog::marginHint() ); + + // Create List View + KListView *taskprops = new KListView( vb, "props_view" ); + taskprops->setResizeMode( QListView::LastColumn ); + taskprops->addColumn( i18n("Property"), 0 ); + taskprops->addColumn( i18n("Type"), 0 ); + taskprops->addColumn( i18n("Value") ); + + // Create List Items + QMetaObject *mo = target->metaObject(); + for ( int i = 0; i < mo->numProperties( recursive ); i++ ) { + const QMetaProperty *p = mo->property(i, recursive); + + (void) new KListViewItem( taskprops, + p->name(), p->type(), + target->property( p->name() ).toString() ); + } + + return vb; +} + +QString KasTaskItem::expandMacros( const QString &format, QObject *data ) +{ + QString s = format; + QRegExp re("\\$(\\w+)"); + + int pos = 0; + while ( pos >= 0 ) { + pos = re.search( s, pos ); + if ( pos >= 0 ) { + QVariant val = data->property( re.cap(1).latin1() ); + QString v = val.asString(); + s.replace( pos, re.matchedLength(), v ); + pos = pos + v.length(); + } + } + + return s; +} + +QWidget *KasTaskItem::createX11Props( QWidget *parent ) +{ + QVBox *vb2 = new QVBox( parent ); + vb2->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Preferred ); + vb2->setSpacing( KDialog::spacingHint() ); + vb2->setMargin( KDialog::marginHint() ); + + // Create View + new QLabel( i18n("General"), vb2, "view" ); + QTextView *tv = new QTextView( vb2 ); + + QString fmt = i18n( + "<html>" + "<body>" + "<b>Name</b>: $name<br>" + "<b>Visible name</b>: $visibleName<br>" + "<br>" + "<b>Iconified</b>: $iconified<br>" + "<b>Minimized</b>: $minimized<br>" + "<b>Maximized</b>: $maximized<br>" + "<b>Shaded</b>: $shaded<br>" + "<b>Always on top</b>: $alwaysOnTop<br>" + "<br>" + "<b>Desktop</b>: $desktop<br>" + "<b>All desktops</b>: $onAllDesktops<br>" + "<br>" + "<b>Iconic name</b>: $iconicName<br>" + "<b>Iconic visible name</b>: $visibleIconicName<br>" + "<br>" + "<b>Modified</b>: $modified<br>" + "<b>Demands attention</b>: $demandsAttention<br>" + "</body>" + "</html>" + ); + + tv->setText( expandMacros( fmt, task_ ) ); + tv->setWordWrap( QTextEdit::WidgetWidth ); + + return vb2; +} + +QWidget *KasTaskItem::createNETProps( QWidget *parent ) +{ + QVBox *vb3 = new QVBox( parent ); + vb3->setSpacing( KDialog::spacingHint() ); + vb3->setMargin( KDialog::marginHint() ); + + // Create View + new QLabel( i18n("NET WM Specification Info"), vb3, "view" ); + new QTextView( vb3 ); + + return vb3; +} + +#include "kastaskitem.moc" diff --git a/kicker/extensions/kasbar/kastaskitem.h b/kicker/extensions/kasbar/kastaskitem.h new file mode 100644 index 000000000..cc7d0d188 --- /dev/null +++ b/kicker/extensions/kasbar/kastaskitem.h @@ -0,0 +1,135 @@ +/* kastaskitem.h +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +// -*- c++ -*- + + +#ifndef KASTASKITEM_H +#define KASTASKITEM_H + +#include <qpixmap.h> +#include "kasitem.h" + +class Task; +class KasPopup; +class KasTasker; +class KPixmap; + +/** + * A KasItem that represents a single Task. + */ +class KasTaskItem : public KasItem +{ + Q_OBJECT + + public: + KasTaskItem( KasTasker *parent, Task::Ptr task ); + virtual ~KasTaskItem(); + + QPixmap icon(); + + /** Reimplemented to paint the item. */ + virtual void paint( QPainter *p ); + + /** Returns the task the item is displaying. */ + Task::Ptr task() const { return task_; } + + /** Returns the parent KasTasker object. */ + KasTasker *kasbar() const; + + QString expandMacros( const QString &format, QObject *data ); + +public slots: + void updateTask(bool geometryChangeOnly); + + /** Create a thumbnail for this task (does nothing if they're disabled). */ + void refreshThumbnail(); + + void startAutoThumbnail(); + void stopAutoThumbnail(); + + void iconChanged(); + void checkAttention(); + + void showWindowMenuAt( QPoint pos ); + void sendToTray(); + void showPropertiesDialog(); + + void toggleActivateAction(); + void showWindowMenuAt( QMouseEvent *ev ); + +protected: + /** + * Reimplemented to create a KasTaskPopup. + */ + virtual KasPopup *createPopup(); + + QWidget *createTaskProps( QObject *target, QWidget *parent=0, bool recursive=true ); + QWidget *createX11Props( QWidget *tabbed ); + QWidget *createNETProps( QWidget *tabbed ); + + /** + * Reimplemented to activate the task. + */ + void dragOverAction(); + +private: + Task::Ptr task_; + QTimer *thumbTimer; + bool usedIconLoader; + bool iconHasChanged; + QTimer *attentionTimer; +}; + +#endif // KASTASKITEM_H + diff --git a/kicker/extensions/kasbar/kastaskpopup.cpp b/kicker/extensions/kasbar/kastaskpopup.cpp new file mode 100644 index 000000000..91f3ecbc9 --- /dev/null +++ b/kicker/extensions/kasbar/kastaskpopup.cpp @@ -0,0 +1,139 @@ +/* kastaskpopup.cpp +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +#include <qpainter.h> +#include <qapplication.h> + +#include <kdebug.h> +#include <kglobalsettings.h> +#include <kpixmapeffect.h> + +#include <taskmanager.h> + +#include "kastaskitem.h" +#include "kastasker.h" + +#include "kastaskpopup.h" +#include "kastaskpopup.moc" + +static const int TITLE_HEIGHT = 13; + +KasTaskPopup::KasTaskPopup( KasTaskItem *item, const char *name ) + : KasPopup( item, name ) +{ + this->item = item; + + setFont(KGlobalSettings::generalFont()); + setMouseTracking( true ); + + QString text = item->task()->visibleIconicName(); + if ( item->kasbar()->thumbnailsEnabled() && item->task()->hasThumbnail() ) { + titleBg.resize( width(), TITLE_HEIGHT ); + + setFixedSize( item->task()->thumbnail().width() + 2, + TITLE_HEIGHT + item->task()->thumbnail().height() + 2 ); + } + else { + int w = fontMetrics().width( text ) + 4; + int h = TITLE_HEIGHT + 1; + titleBg.resize( w, h ); + setFixedSize( w, h ); + } + + KPixmapEffect::gradient( titleBg, + Qt::black, colorGroup().mid(), + KPixmapEffect::DiagonalGradient ); + + connect( item->task(), SIGNAL( thumbnailChanged() ), SLOT( refresh() ) ); +} + +KasTaskPopup::~KasTaskPopup() +{ +} + +void KasTaskPopup::refresh() +{ + QString text = item->task()->visibleIconicName(); + if ( item->kasbar()->thumbnailsEnabled() && item->task()->hasThumbnail() ) { + resize( item->task()->thumbnail().width() + 2, + TITLE_HEIGHT + item->task()->thumbnail().height() + 2 ); + titleBg.resize( width(), TITLE_HEIGHT ); + } + update(); +} + +void KasTaskPopup::paintEvent( QPaintEvent * ) +{ + QPainter p( this ); + p.drawPixmap( 0, 0, titleBg ); + + QString text = item->task()->visibleIconicName(); + + p.setPen( Qt::white ); + if ( fontMetrics().width( text ) > width() - 4 ) + p.drawText( 1, 1, width() - 4, TITLE_HEIGHT - 1, AlignLeft | AlignVCenter, + text ); + else + p.drawText( 1, 1, width() - 4, TITLE_HEIGHT - 1, AlignCenter, text ); + + QPixmap thumb = item->task()->thumbnail(); + if ( !thumb.isNull() ) + p.drawPixmap( 1, TITLE_HEIGHT, thumb ); + + // + // Draw border + // + p.setPen( Qt::black ); + p.drawRect( 0, 0, width(), height() ); +} + diff --git a/kicker/extensions/kasbar/kastaskpopup.h b/kicker/extensions/kasbar/kastaskpopup.h new file mode 100644 index 000000000..8118fff6c --- /dev/null +++ b/kicker/extensions/kasbar/kastaskpopup.h @@ -0,0 +1,90 @@ +/* kastaskpopup.h +** +** Copyright (C) 2001-2004 Richard Moore <rich@kde.org> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to kde-devel@kde.org +*/ +// -*- c++ -*- + +#ifndef KASTASKPOPUP_H +#define KASTASKPOPUP_H + +#include <kpixmap.h> +#include "kaspopup.h" + +class KasTaskItem; + +/** + * A subclass of KasPopup which shows info about a task. + * + * @author Richard Moore, rich@kde.org + */ +class KasTaskPopup : public KasPopup +{ + Q_OBJECT + +public: + KasTaskPopup( KasTaskItem *item, const char *name=0 ); + virtual ~KasTaskPopup(); + +public slots: + void refresh(); + +protected: + virtual void paintEvent( QPaintEvent * ); + + private: + KasTaskItem *item; + KPixmap titleBg; +}; + +#endif // KASTASKPOPUP_H + + diff --git a/kicker/extensions/kasbar/version.h b/kicker/extensions/kasbar/version.h new file mode 100644 index 000000000..57554a838 --- /dev/null +++ b/kicker/extensions/kasbar/version.h @@ -0,0 +1,3 @@ +#define VERSION_STRING "v3-0.06" +#define HOMEPAGE_URL "http://xmelegance.org/kasbar/" + diff --git a/kicker/extensions/sidebar/Makefile.am b/kicker/extensions/sidebar/Makefile.am new file mode 100644 index 000000000..18f0cfbc0 --- /dev/null +++ b/kicker/extensions/sidebar/Makefile.am @@ -0,0 +1,16 @@ +INCLUDES = -I$(top_srcdir)/libkonq $(all_includes) + +kde_module_LTLIBRARIES = sidebar_panelextension.la + +sidebar_panelextension_la_SOURCES = sidebarextension.cpp + +sidebar_panelextension_la_METASOURCES = AUTO +sidebar_panelextension_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) +sidebar_panelextension_la_LIBADD = $(LIB_KDEUI) $(LIB_KPARTS) ../../../libkonq/libkonq.la + + +lnkdir = $(kde_datadir)/kicker/extensions +lnk_DATA = sidebarextension.desktop + +messages: + $(XGETTEXT) *.cpp *.h -o $(podir)/kickersidebarextension.pot diff --git a/kicker/extensions/sidebar/sidebarextension.cpp b/kicker/extensions/sidebar/sidebarextension.cpp new file mode 100644 index 000000000..a959f7f87 --- /dev/null +++ b/kicker/extensions/sidebar/sidebarextension.cpp @@ -0,0 +1,181 @@ +/*************************************************************************** + sidebarextension.cpp + ------------------- + begin : Sun July 20 16:00:00 CEST 2003 + copyright : (C) 2003 Joseph Wenninger + email : jowenn@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. * + * * + ***************************************************************************/ +#include "sidebarextension.h" +#include "sidebarextension.moc" +#include <kdebug.h> +#include <kmessagebox.h> +#include <kglobal.h> +#include <klocale.h> +#include <kparts/part.h> +#include <kparts/componentfactory.h> +#include <qlayout.h> +#include <konq_historymgr.h> +#include <krun.h> +#include <kurl.h> +#include <qvbox.h> +#include <qcursor.h> + +extern "C" +{ + KDE_EXPORT KPanelExtension *init( QWidget *parent, const QString& configFile ) + { + KGlobal::locale()->insertCatalogue("kickersidebarextension"); + KGlobal::locale()->insertCatalogue("konqueror"); + return new SidebarExtension( configFile, + KPanelExtension::Normal, + 0, + parent, "kickersidebarextension"); + } +} + +SidebarExtension::SidebarExtension( const QString& configFile, + Type type, + int actions, + QWidget *parent, const char *name ) + : KPanelExtension( configFile, type, actions, parent, name ),m_resizing(false),m_expandedSize(200) +{ + kdDebug() << "SidebarExtension: Created '" << name << "', '" << configFile << "'" << endl; + new KonqHistoryManager(0,"SidebarExtensionHistoryManager"); + m_layout=new QHBoxLayout(this); + m_layout->activate(); + m_sbWrapper=new QVBox(this); + KParts::ReadOnlyPart *p=KParts::ComponentFactory::createPartInstanceFromLibrary<KParts::ReadOnlyPart>( + "konq_sidebar", + m_sbWrapper, + "SideBar_View", + this, + "Sidebar","universal"); + + KParts::BrowserExtension *be=KParts::BrowserExtension::childObject(p); + if (be) { + connect(be,SIGNAL(openURLRequest( const KURL &, const KParts::URLArgs &)), + this,SLOT(openURLRequest( const KURL &, const KParts::URLArgs &))); + connect(be,SIGNAL(createNewWindow( const KURL &, const KParts::URLArgs &)), + this,SLOT(openURLRequest( const KURL &, const KParts::URLArgs &))); + + } + + m_resizeHandle=new QFrame(this); + m_resizeHandle->setFrameShape(QFrame::Panel); + m_resizeHandle->setFrameShadow(QFrame::Raised); + m_resizeHandle->setFixedWidth(6); + m_resizeHandle->setCursor(QCursor(Qt::SizeHorCursor)); + connect(p->widget(),SIGNAL(panelHasBeenExpanded(bool)),this,SLOT(needLayoutUpdate(bool))); + needLayoutUpdate(false); + m_resizeHandle->installEventFilter(this); + m_resizeHandle->setMouseTracking(true); +// l->add(p->widget()); +// p->widget()->show(); +// l->activate(); + +} + +void SidebarExtension::needLayoutUpdate(bool exp) { + setReserveStrut(!exp); // only reserve a strut when we are collapsed + if (exp) { + m_currentWidth=m_expandedSize; + m_resizeHandle->show(); + raise(); + } else { + m_currentWidth=24; + m_resizeHandle->hide(); + } + topLevelWidget()->setFixedWidth(m_currentWidth); + emit updateLayout(); +} + +void SidebarExtension::openURLRequest( const KURL &url, const KParts::URLArgs &) { + KRun::runCommand("kfmclient openURL \""+url.prettyURL()+"\"", "kfmclient", "konqueror"); + +} + + +SidebarExtension::~SidebarExtension() +{ + KGlobal::locale()->removeCatalogue("kickersidebarextension"); + KGlobal::locale()->removeCatalogue("konqueror"); +} + +bool SidebarExtension::eventFilter( QObject *, QEvent *e ) { + if (e->type()==QEvent::MouseButtonPress) { + m_resizing=true; + m_x=((QMouseEvent*)e)->globalX(); + return true; + } else if (e->type()==QEvent::MouseButtonRelease) { + m_resizing=false; + m_expandedSize=topLevelWidget()->width(); + needLayoutUpdate(true); + return true; + } else if (e->type()==QEvent::MouseMove) { + if (m_resizing) { + Position p=position(); + if (p==Left) { + int diff=((QMouseEvent*)e)->globalX()-m_x; + if (abs(diff)>3) { + topLevelWidget()->setFixedWidth(topLevelWidget()->width()+diff); + m_x=((QMouseEvent*)e)->globalX(); + } + } else if (p==Right) { + int diff=((QMouseEvent*)e)->globalX()-m_x; + if (abs(diff)>3) { + topLevelWidget()->setFixedWidth(topLevelWidget()->width()-diff); + topLevelWidget()->move(topLevelWidget()->x()+diff,topLevelWidget()->y()); + m_x=((QMouseEvent*)e)->globalX(); + } + } + return true; + } + } + return false; +} + +KPanelExtension::Position SidebarExtension::preferedPosition() const { + kdDebug()<<"SidebarExtension::preferedPosition()***************"<<endl; + return KPanelExtension::Left; +} + +QSize SidebarExtension::sizeHint(Position, QSize maxSize ) const +{ + return QSize(m_currentWidth,maxSize.height()); +} + +void SidebarExtension::positionChange( Position position ) { + if (position == Right) { + m_layout->remove(m_sbWrapper); + m_layout->remove(m_resizeHandle); + + m_layout->add(m_resizeHandle); + m_layout->add(m_sbWrapper); + } else if (position == Left) { + m_layout->remove(m_sbWrapper); + m_layout->remove(m_resizeHandle); + + m_layout->add(m_sbWrapper); + m_layout->add(m_resizeHandle); + + } + +} + +void SidebarExtension::about() +{ +} + +void SidebarExtension::preferences() +{ +} + diff --git a/kicker/extensions/sidebar/sidebarextension.desktop b/kicker/extensions/sidebar/sidebarextension.desktop new file mode 100644 index 000000000..8ff52adb7 --- /dev/null +++ b/kicker/extensions/sidebar/sidebarextension.desktop @@ -0,0 +1,147 @@ +[Desktop Entry] +Name=Universal Sidebar +Name[af]=Universele Kantbalk +Name[ar]=الشريط الجانبي العالمي +Name[az]=Ümumi Yan Çubuq +Name[be]=Універсальная бакавая панэль +Name[bg]=Универсален панел +Name[bn]=সার্বজনীন সাইডবার +Name[bs]=Univerzalni sidebar +Name[ca]=Barra universal +Name[cs]=Univerzální postranní lišta +Name[csb]=Ùniwersalnô bòcznô lëstew +Name[cy]=BarOchr Cyffredinol +Name[da]=Universel sidebjælke +Name[de]=Universeller Navigationsbereich +Name[el]=Καθολική πλευρική μπάρα +Name[eo]=Ĝenerala flankzono +Name[es]=Barra lateral universal +Name[et]=Universaalne külgriba +Name[eu]=Alboko barra unibertsala +Name[fa]=میله جانبی عمومی +Name[fi]=Yleissivupalkki +Name[fr]=Barre latérale universelle +Name[fy]=Universele sydbalke +Name[ga]=Barra Taoibh Uilíoch +Name[gl]=Barra Lateral Universal +Name[he]=סרגל־צד אוניברסלי +Name[hi]=सर्वव्यापी बाज़ू-पट्टी +Name[hr]=Univerzalna bočna traka +Name[hu]=Univerzális oldalsáv +Name[is]=Algild hliðarslá +Name[it]=Barra laterale universale +Name[ja]=汎用サイドバー +Name[ka]=უნივერსალური გვერდითი პანელი +Name[kk]=Әмбебап бүйірдегі панель +Name[km]=របារចំហៀងទូទៅ +Name[lt]=Universali šoninė juosta +Name[lv]=Unversālā sānjosla +Name[mk]=Универзална странична лента +Name[mn]=Универсал хажуу самбар +Name[ms]=Bar Sisi Universal +Name[mt]=Sidebar Universali +Name[nb]=Universell sidestolpe +Name[nds]=Siet-Navigatschoonbalken +Name[ne]=विश्वव्यापी छेउपट्टी +Name[nl]=Universele zijbalk +Name[nn]=Universell sidestolpe +Name[pa]=ਯੂਨੀਵਰਸਲ ਬਾਹੀ +Name[pl]=Uniwersalny pasek boczny +Name[pt]=Barra Lateral Universal +Name[pt_BR]=Barra Lateral Universal +Name[ro]=Bară laterală universală +Name[ru]=Универсальная боковая панель +Name[rw]=Umurongokuruhande Mpuzamahanga +Name[se]=Universella holga +Name[sk]=Univerzálny bočný panel +Name[sl]=Univerzalna stranska vrstica +Name[sr]=Универзална бочна трака +Name[sr@Latn]=Univerzalna bočna traka +Name[sv]=Generell sidopanel +Name[ta]=பொது வரலாற்றுப் பக்கப்பட்டி +Name[th]=แถบข้าง +Name[tr]=Genel Yan Çubuk +Name[tt]=Küpçaralı Yantirä +Name[uk]=Універсальна бічна панель +Name[uz]=Universal yon paneli +Name[uz@cyrillic]=Универсал ён панели +Name[vi]=Thanh bên Chung +Name[wa]=Bår di costé universele +Name[zh_CN]=通用侧边栏 +Name[zh_TW]=整體的邊列 + +Comment=Wrapper around Konqueror's navigation panel +Comment[af]='n Toevou program rondom Konqueror se navigasie paneel +Comment[be]=Панэль для хуткай навігацыі +Comment[bg]=Допълнителен универсален панел, подобен на панела на браузъра +Comment[bn]=কনকরার-এর ন্যাভিগেশন প্যানেল-এর প্রসারণ +Comment[bs]=Omotač za Konquerorov navigacioni panel +Comment[ca]=Embolcall al voltant del plafó de navegació del Konqueror +Comment[csb]=Programa òpakòwującô nawigacëjny panel Konquerora +Comment[cy]=Lapiad o gwmpas panel morlywio Konqueror +Comment[da]=Konvolut om Konquerors navigationspanel +Comment[de]=Erweiterung zum Navigationsbereich von Konqueror +Comment[el]=Ενσωματωτής στο Περιηγητή του Konqueror +Comment[eo]=Ŝelo ĉirkaŭ la Konkeranta stirpanelo +Comment[es]=Envoltura para el panel de navegación de Konqueror +Comment[et]=Konquerori liikumisriba skelett +Comment[eu]=Konquerorren arakatze panelerako bilgarria +Comment[fa]=سطرشکن در اطراف تابلوی ناوش Konqueror +Comment[fi]=Kuori Konquerorin navigaatiopaneelin ympärille +Comment[fr]=Un enveloppement autour du panneau de navigation de Konqueror +Comment[fy]=In kontainer rûn de Konqueror's navigaasjepaniel +Comment[gl]=Reutilización do painel de navegación de Konqueror +Comment[he]=מעטפת מסביב ללוח הניווט של Konqueror +Comment[hi]=कॉन्करर के नेविगेशन फलक के चारों ओर रैपर +Comment[hr]=Omotač oko Konqueror navigacijske ploče +Comment[hu]=Segédelem a Konqueror navigációs paneljéhez +Comment[is]=Lag í kringum stjórnborð Konqueror vefrans +Comment[it]=Wrapper per il pannello di navigazione di Konqueror +Comment[ja]=Konqueror のナビゲーションパネルのラッパー +Comment[ka]=Konqueror -ის პანელის დამმუშავებელი +Comment[kk]=Konqueror's басқару панелінің өңдеушісі +Comment[km]=Wrapper ជុំវិញបន្ទះរុករករបស់ Konqueror +Comment[lt]=Konqueror navigacijos pulto dėklas +Comment[lv]=Iekarotāja navigācijas paneļa vraperis +Comment[mk]=Обвивка околу навигациониот панел на Konqueror +Comment[ms]=Pembalut sekeliling panel navigasi Konqueror +Comment[mt]="Wrapper" madwar il-pannell ta' navigazzjoni ta' Konqueror +Comment[nb]=Overbygning på navigasjonspanelet i Konqueror +Comment[nds]=Konqueror sien Navigatschoonpaneel för den Schriefdisch +Comment[ne]=कन्क्वेररको नेभिगेसन प्यानल वरिपरि आवरण +Comment[nl]=Een container rond Konqueror's navigatiepaneel +Comment[nn]=Overbygning på navigasjonspanelet i Konqueror +Comment[pa]=ਕੋਨਕਿਉਰਰ ਦੇ ਏਧਰ-ਓਧਰ ਪੈਨਲ ਲਈ ਸਮੇਟਣ ਵਾਲੀ +Comment[pl]=Program opakowujący panel nawigacyjny Konquerora +Comment[pt]=Uma interface sobre o painel de navegação do Konqueror +Comment[pt_BR]=Wrapper para o painel de navegação do Konqueror +Comment[ro]=O încapsulare a panoului de navigare Konqueror +Comment[ru]=Обработчик панели навигации Konqueror +Comment[rw]=Mufunika hafi y'umwanya w'ibuganya wa Konqueror +Comment[sk]=Obálka pre navigačný panel Konquerora +Comment[sl]=Objemalnik okoli Konquerorjevega navigacijskega pulta +Comment[sr]=Омотач Konqueror-вог навигационог панела +Comment[sr@Latn]=Omotač Konqueror-vog navigacionog panela +Comment[sv]=Omgivning för Konquerors navigeringspanel +Comment[ta]=கான்கொரர் நவிகேஷன் பலகத்தை சுற்றப்பட்டுள்ளது. +Comment[th]=หุ้มอยู่รอบๆ Navigation panel ของคอนเควอร์เรอร์ +Comment[tr]=Konqueror'un yönlendirme paneli çevresindeki satır atlatıcı +Comment[tt]=Konqueror'nıñ küçü taqtasınıñ sıydırması +Comment[uk]=Обгортка навколо навігаційної панелі Konqueror +Comment[vi]=Bao bọc xung quanh bảng duyệt của Konqueror +Comment[wa]=On bagaedje åtoû do scriftôr di naiviaedje di Konqueror +Comment[zh_CN]=Konqueror 导航面板的转换器 +Comment[zh_TW]=包裝於 konqueror 的導覽面板 + +Icon=view_sidetree + +X-KDE-Library=sidebar_panelextension +X-KDE-UniqueApplet=true +X-KDE-PanelExt-Resizeable=true +X-KDE-PanelExt-StdSizes=true +X-KDE-PanelExt-StdSizeDefault=1 +X-KDE-PanelExt-CustomSizeMin=24 +X-KDE-PanelExt-CustomSizeMax=400 +X-KDE-PanelExt-CustomSizeDefault=200 +X-KDE-UniqueExtension=true +X-KDE-PanelExt-Positions=Left,Right diff --git a/kicker/extensions/sidebar/sidebarextension.h b/kicker/extensions/sidebar/sidebarextension.h new file mode 100644 index 000000000..a44c270ba --- /dev/null +++ b/kicker/extensions/sidebar/sidebarextension.h @@ -0,0 +1,63 @@ +/*************************************************************************** + sidebarextension.h + ------------------- + begin : Sun July 20 16:00:00 CEST 2003 + copyright : (C) 2003 Joseph Wenninger + email : jowenn@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. * + * * + ***************************************************************************/ +#ifndef SIDEBAREXTENSION_H +#define SIDEBAREXTENSION_H + +#include <kpanelextension.h> +#include <kurl.h> +#include <kparts/browserextension.h> + +class QHBoxLayout; +class QVBox; + +class SidebarExtension : public KPanelExtension +{ + Q_OBJECT + +public: + SidebarExtension( const QString& configFile, + Type t = Normal, + int actions = 0, + QWidget *parent = 0, const char *name = 0 ); + + virtual ~SidebarExtension(); + + QSize sizeHint( Position, QSize maxSize ) const; + Position preferedPosition() const; + + virtual void positionChange( Position position ); + +protected: + virtual void about(); + virtual void preferences(); + virtual bool eventFilter( QObject *o, QEvent *e ); +protected slots: + void openURLRequest( const KURL &, const KParts::URLArgs &); + void needLayoutUpdate(bool); + +private: + int m_currentWidth; + int m_x; + QFrame *m_resizeHandle; + bool m_resizing; + int m_expandedSize; + QHBoxLayout *m_layout; + QVBox *m_sbWrapper; +}; + +#endif + diff --git a/kicker/extensions/taskbar/Makefile.am b/kicker/extensions/taskbar/Makefile.am new file mode 100644 index 000000000..4dfa1b929 --- /dev/null +++ b/kicker/extensions/taskbar/Makefile.am @@ -0,0 +1,23 @@ +INCLUDES = -I$(srcdir)/../../taskmanager -I$(srcdir)/../../taskbar -I$(srcdir)/../../libkicker -I$(top_builddir)/kicker/libkicker $(all_includes) + +kde_module_LTLIBRARIES = taskbar_panelextension.la + +taskbar_panelextension_la_SOURCES = taskbarextension.cpp taskbarextension.skel +taskbar_panelextension_la_METASOURCES = AUTO +taskbar_panelextension_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) +taskbar_panelextension_la_LIBADD = $(LIB_KDEUI) $(LIB_KPARTS) \ + ../../libkicker/libkickermain.la \ + ../../taskmanager/libtaskmanager.la \ + ../../taskbar/libtaskbar.la + +noinst_HEADERS = taskbarextension.h + +lnkdir = $(kde_datadir)/kicker/extensions +lnk_DATA = taskbarextension.desktop + +EXTRA_DIST = $(lnk_DATA) + +messages: + $(XGETTEXT) *.cpp *.h -o $(podir)/taskbarextension.pot + +taskbarextension.lo: ../../libkicker/kickerSettings.h diff --git a/kicker/extensions/taskbar/taskbarextension.cpp b/kicker/extensions/taskbar/taskbarextension.cpp new file mode 100644 index 000000000..a25297b39 --- /dev/null +++ b/kicker/extensions/taskbar/taskbarextension.cpp @@ -0,0 +1,235 @@ +/***************************************************************** + +Copyright (c) 2001 Matthias Elter <elter@kde.org> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + +#include <qlayout.h> +#include <qtimer.h> +#include <qwmatrix.h> + +#include <dcopclient.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kglobal.h> +#include <klocale.h> +#include <krootpixmap.h> +#include <kstandarddirs.h> + +#include "global.h" +#include "kickerSettings.h" +#include "taskbarcontainer.h" + +#include "taskbarextension.h" +#include "taskbarextension.moc" + +extern "C" +{ + KDE_EXPORT KPanelExtension* init( QWidget *parent, const QString& configFile ) + { + KGlobal::locale()->insertCatalogue( "taskbarextension" ); + return new TaskBarExtension( configFile, KPanelExtension::Stretch, + KPanelExtension::Preferences, parent, "taskbarextension" ); + } +} + +TaskBarExtension::TaskBarExtension(const QString& configFile, Type type, + int actions, QWidget *parent, const char *name) + : KPanelExtension(configFile, type, actions, parent, name), + m_bgImage(0), + m_bgFilename(0), + m_rootPixmap(0) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + m_container = new TaskBarContainer(false, this); + m_container->setBackgroundOrigin(AncestorOrigin); + positionChange(position()); + layout->addWidget(m_container); + + connect(m_container, SIGNAL(containerCountChanged()), + SIGNAL(updateLayout())); + + kapp->dcopClient()->setNotifications(true); + connectDCOPSignal("kicker", "kicker", "configurationChanged()", + "configure()", false); + + connect(kapp, SIGNAL(kdisplayPaletteChanged()), + SLOT(setBackgroundTheme())); + + QTimer::singleShot(0, this, SLOT(setBackgroundTheme())); +} + +TaskBarExtension::~TaskBarExtension() +{ + KGlobal::locale()->removeCatalogue( "taskbarextension" ); +} + +void TaskBarExtension::positionChange( Position p ) +{ + + m_container->orientationChange(orientation()); + + switch (p) + { + case Bottom: + m_container->popupDirectionChange(KPanelApplet::Up); + break; + case Top: + m_container->popupDirectionChange(KPanelApplet::Down); + break; + case Right: + m_container->popupDirectionChange(KPanelApplet::Left); + break; + case Left: + m_container->popupDirectionChange(KPanelApplet::Right); + break; + case Floating: + if (orientation() == Horizontal) + { + m_container->popupDirectionChange(KPanelApplet::Down); + } + else if (QApplication::reverseLayout()) + { + m_container->popupDirectionChange(KPanelApplet::Left); + } + else + { + m_container->popupDirectionChange(KPanelApplet::Right); + } + break; + } + setBackgroundTheme(); +} + +void TaskBarExtension::preferences() +{ + m_container->preferences(); +} + +QSize TaskBarExtension::sizeHint(Position p, QSize maxSize) const +{ + if (p == Left || p == Right) + maxSize.setWidth(sizeInPixels()); + else + maxSize.setHeight(sizeInPixels()); + +// kdDebug(1210) << "TaskBarExtension::sizeHint( Position, QSize )" << endl; +// kdDebug(1210) << " width: " << size.width() << endl; +// kdDebug(1210) << "height: " << size.height() << endl; + return m_container->sizeHint(p, maxSize); +} + +void TaskBarExtension::configure() +{ + setBackgroundTheme(); + update(); +} + +void TaskBarExtension::setBackgroundTheme() +{ + if (KickerSettings::transparent()) + { + if (!m_rootPixmap) + { + m_rootPixmap = new KRootPixmap(this); + m_rootPixmap->setCustomPainting(true); + connect(m_rootPixmap, SIGNAL(backgroundUpdated(const QPixmap&)), + SLOT(updateBackground(const QPixmap&))); + } + else + { + m_rootPixmap->repaint(true); + } + + double tint = double(KickerSettings::tintValue()) / 100; + m_rootPixmap->setFadeEffect(tint, KickerSettings::tintColor()); + m_rootPixmap->start(); + return; + } + else if (m_rootPixmap) + { + delete m_rootPixmap; + m_rootPixmap = 0; + } + + unsetPalette(); + + if (KickerSettings::useBackgroundTheme()) + { + QString bgFilename = locate("appdata", KickerSettings::backgroundTheme()); + + if (m_bgFilename != bgFilename) + { + m_bgFilename = bgFilename; + m_bgImage.load(m_bgFilename); + } + + if (!m_bgImage.isNull()) + { + QImage bgImage = m_bgImage; + + if (orientation() == Vertical) + { + if (KickerSettings::rotateBackground()) + { + QWMatrix matrix; + matrix.rotate(position() == KPanelExtension::Left ? 90: 270); + bgImage = bgImage.xForm(matrix); + } + + bgImage = bgImage.scaleWidth(size().width()); + } + else + { + if (position() == KPanelExtension::Top && + KickerSettings::rotateBackground()) + { + QWMatrix matrix; + matrix.rotate(180); + bgImage = bgImage.xForm(matrix); + } + + bgImage = bgImage.scaleHeight(size().height()); + } + + if (KickerSettings::colorizeBackground()) + { + KickerLib::colorize(bgImage); + } + setPaletteBackgroundPixmap(bgImage); + } + } + + m_container->setBackground(); +} + +void TaskBarExtension::updateBackground(const QPixmap& bgImage) +{ + unsetPalette(); + setPaletteBackgroundPixmap(bgImage); + m_container->setBackground(); +} + +void TaskBarExtension::resizeEvent(QResizeEvent *e) +{ + QFrame::resizeEvent(e); + setBackgroundTheme(); +} + diff --git a/kicker/extensions/taskbar/taskbarextension.desktop b/kicker/extensions/taskbar/taskbarextension.desktop new file mode 100644 index 000000000..691e3fe0e --- /dev/null +++ b/kicker/extensions/taskbar/taskbarextension.desktop @@ -0,0 +1,147 @@ +[Desktop Entry] +Name=External Taskbar +Name[af]=Eksterne Taakbalk +Name[ar]=شريط المهام الخارجي +Name[az]=Xarici Vəzifə Çubuğu +Name[be]=Вонкавая панэль заданняў +Name[bg]=Допълнителна лента +Name[bn]=বহিঃস্থ টাস্কবার +Name[br]=Barrenn dleadoù diavaez +Name[bs]=Eksterni taskbar +Name[ca]=Barra de tasques externa +Name[cs]=Externí pruh úloh +Name[csb]=Bùtnowô lëstew dzejaniów +Name[cy]=Bar tasgau allanol +Name[da]=Ekstern opgavelinje +Name[de]=Externe Fensterleiste +Name[el]=Εξωτερική γραμμή εργασιών +Name[eo]=Ekstera Taskostrio +Name[es]=Barra de tareas externa +Name[et]=Väline tegumiriba +Name[eu]=Kanpoko ataza-barra +Name[fa]=میله تکلیف خارجی +Name[fi]=Ulkoinen ohjelmapalkki +Name[fr]=Barre des tâches externe +Name[fy]=Eksterne taakbalke +Name[ga]=Tascbharra Seachtrach +Name[gl]=Barra de Tarefas Externa +Name[he]=שורת משימות חיצונית +Name[hi]=बाहरी कार्यपट्टी +Name[hr]=Vanjska traka zadataka +Name[hu]=Külső feladatlista +Name[id]=Taskbar eksternal +Name[is]=Utanáliggjandi verkefnaslá +Name[it]=Barra delle applicazioni esterna +Name[ja]=外部タスクバー +Name[ka]=გაფართოვებული ამოცანათა პანელი +Name[kk]=Сыртқы тапсырмалар панелі +Name[km]=របារភារកិច្ចខាងក្រៅ +Name[lo]=ຖາດງານພາຍນອກ +Name[lt]=Išorinė užduočių juosta +Name[lv]=Ārējā Uzdevumjosla +Name[mk]=Надворешна лента со програми +Name[mn]=Гадаад ажлын самбар +Name[ms]=Taskbar Luaran +Name[mt]=Taskbar Estern +Name[nb]=Ekstern oppgavelinje +Name[nds]=Extern Programmbalken +Name[ne]=बाह्य कार्यपट्टी +Name[nl]=Externe taakbalk +Name[nn]=Ekstern oppgåvelinje +Name[nso]=Bar ya Mosongwana wa Kantle +Name[pa]=ਬਾਹਰੀ ਕੰਮ-ਪੱਟੀ +Name[pl]=Zewnętrzny pasek zadań +Name[pt]=Barra de Tarefas Externa +Name[pt_BR]=Barra de Tarefas Externa +Name[ro]=Bară de procese externă +Name[ru]=Внешняя панель задач +Name[rw]=Umurongoibikorwa w'Inyuma +Name[se]=Olgguldas bargoholga +Name[sk]=Externý taskbar +Name[sl]=Zunanja opravilna vrstica +Name[sr]=Спољашња трака задатака +Name[sr@Latn]=Spoljašnja traka zadataka +Name[sv]=Externt aktivitetsfält +Name[ta]=புற பணிப்பட்டி +Name[tg]=Сафҳаи масъалаҳои васеъ +Name[th]=ถาดงานภายนอก +Name[tr]=Harici Görev Çubuğu +Name[tt]=Tışqı Eşlärtirä +Name[uk]=Зовнішня смужка задач +Name[uz]=Vazifalar tashqi paneli +Name[uz@cyrillic]=Вазифалар ташқи панели +Name[ven]=Bara ya mushumo ya nga nnda +Name[vi]=Thanh tác vụ Ngoài +Name[wa]=Bår ås bouyes då dfoû +Name[xh]=Ibar yomsebenzi Wangaphandle +Name[zh_CN]=外部任务栏 +Name[zh_TW]=外部工作列 +Name[zu]=Ibha yemisebenzi yangaphandle +Comment=External taskbar panel extension +Comment[af]=Eksterne taakbalk paneel uitbreiding +Comment[ar]=تمديدة لوحة شريط المهام الخارجي +Comment[be]=Вонкавае пашырэнне панэлі заданняў +Comment[bg]=Допълнителна лента за задачите +Comment[bn]=মূল প্যানেল-এর বাইরে আলাদা টাস্কবার +Comment[bs]=Proširenje panela za eksterni taskbar +Comment[ca]=Extensió del plafó de la barra de tasques externa +Comment[cs]=Rozšíření s externím pruhem úloh +Comment[csb]=Rozszérzenié panelu z bùtnową lëstwą dzejaniów +Comment[cy]=Estyniad panel bar tasgau allanol +Comment[da]=Paneludvidelse - ekstern joblinje +Comment[de]=Eine alternative Fensterleiste +Comment[el]=Επέκταση του πίνακα εξωτερική γραμμή εργασιών +Comment[eo]=Ekstera taskostria panelaldono +Comment[es]=Extensión del panel con barra de tareas externa +Comment[et]=Välise tegumiriba laiendus +Comment[eu]=Panelaren hedapena kanpoko ataza-barrarekin +Comment[fa]=پسوند تابلوی میله تکلیف خارجی +Comment[fi]=Ulkoinen ohjelmapalkin paneelilaajennus +Comment[fr]=Barre des tâches externe +Comment[fy]=Eksterne taakbalke +Comment[gl]=Extensión do painel da barra de tarefas externa +Comment[he]=הרחבת שורת משימות חיצונית +Comment[hr]=Vanjsko proširenje ploče trake zadataka +Comment[hu]=Külső feladatlista-kiterjesztés +Comment[is]=Útvíkkun utanáliggjandi spjalds +Comment[it]=Barra delle applicazioni esterna +Comment[ja]=外部タスクバーパネル拡張 +Comment[ka]=გარე პულტისა და პანელის გაფართოება +Comment[kk]=Қосымша тапсырмалар панелі. +Comment[km]=ផ្នែកបន្ថែមបន្ទះរបារភារកិច្ចខាងក្រៅ ។ +Comment[lt]=Išorinis užduočių juostos praplėtimas +Comment[mk]=Екстензија на панелот - надворешна лента со програми. +Comment[nb]=Oppgavelinje utenfor panelet +Comment[nds]=En Programmbalken buten dat Paneel +Comment[ne]=बाह्य कार्यपट्टी प्यानल विस्तार +Comment[nl]=Externe taakbalk +Comment[nn]=Oppgåvelinje utanfor panelet +Comment[pa]=ਬਾਹਰੀ ਕੰਮਪੱਟੀ ਪੈਨਲ ਵਧਾਰਾ +Comment[pl]=Rozszerzenie panelu z zewnętrznym paskiem zadań +Comment[pt]=Extensão do painel de barra de tarefas externa +Comment[pt_BR]=Extensão do painel para a barra de tarefas externa +Comment[ro]=Extensie pentru bară de procese externă +Comment[ru]=Внешняя панель задач KDE +Comment[se]=Olgguldas bargoholga viiddádus +Comment[sk]=Rozšírenie externého panelu úloh +Comment[sl]=Zunanja razširitev opravilne vrstice +Comment[sr]=Спољашња трака задатака, проширење панела. +Comment[sr@Latn]=Spoljašnja traka zadataka, proširenje panela. +Comment[sv]=Extern utökning till aktivitetsfältet +Comment[th]=ส่วนขยายเพิ่มเติมแอพเพล็ตถาดงานภายนอก +Comment[tr]=Harici görev çubuğu uzantısı. +Comment[uk]=Зовнішнє розширення панелі задач +Comment[vi]=Bảng điều khiển mở rộng có thanh tác vụ bên ngoài +Comment[wa]=On module di scriftôr di bår ås bouyes då dfoû +Comment[zh_CN]=外部任务栏面板扩展 +Comment[zh_TW]=外部工作列面板延伸 + +Icon=taskbar +X-KDE-Library=taskbar_panelextension +X-KDE-UniqueApplet=true +X-KDE-PanelExt-Resizeable=true +X-KDE-PanelExt-StdSizes=true +X-KDE-PanelExt-StdSizeDefault=1 +X-KDE-PanelExt-CustomSizeMin=24 +X-KDE-PanelExt-CustomSizeMax=400 +X-KDE-PanelExt-CustomSizeDefault=58 diff --git a/kicker/extensions/taskbar/taskbarextension.h b/kicker/extensions/taskbar/taskbarextension.h new file mode 100644 index 000000000..021420483 --- /dev/null +++ b/kicker/extensions/taskbar/taskbarextension.h @@ -0,0 +1,72 @@ +/***************************************************************** + +Copyright (c) 2001 Matthias Elter <elter@kde.org> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + +#ifndef __taskbarextension_h__ +#define __taskbarextension_h__ + +#include <qimage.h> + +#include <dcopobject.h> +#include <kpanelextension.h> + +class KRootPixmap; +class TaskBarContainer; + +class TaskBarExtension : public KPanelExtension, virtual public DCOPObject +{ + Q_OBJECT + K_DCOP + +k_dcop: + int panelSize() { return sizeInPixels(); } + int panelOrientation() { return static_cast<int>(orientation()); } + int panelPosition() { return static_cast<int>(position()); } + void setPanelSize(int size) { setSize(static_cast<Size>(size),true);}///slotSetSize(size); } + void configure(); + +public: + TaskBarExtension( const QString& configFile, Type t = Normal, + int actions = 0, QWidget *parent = 0, const char *name = 0 ); + ~TaskBarExtension(); + + QSize sizeHint( Position, QSize maxSize ) const; + Position preferedPosition() const { return Bottom; } + +protected: + void resizeEvent(QResizeEvent*); + + void positionChange( Position ); + void preferences(); + +private: + TaskBarContainer *m_container; + QImage m_bgImage; + QString m_bgFilename; + KRootPixmap *m_rootPixmap; + +private slots: + void setBackgroundTheme(); + void updateBackground(const QPixmap&); +}; + +#endif |