diff options
Diffstat (limited to 'chalk/plugins/viewplugins')
215 files changed, 20266 insertions, 0 deletions
diff --git a/chalk/plugins/viewplugins/Makefile.am b/chalk/plugins/viewplugins/Makefile.am new file mode 100644 index 00000000..e5739b36 --- /dev/null +++ b/chalk/plugins/viewplugins/Makefile.am @@ -0,0 +1,24 @@ +if compile_kross +SCRIPTINGDIR = scripting +endif + +SUBDIRS = \ + substrate \ + colorrange \ + colorspaceconversion \ + dropshadow \ + filtersgallery \ + histogram \ + histogram_docker \ + imagesize \ + modify_selection \ + rotateimage \ + screenshot \ + separate_channels \ + shearimage \ + selectopaque \ + $(SCRIPTINGDIR) + +# variations +# history_docker +# performancetest diff --git a/chalk/plugins/viewplugins/colorrange/Makefile.am b/chalk/plugins/viewplugins/colorrange/Makefile.am new file mode 100644 index 00000000..fc29a370 --- /dev/null +++ b/chalk/plugins/viewplugins/colorrange/Makefile.am @@ -0,0 +1,25 @@ +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +kde_module_LTLIBRARIES = chalkcolorrange.la + +chalkcolorrange_la_SOURCES = colorrange.cc dlg_colorrange.cc wdg_colorrange.ui +noinst_HEADERS = wdg_colorrange.h dlg_colorrange.h colorrange.h + +chalkcolorrange_la_LIBADD = ../../../libchalkcommon.la +chalkcolorrange_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) chalkblurfilter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui + +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = colorrange.rc +EXTRA_DIST = $(chalkrc_DATA) + +kde_services_DATA = chalkcolorrange.desktop + +chalkcolorrange_la_METASOURCES = AUTO + +KDE_OPTIONS = nofinal diff --git a/chalk/plugins/viewplugins/colorrange/chalkcolorrange.desktop b/chalk/plugins/viewplugins/colorrange/chalkcolorrange.desktop new file mode 100644 index 00000000..dde9b936 --- /dev/null +++ b/chalk/plugins/viewplugins/colorrange/chalkcolorrange.desktop @@ -0,0 +1,40 @@ +[Desktop Entry] +Name=Colorrange +Name[bg]=Цветови обхват +Name[ca]=Rang de color +Name[da]=Farveområde +Name[de]=Farbbereich +Name[el]=Χρωματικό εύρος +Name[en_GB]=Colourrange +Name[eo]=Kolorgamo +Name[et]=Värvivahemik +Name[fa]=گسترۀ رنگ +Name[fr]=Plage de couleurs +Name[fy]=Kleurberik +Name[gl]=Gamas de Cores +Name[he]=טווח צבעים +Name[hu]=Egyszerű +Name[is]=Litasvið +Name[it]=Intervallo di colori +Name[ja]=色の範囲 +Name[km]=ជួរពណ៌ +Name[nb]=Fargeområde +Name[nds]=Klörenrebeet +Name[ne]=रङदायरा +Name[nl]=Kleurbereik +Name[pl]=Zakres kolorów +Name[pt]=Gamas de Cores +Name[pt_BR]=Intervalos de Cores +Name[ru]=Цвета +Name[se]=Ivdnegaskkadat +Name[sk]=Rozsah farieb +Name[sl]=Barvni razpon +Name[sr]=Опсег боја +Name[sr@Latn]=Opseg boja +Name[sv]=Färgintervall +Name[uk]=Діапазон кольорів +Name[zh_TW]=色彩範圍 +ServiceTypes=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkcolorrange +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/colorrange/colorrange.cc b/chalk/plugins/viewplugins/colorrange/colorrange.cc new file mode 100644 index 00000000..1bf90bbc --- /dev/null +++ b/chalk/plugins/viewplugins/colorrange/colorrange.cc @@ -0,0 +1,82 @@ +/* + * colorrange.h -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include <math.h> + +#include <stdlib.h> + +#include <tqslider.h> +#include <tqpoint.h> + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> + +#include <kis_doc.h> +#include <kis_image.h> +#include <kis_layer.h> +#include <kis_paint_device.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_view.h> +#include <kis_selection.h> +#include <kis_selection_manager.h> +#include "colorrange.h" +#include "dlg_colorrange.h" + +typedef KGenericFactory<ColorRange> ColorRangeFactory; +K_EXPORT_COMPONENT_FACTORY( chalkcolorrange, ColorRangeFactory( "chalk" ) ) + +ColorRange::ColorRange(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + + if (tqparent->inherits("KisView")) { + setInstance(ColorRangeFactory::instance()); + setXMLFile(locate("data","chalkplugins/colorrange.rc"), true); + m_view = dynamic_cast<KisView*>(tqparent); + m_view->canvasSubject()->selectionManager()->addSelectionAction( new KAction(i18n("&Color Range..."), 0, 0, this, TQT_SLOT(slotActivated()), actionCollection(), "colorrange") ); + + } +} + +ColorRange::~ColorRange() +{ +} + +void ColorRange::slotActivated() +{ + KisPaintDeviceSP layer = m_view->canvasSubject()->currentImg()->activeDevice(); + if (!layer) return; + + DlgColorRange * dlgColorRange = new DlgColorRange(m_view, layer, m_view, "ColorRange"); + Q_CHECK_PTR(dlgColorRange); + + dlgColorRange->exec(); +} + +#include "colorrange.moc" + diff --git a/chalk/plugins/viewplugins/colorrange/colorrange.h b/chalk/plugins/viewplugins/colorrange/colorrange.h new file mode 100644 index 00000000..38e008d9 --- /dev/null +++ b/chalk/plugins/viewplugins/colorrange/colorrange.h @@ -0,0 +1,45 @@ +/* + * colorrange.h -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef COLORRANGE_H +#define COLORRANGE_H + +#include <kparts/plugin.h> + +class KisView; + +class ColorRange : public KParts::Plugin +{ + Q_OBJECT + TQ_OBJECT + public: + ColorRange(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~ColorRange(); + + private slots: + void slotActivated(); + + private: + KisView * m_view; + KisPainter * m_painter; + +}; + +#endif // COLORRANGE_H diff --git a/chalk/plugins/viewplugins/colorrange/colorrange.rc b/chalk/plugins/viewplugins/colorrange/colorrange.rc new file mode 100644 index 00000000..39d49cd8 --- /dev/null +++ b/chalk/plugins/viewplugins/colorrange/colorrange.rc @@ -0,0 +1,10 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkcolorrange" version="1"> +<MenuBar> + <Menu name="Select"><text>Select</text> + <Separator/> + <Action name="colorrange"/> + <Separator/> + </Menu> +</MenuBar> +</kpartgui> diff --git a/chalk/plugins/viewplugins/colorrange/dlg_colorrange.cc b/chalk/plugins/viewplugins/colorrange/dlg_colorrange.cc new file mode 100644 index 00000000..43f98a53 --- /dev/null +++ b/chalk/plugins/viewplugins/colorrange/dlg_colorrange.cc @@ -0,0 +1,351 @@ +/* + * dlg_colorrange.cc - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <tqapplication.h> +#include <tqpushbutton.h> +#include <tqcheckbox.h> +#include <tqslider.h> +#include <tqcombobox.h> +#include <tqpixmap.h> +#include <tqimage.h> +#include <tqlabel.h> +#include <tqcolor.h> +#include <tqradiobutton.h> + +#include <knuminput.h> +#include <klocale.h> +#include <kdebug.h> +#include <kaction.h> + +#include <kis_canvas_subject.h> +#include <kis_iterators_pixel.h> +#include <kis_layer.h> +#include <kis_paint_device.h> +#include <kis_selection.h> +#include <kis_selection_manager.h> +#include <kis_types.h> +#include <kis_undo_adapter.h> +#include <kis_view.h> +#include <kis_colorspace.h> +#include <kis_profile.h> +#include <kis_color_conversions.h> +#include <kis_selected_transaction.h> +#include <kis_cursor.h> + +#include "dlg_colorrange.h" +#include "wdg_colorrange.h" + +namespace { + +// XXX: Poynton says: hsv/hls is not what one ought to use for colour calculations. +// Unfortunately, I don't know enough to be able to use anything else. + + bool isReddish(int h) + { + return ((h > 330 && h < 360) || ( h > 0 && h < 40)); + } + + bool isYellowish(int h) + { + return (h> 40 && h < 65); + } + + bool isGreenish(int h) + { + return (h > 70 && h < 155); + } + + bool isCyanish(int h) + { + return (h > 150 && h < 190); + } + + bool isBlueish(int h) + { + return (h > 185 && h < 270); + } + + bool isMagentaish(int h) + { + return (h > 265 && h < 330); + } + + bool isHighlight(int v) + { + return (v > 200); + } + + bool isMidTone(int v) + { + return (v > 100 && v < 200); + } + + bool isShadow(int v) + { + return (v < 100); + } + +} + +TQ_UINT32 matchColors(const TQColor & c, enumAction action) +{ + int r = c.red(); + int g = c.green(); + int b = c.blue(); + + int h, s, v; + rgb_to_hsv(r, g, b, &h, &s, &v); + + + + // XXX: Map the degree in which the colors conform to the requirement + // to a range of selectedness between 0 and 255 + + // XXX: Implement out-of-gamut using lcms + + switch(action) { + + case REDS: + if (isReddish(h)) + return MAX_SELECTED; + else + return MIN_SELECTED; + case YELLOWS: + if (isYellowish(h)) { + return MAX_SELECTED; + } + else + return MIN_SELECTED; + case GREENS: + if (isGreenish(h)) + return MAX_SELECTED; + else + return MIN_SELECTED; + case CYANS: + if (isCyanish(h)) + return MAX_SELECTED; + else + return MIN_SELECTED; + case BLUES: + if (isBlueish(h)) + return MAX_SELECTED; + else + return MIN_SELECTED; + case MAGENTAS: + if (isMagentaish(h)) + return MAX_SELECTED; + else + return MIN_SELECTED; + case HIGHLIGHTS: + if (isHighlight(v)) + return MAX_SELECTED; + else + return MIN_SELECTED; + case MIDTONES: + if (isMidTone(v)) + return MAX_SELECTED; + else + return MIN_SELECTED; + case SHADOWS: + if (isShadow(v)) + return MAX_SELECTED; + else + return MIN_SELECTED; + }; + + return MIN_SELECTED; +} + + + +DlgColorRange::DlgColorRange( KisView * view, KisPaintDeviceSP dev, TQWidget * tqparent, const char * name) + : super (tqparent, name, true, i18n("Color Range"), Ok | Cancel, Ok) +{ + m_dev = dev; + m_view = view; + + m_subject = view->canvasSubject(); + + m_page = new WdgColorRange(this, "color_range"); + Q_CHECK_PTR(m_page); + + setCaption(i18n("Color Range")); + setMainWidget(m_page); + resize(m_page->tqsizeHint()); + + if (m_dev->image()->undo()) m_transaction = new KisSelectedTransaction(i18n("Select by Color Range"), m_dev); + + if(! m_dev->hasSelection()) + m_dev->selection()->clear(); + m_selection = m_dev->selection(); + + updatePreview(); + + m_invert = false; + m_mode = SELECTION_ADD; + m_currentAction = REDS; + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); + + connect(this, TQT_SIGNAL(cancelClicked()), + this, TQT_SLOT(cancelClicked())); + + connect(m_page->chkInvert, TQT_SIGNAL(clicked()), + this, TQT_SLOT(slotInvertClicked())); + + connect(m_page->cmbSelect, TQT_SIGNAL(activated(int)), + this, TQT_SLOT(slotSelectionTypeChanged(int))); + + connect (m_page->radioAdd, TQT_SIGNAL(toggled(bool)), + this, TQT_SLOT(slotAdd(bool))); + + connect (m_page->radioSubtract, TQT_SIGNAL(toggled(bool)), + this, TQT_SLOT(slotSubtract(bool))); + + connect (m_page->bnSelect, TQT_SIGNAL(clicked()), + this, TQT_SLOT(slotSelectClicked())); + + connect (m_page->bnDeselect, TQT_SIGNAL(clicked()), + this, TQT_SLOT(slotDeselectClicked())); + +} + +DlgColorRange::~DlgColorRange() +{ + delete m_page; +} + + +void DlgColorRange::updatePreview() +{ + if (!m_selection) return; + + TQ_INT32 x, y, w, h; + m_dev->exactBounds(x, y, w, h); + TQPixmap pix = TQPixmap(m_selection->tqmaskImage().smoothScale(350, 350, TQ_ScaleMin)); + m_subject->canvasController()->updateCanvas(); + m_page->pixSelection->setPixmap(pix); +} + +void DlgColorRange::okClicked() +{ + m_dev->setDirty(); + m_dev->emitSelectionChanged(); + + if (m_dev->image()->undo()) m_subject->undoAdapter()->addCommand(m_transaction); + accept(); +} + +void DlgColorRange::cancelClicked() +{ + if (m_dev->image()->undo()) m_transaction->unexecute(); + + m_subject->canvasController()->updateCanvas(); + reject(); +} + +void DlgColorRange::slotInvertClicked() +{ + m_invert = m_page->chkInvert->isChecked(); +} + +void DlgColorRange::slotSelectionTypeChanged(int index) +{ + m_currentAction = (enumAction)index; +} + +void DlgColorRange::slotSubtract(bool on) +{ + if (on) + m_mode = SELECTION_SUBTRACT; +} +void DlgColorRange::slotAdd(bool on) +{ + if (on) + m_mode = SELECTION_ADD; +} + +void DlgColorRange::slotSelectClicked() +{ + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + // XXX: Multithread this! + TQ_INT32 x, y, w, h; + m_dev->exactBounds(x, y, w, h); + KisColorSpace * cs = m_dev->colorSpace(); + TQ_UINT8 opacity; + for (int y2 = y; y2 < h - y; ++y2) { + KisHLineIterator hiter = m_dev->createHLineIterator(x, y2, w, false); + KisHLineIterator selIter = m_selection ->createHLineIterator(x, y2, w, true); + while (!hiter.isDone()) { + TQColor c; + + cs->toTQColor(hiter.rawData(), &c, &opacity); + // Don't try to select transparent pixels. + if (opacity > OPACITY_TRANSPARENT) { + TQ_UINT8 match = matchColors(c, m_currentAction); + + if (match) { + // Personally, I think the invert option a bit silly. But it's possible I don't quite understand it. BSAR. + if (!m_invert) { + if (m_mode == SELECTION_ADD) { + *(selIter.rawData()) = match; + } + else if (m_mode == SELECTION_SUBTRACT) { + TQ_UINT8 selectedness = *(selIter.rawData()); + if (match < selectedness) { + *(selIter.rawData()) = selectedness - match; + } + else { + *(selIter.rawData()) = 0; + } + } + } + else { + if (m_mode == SELECTION_ADD) { + TQ_UINT8 selectedness = *(selIter.rawData()); + if (match < selectedness) { + *(selIter.rawData()) = selectedness - match; + } + else { + *(selIter.rawData()) = 0; + } + } + else if (m_mode == SELECTION_SUBTRACT) { + *(selIter.rawData()) = match; + } + } + } + } + ++hiter; + ++selIter; + } + } + updatePreview(); + TQApplication::restoreOverrideCursor(); +} + +void DlgColorRange::slotDeselectClicked() +{ + m_dev->selection()->clear(); + updatePreview(); +} + + +#include "dlg_colorrange.moc" diff --git a/chalk/plugins/viewplugins/colorrange/dlg_colorrange.h b/chalk/plugins/viewplugins/colorrange/dlg_colorrange.h new file mode 100644 index 00000000..ce39ebd2 --- /dev/null +++ b/chalk/plugins/viewplugins/colorrange/dlg_colorrange.h @@ -0,0 +1,100 @@ +/* + * dlg_colorrange.h -- part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef DLG_COLORRANGE +#define DLG_COLORRANGE + +#include <tqcursor.h> + +#include <kdialogbase.h> + +#include <kis_types.h> + +#include <kis_selection.h> // For enums +#include <kis_types.h> +#include <kis_global.h> + + +class KisView; +class KisCanvasSubject; +class DlgColorRange; +class KisSelectedTransaction; +class WdgColorRange; + +enum enumAction { + REDS, + YELLOWS, + GREENS, + CYANS, + BLUES, + MAGENTAS, + HIGHLIGHTS, + MIDTONES, + SHADOWS +}; + + + /** + * This dialog allows the user to create a selection tqmask based + * on a (range of) colors. + */ +class DlgColorRange: public KDialogBase { + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + + + +public: + + DlgColorRange(KisView * view, KisPaintDeviceSP layer, TQWidget * tqparent = 0, const char* name = 0); + ~DlgColorRange(); + +private slots: + + void okClicked(); + void cancelClicked(); + + void slotInvertClicked(); + void slotSelectionTypeChanged(int index); + void updatePreview(); + void slotSubtract(bool on); + void slotAdd(bool on); + void slotSelectClicked(); + void slotDeselectClicked(); + +private: + TQImage createMask(KisSelectionSP selection, KisPaintDeviceSP layer); + +private: + + WdgColorRange * m_page; + KisSelectionSP m_selection; + KisPaintDeviceSP m_dev; + KisView * m_view; + KisCanvasSubject * m_subject; + enumSelectionMode m_mode; + TQCursor m_oldCursor; + KisSelectedTransaction *m_transaction; + enumAction m_currentAction; + bool m_invert; +}; + + +#endif // DLG_COLORRANGE diff --git a/chalk/plugins/viewplugins/colorrange/wdg_colorrange.ui b/chalk/plugins/viewplugins/colorrange/wdg_colorrange.ui new file mode 100644 index 00000000..3eafd180 --- /dev/null +++ b/chalk/plugins/viewplugins/colorrange/wdg_colorrange.ui @@ -0,0 +1,252 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgColorRange</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgColorRange</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>515</width> + <height>528</height> + </rect> + </property> + <property name="caption"> + <string>Color Range</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout10</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout8</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout7</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQComboBox"> + <item> + <property name="text"> + <string>Reds</string> + </property> + </item> + <item> + <property name="text"> + <string>Yellows</string> + </property> + </item> + <item> + <property name="text"> + <string>Greens</string> + </property> + </item> + <item> + <property name="text"> + <string>Cyans</string> + </property> + </item> + <item> + <property name="text"> + <string>Blues</string> + </property> + </item> + <item> + <property name="text"> + <string>Magentas</string> + </property> + </item> + <item> + <property name="text"> + <string>Highlights</string> + </property> + </item> + <item> + <property name="text"> + <string>Midtones</string> + </property> + </item> + <item> + <property name="text"> + <string>Shadows</string> + </property> + </item> + <item> + <property name="text"> + <string>Out of Gamut</string> + </property> + </item> + <property name="name"> + <cstring>cmbSelect</cstring> + </property> + </widget> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>chkInvert</cstring> + </property> + <property name="text"> + <string>&Invert</string> + </property> + </widget> + </hbox> + </widget> + <widget class="TQButtonGroup"> + <property name="name"> + <cstring>grpSelection</cstring> + </property> + <property name="title"> + <string></string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radioAdd</cstring> + </property> + <property name="text"> + <string>&Add to current selection</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radioSubtract</cstring> + </property> + <property name="text"> + <string>&Subtract from current selection</string> + </property> + </widget> + </vbox> + </widget> + </vbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout9</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQPushButton"> + <property name="name"> + <cstring>bnSelect</cstring> + </property> + <property name="text"> + <string>&Select</string> + </property> + </widget> + <widget class="TQPushButton"> + <property name="name"> + <cstring>bnDeselect</cstring> + </property> + <property name="text"> + <string>&Deselect</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer9</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </hbox> + </widget> + <widget class="TQGroupBox"> + <property name="name"> + <cstring>grpPreview</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>1</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Preview</string> + </property> + <property name="flat"> + <bool>false</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>pixSelection</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>1</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>false</bool> + </property> + <property name="tqalignment"> + <set>AlignCenter</set> + </property> + </widget> + </grid> + </widget> + </vbox> +</widget> +<images> + <image name="image0"> + <data format="XPM.GZ" length="55092">789cccbd47b7eb38b2ef397f9fa2d6e5ecae5e7cf266d0035266cb6da7ed77af1ed07b2f1aa9bf7c83883f704c56d5cd7c75bb5f95d6c9ca5f8a22114044202200f0fccffffcdbe7d3fddffef37ffe8fea625c02eb6f966f947ffb4fbb4e92ebfff57fff9fffcffff88fe160f0b7fecf68389bfe6df41fffc7fff80febf96fd6df9401ff5fcff64232ffde36244f7a762ac953fefd56f29cf35cf2a267f3072ff9f733c906e7836493f35eb2c59fd74ab6797b1f243bfcfb46b2cb7fef0a1e72799c5af2907f7f94cce5732cc963fefd483297cf3a8387d43f992999ffde0c25f3dfb79a64de5f662099dfcfe924cf386f24f3fe4a44ff0fd17e5b327f9e772799dfcfb8078fa87d662499cbebbb9249de6fc9bcbd9d2f99dab795ccc7b31a48e6e3b71a4ae6e315ed25f3f1b04f82a93f0dc1636a9ff32999daf32599f757a54ae6fde17e48e6fae23892b97e78a2bd63ea1f438cef849e97e892f9f7652b99b76f3d91cce53763f0947e6f08fd9c1137b664de5e43c83fc7f53bf0022cf475499c8be719c4f113d824de5cc01671fd0eb6895dbaff50d8ab174ae6f2ad3ac9a47f63c924df4832d73f732a99f777f324998fb73993ccfb5f7f96ccc7df3a49e6e3514592b9bd3aa664ae1fd6bd646eaf9a2b98f4ddf52573fdb58e60d89f6d49e6df9b13c97c3c1d45326fbf634826ffb2934cfee40086fdf88164de7ff65232d9eb9b646e1fa607867e9bbe641a8f816092cf14f2423f4d070c7d8b9f25f3e7bbaf60e89fb791ccfb3b15df43ffe22f30f42f13f240ffea1b18fab716bf877ee967b043dc92bf1f0ea16fdd9af3a8f740bc3dbe64f2f70bc9bcbfcd2fc9bcbfbd4432f90b4730f5cff55e3297bfc9c0187f732899f4772099c6e35b321f7f6b0fc6f8daa6649aff7692f9f3724d32d7f7cb4932ef6ffb4e32e9b302c6f86723c9dcdefc50326f9ff32e99f7975382a10fd75c32d7e795906742fdd3bd49e6df67a2bdd09ff20886beb89164fefcd54932ef9ffa2c98fca72bda0b7d6a9f25f3feb0c4f842bf9a07b0d02fd13fd0afe2090cffd6c660e85b24ae87be05a40f63e1df8277c9bc7debab643e5e575732efef6e2799cb1bfcf89ecbdbed2573fd5cfd781e1fcf952d98fa3b91cf277f74cd24f3fe0f3ec08807ba8d64ae9fc54232e98f27993faff9f13df787ae680ff4d57995cce57103c95c7fac3bc97c7c7c5f308d67b8028bf9f72299cbd3dc49e6f2981f92797fd69664de5f7e2499dbb33b92ccdb6f2dc1d067772099fca72e99b7ff6a49a6f946f437f4b9bd48267934b0d0ef77c9bc7dad68df9cee9fee25f3fe69447fcc31df88f1843eaf6e92f9f3da89649a0fee25f3f1cb85be41ff0331bed07f5f8ca7f0a7d43f13a1df9d2a99f777f32899dfffea80111faeae92b93cee41f090f7effa0c463ce77f48a6f9ee51321fafeb4930f547bb01433fecb164fe7cff5b321f2f2f92ccfb3f93d793bd745b30f421ae2593bfd94be6fd1b2692b93cde4e32b79fda164ced8ddec1d017e74332f9dbb564de5e772899e299140c7dcaa692b93db8df92797fe61d18fe3117e303fd59b792e979b164de3f8918ff05f5cf46f40ff4c715e301fdb9bd80e13f57f792797fad4a30fce906bf17f3f51ae331c4fc19a13d43f89780e693a9f0a7ed028cebfd4e321fafe6198c7cc00b2473f9bc77c95cdf4a4ff0908fc75a5c8f78bfb52553fcf02999ebbfdf08a6f10e5ec1c2bfdc49a6f97c2b99e6ff27c9642f3fbee7fab416f2407fc299643efe912f99ec692099cbd3b492b9bc9ab8ff94c63711fd0bfdb2a792c93e2ac9140f689229df5125f3feed5660e85ffd2a99fce34432efdfee00867e5e14c9941f8ec0d0bfcc904cf9572a99b7a76e25f3fe73c760a1afaa646ebf99e85fe86f2ec61bfaea0b79e11f0ba12f2eda8bfb4b7d267b98897c64dd81a1cfeb503297afbd934cf1d45e30fc93f81ef363b896ccefbf3a4a26793dc1149fae7d30f247ff2a99ea1d3fbee7fed68b05a31eb1924cf9c2083ca5f6076bc9542fd948e6fa900e2473fdbbbc09463d630246be1a6692f9f84481643edef95532b73f5df01cfd7993ccdb7be92453beb5924cf3c14432efbf5cfc7e01fffa2999e6bfb1646e5f9b022ce2cba364de3e37114cfec132c0d047f74d32f9e37b30f26b2f05431f5763c9bc7f42c1d04797e6cf99d0c71be41fc21fa52a18fe24207d9f0bfd5a1d04d3f8570fe009d573dca3642e7fbb054f697ca237c1246f3a944cf53a5b32c5a72f60f81bd796ccaf4f2bc994af2d2593be6f2453bea682e7345eed4e32d5ff14c9bcbf2f57c95cff7dd15ef8a35097ccdb93cd25537e2bfa6b3124fffd055ec2bfcc24537c548045fe518331decda7647ebd2eda6ba37fc478c01f6d44ffb8d43e1ded17e3af3960cc97f5022cf481e257a6dd149fd96bf08cc6ffe64aa6f92604c35eec4032b7efab2799e2375b30e94b2aae5f50ff58aa642e6fe148a67ce1065e927fb80d2553bd2494cc9fdf3e49a6fc45c863c07e1dc97cfcd3a3606a5f7d05633e887682497faf4bb08df8e2030cfb2bc9de17a2ff4bf49f886762f4cf10f666bd80618f3e8dff92f5177f5e914be6ed2f36e005c91b5f24533cf22598ecafeec04be467ae64f28757b041bfaf5f040f29fe68c0268d9726da63917e14a2bdd0c7f424998f5f44fdb314fd91bf83a18f8105467fdc4660e86783e789fee94a30e215e3118c78a3a0f9dc60fd45fa34072f491fc329d8a0f685a964aae7dfc0265d5f2f05537f568f60d86bb091ccfbe36248e6fad988dfbba85f8e24533e48f66f88fe892b30fa67634ba6f97508467f6d1cb0a827435ed11f35fa6388f9c9a7f8c814f157fd065e92fe5f6e6083e42f5cb0897ac417d8227dca3fc036f55fb305431fba77c1747f3b02bba4df3ad9ab29e42f669229df46fb647fe460d8d3aa0243fecd2758d4bbefc0a21eb403a33f2a8a772c263f6fff35055ba827d1f85aa2bf2f1a58f4f70a8cfb252a18febdf1c0f02701f58f2dda7f5d48a6fe9b8071fff21d2cfc83603caf51c1b87fb106433f4b1a1f87fd17eebf1b17ec903efbd43e46b0f71a0c79cb2d58c4e72d18cf2f1bb078be0dc6f3339abf5cd11f8906c6f5de1a8cf846e3f6c1cbe724df068cf6548964ae3f1b130c7f9096608c7f7603a3bde90e8ce7bb2f60b4d77e00c39f075c9f98f639e47fa34832d7e7f84c2c9eb7ba80216ffb08c6f3cc042cd64f1a30e42f9760d88fe382d19e1ced19c11e42aebf0cf17cd306435ecb04a33d610e16f20b16f1470a16ed3981457cf9443c82bdae2660e19f79bc341c8be7d70e18cfd71ec022df8ac178feaa05e379d72bf108e3df70ff369cc8fe1d8345bc9c81d1fe60452cfaeb7a03c3be74ba7e2adbd382f1fbcb3b18e3910dc1689f4df24e657fd4603cafb2c168bffb0cc6f32b1ebf0c67e2fe01e9d34cdcef1283e12faa6f30ee67f860e1ffe660a1efdc7f0ee7e2fed58c58b6e70cc6ef8d002cd6173db0a83f2dc0d0b78edbf77021e5bd078bf6aec1f87d41fabd14f2155bb0f8fd108cdfeb2330da93de83f1fc8ac6d310f2ac1a309ed772ff3734c5fdb48d64ee0fb72e58d4e75ec0f87d7202a33f0d713df4a5237bb7e4782a60b11ee681d15eed112cee1782a1cf158f4f86b6b8bf6581c5fa2af5a733823f762d30eed7d2efdd11f2efcd1d18d76bdc5e468311f2a3c007e379f5082cea75f760e8fbfa8d782cf49dfba3d150fcbebc030b7bdc83a17f099faf472371ffe64c2ceed73460e883cefb6b3416f7ab4fc463e10f2c30e46b8927e279b94b2cee6f6cc1d087ec092cec4930c6f342f24f85fc46442caef75660e8cf85fb93d18cfd9ec783f1162ceaa37cfe19cdc5fd3ceabfb990d79d80d13eeb152cd64fe9fa85f8de7c05a33df9188cf66cbec0d0c7f50d0c7df3b8ff1f2d85bcce002ce227078ceb1d0f2cfca54e3c41fb6f74bd21ef5780f17c5d058bf53beeaf46e618ebd77a2299c77f5bba9f25c6b7f4c1c2bfbd80d19eeb07f104fda1933cb678de2603e37eba01c6ef6f57b0a8ff71ff3d72c6a8b7e8d47faee88fb507c6effd188cdf3bdc1ec67d38c739e2e3c5a63393e21723269e60fde4f22c99d677b93e307577285eb7b8fd8f27ecfe9cf50e0c7d8a79ff8ca7ec7bfefb6b412cc627db81c57e823730ead9eb1158d43fb8bce399b8fe7a0716eb5d7330c663c3fb733c67eda1fa484d2cc6c39a83a11fed193ca57a651282b13e16f3f96ebc9860bdc8d880c5fe810c2cf21bae8fe3e544d4cb23c93c5ed30a30ea071b170cff92d0f81813d443d71730eaed9a07c6f53eb7b7b1c9bee7fa117c49a6f5024b30c5b3760cb6b19ec9e3adb13331e8face93ccfbaf3883f13c23013ba8a72e05d3fd0d1b8c7c734df23b53d8df86facf9da03e7e1b80f1fc82f7e76430813e6d63e229fa3be5e333194e4cd40b52b04ded31b8fe4e4653110ff2fa0a73a736f28d9a788afd67fa180cfd6a1db0588fe3fe7f32610accfb77c3f59721f2c77c493cc5fe0aaf00e37eb731788afa4e059ed1f8361f60d48f6dde1f93d914ebc7460a46bd2fe4fd37994fc7940f6cbec1e89f98cf5f93a578def5013c433d86da6f4c51bf09b9bd4dcce982f2b39cebcbc49a22fff6b83e4dec29ea15d95932adb704c433acffebf43c776ad1fd039d7886f5d315bf3f5356f09acf77d3d1d4a5fa65734f3cc3fe035d134cf7372c30ec355b824dc413dc3fb0e9906574dcdf79c4e2f74501c6fa5b74104cdfb73c3e9d4ea6d6887f7fdb10b3e791bef1f9940ddf1ceb078fe005f5b7c5e7e3e96c86f58f8d0246fd3a76c1f311f9b377b043e31bf07c693a9fa1de19df816dec07f804bb584fa3fe5accc47a86069e517b82002cd6f775b043f39bc6e3dde9923d8eeb7332035bd47f3705ec60ff824d3cc7fecf84ebefd498c19e2faf609bfa2be6f9f0d49c2d51cff5c016e5fb2b176c8f78fb8b15d8a5fa99c9e7d7a93543fdab1b831dfafde6287844f5d10e8cf1af49bfac39c63bff024f499e98ee6fb3fb937f7d023bd4fed407bb435aafb124d37e2d5d30b53f03cf87d43eeb0d8cf5dd7803c67cb7e1f63d75587f707df1e9fece7c30a2fd5d7b30f6b3469f9269fdc792cce5594dc1587fba52ffb84c1edebecd5e326f7f41faebceb19f2cda8271bfa6133ca2e727e0118d4fb2164cfa9c2892f978af4c30eca1f1c19321d7bf2bff7e3660e34ff5e53bb043cfaf5dc174bf6c0076a97fdb929805acfcfb6d0446bdbee4ed9f0d857eddd660f89b6e2298da5f05c4ac3f687e6bc0c311ad87e07a263f9f0fda77f094da537f8067245fc5f569369a1963d29f2b31eb5fdabfe20ba6e7a777e0d188ff3eb9815906c29fa78227d04f053ca3f6b65c3f6663260fd553a93d2cfca4fec91bc95cfeea041e517f5fb8fece2662fcdd023c86ff33c1d31167cd06cf21cf5c308d679d8017d41f0df72fb3e9cc1ef3ebab14ec8c69bfc05432ed47d38885fe5d4cc9b4fe37028fc8fecb37c9649f25784cf6ebbf82e7f47dbc042fe87e05f5cf4ce8936b82e7f4fb36113ca6f17a002fe8f986b8de80fe8bef4dd28fc292cce52fa68269fc4d1effb0db2f49decd0c0c7fdc92fe2ce6131a3f6d2d98fcb7bf02cf49bf370330d68fea5a30fdde38831dfabea3fe59b2fea178b0009bd41e4f03db23aeff37713decb5f00593fc2df5a7c1ee47eb6f2330eadd17156c8ea87ff7609bfc45590b267f78d5c02e714bfa6ab2f1207ff80136c87ef22918f34dfe06c67cd186c48b018dafcee3cd99c5ee47faa48217647f99609bf4c7a0f1b2160392afa3f6da6cfc68bcd69279ff949f6093daef4ec1f067f5817831a4e76de8f70ebb9ece177c806d6abfb3235ec0dfba2bc9b4df9bc6d7ed1376ae5f5c3fe703263f6f4f520a1e53fc99102f66d4be8cf7cf7cc8e4e3d7673e784c7cdd82a7d4de5a03c3fe751e9f3265c2fca09be009d94fc2e397394b87c99f186bf08cfa4fe3fd3b9fb0e7717dacc792e97c0b8f5f58f8bb20d6793d613e5f2cc7b49fc5005bd49e35b56fb1c4fcecf1fe9e2fd9f7743dfdde582ca83f8267b049ed59f3f9686eb2eb69fd782699d62fa83de67244f67de1fa3eb79643b237ef2698f4ab9e8347d4feb0008fc99e1c6a8fbd70d05f4762261e6f9f46e3e730a6f3160618fdbbe6f9c6dc5d0ea8bd0df5bf6b88f89aebdfa25f00a5f8ff4e32edd749c0636aff66019ee17939780e7de2f92a73f643e8bb031e537b7c133c237bf5dec073ba7f44f71f1a225ea3e78f447f79dfe011ddcfe3f22dc68c29feff06e379ba0e9ed2ef0b1effb1747d44f3b1fd0d5ed2f78d0236c65cdf367c7e5fb0009858bf07cfd15f7bf082f4a3492473f96f19d8257b6df8f82e66cb05f55fbe223630ff6f797cbc98b3f67079527afe82319d17e1f6b7581a03fafdc693ccc7d7a0fb194b97da7bbb111b63f2af1bae9f0bd31810eb7cbd61612d1dd2bf94da671943c8cfe7af856d8c69be6e0563be594f2573fdd7b8bd2c1c763ded0f53c01392c7bb4ae6fdd3717d5db8c684fa4bbb134cdfa767f094e28180fba3e5c080fff15fc0b309f5ef9764d24ff13dfc43cae7a3e5d0807d6cf8782d47acbdfcfeed0b783ea1fad50ebca0ef6f3ed82079a32f30f2c5644f6c627f5acce7df655fd0e1e3930460a662dc3f1cc14beaaf40133ca178a8069bf47cdf90ccc74ff3c10e8de78dfa676c8afd09b564daff5982b1ff36a6f64c58ffd2fed40b7836a1fac504bc9c50fd6101c6fc97abc426e2b3700fc67911f3018cf33ac99d643e1edd198cf3176e07463da4fa0063bf8826be47bd53e7fe773965e345fded806db217eb1d8c78f29612b3f6923ea9603cbffb0663bf4949d7b38083c663b3022f68fceb7bb043f6118682a9ff8c02ec92bfcbe9fe7dba49f5c30d18fb636c9e2f2ce7ecf7144f2a6097e4bbe5c4ecf7140fcdc0b0b734018bfde03a784af3c53504cfb15f47dc0ffb0bbb8160ecbffc002fa95e58edc1d8bf1a4dc1163d2f36c1a8575495609c5f1a4aa6f3a134febd83e2ed2f376093faafa3e72fcc01f1f50b3c217ddd5660ac37ad63f00cfe5407cf69beef5230ea35c6026c60bfe55532e55b39d8a4eb6f73b0d8df20ee6f637fe04a32cdff03b043fd757b904cf9d9168c7ae7ed2299ce7b3692697fc898d8c2f99ddb128cf3b317f49f85fa6348f75f1a06d9afb604c37ff817b04dfa1c0ec10ee9bb4ef22ecd015d7fdd8047345eb5079e907e598e60d2d7b40363ffe3762598e2d5750e16e703d692297ffc128cf35768af897afb36108cfaee5c32d56b0f9269fe2e24f3f61731d880ff5125d37ed80558ac974c25d37ec09d64de7fe64132f73fea27d8a2f15732c9b4bea008a6f655a23fb1dfb28c24d3fe470d8c7ae1ed5132e95b2099cf8fa6e82fd4e3c32fc9b4bee3125b38ef7723ff641816d99b7d03dbe48fc22bd8a1f9f95a825d9adf4af28706eb1ede5eaf060fe97aaf133ca1fc5605237e6d8ee009e5bbd5198cf58b4efc1efb6fb71730f67bae66e025c5df8a09c6fecae020998fafd248a6f3ba909fd93b6f4f71025bb0af52329ddf9849e6cf533fc036e993924ba6f96726993f2fcec00ef57ff12e99e2c34a32ed7f0cc1f017d5bb649aef7cc9bc3f22f13c97fa4fc3f859388f5a6d25f3f69443c1d86f3b06e37c4be54ae6edd354c9bc7dd791643aefdc4aa67acf2b18e7f134f13dced325a4ef26d3379affc95f9826e2cb952a99c6f7153ca57835fd0463ff691108267fb579028b78c2001b34dee14532bf7f62814df88b4832d52f2ab085f59d0118eba3752899ecff2699eae307c9b43fb405431f9454329d2fbb97ccdb938cc02ee95b2adaebd2f8b590dfc279e448974ce3f12998e67b4d30ce074713c934ff403e0be72d2dba9fc5e607defeca014fc85f5413f094e2313b954cfea0114cfe467901233fd41792a99e6a49a6f527c198afd71bc9549fb9822dea8fba944cf9502799dad782b17e6d7592c9be6782495fea42321fdff8c7f77cbcb477b043fa1deb9229ff4904e37cc697641a7f0decd27828aa647abfc45032ade7b982495f13b25fcbc2fb0c944032d9cb93606abf5949a6f314cf60bc4fc00a24f3f6b79960d29f5a914cf11dfa53d87bf82999d6df303e16ceb755a4cf369b3fc8ff7660ec3f57de04933ff0f760ac5f665bc114df2b67c1a44f57156c507f5f1cc9b49ff3198cfdc69bab60aac7ac4f601be7fd22c1781fc95132ddaf95ccdbabd492b93e794f60e883229e87fd9ef959326fbf3a964cf9e00318fe5d9d4be6fda192fed916ce83a92f92a93dbe64ca8fd11f229e4c6f92f9f3938164ca1f4f82b1fe994ae6df871f60acf79a6bc9bc7f62f49785f3b1b75230d95775914cf30bfacfc279b22df90f47c413a621995f9f7be011f99b6d2b98e2136d021e4f683d63059e4cb83e7ae2fa19dd4f3b83e734df943118f581f22099cba33c8397549f592dc026d69b8f9279fb6f9f60e453d6156c537f5a63c9644f8160aa47695330fc8dee0aa6e7c5b964f28791648a6fe692297e580aa6fa6628da8bf8c3bc974cf9642118fa38954cf58f89649acf1692e93c27e9936361ffbdd149e6df2b9e609c1f7d96ccf549ad24d37974e887d0676721998f8fba924cf1fa9364b247713df687754f92e9fc672399ea45a23d581f35af92f9f7b9f81eef13885ac1181f4b32d5dfa10f16f6a3044bc974dee9158cfd3f892399fcbb2d993fff26fa6786fd3ba23f711ef146d7bbcc7e283f7b944ce7995ec0639aafab25784af671db0a9e52feb200cfc9fe320f2cec650f5e52beae7d49a6f319e2fe4bd457766083f453bf80b11fa878154cf6b2adc1585f37c4fde0af235530f251717fc45b9e90d7c17ca848a67add5530ad1f74a160aa8f76e279c8e7c34630f97f3b174cf2379a645abf247fe35a781f90ff2818f3c1443297571d49a67cfd4930cd87da1b58e8ff5630ece74b32cd1fa564aaef7982697dc87900633f73694ae6faa0be4aa6fd789a648aa724637fd25a32ed3f79924ceb3d3330f6f325ad64de1fd98364927f2598facbd42553fd3594ccafcf311e16cecbdf22c95c5e652a99de7f267e8ff3c9e1bb641a6f4732bf3efb008bfd812f92297eb32473794b31bec87fa30a2ccea3ee0493ff30f79269bfe23718f53e6b2099ea0377609c7f34be2453fc7b914cf91c1f2f63c0e6478a0fb6e019d58be207c1538aff8fe039e503712b99e6eb5c3297a750c04b1afff22618fb1922c1347fc73bc9b47f4630f2f9eda360b2efab2e98fcd1ea158cfd83452598f47f6b48e6cf8feec1a8b7a40bc1f05f3bc9bcffb61918f596f85d32d5e3447fbaa48ff94030f6ffdc24737bf267c416f6a7ac3f2453fe580bc67e99122cceeb9c24533d6b2299f4ad108cfce30773fd500cc9341f7792a9fe6b0ba6f5da6b2399ce372ec1d85f1d9d25f3efd59b60f89f3bc9bc3fd4a364f22f6f60ec97543792797fa8a960d8c74d32f9932918f61ed49269ff832d99e44d24f3f61a23c1d43f96fc1ef1fe1c8cf763448e645a3f16cfc3fe3d632899e2955832cdafd01f0be7d5ad4a32ad9f3792b9fcc64030ced3d792b93e9723c9b41feb02c6fe67732b99f68b7c4aa6faa3180f9c17f6499ffa032dc46bf098ec5d8f24d3fe08133ca1f530ed049e527eb7f50593ffb83c48a6fd570a7846f7d36b30e6fff25b32d5ab73c1145f28ef82299ed1e660d473b64f92a9def92698fcdd5a3cdf46fd24914cfbcd74c9b43e21e445fda611f7437cb1fe124cf65edcc02edd3f7225d3fb001e05d3fc5ebd108b7879bb93ccfbc72f05937e66a9605abf538e92493f56e021d99f6249a6fa5b2b98fc9f72914cedc3785a789f52f12698e42943c964ef17c9e40fe792697e1849e6f2648e60ac470660bc9f243b4aa6fd3fa1647ebda20826f9d24c32ef0ff55e32d5d7447f60fe2f9f25933f5a4aa6f8e62c18f9502299f40ffa61e1fd4b4a2899f6279492495ed19e29e297028cf795048d64dedef05530e29137c9e47fe4efb19f740cc6fed152134ced0f55c9fcfb488c17dedf74b9934cf64dfa3c326754ffab0cc1643f510ac67a78ba04633e77466083ecb309c026cdffa921998f476582b19fa7ba0aa6f93e5e0ba6fca6188051bf4b447bb1bf4aff00237ff60f92e9fd41f792e9bc7d2599e6f717c1d8cf247e8f7a5d160ba6fecf23c1b4bf21a0f86264e13c72f82499f2fd57c1f06727c954bfcec098df755b30d9ef7a2e98ecdf78974cf54cb447d47b3d5330e2cb0fc9b4df47dc0ffbd12ea9647a9fec1e2cde07f92e99f60b1c05239e3e4ba6f9df974cf9d74932ed9ffff17b2e5f70014f90ef288261df8664b25f5332bd6f0ae36be1fc4ef92499f22d4b3297ff593c0fefb7525dc9e4df3c30de5fa53a9229feb12553bc2ec66f46f2565f92c97f37609ca7b4df25d37e825a32adff89fba39eaafb92293fea24f3ebb7627cb13ebbfd944cfbadbf2453fe37154cf287a664d257d15e715e80fa6fcce673f2af117846f94076075e503d2188c1d88f9a9b82c91f2457c954cf38832df2279ba9647adfe70a8cfaecf62098e2ef6e2699ce27ed04533cb2d5c0d8efaa3c09a6fa46f12199ec5d3c0feba51dcd9f63517f5dbd0886bd3f4be6d76f7f30d59b62c164afde5432d5271f2453bdf0118c7abd77124ced4f1ac914afae2553bd5edc0ff3b9f32498ec6d1308a6f66c55c9341fdd83313f9ba23da8ef46a564dabf664aa6fd21f27b8a37e291643abfe249a6f9ce174cfb13a2028cf78b25b9647a1fd4a364f20fdf92c97f0c25d37a512599d607a03f22bf375ac994ffa49229ff78944cf94a2618fe48fe1ef59e4632bd3f270163becf2ac994bf8beb71fe4b0d2453bd27964cf552d13fa807da2f9269ff612499e627d13ed40f424330b55f13d763bfc6ed4332c50f37c1f0f78a64daff3d964cfb43c578637daf7a138cfd39429f719e6745fa30314df21f590ec6fedd32134cfbb10c5d30f98bcb8b64da2f3c01dbd87fbc174cf5c92001e37c4d25eee760fff1b7605a0fc8b792e9fc81b8bf43f149740263ff68fe2a989eb722fb9c8878201849a6f75f9e25d3f37cc974fee15532bdaf752898ecdd0904d37a475080512faf7e30e9432e18e7f56e82914f5482c91e0bf13ce4ff7e2698c627fb924cebcfe2f7d8ff1b3e80719eaa934cfaee3992491e717ff80f6f2699f22ff13dcecfa753c9e4bf0e92293f394aa6fd139660b2cfc8904cf9df4230e68b4a32add78bf1c0feda740ec6fbebcab3648a8f2792c95fd492299e1848a67ccd164cf25b2d58f887ab64f2379d64de3fea4132bd6f4efc7e8e7827944cfb7f1e2553bd4f134cfa6c799269ffb6781eea8df14432b57f2718ebe591645a2f8b05231f15bfc77e0f652699e229f13cbc7faa9a4ba6f361427fb03f5013fa8cf5e2c495ccbfd73dc924af180fec0fd33e24737922f17c9c6f6cc91ea626f69b5e13f082fccfe64d32d547bfc0385f565ec0886fba1cecd07a663394ccfb237b05633d627b144cf6779949a6f75fd682c93f06349f4dc5fa433d154cfaace982697d721b4aa6f3c11918f585742299fce5bd64aa67958229be5ac560ac27ac12c178bfd79b64da0ff1e37b7adf95fc3dcef70592a95ebb174cfe3a10cf47fda01c08c67e1b5f32bdcfb0134cfde12a92493ed17f585fc81f25d378dc49a6f8e253308d57249e3f417c7a904cfbcd7e30c5d382b11e982592797f24df82b1de954ba67aa6907f4af69baec138af6c8d24533d692f99ea733bc1e4ff3c0b2cde37be944cfe712499f2b1b964b2675732c52bd0670bfb45d54832e58fba64da0fb301e3fd8d4a2499d67f857ee0fc72f82d99be5f81713e3e194aa6fd49e27e588fb89ec1884fae13c9d4ffa27fb0bff0229e67537fae481f66e612fb2d776083ec3debc026eaa53618f18a3b0323fe580f04d3f5c98b64da7f63825df217852e99ce77907c33113f6c4dc134df6f1f24d37c9982b17ee04f05537b9a77c9148f88dfa3deb07a92ccfb7f73168cf365778229be48bf25537d19f28bf501e55e309d4fc94f92c97fcec158cf2b12c1e41fbb4fc9b43e3d104cf3f7f6158cf87ebb170cffe448267942c1e47fba05187f1f455049a6f5614330f4ff0d8cf3b88ab83fde3770d94ba6fafc12bca0f6a557c1c80f6dc9644fb964aa7f1492a99eb1934cf3f718bc44fd632199f2ab67c914bfd782518f16e389f78346a23dd8bfa58c25d379ba4030c95b5f2453fc5c824deacfec2299f6eb6c25d37ae74630e2b94632ad170bf9b13fb87b964cf514713df61bd4aa643a9f0f7bb31cecbf10fa28f6e3f89269bd83e2adb9399f52bd33032fa6fcfef9086cd07e8d95f81eeb1b97a964b2bf0dd8a2f958ff02dbb41fbbbb825d9a3f2eb5608a3fe28560caafb6141fcd45fdb11a83b11e180f05d37e5c5f114cfe669d8051ef6f3dc1a40fab108cf3d9e55a30ce3b1a60d4d78bab649a5fe5f7645f978364dededbb360f247452899ea616730d6e7d6779269fdfb4330f9bbd4148cf8e7058cf5b8e44932bdffe25e30f6835c24d3f9d1b964b27f713decdd16ed9b937fd2f792a99ed2082679a247b0380f33964cf3ab18af05c52f57d1df381f5baf2453bcff0046fcacfe60daaf6a4aa6f9ed4b30ce7fce25d3fedd1918f65f8af1c37e6d4f954cf9cf5a32c927fa17fbede254326faf22aec77c1bd582a9fd971d58ecef3524d3fe5ea1bfd84f97d1f82ec47a83be124cf5c8ca07dba4efbab8de9df2dffba44f0b51afeb5cc1747d32154cf61eecc043ccf74f9269ffd3098cf7495c1e25d3f9c14a30ad9f281f92693de2001ee3bcf34430e94f71114cfe259883f17ef6b52599de2f36144cfaa23c4aa6fafd188cfa79d60a267de832c1345f1786649a3f7e30cd97a2bdc86ff55232c54fb9648a6fc4f367e44fbaa1649a5f669269ffb7f87e4ef6915f2453beaf4ba6f9443c1feb655a2c99e47b944cfb532493ff6bef25d3f86ec1e2bc532318ef1712fa82f3cdc55e32b5ff1b0c7b5acd25d3df9fa04ba67ac25e32bd0f44b4cfc0f95ad13f787f759c08c6fb8f34c9141f6e2453fee80b46fe22fac7c2fbafef24933f17fa8efdf9590dc6fb8d4a8a079626ceb3d513b04bfa5a527cb664f645eb65067848f359fd8369bfec063cc27ae45532d5e31f25f3f15c3d83315f5d12c9544f740553fe1e6592a93f3dc158bfb88127145ffb9560b2873a96cce5d75f25537ce90ba6fa62f283a95e2ae49bd2f82b0f82c93ef385645a6f17ed453d39984aa6fac04c32fdfd5607c1a42ff14a30cdb7b74232e5a76f60e483fe5132cdafb960c4fb5f60c4aba52218ebaf7b30d69fb6e27b9c1f0ceec1d82f962b92c95f1d24537da7148cf93d05239f534f92e9bc8bb81fcefb1547c9544fabc1383fe68af1c67e92f807d3fe43213ff6af7662fcb19fdaa37cc410f5ebfc5e30cd1f6b07ecd2f85a347e06332faa8f1cc0d0efdb17784cf6e91a82499ff44ff004eb318f92693fdebd649adf5f05937efa67c1347fe91618e7bb6e7782112faa60ac8736a1601a8fac00a31ee98c05e37d155bc1347ff8aa647a1fc009bca0f1f21682c99f9ae2fe0b6acf360763fd62bb168cfcb0148cf7790879f1be9ad4954cf53cd17fd8bfe49f24533db1164cfdbd7d07e33cd346fc1efb17b789643a4f300423bf303760bcdfec42f669b27885ee47f38169e1bc977e124cf18d3706e3fd11fa163c22fdda9482a7b43e7805c3ff058660ba9f2b9e87f364d14632d5fb4792e9ef37fe02e33cd926028bf364efe039c9b712f747fdd9ad24d3f58231fee58b601affdb9b648a6f7230dedfe12d25d3fa760a467d3817f218145fd99f9269bda1924cefdf93df23fe7e009b349f98623c2c1a5ffb2298ee97d8609c3f32e6609c3f8b2cc9646f0bc914cf3f4aa6786607c6fe958ee20f8bcdafb43f81e20b165e93fe5c3e25d37e30f13dea3ddd093cc27ede2d18f5983804e3fd1d9a25989ed7168269ff61fa089e223f9e8167d47f862699d6f39e25d3fe68152ce2b70318e7c9ec67c9f4fe12138cf70f252918f1932b9e67507caf08f9f1be9938069b648fc15e308dbf32108cf7df88e7637f627c150cff7a0163ff42f000c6f99c88ec9b4d37a867d1fc62b3f1a3fd3c743f5b8c5ff102463cb2da82117fb4df9269bde12498ec510f25d3fef01c8cfcb8b425d37eaa5232bd5f2506235ed85a9269bda4154ce31d89f6cef17ea8037841f76b447b17d84fb6012fa9fd6b211fea49978b608a4f0c156c423f3bc9b49f3602c31e6f7bc1d0bf4a32c50fe44f6c1bfb3be22918e7e93a6287d907adb70ec063eacfd51b784afdb3d1c0c85f8a5232cd97afe0398ddf652d99fcf75130e5879d09c67c961482c97eae7bb049f74b3ac9349e86649a4f2692b93cb978be8df749b88229be509660eca7f39f24d3f922713dd6afaedf8269bcd690c7c6f9d755001e52bc5b533ceb5a63d29fab2199ce63edc1139a9f82083c25f9f5068cf745dd2cf082c6238d25d3fb1d378229bf503ec178dfce6a0946fce9bd0aa6fe5ccf04e37d0af27aca77ac1bd8a2e747df9229fe2dc136f98ffc4530e9f34a934cf9f10fa6e78be739387f48fde9daa8f7273c3e310716f67b260f9269ffde1318efefb91e24537dcd06e3fd79f6156ca0deb1904cf6a080d1fe6a2199e67b5f303d4fbb801dd8fb0a8cf8f9a611db78ff5dac8211df745f60d413133e7e2c389be17ccc183c27ff97459279ffac4b30de27947e0826f94c4532bd7f5d032fa9fd6d2a784af58e21d8a0f9e1aa48a6f53f5b30d58ffd6730de5f94ad89ed01d9ef86eb2b0b2eb0feac6fc04b92af7525d3fbcd8f6093fccde64532d9cb4d30c57fe1128cfd33eb77c1a41feb028cf7355a1f82e9f9ee1cec62ffea9b60f227892918e785f0bd8dfdafe9b3601a4f270463fda81980f17ea59adbbf3966fd41ef472dc14bf2075b1b6c60fdec4132d50f0bc9944f1cc126c693dad7bf5e9ff2075c6f63bd6b45fd33b1e6549fb8adc0580fdc7682c97fdd5ab035a5f74309c67961e50bec523c1de2f736eaf7f11c3ca4feaba8bfa6d664467fffdc080c7f53b492a97e6f08a6f686776013fab4964cf69982717ed224ff30b5b15fe81608c6fbd3ce60c48b2d8dd78cdd8ff2eb5430c5839b5730f2dff60086be74a4af33d6ff148fdd8391ff6a74bf390b30693de808b6917f64c436ce8fdf1230f6bfb7345e0b6b3a27fbe9c0f319bdaf8bfcc782a5f7e43f0f60cc4705f99f256b3fedf71c826d92ef3625b627349f68dcdf9b2c9f9b927f237d3458ffd1fc5b8327f007241f530f1aaf6b00467cad51ffb2f8674efd41fed5b6711ed0e4fac192cf39b57733022fe97ecf977feda32abf7d8c9f3e26ffa7827fa74fcf0afb9da5daaac3fe58ff6a0be8f3df21cb2f72b9ecf3bb5c0afe9b90afff77f7df5116d62247f5d81ffad87ddba87590cbfd87bfb3f1f9779605f20899fa6be8cfffb79fff167b71e9f393743ffadc1663f4e33aa96fbdedf8eccf3f18b9ffff65e16dfbc90e6009240d1fa9bf2b3bc9439ee0df4d1661eb3f64f9313a3f24f3e4e717cbfa7791e5379fecfefa91d758f05a8e94457a8a7f2b590235542335561335553335570b364ea55aa917b5669f86e951ab76ec7365b2de544dd5d99f15ff9dc67eb1fe379365a3aed827652391a85bf6b963d2ecd43dfbec982c07464726dd91fdfb4e3da9f74cce7bf5817d0c76e53ff4daff5b6479e43dfdc446e699fddb597d515fb94ebda9efea87faa906ec9a9449f8c524f85607ea501da96375a24ed5993a67d2fc1bc9c25a7a5637ec9f91ba607f02d8fd92c9f2cafe6929aafaa4284cc7be15431d2ba662b18fad380af31a8aa7f8ff3d92fcf7cc954aa0844aa4c44aa2a44aa6e44ccf5ca63d2dfbf4b6622a059b45064aa954ca45a9954669954eb92a3745537465a5acffe8b5ff37cab251b6ca9db253cf8aa2ec95036bf1513929f7ca83f2a83c29cfca5979515e9537e55df9503e952ff6dfbf9581325446ca589928d37f23596c65a6cc9505d3b393b26413cd83f261288661b044c0b00dc7700dcff08dc0088dc8888dc4488dccc88dc2288dcab8a87746fddf23c99f9345b58ca6ff23a390df6677a3353ae36adc0ccdd08d95b13636c6d6b83376c69efd391847e364dcb3cf897d8e8c1fd8e7d178329e8db3f162bc1a6fc6bbf1c1b4b0cf02685e757f9b797f9aadfe999ff8af6561527c1a5feccfb7313086c6c818315fd4186363624c8d194b9916c6b2370ad3304dd3326de3683aa68b8fc73ebe19b04f684666c465eaa53a9a31936a6726666a66666e16666956e6c5accdc66ccdcebc9a375333757365aecdcd2f33b1f2eb1cfcd764311a736bde3169becd9db9e7b21ccc8379344fe6bdf9603e9a4fe6b379365fcc57f3cd7c373fcc4ff38b7dbecd8139c467648ed967c23e63736aceccb9b960992a3334e3de322cd3b22cdb722cd7f22cdf0aacd08aacd84aacd4caacdc2aac12b9dc2f91c5ffaa2c56655dac4b3f2e566d0cad5a3d5b8dd55a9d75b56e9666e9d6ca5a5b1bd6d3f7ccd96ead3bd6522689b5b3f61677bfd6019f2393666a9dac7beb817d1ead27ebd93ab351da592fd6abf566bd5b1fd6274b98bf5884b0601e3d61b3e9c0faeea3cf1fd1d1bfa2634cb31a8bfe82f001fff74a89aca135b2c6d6c49a5a336b6e2d7acdb196cc74fa4a9ed18f85b5b34d48f2439643bf4c614e6ddb766cd77ab03ddbb7033bb42326cfc178b4633bb1533bb37336abda766197ea935dd997de92fecce74fc932307756cdc6646055aa67d77663b776675fed9badd9ba71303fec95bdb6376c249ef9676fed9924625414662bcc5e602bf766681bf6d6beb377f6de3eb0cfde3eda27fb9e8debde7eb01fed27fbd93eb319d7b35fec57656fbfb1d1b07efffcafc9f27cb16a66274cb78cc6f8b4df992c1ff6a7fd657fdb037bc8faf3c47a7864bbe6dc1edb137b6a2db924bb7e64fab161ff9cb1f6ce85fd9b91bdb0972c485698ddcc1dc3311d662c8eed384cd2bde33a9ee33b8113b218f5dd89545df17fcdecfe155954d7183ab113333bb1edda499cd4c9ec2f27778a5e0ea7640ff0ed3d6b55653d3b17361acf4cc706cc6216dc6ed8ff3b356b6be3b44ca6b9d3998173756e8e66f7938feeac9cb5b3b1b7ecf78eb365d21c8d9d73e7ec9cbd73708ecec9b9771e7ec9107ecb7a7eb6a03f234b2f09f3c683fe7ecea3f3e43c3b67e7c58cadb33db1ced6b33d6656cc3ece2b6b5dc5dab5c0a7f765ec63cfe9e374f8bc39efbd24f6d20e9d0f66fd47e7d3f9ea7fe954ce379366dffff5f6cec8e9ff5acca933b3eb9fe4f8576599ab9db3b05f9c25fba1e21a6ce2b08c23f34accd3bab6ebb8aebd702a73e17ab66b1f5d9ff9a8931b981fccdacfaca5f76ec86c2ae673e6d18ddcd84d98bde0e3746e6a7acc73b02b594fbcd93336be67377373b7704bb7722f6e6d176e63356e6b358ae67656f3afe8987a70afaaeddeecd6d55cdd5db96b3626cfeec6dd9a43f7ceddb97b3622dbde86dd837bb4576e6031ed331df7e4debb0feea3fbe43e1b817b765fdc472195fbeabeb9efec5707f7c3f9703fdd2ff7db1db84377c474f1c0fe7dec4edca93b73e7eec25daabd2f6091b8a7aa81f70fbdda9f91c533d8f46d79b6e778ae937b9e71b2179eef055ec8e4601fdbf0222ff612e6030eb6d1eb8c977a99977b85577a9577f16aaff15aaff3aedecdd33cdd5b796b36e7c7c6c9db785befce7a70471ebb0b1b5d9dfd3ff36fde8e59cec1db7b07efe89dbc7bb5f01e58467af31ebcc71f5af5bb1ff853b23c79cfded97bf15ebd37a730637362dbde3bd32f2e099368cbe6f229b39ae7de76bd0fefd3fbf2bebd8137f446ded89b78536fe6cdbd85b76441d7a3aff8866ffa966ffb8e71f45ddfb31e7c9ff9e8ad6df8811ff663e547ee8069e4831ffb899ffa198bd6be51bffd523c9189fe75599e2f7eee177ee957fec5af0d6603e6d46f7a49fc967d3aff6acead27ffd6cf77bee6ebfeca5ffb1b7febdff93b7fef1ffca37f62f966a2bef8f78aea3ff88ffe93ffec9ffd17ffd57ff3df8da3bdf03ffc4fff8bf9f485bd30c74ee57ffb037fe88f8cbd3ff627fed49ff9737fa1382c27fd6679f70f597ea97dfc99d8d25f066aa004060b112da65f6aff97c0f7fae5b7811d38fe3570cd0fe31478811f04411844411c24411a64411e14411954c14509839a7d1afb3d68838ee59af3e06a3f07b7400bf460c5fc48ef0d9560ddeb99ad30d906f6c27a0e36ecaedbe02ed8057ba50e0e4a191c8353708f0af54f35ab3f2d8b1d3c048fc153f01c9ccdd829ad73f012bcf6da15bc05ef81137c049fccf38c83afe03b1804c360148c8309fb330d66c19c49b47016c1325443253442d3188416fbc39c71e8865ee88741188651c86cc73a8709f3cb4698f29881c50f61d6fbfc300f8bb00cabf012d661e32fd421d3b41fb2387f94e5e77af6cf63d25f1db661175ec39b19875aa8b3bbafac636f27e13a5c33795e8c7b2f0d37e136bc0b77e13e3c84c7f014de870fe163f8143e8767f52d7c095fc337ab08dfc38ff033fc62d2982c22f6d97ff90e07e1301c8563e3184ed82cb40dd6e1943d63e6ee99fd7c9b53f6dfe7e1225c466aa428456444e68fcacdaf5a46b288ff862c28f1d4c8525fd5d7c88e1c7f19b9e673e41987c8376751c02375a61351c8e2f7cf88e524511c25511a65c62dca8347ab65f369cafe3c4645f01895aa1255d125aaa3266a5910d345d7e8166966678ccc75d4467ab48ad6d126da4677c629da452c82f0039ef778d68ecdb40bf6bc7d74888ed129ba77d2e8217aecefcdabed866af4d1eeaff6f2932c068fb043b77516ca2e7a8a9ea373f4629ea357f6a437e6750d16a79ca37773c2e6e8aad7eae823fa8cbea2ef68a0ce153f1a2aea8f2a2c7f9e1b8da27134096d2b8ca6d1cc8aa379b48896b11a2b56111b319bac629b85166eccbc3d9f73962c7f93b29843e33ef6e3200ea3fb388ae3f081f554cadbcafc5a1f25fe2c0b7ff68f7131d4f8f9e22cd4f73889d3388bf3b888cbb86277bcb0f87111d7d6dedd5b4f7c2639b959dcc46ddcc557ff515dfdb4f662cb3bbaca5875e25bacc5ba3f8b57f13adec4dbf82edec57ba5890fea323ec6a7f83e7e881fe327e3143fb3d866c9bc7380b86e689de373fc120ce2d76011bfc5effd88736b3055a38fdeff992c0ad34726cb6b9cb8adba8a3f4c23fe649db7641ec6b09ee3da665ed3fc0c33f6dcaff83b1ec4c378a456eaca7e51ee94713c862c3c1eecff9dfdb7493c55f57816cfe345bc4c54e3c17e4894c448ccc44aecc449dcc44bfc24484263efde9b3e8bd8d887e7a42c3b65f3d6d17c4da2244e92244db2a84872b1baf07765b1c886f8155b36bbb2fe65914fa2b8499194e69b71f26fd69e8dc9d9b998dff6c13ad953e39054c925a99326d6d5f7beea9db4ccca52f40d55c1d97d95bb385332bb4abae49adc12cd38252ceb4956c93ad924dbe42eba26bb641f1c9243724cd82c657a8ec272014364d94c9b4b2f4dee9387e4d158264f09b34ab146d2e722ff4c96e499f5e198e50e2bf6efe7e4257935dfad3e3f3f276f56ff8afa7df26ece8dfb709c7c249fc957f29d0c143d192a8b64c4abe3bdc7b4fbac8dc9c264b2df93713231de9269324be6c63159d8c76469c6a99a2aa9919aa995daa9e3dfa76eeaa5bef1603a2cbfe1b2f45910cb54b769601cd3308dd2384dd294cbc2d76dfa7cc4180aaff6932c96b0fe3453466e6b97cc8e9d344f8bb4343fd22a4c98f75a5afdfe8687f4621becee75daa46ddaa5d7d451f4a04b6fa996ea91c9fd3f978549c3644957e93adda4dbf42eddb15fedd3837d4c8fe9c9d8a7f7e943fa18fae953642b7a344c9fd373fa92bed2c8902c2ca7db4681719fbea5efe947fa997ef5feb197a56f7f9f5bfd2acb8f91e17a78607dbb5412ff2139a7dfce9069eb673ae86da5f7c54ee5fa696f8f553a4ac7e9249da6b3a4b50b65c3f42c5177fe23ef31361a7d0edad724d379ba4897999a29c63163f971b4efb3e3ccecb3e2649559999d39ea57ea0475e6665ee66781e9fa81a3a06ab0eb675096e1c5599845599c25ce23b3172e8b6af5b9d52fb2889a9add3f99d14efd4a064ccf952c553eb2cc74cc2fe61b077dcecbf477613d982316e37efaeb2ccf8aaccc2a61e7e45b98b34db24b56678d5dc763f53b6bb32ebb662c62f343d6df6ff6c2fd66de9c652c99661ce3a74ccf56d93adb306bd3b36d76e74efa5999c53363a603cf76bfcd8445369691edb23d93e5901db313d31d85db7491ddff268bf28b2ca67a973d3032b24743c99eb82ccc37f67d642ebcc4661146f69c9db397ec357bcbde852c1855577d4bdaec23fb8c9e93419a655fd97736c8d8e866a36cec8eb24936355da7cc66d9bcf7ebacbf17d93257734509552b377233b7723b77d8377d3d6dc29edad74398b7cedddccbfdec900779a828ff4496be024a7dabf8bd36f63edacc23c330ee982cbd97efed70c024619219f7799c27fe364ff32c3c30597eac4172bf95e779919779a556f925aff3266f8d63dee5d75eb7dc613f1ef9cdfdeeb3e25cb316f153aee7ab7cad9eed32dfe4dbfcced67396c1b09879c8729a4bafd9feb7719f29f93e3fe4c73cc88e4c9b1392c52afe812cbd0f559209d332db2ed5263f1926f32baed05ca6678eed5877ecbfbce6f7fe5dfe104cf347a3fd690d92d97afe943f671725cecff94bfe9abfe5ef7dd4937ff49909af719cddaf6cca73628dcd8871fe997fe5dff9404d9cc833f3613ecac7f1579ff1997dbc4c51b4cfee30c9a7f92cc9988e1d59a699f47e377c0bdffe200bb75792259fab7b854d65ea77be302c63cfd2fb1dd5bc481673943bf9b2500b8545f5b3e8814547b6dcabc0575793b1fa919f0ba33059b7d9ac557d2cbfe8f312ebaeb7e4c2e96b1785cb62ad53e1157e111461112923d52ee22229d22233f67d5ec365611ac6aecdd98cb92f8aa22caa3c2459faf6b398f5f597f9e5375958c6b34f6fcc62be8b0b7be4ce74a97227646177ae8ba6688b2e288a6b714bf25f7684303d53fc645268855eac8ab5710835e7b597a5d8b06cabaf6a7ef4d5be60cd243916dbe2aed815fbe2a0d8c5317b284ec57df1503c16cc3efa1a279764614e0b268f7128cec54bf15abcfd248b1aaa7f57164fcab22bde59fe742a3ed894b5efa33c5420875c9645f1597c15dfc5a01806398ba2c90bffd8555114a3625c4c8a692f4931ebd72c989ea8c5bc8f467b5b6677e03163b12cd5ecbb544287c540d7d250c2d22cadd22e9dd2354ebc22c2ae36c7f6a1f498cdc6a55f06e1ae64290dd731f7efc822d654c40cf3adb665c472b053191b2ecbef852cfb5e16f3cb3a9749999659996749745f163f564a7824669465599597b22e9b5e92b2cd34661b565f3b6371dc985bb4e10ffaaca7ecca6b79b3be4acd0a4a9d8d67c4a45995eb72536e992cbabdeda326368e5bebbecf64cabb7257ee7b591425cd7a6d28b552fb45961fd13ef773ea8dcd103b75c56439183e1bebc81c5b7d3d2cb0674e63cfcb63792aefcb87f2b17c6271ce86e527a398c594ca9d5d97cfe5b97c295fcbb7f29d79d12eef32adafee9bb3bebec13f337b5f7eb079bc2c3fcbaff2bb1c985d392c47e5b89c94d3c42d67e5bc5c944be3c45c7d156a7c4c0f665f1939564a655466d06746a7e0d4ef2ab2aadf62fedefb3059d8b7663f36c8d834bbaa2c26cbbd19b2deec97483a264b6b06c6a1b22bc79bc5e3a00996e5c4dc562e538ba86236cfa29545e5574115329fca66bb3ea736471513d73a313946fd9a4515dbdb2aa9d22aabf2aaa84a2bacaaea52d55553b5556745c1b1ba062b362e5ba7a355b57ebda3aff254b74aabf42467b21c83a36ad9f51f641151a5cf6571d488e9e246bd315559556b264bc4662c268b193269f64c96a37bf65a6fae2e2387e9eb5bb5a9b6d55db5abf6cab53a54c7ea54f575e17be6c717d681c5d5233e26a3fe2ebd3d570f4c96c7eaa97af646d5b97ab1aaead5dc556fd57bf5517d565ff128afabef5e966ac07ac2e5f5cf678bddb11a56a36a9ce4ce23c6c5339adf627e4bca6270efba60d1ee539ac5a36a524db98e912c51af654c965335f33a8f656bca3c34ccae9a87af9eaac6ac3f17d5f2a26637f7f5a25cb81fb615f38349d17f26b406c3ee7570377d7e75312fd6c5be38e1cbc5bd78179f8d897f092e6134b8449798c9d2b91fccbadefb159cde673059946a7449823e47f6d9c7fea32ca859283c96225912f549bdbfa4ec9e593fc6fdfa9c6df523d4af3d18a774e75d2fb9925e8ad0c8eefbbcfd525eaacbe5525f9a4b6b9c2edde56a6fcdd1e5165f98bd93244764f10773e445d68e5da55df4cbeab2b6c2cbe6b2bddc5d7655a7b697fde57039ba2fbd2c173633b1d8cde27fd5d684fde2fef27079e4b2a0adfd5add3f95256071f24d29c2faf27479eeb585d61bfb95a07ecd81e9d8a377f35545b3df7975c88ca6feec72bebc5c5ecdc4383afae58daf136d8235f75dbd7e8db92c7c3d96f5f196c5dd5333bebc5f3e2e9f97afcb777cbcf06a13d388e16578195dc66c869ddb6c66cd466c967db5ee7adbbf4c2ed3cb8ccba2f0bcc2fe5d16392f4096545373b5cdcf97f9657159f6eb90bdcdb2d8b85fd50accc08d8c83a7298f8a1fb4c620fca8d55a49b6b5519bc98ac9f9565bb56def1cc38bfaf99ecd8d336ef74cc7b8341e9b3146e6dcdef82cdeac9ddaadbddaaf83484b46e9ad0eeba88eeb84e5ca9fcce3796c6e9db008f4c9dd32590e755a67756e325990875bfd0aeaeff9cbcfb2287eaa2b6e5dd4a5f25557c68149c0bc0fb3dfa8978569716cc69eee2b6aa9cc422bfc8caa9a4590ec7f0d6b5beb7eb84347cdaf2c63af9cd73063f67faa22f6ebdeaff7d27875c746f9cbfc626d5cd6d7fa566bb55eafea35d36ca77c8af27a536fcdd8b9b23cdceb6318d6239bdec2eabb7a57efcb3d932515759e3fe695d8112074cc55efd44370523ae5b13e184cb3597e7f6fdbbc12cfda581f599b4ff57dfde0b6a1556d13b77eac9fea67e3549feb17a65b8bfab59f159cd728b02d1691ceeb37bfb1b7fe376fd994b220ca89acbdfb5abfd71ff56738a8bfeaef7a500fcba01e992ed3c27db17077aec3f29881cb324b63578feb493de5b2507ef20f7264f6a797a59ffb13f6ff0d9bfda7f5ac9ed70b9657b2fc8bc52e5b7b592f9d779bcdc98dda288de13f5a35f3ca1f8dd958c64363db47f6d9374e3f438693be6ed3fbb2c665ff34a2d0def09a9af1cb1ae0d074eb5be3357e1334a1f3d4444ddc244dcafae291e54977eeaec9ac2dfb158b429bbc299ab2a9b8bdd09ca8f42b763fcb42732397c5e4b364aa8cd2cc99c77a7369eaa6316377c3eefb7039352d0b8359d6e186c6aee99a6b738badd0b48a466b74fbc18c9b557aecc7c57c6fd64cdfc76c2c3efa5cbdd9345bebdcdcb9dbbe8283d53fac9c9b5ebfb3a4d935fbe6604d9a63736aee9b0726c363f3d43c3799bbeb6be64c2fe3e6dcbc34afcd9b948559c51f65a1d95ecaa2f1959bb5faa138cd7bf3c1a22ac7ff609e89d973bfa6686f9b4fe3e0dbcd57f31dbae167ad3483669828d60b7bde283359ae356bc66c961b46611f41369366dacc9ab971b296eeb6e1e3815566167d9b9ed3354b63efad5bb5555aa3355bcbe8ebd581396efb15c45d9f2b87ba71689dd66dbdd6ef63181e7719aadfaf09ff365752a5cfa4bdc2fdfa937a8bc76de03dc65d1b1afd4afdb658703fbbed6dba8d8c531bb7499b865ef5de666d9e9fdaa22ddbcad8370fed85595585fce4beaddba66ddbaebd5e5876dfded8bcf3ddd70ee4eabfefed5aaddf1de36baddeaeda755bb35f6dda6df0dede056f5ec89eb7734a63d7eedb437b6c4f52163f38fd41161bd97abff39945bc2c951e313ddbe5b9a2b7f7ed43fbc8b4f7686ffa9d05b5d53ef55adf326fdf9edb97f6d518861f4e5c44ed5bb269df59ccb3cf3b7bc9645ef5f949fbd17eb65fed773b6887eda865b3068b697aed123b19f67e906bf6b69db0acf8d44edb593b6751cb397875ed76d12e3bb59fdbeace38754a67746667c571922779af472c8e39fe4116e75759d84c99a94967770e93e6dab99d67192cd770d89cb063be56ef7c7b5b9f7d3753baa00bbba8da767197746997b1b0b8e8ca7e6dc8db75157bfea5abbbc6df756dd775d7eed6699ddeadfaac8e723b5ec95b326b687b8fe2fb4e65dce75db7ee36eeaedb76776c02d875fbe6397aef0eddb13b75f7dd43f7f8ab2cbfc563b40fdae2fbb87b59fabdb76ef7d43de7cfddb97be95e6bc738b9ae7de8ff1a4166c38eb3eddeba77964f9cba8feeb3fbeabe9d85fad80dba6137eac6d19d195b0b33f6b56ed24dbb5937ef16ddf2aa5e95ab71358d9dfbca7763f9bd1ce6d00ffa99fd6ad97bc7bada4cbe73b7bb322bb18ee1cadd5d5deffdea3109dfaffe35b886d7280fa302b66ffe1d1d13eb0b72bf196a7fdcef5de36b52b2d65d53ebe19ab119ef6c9dddcf7eb5f79ab3ff5a5ccb6bc5e29897ebe55a5bfeb5b9b6d7ee7acd27d7db55bb321d5533b30bdf8da69c5c57d7f57573dde6937efe655aa8f4750ce623a2be06c6f7638dd87c74ecfd38d515ade7de5aaa8171bcde5d77d7bdda3847b5edab2c5993353c07367f9c07f8afd7f89ca7ebe17a8cd953afa7eb3d3dddbf998b6641d1eef5e1fa787dba3e5fcfd797eb6bad3069deaeefd78febe7f5ebfa5d75d74139bc0eafa3eb987d26d7e975769d7b6bd60b8bcccccceb92dba2f5f327f2dd7d73c7fc1c27ebcc52c3a79b7263f955348c4c36f3b9aa6dbf33591cbebef31764b99937eb66df1cd6379ecb66877edf8bad140b2fb9b139d0b8f7b51b0b346f8152ddc25b748bd5db2db9a5b7ec96df8a68d025e15755df4a7377ab6e97f0e3c626c65b5bac6e9db1ef772df0fd16d6af1f5eafb0d86cc4246aee7236b3dcaeb7db4d4bc6d133cb2d44fefb87ddf3ffb52ce6e34dbfad6eeb86c5860d1b0d663515f3f8ecff6d8fc5eecc9fe593dbe6b6bdddd5a5fa62d7cae2b65386b7fdeda0d4ea58dd869f55773bde4eb7fbcbddede1f6787bba3ddfce51623f180fb71733643e7af24759983454afa4fbbfdede54f7f67efb48068a226ac97f7d7d3f2a6e9fb7afdbf76dc02b565f2cb35c58776c86d89a73162f6d6e43e3741bddc6b7c96d9abab759eadce6f1241ef77bf56f8bc80a5fa2eab6d4d4a8d394a85202f5ac199aa9599aadb1b16e5acdedade4e78fbbef3396c82759cc58f3345f0bb4508bf242d1d20ce3f287d3597fc25e1eb5584bb454cbfad981dd7b617e7a119385f624cdedad96f733a75668a5566917ad564325615ed0b65fe289b25322add15aadd3aedacdf84c1dd573979aa6e9da4a5b6b1b7ba16da99af0ebc8b03f2a8bb1ad7667dada9db653bba0b9bddbef2c7f37642dcfa1f8f22fc8926a7beda01db59376af3db008efce9cfa1f2c3bda71eb6451633568f92e43ed517bd29eb5b3f6a2bd46b935d2de8c85f61e4fb40f36269f2c216e94246ccb2767e999da97f6ad0d3436a6edeeefd98bf5dcee2c35f2b59136d6260a8bd955d72eed525db37111f562ef2fcbf2a84db59936d716da52578d7da8318f79673d9993b86e6fecb363518056b6bac26c79a71bbad92a9dab5bc64db77527327457c97596ee844e7fe622ce597e32d4033dd4233dd6133dedc7e0d74f98f5b2447e2f95bbd7333dcfebb2d20bf6fbfe0c84266b797c86ff2b3a16157aa957fa45aff5466ff5aedf11c3f2de39af8f322fa45ffb798faffbfaa6ebbe66817ed3355dd757fa5adfe85bfdcef850bff59dbe77c6d5413fe847fda4dfeb0ffaa3fe14bd07aece722db28dde4ef86e0bf3e78fe9e8e764adbfe8af4aa36ead86cdca34abf4f6eff075c43fbd8724c9f537fdbdb8ea1ffaa7fea57febcc07588affed6ed3ca56a3f7beea637afd3a561f4733895c33d687fa888dd0589fe8537da6cff585be5ca92b6565accc95e5eddd3c7ded778d38d5ca5e39b6e1eec90f0b0ff68b2cae7170dc95bbf2567e3c535f56415f310a4e2cdeea57df6a5a7bfb73b2048fab701505b355bc4a56e92a5be5ed78555807166b6efa5ccb3afe248bc9b28265dee5ceed8565b4b755b9aa5697555dcd568d3e5ab5b1c7f7c23129dcddaaeb76abab395e752c5bbbe3f66e626ef955166f7533e3b261f9d270a5b1f178e335567efeafaf2afd9571311f57fa6ab55a6bb362b8daacb6abbbcbc76ad75767d2a05f79b0b67d0ecf64796372ec983c0adfc570cff7819ef85efea3d8cf6bdcbbdf76e87ff8cd6abf3aac8ead1d7cb84edffa7e9e679aa6b63b6627bfcae2af4eab7b9643ad570fcdfbea919fce727f3a052c4f69fca971795a3dafceab176db67ad5ebd5dbea7df5b1fa8cbff26ef595f615a31fbbddf98749f7c177bc0f9d57f6795b7daf06d17e35147b2cfbbdbccd9339ee7739b58bd5a8d72e173b9358e3acdf65b1ceab717d67ec5693d574355bcd51c3b7708ec1fdf3314c92af16abe55a5d2b6b439badcdb5b5b6d7ceda5d7bc69e45cffb1f7bdefb489eaffb32097a7b62b3105fc7e3fba9f9beea7e36627e6318266b7f1dacc3c0091cbecb91452c6431bd17f85d967e7473dbd8d7efeb681dab77e20c2d9745f9b16be9cff8b1f03198af933c5d5bc1789daeb375be2ed6e5ba5a5fd6b5b5b437741601fbf7fbd5b30fbe57a25f6bb15a16fc34ceba757416dfb3e83e9ce9d77ecd807df6ebceefd6cc62bc50c8d2eeb411f366bfd90bd7d26374b7beadb53573e4b2fee5fed5793f628aba5eaf37ebedfa6ebd5befd787f5717d5adfaf1fd68feba790c5fdd69eef5ac1b8b04fbf9ef76a7e704b3e584bbedb9f5950bffba8f7e2eb7e97fcb1df83b63eaf5f02d736cc28effa73246c8e1feb193f73d2e7373edfafe4b23c69bb7e5dbf35cafa7dfdc1e617c8f2f7f78ffdf38ff3283f69566595d196e7f5e7fa6bfdbd1eac87eb11d335bea38c568b980e4db0afbf8fa6c6acc7cffc04c6b2dfadd7cbe90f7a7bea77569a43967505d5e0a69a713e6171d79d36d1f3f5b8f776eb49bfa3b61f93cb389f38de7aba9eade7eabdd8d32b674be7afc8f2d3d9621ecf798f6a11dcaf179774bdcc5f36ea46d9181bb37faead164ebf368979c230a77db5439cb4602336661ab91436d3dc39174ba1fd0a2caa7f6511e4ae0f0b36569fdfacc6cce59f8ce3c6c9271b77e36dfc4d607da94f56f35b9bfed2b8fc7eb6381a2a9ee2da55972acd26dc449b78936cd24db6c9f9aa0bcb6eac27ffdbf68bbc782effdf76ae6549552488eee733a6f615fdba7dbb6356a899203e5a6db51f3b4444f0c14b1489987f9faa8202a4bd37b457331113b9d010943a661645669d93b6d9e37b5a6207f5ce54d90a7b630ee6244ed8f3c2d4532060d9afca32ad349d280e4d481246103617866ae8b10a11c3b2b36c86248e1fe983506f36cb7bd7f59cde1344592e9dd23decc91c0e90c0115250a0014d680104cf80a691efb672cf7c667bc1191af13a6a6c8d2ed758790ea8a041fba8a546ca6681e23a2c67047dffd9b4a1130fb9e20cbad0833e2ce34747a706bc2c0e85fef98baee722bfd4f4404187dc51957668dcd0c2d0b660004318c12b8c61025378f3347fb13bb0acbe5df0f8ab3a31cdd0e01d3ee0136ee036e9c2ddb1ed7437f7e95459c13d7169c0bcfd003fe0117eb2bb700a4ff08c94def1b9eef5e9337dca1557dfc052a8ea8aefae6ed98c216b9d45ef4ffa485524aebeeaa181333471eeaa5edbb7f71bff47100423b4421517519a70a1686ff7106f632dbe471b97ebe0a027b3a4874ec8a276354cdffc603e255ca59dee228325a4b8c2354b719e8d29bbca113774bcb961e319c8f15c1f6327bd3884873ca043ee1bdcda7dce35430f7d0c30740718e10e636fed2f7ddd7f0cc2861b3aa1161991827b3cecfa8d66ec6112bce2115354f693204dfadb96d559cd6ccab25f967cd21655d61b3627a2d61336b0892d72a03dc20e53978ef868d8fa229f5faee75a7fe935c07eb745b764495b08ec7d0311d5f514356ca3bffd70224ff774bfb3f1822818bb5ad8461d3bd8c5de6e837df6fe0507fb088787258ef015c7d68bd0fa1a7cc79ef3f0a8623d21573237714a0f6bb636061dba66de58d0211dac1b76bfe293ef6039b59ad281736c393795d713791dceebf80ee712f96e3009ddd07544a5d179e13613e6e4967d435ca3ec245389a0cad56bfd58aad7bf7aee9fc122ff178e852391e3f3ba9c7d9399eff23a234758aeb7d96b869def6fe7fb0f468e60216ac18678a2378b9890bd31a42ee18c42f1d27b720dcf09969c1fb0909d7904e76ec356026184f0baafc89d66956e3da5fecbf6f6f369d67545d6b5c5d924df135a7ec542cb5e26e49a7cbfc201afa191da8093df3604f79408ae9ab0ad576031ca9ca3caca1635c83935653d22cfb448ce3bcf6adc752c32e62a9eb9443352aa19aaaae7e288acea1ab4729f2cb50e052bf5d4871cf952b02732ae47d9db635ea9689b453c57bc2062244752ad5f5e84c592fcc3e1ee4c949995795bc152fdbea830d827ffc84c20e9088f91d2fb395e4b665b520152c3422492ebf27dce3a1163b10a2cc60916c11710bad85b6ed69a7320cdc09db863ceee0a1533e20c1ccef6c814cd995eb334f9fc9ecf4b7ebda988b5c23b67b1108e04dff03d63da7fc32f8b9a5f4caeec2fc7c9c7e6f5bc5e154b795ce2e596e3679fca7dd222b624e3bc58134fe3a1e0bbcd199677fcb81c4b3d6a7ea7d6aeb0fb7e71ceb9a3f5738b7cbeda2ba7de3ba79caf57e52fff15fb1fcbbfd3fefcfbaf3ffe0193cc32fd</data> + </image> +</images> +<tabstops> +</tabstops> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/plugins/viewplugins/colorspaceconversion/Makefile.am b/chalk/plugins/viewplugins/colorspaceconversion/Makefile.am new file mode 100644 index 00000000..cfc849f9 --- /dev/null +++ b/chalk/plugins/viewplugins/colorspaceconversion/Makefile.am @@ -0,0 +1,27 @@ +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = colorspaceconversion.rc + +EXTRA_DIST = $(chalkrc_DATA) + +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../ui \ + -I$/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + + +kde_module_LTLIBRARIES = chalkcolorspaceconversion.la + +chalkcolorspaceconversion_la_SOURCES = wdgconvertcolorspace.ui colorspaceconversion.cc dlg_colorspaceconversion.cc +noinst_HEADERS = wdgconvertcolorspace.h dlg_colorspaceconversion.h colorspaceconversion.h + +chalkcolorspaceconversion_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) chalkblurfilter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui +chalkcolorspaceconversion_la_LIBADD = ../../../libchalkcommon.la + +chalkcolorspaceconversion_la_METASOURCES = AUTO + +kde_services_DATA = chalkcolorspaceconversion.desktop + diff --git a/chalk/plugins/viewplugins/colorspaceconversion/chalkcolorspaceconversion.desktop b/chalk/plugins/viewplugins/colorspaceconversion/chalkcolorspaceconversion.desktop new file mode 100644 index 00000000..0993dcc7 --- /dev/null +++ b/chalk/plugins/viewplugins/colorspaceconversion/chalkcolorspaceconversion.desktop @@ -0,0 +1,40 @@ +[Desktop Entry] +Name=Colorspace Conversion +Name[bg]=Цветово обръщане +Name[ca]=Conversió d'espai de color +Name[da]=Farverumskonvertering +Name[de]=Farbraumumwandlung +Name[el]=Μετατροπή χρωματικού χώρου +Name[en_GB]=Colourspace Conversion +Name[eo]=Kolorspackonvertado +Name[es]=Conversión de espacio de color +Name[et]=Värviruumi teisendus +Name[fa]=تبدیل فاصله رنگ +Name[fr]=Conversion d'espaces de couleurs +Name[fy]=Konversje fan kleurspektrum +Name[gl]=Conversión de Espazos de Cores +Name[hu]=Színtér-konverzió +Name[is]=Litasvæðis umbreyting +Name[it]=Conversione dello spazio dei colori +Name[ja]=カラースペース変換 +Name[km]=បម្លែងប្រភេទពណ៌ +Name[nb]=Fargerom-konvertering +Name[nds]=Klörenruum-Ümwanneln +Name[ne]=रङ खालीस्थान रूपानान्तरण +Name[nl]=Conversie van kleurspectrum +Name[pl]=Konwersja przestrzeni barw +Name[pt]=Conversão de Espaços de Cores +Name[pt_BR]=Conversão de Espaços de Cores +Name[ru]=Цветовые пространства +Name[se]=Ivdnegaskkadat-konveršuvdna +Name[sk]=Konverzia farebného priestoru +Name[sl]=Pretvorba barvnega prostora +Name[sr]=Претварање простора боја +Name[sr@Latn]=Pretvaranje prostora boja +Name[sv]=Färgrymdskonvertering +Name[uk]=Перетворення простору кольорів +Name[zh_TW]=色彩空間轉換 +ServiceTypes=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkcolorspaceconversion +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/colorspaceconversion/colorspaceconversion.cc b/chalk/plugins/viewplugins/colorspaceconversion/colorspaceconversion.cc new file mode 100644 index 00000000..10479a3c --- /dev/null +++ b/chalk/plugins/viewplugins/colorspaceconversion/colorspaceconversion.cc @@ -0,0 +1,155 @@ +/* + * colorspaceconversion.cc -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <stdlib.h> + +#include <tqradiobutton.h> +#include <tqcheckbox.h> +#include <tqlabel.h> +#include <tqcombobox.h> +#include <tqbuttongroup.h> +#include <tqapplication.h> +#include <tqcursor.h> + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> + +#include <kis_doc.h> +#include <kis_config.h> +#include <kis_cursor.h> +#include <kis_image.h> +#include <kis_layer.h> +#include <kis_global.h> +#include <kis_types.h> +#include "kis_meta_registry.h" +#include <kis_view.h> +#include <kis_paint_device.h> +#include <kis_colorspace_factory_registry.h> +#include <kis_cmb_idlist.h> +#include <squeezedcombobox.h> + +#include "colorspaceconversion.h" +#include "dlg_colorspaceconversion.h" +#include "wdgconvertcolorspace.h" + +typedef KGenericFactory<ColorSpaceConversion> ColorSpaceConversionFactory; +K_EXPORT_COMPONENT_FACTORY( chalkcolorspaceconversion, ColorSpaceConversionFactory( "chalk" ) ) + + +ColorSpaceConversion::ColorSpaceConversion(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + + if ( tqparent->inherits("KisView") ) + { + m_view = (KisView*) tqparent; + + setInstance(ColorSpaceConversionFactory::instance()); + setXMLFile(locate("data","chalkplugins/colorspaceconversion.rc"), true); + + (void) new KAction(i18n("&Convert Image Type..."), 0, 0, this, TQT_SLOT(slotImgColorSpaceConversion()), actionCollection(), "imgcolorspaceconversion"); + (void) new KAction(i18n("&Convert Layer Type..."), 0, 0, this, TQT_SLOT(slotLayerColorSpaceConversion()), actionCollection(), "layercolorspaceconversion"); + + } +} + +ColorSpaceConversion::~ColorSpaceConversion() +{ + m_view = 0; +} + +void ColorSpaceConversion::slotImgColorSpaceConversion() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + + if (image->colorSpace()->willDegrade(TO_LAB16)) { + if (KMessageBox::warningContinueCancel(m_view, + i18n("This conversion will convert your %1 image through 16-bit L*a*b* and back.\n" + "Watercolor and openEXR colorspaces will even be converted through 8-bit RGB.\n") + .tqarg(image->colorSpace()->id().name()), + i18n("Colorspace Conversion"), + KGuiItem(i18n("Continue")), + "lab16degradation") != KMessageBox::Continue) return; + + } + + DlgColorSpaceConversion * dlgColorSpaceConversion = new DlgColorSpaceConversion(m_view, "ColorSpaceConversion"); + Q_CHECK_PTR(dlgColorSpaceConversion); + + dlgColorSpaceConversion->setCaption(i18n("Convert All Layers From ") + image->colorSpace()->id().name()); + + if (dlgColorSpaceConversion->exec() == TQDialog::Accepted) { + // XXX: Do the rest of the stuff + KisID cspace = dlgColorSpaceConversion->m_page->cmbColorSpaces->currentItem(); + KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(cspace, dlgColorSpaceConversion->m_page->cmbDestProfile->currentText()); + + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + image->convertTo(cs, dlgColorSpaceConversion->m_page->grpIntent->selectedId()); + TQApplication::restoreOverrideCursor(); + } + delete dlgColorSpaceConversion; +} + +void ColorSpaceConversion::slotLayerColorSpaceConversion() +{ + + KisImageSP image = m_view->canvasSubject()->currentImg(); + if (!image) return; + + KisPaintDeviceSP dev = image->activeDevice(); + if (!dev) return; + + if (dev->colorSpace()->willDegrade(TO_LAB16)) { + if (KMessageBox::warningContinueCancel(m_view, + i18n("This conversion will convert your %1 layer through 16-bit L*a*b* and back.\n" + "Watercolor and openEXR colorspaces will even be converted through 8-bit RGB.\n") + .tqarg(dev->colorSpace()->id().name()), + i18n("Colorspace Conversion"), + KGuiItem(i18n("Continue")), + "lab16degradation") != KMessageBox::Continue) return; + + } + + DlgColorSpaceConversion * dlgColorSpaceConversion = new DlgColorSpaceConversion(m_view, "ColorSpaceConversion"); + Q_CHECK_PTR(dlgColorSpaceConversion); + + dlgColorSpaceConversion->setCaption(i18n("Convert Current Layer From") + dev->colorSpace()->id().name()); + + if (dlgColorSpaceConversion->exec() == TQDialog::Accepted) { + KisID cspace = dlgColorSpaceConversion->m_page->cmbColorSpaces->currentItem(); + KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry() -> + getColorSpace(cspace, dlgColorSpaceConversion->m_page->cmbDestProfile->currentText()); + + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + dev->convertTo(cs, dlgColorSpaceConversion->m_page->grpIntent->selectedId()); + TQApplication::restoreOverrideCursor(); + } + delete dlgColorSpaceConversion; +} + +#include "colorspaceconversion.moc" diff --git a/chalk/plugins/viewplugins/colorspaceconversion/colorspaceconversion.h b/chalk/plugins/viewplugins/colorspaceconversion/colorspaceconversion.h new file mode 100644 index 00000000..a1f7f5c0 --- /dev/null +++ b/chalk/plugins/viewplugins/colorspaceconversion/colorspaceconversion.h @@ -0,0 +1,51 @@ +/* + * colorspaceconversion.h -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef COLORSPACECONVERSION_H +#define COLORSPACECONVERSION_H + +#include <kparts/plugin.h> + +class KisView; + +/** + * Dialog for converting between color models. + */ +class ColorSpaceConversion : public KParts::Plugin +{ + Q_OBJECT + TQ_OBJECT +public: + ColorSpaceConversion(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~ColorSpaceConversion(); + +private slots: + + void slotImgColorSpaceConversion(); + void slotLayerColorSpaceConversion(); + +private: + + KisView * m_view; + KisPainter * m_painter; + +}; + +#endif // COLORSPACECONVERSION_H diff --git a/chalk/plugins/viewplugins/colorspaceconversion/colorspaceconversion.rc b/chalk/plugins/viewplugins/colorspaceconversion/colorspaceconversion.rc new file mode 100644 index 00000000..94f6066d --- /dev/null +++ b/chalk/plugins/viewplugins/colorspaceconversion/colorspaceconversion.rc @@ -0,0 +1,11 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkcolorspaceconversion" version="1"> +<MenuBar> + <Menu name="Image"><text>&Image</text> + <Action name="imgcolorspaceconversion"/> + </Menu> + <Menu name="Layer"><text>La&yer</text> + <Action name="layercolorspaceconversion"/> + </Menu> +</MenuBar> +</kpartgui> diff --git a/chalk/plugins/viewplugins/colorspaceconversion/dlg_colorspaceconversion.cc b/chalk/plugins/viewplugins/colorspaceconversion/dlg_colorspaceconversion.cc new file mode 100644 index 00000000..616b1714 --- /dev/null +++ b/chalk/plugins/viewplugins/colorspaceconversion/dlg_colorspaceconversion.cc @@ -0,0 +1,91 @@ +/* + * dlg_colorspaceconversion.cc - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqradiobutton.h> +#include <tqcheckbox.h> +#include <tqlabel.h> +#include <tqcombobox.h> +#include <tqptrlist.h> + +#include <klocale.h> +#include <knuminput.h> +#include <kdebug.h> + +#include "kis_meta_registry.h" +#include <kis_colorspace_factory_registry.h> +#include "kis_profile.h" +#include "kis_colorspace.h" +#include <kis_id.h> +#include <kis_cmb_idlist.h> +#include <squeezedcombobox.h> + +#include "wdgconvertcolorspace.h" +#include "dlg_colorspaceconversion.h" + +DlgColorSpaceConversion::DlgColorSpaceConversion( TQWidget * tqparent, + const char * name) + : super (tqparent, name, true, i18n("Image Size"), Ok | Cancel, Ok) +{ + m_page = new WdgConvertColorSpace(this, "colorspace_conversion"); + Q_CHECK_PTR(m_page); + + setMainWidget(m_page); + resize(m_page->tqsizeHint()); + + m_page->cmbColorSpaces->setIDList(KisMetaRegistry::instance()->csRegistry()->listKeys()); + + fillCmbDestProfile(m_page->cmbColorSpaces->currentItem()); + + connect(m_page->cmbColorSpaces, TQT_SIGNAL(activated(const KisID &)), + this, TQT_SLOT(fillCmbDestProfile(const KisID &))); + + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); + +} + +DlgColorSpaceConversion::~DlgColorSpaceConversion() +{ + delete m_page; +} + +// SLOTS + +void DlgColorSpaceConversion::okClicked() +{ + accept(); +} + + +void DlgColorSpaceConversion::fillCmbDestProfile(const KisID & s) +{ + m_page->cmbDestProfile->clear(); + + TQValueVector<KisProfile *> profileList = KisMetaRegistry::instance()->csRegistry()->profilesFor(s); + TQValueVector<KisProfile *> ::iterator it; + for ( it = profileList.begin(); it != profileList.end(); ++it ) { + m_page->cmbDestProfile->insertItem((*it)->productName()); + + } +} + + +#include "dlg_colorspaceconversion.moc" diff --git a/chalk/plugins/viewplugins/colorspaceconversion/dlg_colorspaceconversion.h b/chalk/plugins/viewplugins/colorspaceconversion/dlg_colorspaceconversion.h new file mode 100644 index 00000000..608989ab --- /dev/null +++ b/chalk/plugins/viewplugins/colorspaceconversion/dlg_colorspaceconversion.h @@ -0,0 +1,50 @@ +/* + * dlg_colorspaceconversion.h -- part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef DLG_COLORSPACECONVERSION +#define DLG_COLORSPACECONVERSION + +#include <kdialogbase.h> + +#include <kis_id.h> + +class WdgConvertColorSpace; + +/** + * XXX + */ +class DlgColorSpaceConversion: public KDialogBase { + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + + DlgColorSpaceConversion(TQWidget * tqparent = 0, const char* name = 0); + ~DlgColorSpaceConversion(); + + WdgConvertColorSpace * m_page; + +public slots: + + void okClicked(); + void fillCmbDestProfile(const KisID &); +}; + +#endif // DLG_COLORSPACECONVERSION diff --git a/chalk/plugins/viewplugins/colorspaceconversion/wdgconvertcolorspace.ui b/chalk/plugins/viewplugins/colorspaceconversion/wdgconvertcolorspace.ui new file mode 100644 index 00000000..ae183206 --- /dev/null +++ b/chalk/plugins/viewplugins/colorspaceconversion/wdgconvertcolorspace.ui @@ -0,0 +1,218 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgConvertColorSpace</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgConvertColorSpace</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>399</width> + <height>228</height> + </rect> + </property> + <property name="caption"> + <string>Colorspace Conversion</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>lblConvert</cstring> + </property> + <property name="text"> + <string>&Target color space:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cmbColorSpaces</cstring> + </property> + </widget> + <widget class="KisCmbIDList" row="0" column="1"> + <property name="name"> + <cstring>cmbColorSpaces</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <widget class="SqueezedComboBox" row="1" column="1"> + <item> + <property name="text"> + <string>Default</string> + </property> + </item> + <property name="name"> + <cstring>cmbDestProfile</cstring> + </property> + </widget> + <widget class="TQButtonGroup" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>grpIntent</cstring> + </property> + <property name="title"> + <string>&Rendering Intent</string> + </property> + <property name="toolTip" stdset="0"> + <string></string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQRadioButton" row="0" column="0"> + <property name="name"> + <cstring>radioPerceptual</cstring> + </property> + <property name="text"> + <string>Perceptual</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>For images</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Hue hopefully maintained (but not required), +lightness and saturation sacrificed to maintain +the perceived color. White point changed to +result in neutral grays. Intended for images.</string> + </property> + </widget> + <widget class="TQRadioButton" row="1" column="0"> + <property name="name"> + <cstring>radioRelativeColorimetric</cstring> + </property> + <property name="text"> + <string>Relative colorimetric</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="whatsThis" stdset="0"> + <string>Within and outside gamut; same as Absolute +Colorimetric. White point changed to result in +neutral grays. + +If adequate table is present in profile, +then, it is used. Else reverts to perceptual +intent.</string> + </property> + </widget> + <widget class="TQRadioButton" row="2" column="0"> + <property name="name"> + <cstring>radioSaturation</cstring> + </property> + <property name="text"> + <string>Saturation</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="toolTip" stdset="0"> + <string>Best for graphs and charts</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Hue and saturation maintained with lightness +sacrificed to maintain saturation. White point +changed to result in neutral grays. Intended for +business graphics (make it colorful charts, +graphs, overheads, ...) + +If adequate table is present in profile, +then, it is used. Else reverts to perceptual +intent.</string> + </property> + </widget> + <widget class="TQRadioButton" row="3" column="0"> + <property name="name"> + <cstring>radioAbsoluteColorimetric</cstring> + </property> + <property name="text"> + <string>Absolute colorimetric</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="toolTip" stdset="0"> + <string>Best for spot colours</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Within the destination device gamut; hue, +lightness and saturation are maintained. Outside +the gamut; hue and lightness are maintained, +saturation is sacrificed. White point for source +and destination; unchanged. Intended for spot +colors (Pantone, TruMatch, logo colors, ...)</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>lblDestICMProfile</cstring> + </property> + <property name="text"> + <string>&Destination ICM profile:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cmbDestProfile</cstring> + </property> + </widget> + </grid> +</widget> +<customwidgets> + <customwidget> + <class>KisCmbIDList</class> + <header location="local">kis_cmb_idlist.h</header> + <sizehint> + <width>1</width> + <height>24</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> + <customwidget> + <class>SqueezedComboBox</class> + <header location="local">squeezedcombobox.h</header> + <sizehint> + <width>-1</width> + <height>i24</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>3</hordata> + <verdata>0</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image1</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="870">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000032d49444154388db59531681c4714863f892dde8004b320c32e3870020b74458a6b0f5458e581c016a809a8496b42208454098604d2c4904a6954a410511ae752085b858c1208dc35221244b00119f60ac12ee860062c980719708a95a248f129459cd7cceeccf0edb76fff61a706830197d5ed765ff3166a30184c4d5d829fed3c7bdd5e6ce3bda71a5738ef301802e1d6d179477152303c1842bc822797a64fbf7b4a9a43be00ada817cb0e12011c2611205ccd73755f9c087c6b19bef0d7c100f5b8267d07caf10fe8ab9210156320fc01be16aa5a11043307f30b20a21041019985f48ef2f7fa0becc68e80475fd584e831b396f210f67795c3831a4940a3228925bb27f4d652ba4b01a199b73342f3981be0ca57745042ac30c632d853b6373d44b056c8ef0922508d94d14be59b2f4aeaf58cd5751069e06f3436890114332b9487d0bf80f61e64dc5f813c3790045453f67703fd4d4f7f6b4496b5597e689044af194f5f5e841800210478bee3d1a8f41e64acbe0f69ae6852e1cf0ccf7f74f4d652defbc042226c6f55e8f89f91bb6e9c387c9d521c9558db988a3416fe3c67e32b4779ec7167f0e8939ce19ea7fc5d298a80c875f03563930855ed2081bc05e91d5014ef53363eaf288e3d6285ee520a338e76c7a251a94e41e30470d3631004a262672e3eca59cec6978ef2b889979d11f2bb904af3be92081a416e28dfe831983920b1142345d5b0ff2234a6334276d7321ad53c795c511ca654a5a251996f19b83d158ef602b45a423d52f67703abeb29ee4ce9de4fc93378f218462f6b3efdb042cf3d59666977a0aa6fe9310888d25b13342afd4dcffeaee3d147399da540ab13f8f8b39c2cb3f8710d11ba2b96f9c57fcd7180287497a03ecde86f8dd8fe1a867b9ef6bb1612a84a871f6bd35b94e217a53832589970f2dcd85d9c7d4580d57521cbdaf4bfaf288e95e268d4ec8e60e72ccb0f2dbffea454e71e8d29f57882717152509482a48d8924b0bc12e82ee51445a03a6da079cbd0eec0fc22142b06620e89a3fc8d3783870743d814d2bc8994aa6ff286472e764902e5a96f72bbd3b4c37b280e95aa9e604c84e1cf978b37c74935797d7ae2ca7fac6968fe51ff0bf86dc30783c1d49f0baa9bb819e612310000000049454e44ae426082</data> + </image> + <image name="image1"> + <data format="PNG" length="1003">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b249444154388db5944d4c5c5518869f73ce9db9cc40f929cc30300e18129a50685268a28291982e1a2175212eaab1c49d3f8971e7aec6aedb54a32b435dd8685cb8c0c4b8b0feb421b7bd8186a069d23209144b18cb0c02f3732ff3c3ccbdd705a571941213f1dd9d93739ef37e6fbeef08d334d9d5d0d090c701c8344d2176c1a6697a5d5d5dd8b64d2a95c2b2ac7f05b12c8b783c8e6118d8b6fd685fdb753a39394928e2a7c55724d693a7e214104220242805520a84d8b9e4790f0b1302c7751958f1e30534be9fa41a0c60db362dbe227f64af91b6e7719c2dfc0117a71c603da591de2882a7d3d4ec27122b10acad50aeb88044d542b84de3af7ab44aa55274f4e449dbf354bc347aa096fbf37e7efa2ecbad1b36907d78b289de8120232f37726250c3f52cf0a026a0f6065b9645d929e038167aa096d91b307171059034b5f8e9e9eb44fa052b4b25eeccd9dc99cb71f6ad082fbea2e351c075bdbdc13b9109fc01b83fef63e2e232e03076b68393231a0dcd024daf502c1e66e67a89cb971ef0e5a74bb4b61e6378248094b92ab0ac024b70ca017ef8360394187b2dc6d8b89ffa500e4d4f93d9083275d5e6f9913ade3dd70ee87c7d25c95646a25415aadab152b09ed4f8c5cc130a853839eac3951b684a61e70ef3f9c739668c24eba912afbfddc6d4d506e6a6d7b8b7d082aa8eb8dab19482cdcd220e36dd3dc19df23545de0a71f952861923493456cfd3cf36123c54a0b7bf0e8064621b21f7712c040857071ca4eea0f40a99f510573ec971cb48030e811a1faded3e94be85f2fb00703d1ff26f96ab9f011a5b04d0c4f26fdb948a754c1b25668c2491483d5d5d611617d6b8f0fe32cb779b492ce65168b4c774a4701eefd8f3a02d56e6e8f13aeefe9a63fa5a89d1970e91d908f3d46003e1480d173e28b37827c9b977348ab92ce16890237d1ec907ee3e8e3d8f60d0e1f4583d009f7d9860662acff89bad1c1faad0717493f7ce7713ed8cb0995c255f2a317a26427b67198f6a70f51c0a41b902279ed1187f23cc17130b7c74de65eac77a7a8f05517e41e2deefa4930576db60fa7a8ee1535134df3e93e7b82e0817476439fd6a9070a49f6fbe4a3077739db99b15c001146dd13a46cf1cc1f83943c62e51de76b0738fc9381e8f3390f0236b252e124999e11724fd833196164bacadb87848224fe874f779b43fe9f2dca928956d505a96dbb3f9bdc18661e00534c26d1a7a40e13912a11c9454280da41048a9915c75585df500074d53d816dc9edd229528ef0db66dbbea3ffdaffa471f1f28d8344df1bf800f1a6e9aa6f813c39885bc050f269c0000000049454e44ae426082</data> + </image> +</images> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/plugins/viewplugins/dropshadow/Makefile.am b/chalk/plugins/viewplugins/dropshadow/Makefile.am new file mode 100644 index 00000000..98ba3550 --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/Makefile.am @@ -0,0 +1,31 @@ +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = dropshadow.rc +EXTRA_DIST = $(chalkrc_DATA) + +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../colorspaces/rgb_u8 \ + -I$(srcdir)/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + + +kde_module_LTLIBRARIES = chalkdropshadow.la + +chalkdropshadow_la_SOURCES = wdg_dropshadow.ui \ + kis_dropshadow.cc dlg_dropshadow.cc \ + kis_dropshadow_plugin.cc + +noinst_HEADERS = wdg_dropshadow.h kis_dropshadow_plugin.h \ + kis_dropshadow.h dlg_dropshadow.h + +chalkdropshadow_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) chalkblurfilter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui +chalkdropshadow_la_LIBADD = ../../../libchalkcommon.la ../../../colorspaces/rgb_u8/libchalkrgb.la + +kde_services_DATA = chalkdropshadow.desktop + +chalkdropshadow_la_METASOURCES = AUTO + +KDE_OPTIONS = nofinal diff --git a/chalk/plugins/viewplugins/dropshadow/chalkdropshadow.desktop b/chalk/plugins/viewplugins/dropshadow/chalkdropshadow.desktop new file mode 100644 index 00000000..a48a477e --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/chalkdropshadow.desktop @@ -0,0 +1,39 @@ +[Desktop Entry] +Name=Dropshadow +Name[bg]=Сянка +Name[ca]=Gota d'ombra +Name[da]=Faldskygge +Name[de]=Schattenwurf +Name[el]=Ρίψη σκιάς +Name[et]=Varju heitmine +Name[fa]=سایۀ قطره +Name[fr]=Jet d'ombre +Name[fy]=Skaad sette +Name[gl]=Sombreado +Name[hu]=Ejtett árnyék +Name[is]=Undirskuggi +Name[it]=Getta ombra +Name[ja]=影付け +Name[km]=ទម្លាក់ស្រមោល +Name[nb]=Skygge +Name[nds]=Schaddeneffekt +Name[ne]=छायाँ छोड्नुहोस् +Name[nl]=Schaduw plaatsen +Name[pl]=Dodaj cień +Name[pt]=Sombreado +Name[pt_BR]=Sombreado +Name[ru]=Тень +Name[se]=Suoivvan +Name[sk]=Tieň +Name[sl]=Senca +Name[sr]=Падајућа сенка +Name[sr@Latn]=Padajuća senka +Name[sv]=Fallskugga +Name[uk]=Тінь +Name[uz]=Soya tushirish +Name[uz@cyrillic]=Соя тушириш +Name[zh_CN]=阴影 +ServiceTypes=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkdropshadow +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.cc b/chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.cc new file mode 100644 index 00000000..797fc098 --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.cc @@ -0,0 +1,117 @@ +/* + * dlg_dropshadow.cc - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2005 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqbutton.h> +#include <tqbuttongroup.h> +#include <tqcheckbox.h> +#include <tqcolor.h> +#include <tqcombobox.h> +#include <tqlabel.h> +#include <tqradiobutton.h> +#include <tqslider.h> + +#include <kcolorbutton.h> +#include <kconfig.h> +#include <kdebug.h> +#include <klocale.h> +#include <knuminput.h> + +#include "dlg_dropshadow.h" +#include "wdg_dropshadow.h" + +DlgDropshadow::DlgDropshadow( const TQString & /*imageCS*/, + const TQString & /*layerCS*/, + TQWidget * tqparent, + const char * name) + : super (tqparent, name, true, i18n("Drop Shadow"), Ok | Cancel, Ok) +{ + m_page = new WdgDropshadow(this, "dropshadow"); + Q_CHECK_PTR(m_page); + setMainWidget(m_page); + resize(m_page->tqsizeHint()); + + KConfig * cfg = KGlobal::config(); + m_page->xOffsetSpinBox->setValue( cfg->readNumEntry("dropshadow_x", 8) ); + m_page->yOffsetSpinBox->setValue( cfg->readNumEntry("dropshadow_y", 8) ); + m_page->blurRadiusSpinBox->setValue( cfg->readNumEntry("dropshadow_blurRadius", 5) ); + TQColor black(0,0,0); + m_page->shadowColorButton->setColor( cfg->readColorEntry("dropshadow_color", &black) ); + m_page->opacitySlider->setValue( cfg->readNumEntry("dropshadow_opacity", 80 ) ); + m_page->opacitySpinBox->setValue( cfg->readNumEntry("dropshadow_opacity", 80 ) ); + m_page->allowResizingCheckBox->setChecked( cfg->readBoolEntry("dropshadow_resizing", true ) ); + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); +} + +DlgDropshadow::~DlgDropshadow() +{ + delete m_page; +} + +TQ_INT32 DlgDropshadow::getXOffset() +{ + return m_page->xOffsetSpinBox->value(); +} + +TQ_INT32 DlgDropshadow::getYOffset() +{ + return m_page->yOffsetSpinBox->value(); +} + +TQ_INT32 DlgDropshadow::getBlurRadius() +{ + return m_page->blurRadiusSpinBox->value(); +} + +TQ_UINT8 DlgDropshadow::getShadowOpacity() +{ + double opacity = (double)m_page->opacitySpinBox->value(); + //convert percent to a 8 bit opacity value + return (TQ_UINT8)(opacity / 100 * 255); +} + +TQColor DlgDropshadow::getShadowColor() +{ + return m_page->shadowColorButton->color(); +} + +bool DlgDropshadow::allowResizingChecked() +{ + return m_page->allowResizingCheckBox->isChecked(); +} + +// SLOTS + +void DlgDropshadow::okClicked() +{ + KConfig * cfg = KGlobal::config(); + cfg->writeEntry("dropshadow_x", m_page->xOffsetSpinBox->value()); + cfg->writeEntry("dropshadow_y", m_page->yOffsetSpinBox->value()); + cfg->writeEntry("dropshadow_blurRadius", m_page->blurRadiusSpinBox->value()); + cfg->writeEntry("dropshadow_color", m_page->shadowColorButton->color()); + cfg->writeEntry("dropshadow_opacity", m_page->opacitySpinBox->value()); + cfg->writeEntry("dropshadow_resizing", m_page->allowResizingCheckBox->isChecked()); + + accept(); +} + +#include "dlg_dropshadow.moc" diff --git a/chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.h b/chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.h new file mode 100644 index 00000000..9f3ca469 --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.h @@ -0,0 +1,60 @@ +/* + * dlg_dropshadow.h -- part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2005 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef DLG_DROPSHADOW +#define DLG_DROPSHADOW + +#include <kdialogbase.h> +#include <kis_dropshadow.h> + +class WdgDropshadow; +class TQColor; + +/** + * This dialog allows the user to configure the decomposition of an image + * into layers: one layer for each color channel. + */ +class DlgDropshadow: public KDialogBase { + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + + DlgDropshadow(const TQString & imageCS, const TQString & layerCS, TQWidget * tqparent = 0, + const char* name = 0); + ~DlgDropshadow(); + +public: + + TQ_INT32 getXOffset(); + TQ_INT32 getYOffset(); + TQ_INT32 getBlurRadius(); + TQ_UINT8 getShadowOpacity(); + TQColor getShadowColor(); + bool allowResizingChecked(); +private slots: + void okClicked(); + +private: + + WdgDropshadow * m_page; +}; + +#endif // DLG_DROPSHADOW diff --git a/chalk/plugins/viewplugins/dropshadow/dropshadow.rc b/chalk/plugins/viewplugins/dropshadow/dropshadow.rc new file mode 100644 index 00000000..fcd0be0e --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/dropshadow.rc @@ -0,0 +1,11 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkdropshadow" version="6"> +<MenuBar> + <Menu name="Layer"><text>La&yer</text> + <Separator/> + <Menu name="layerEffects"><text>Layer Effects</text> + <Action name="dropshadow"/> + </Menu> + </Menu> +</MenuBar> +</kpartgui> diff --git a/chalk/plugins/viewplugins/dropshadow/kis_dropshadow.cc b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow.cc new file mode 100644 index 00000000..207c86c3 --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow.cc @@ -0,0 +1,758 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * The gaussian blur algoithm is ported from gimo + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <limits.h> + +#include <stdlib.h> +#include <vector> + +#include <tqcolor.h> + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> +#include <knuminput.h> + +#include <kis_doc.h> +#include <kis_image.h> +#include <kis_iterators_pixel.h> +#include <kis_layer.h> +#include <kis_paint_layer.h> +#include <kis_group_layer.h> +#include "kis_meta_registry.h" +#include <kis_transaction.h> +#include <kis_undo_adapter.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_progress_subject.h> +#include <kis_progress_display_interface.h> +#include <kis_colorspace.h> +#include <kis_colorspace_factory_registry.h> +#include <kis_view.h> +#include <kis_paint_device.h> +#include <kis_channelinfo.h> +#include <kis_convolution_painter.h> +#include "kis_rgb_colorspace.h" + +#include "kis_dropshadow.h" + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + +KisDropshadow::KisDropshadow(KisView * view) + : m_view(view) +{ +} + +void KisDropshadow::dropshadow(KisProgressDisplayInterface * progress, TQ_INT32 xoffset, TQ_INT32 yoffset, TQ_INT32 blurradius, TQColor color, TQ_UINT8 opacity, bool allowResize) +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + if (!image) return; + + KisLayerSP src = image->activeLayer(); + if (!src) return; + + KisPaintDeviceSP dev = image->activeDevice(); + if (!dev) return; + + m_cancelRequested = false; + if ( progress ) + progress->setSubject(this, true, true); + emit notifyProgressStage(i18n("Add drop shadow..."), 0); + + if (image->undo()) { + image->undoAdapter()->beginMacro(i18n("Add Drop Shadow")); + } + + KisPaintDeviceSP shadowDev = new KisPaintDevice( KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA",""),"" ), "Shadow"); + KisPaintDeviceSP bShadowDev; + KisRgbColorSpace *rgb8cs = static_cast<KisRgbColorSpace *>(shadowDev->colorSpace()); + + TQRect rect = dev->exactBounds(); + + for (TQ_INT32 row = 0; row < rect.height(); ++row) + { + KisHLineIteratorPixel srcIt = dev->createHLineIterator(rect.x(), rect.y() + row, rect.width(), false); + KisHLineIteratorPixel dstIt = shadowDev->createHLineIterator(rect.x(), rect.y() + row, rect.width(), true); + while( ! srcIt.isDone() ) + { + if (srcIt.isSelected()) + { + //set the shadow color + TQ_UINT8 alpha = dev->colorSpace()->getAlpha(srcIt.rawData()); + rgb8cs->setPixel(dstIt.rawData(), color.red(), color.green(), color.blue(), alpha); + } + ++srcIt; + ++dstIt; + } + emit notifyProgress((row * 100) / rect.height() ); + } + + if( blurradius > 0 ) + { + bShadowDev = new KisPaintDevice( KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA",""),"" ), "bShadow"); + gaussianblur(shadowDev, bShadowDev, rect, blurradius, blurradius, BLUR_RLE, progress); + shadowDev = bShadowDev; + } + + if (!m_cancelRequested) { + shadowDev->move (xoffset,yoffset); + + KisGroupLayerSP tqparent = image->rootLayer(); + if (image->activeLayer()) + tqparent = image->activeLayer()->tqparent().data(); + + KisPaintLayerSP l = new KisPaintLayer(image, i18n("Drop Shadow"), opacity, shadowDev); + image->addLayer( l.data(), tqparent, src->siblingBelow() ); + + if (allowResize) + { + TQRect shadowBounds = shadowDev->exactBounds(); + + if (!image->bounds().tqcontains(shadowBounds)) { + + TQRect newImageSize = image->bounds() | shadowBounds; + image->resize(newImageSize.width(), newImageSize.height()); + + if (shadowBounds.left() < 0 || shadowBounds.top() < 0) { + + TQ_INT32 newRootX = image->rootLayer()->x(); + TQ_INT32 newRootY = image->rootLayer()->y(); + + if (shadowBounds.left() < 0) { + newRootX += -shadowBounds.left(); + } + if (shadowBounds.top() < 0) { + newRootY += -shadowBounds.top(); + } + + KCommand *moveCommand = image->rootLayer()->moveCommand(TQPoint(image->rootLayer()->x(), image->rootLayer()->y()), + TQPoint(newRootX, newRootY)); + Q_ASSERT(moveCommand != 0); + + if (moveCommand) { + moveCommand->execute(); + if (image->undo()) { + image->undoAdapter()->addCommand(moveCommand); + } else { + delete moveCommand; + } + } + } + } + } + m_view->canvasSubject()->document()->setModified(true); + } + + if (image->undo()) { + image->undoAdapter()->endMacro(); + } + + emit notifyProgressDone(); +} + +void KisDropshadow::gaussianblur (KisPaintDeviceSP srcDev, KisPaintDeviceSP dstDev, TQRect& rect, double horz, double vert, BlurMethod method, KisProgressDisplayInterface *) +{ + TQ_INT32 width, height; + TQ_INT32 bytes; + TQ_UINT8 *dest, *dp; + TQ_UINT8 *src, *sp, *sp_p, *sp_m; + TQ_INT32 *buf = NULL; + TQ_INT32 *bb; + double n_p[5], n_m[5]; + double d_p[5], d_m[5]; + double bd_p[5], bd_m[5]; + double *val_p = NULL; + double *val_m = NULL; + double *vp, *vm; + TQ_INT32 x1, y1, x2, y2; + TQ_INT32 i, j; + TQ_INT32 row, col, b; + TQ_INT32 terms; + double progress, max_progress; + TQ_INT32 initial_p[4]; + TQ_INT32 initial_m[4]; + double std_dev; + TQ_INT32 pixels; + TQ_INT32 total = 1; + TQ_INT32 start, end; + TQ_INT32 *curve; + TQ_INT32 *sum = NULL; + TQ_INT32 val; + TQ_INT32 length; + TQ_INT32 initial_pp, initial_mm; + + x1 = (TQ_INT32)(rect.x() - horz); + y1 = (TQ_INT32)(rect.y() - vert); + width = (TQ_INT32)(rect.width() + 2 * horz); + height = (TQ_INT32)(rect.height() + 2 * vert); + x2 = x1 + width; + y2 = y1 + height; + + if (width < 1 || height < 1) return; + + emit notifyProgressStage(i18n("Blur..."), 0); + + bytes = srcDev->pixelSize(); + + switch (method) + { + case BLUR_IIR: + val_p = new double[MAX (width, height) * bytes]; + val_m = new double[MAX (width, height) * bytes]; + break; + + case BLUR_RLE: + buf = new TQ_INT32[MAX (width, height) * 2]; + break; + } + + src = new TQ_UINT8[MAX (width, height) * bytes]; + dest = new TQ_UINT8[MAX (width, height) * bytes]; + + progress = 0.0; + max_progress = (horz <= 0.0 ) ? 0 : width * height * horz; + max_progress += (vert <= 0.0 ) ? 0 : width * height * vert; + + + /* First the vertical pass */ + if (vert > 0.0) + { + vert = fabs (vert) + 1.0; + std_dev = sqrt (-(vert * vert) / (2 * log (1.0 / 255.0))); + + switch (method) + { + case BLUR_IIR: + /* derive the constants for calculating the gaussian + * from the std dev + */ + find_constants (n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev); + break; + + case BLUR_RLE: + curve = make_curve (std_dev, &length); + sum = new TQ_INT32[2 * length + 1]; + + sum[0] = 0; + + for (i = 1; i <= length*2; i++) + sum[i] = curve[i-length-1] + sum[i-1]; + sum += length; + + total = sum[length] - sum[-length]; + break; + } + + for (col = 0; col < width; col++) + { + switch (method) + { + case BLUR_IIR: + memset (val_p, 0, height * bytes * sizeof (double)); + memset (val_m, 0, height * bytes * sizeof (double)); + break; + + case BLUR_RLE: + break; + } + + //gimp_pixel_rgn_get_col (&src_rgn, src, col + x1, y1, height); + srcDev->readBytes(src, col+x1, y1, 1, height); + + multiply_alpha (src, height, bytes); + + switch (method) + { + case BLUR_IIR: + sp_p = src; + sp_m = src + (height - 1) * bytes; + vp = val_p; + vm = val_m + (height - 1) * bytes; + + /* Set up the first vals */ + for (i = 0; i < bytes; i++) + { + initial_p[i] = sp_p[i]; + initial_m[i] = sp_m[i]; + } + + for (row = 0; row < height; row++) + { + double *vpptr, *vmptr; + terms = (row < 4) ? row : 4; + + for (b = 0; b < bytes; b++) + { + vpptr = vp + b; vmptr = vm + b; + for (i = 0; i <= terms; i++) + { + *vpptr += n_p[i] * sp_p[(-i * bytes) + b] - + d_p[i] * vp[(-i * bytes) + b]; + *vmptr += n_m[i] * sp_m[(i * bytes) + b] - + d_m[i] * vm[(i * bytes) + b]; + } + for (j = i; j <= 4; j++) + { + *vpptr += (n_p[j] - bd_p[j]) * initial_p[b]; + *vmptr += (n_m[j] - bd_m[j]) * initial_m[b]; + } + } + + sp_p += bytes; + sp_m -= bytes; + vp += bytes; + vm -= bytes; + } + + transfer_pixels (val_p, val_m, dest, bytes, height); + break; + + case BLUR_RLE: + sp = src; + dp = dest; + + for (b = 0; b < bytes; b++) + { + initial_pp = sp[b]; + initial_mm = sp[(height-1) * bytes + b]; + + /* Determine a run-length encoded version of the row */ + run_length_encode (sp + b, buf, bytes, height); + + for (row = 0; row < height; row++) + { + start = (row < length) ? -row : -length; + end = (height <= (row + length) ? + (height - row - 1) : length); + + val = 0; + i = start; + bb = buf + (row + i) * 2; + + if (start != -length) + val += initial_pp * (sum[start] - sum[-length]); + + while (i < end) + { + pixels = bb[0]; + i += pixels; + if (i > end) + i = end; + val += bb[1] * (sum[i] - sum[start]); + bb += (pixels * 2); + start = i; + } + + if (end != length) + val += initial_mm * (sum[length] - sum[end]); + + dp[row * bytes + b] = val / total; + } + } + break; + } + + separate_alpha (src, height, bytes); + + dstDev->writeBytes(dest, col + x1, y1, 1, height); + + progress += height * vert; + if ((col % 5) == 0) emit notifyProgress( (TQ_UINT32)((progress * 100) / max_progress)); + } + } + + /* Now the horizontal pass */ + if (horz > 0.0) + { + horz = fabs (horz) + 1.0; + + if (horz != vert) + { + std_dev = sqrt (-(horz * horz) / (2 * log (1.0 / 255.0))); + + switch (method) + { + case BLUR_IIR: + /* derive the constants for calculating the gaussian + * from the std dev + */ + find_constants (n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev); + break; + + case BLUR_RLE: + curve = make_curve (std_dev, &length); + sum = new TQ_INT32[2 * length + 1]; + + sum[0] = 0; + + for (i = 1; i <= length*2; i++) + sum[i] = curve[i-length-1] + sum[i-1]; + sum += length; + + total = sum[length] - sum[-length]; + break; + } + } + + for (row = 0; row < height; row++) + { + switch (method) + { + case BLUR_IIR: + memset (val_p, 0, width * bytes * sizeof (double)); + memset (val_m, 0, width * bytes * sizeof (double)); + break; + + case BLUR_RLE: + break; + } + + + //gimp_pixel_rgn_get_row (&src_rgn, src, x1, row + y1, width); + dstDev->readBytes(src, x1, row + y1, width, 1); + + multiply_alpha (dest, width, bytes); + + switch (method) + { + case BLUR_IIR: + sp_p = src; + sp_m = src + (width - 1) * bytes; + vp = val_p; + vm = val_m + (width - 1) * bytes; + + /* Set up the first vals */ + for (i = 0; i < bytes; i++) + { + initial_p[i] = sp_p[i]; + initial_m[i] = sp_m[i]; + } + + for (col = 0; col < width; col++) + { + double *vpptr, *vmptr; + terms = (col < 4) ? col : 4; + + for (b = 0; b < bytes; b++) + { + vpptr = vp + b; vmptr = vm + b; + for (i = 0; i <= terms; i++) + { + *vpptr += n_p[i] * sp_p[(-i * bytes) + b] - + d_p[i] * vp[(-i * bytes) + b]; + *vmptr += n_m[i] * sp_m[(i * bytes) + b] - + d_m[i] * vm[(i * bytes) + b]; + } + for (j = i; j <= 4; j++) + { + *vpptr += (n_p[j] - bd_p[j]) * initial_p[b]; + *vmptr += (n_m[j] - bd_m[j]) * initial_m[b]; + } + } + + sp_p += bytes; + sp_m -= bytes; + vp += bytes; + vm -= bytes; + } + + transfer_pixels (val_p, val_m, dest, bytes, width); + break; + + case BLUR_RLE: + sp = src; + dp = dest; + + for (b = 0; b < bytes; b++) + { + initial_pp = sp[b]; + initial_mm = sp[(width-1) * bytes + b]; + + /* Determine a run-length encoded version of the row */ + run_length_encode (sp + b, buf, bytes, width); + + for (col = 0; col < width; col++) + { + start = (col < length) ? -col : -length; + end = (width <= (col + length)) ? (width - col - 1) : length; + + val = 0; + i = start; + bb = buf + (col + i) * 2; + + if (start != -length) + val += initial_pp * (sum[start] - sum[-length]); + + while (i < end) + { + pixels = bb[0]; + i += pixels; + if (i > end) + i = end; + val += bb[1] * (sum[i] - sum[start]); + bb += (pixels * 2); + start = i; + } + + if (end != length) + val += initial_mm * (sum[length] - sum[end]); + + dp[col * bytes + b] = val / total; + } + } + break; + } + + separate_alpha (dest, width, bytes); + + //gimp_pixel_rgn_set_row (&dest_rgn, dest, x1, row + y1, width); + dstDev->writeBytes(dest, x1, row + y1, width, 1); + + progress += width * horz; + //if ((row % 5) == 0) gimp_progress_update (progress / max_progress); + if ((row % 5) == 0) emit notifyProgress( (TQ_UINT32)((progress * 100) / max_progress )); + } + } + + /* free up buffers */ + switch (method) + { + case BLUR_IIR: + delete[] val_p; + delete[] val_m; + break; + + case BLUR_RLE: + delete[] buf; + break; + } + + delete[] src; + delete[] dest; +} + +void KisDropshadow::find_constants (double n_p[], double n_m[], double d_p[], double d_m[], double bd_p[], double bd_m[], double std_dev) +{ + TQ_INT32 i; + double constants [8]; + double div; + + /* The constants used in the implemenation of a casual sequence + * using a 4th order approximation of the gaussian operator + */ + + div = sqrt(2 * M_PI) * std_dev; + constants [0] = -1.783 / std_dev; + constants [1] = -1.723 / std_dev; + constants [2] = 0.6318 / std_dev; + constants [3] = 1.997 / std_dev; + constants [4] = 1.6803 / div; + constants [5] = 3.735 / div; + constants [6] = -0.6803 / div; + constants [7] = -0.2598 / div; + + n_p [0] = constants[4] + constants[6]; + n_p [1] = exp (constants[1]) * + (constants[7] * sin (constants[3]) - + (constants[6] + 2 * constants[4]) * cos (constants[3])) + + exp (constants[0]) * + (constants[5] * sin (constants[2]) - + (2 * constants[6] + constants[4]) * cos (constants[2])); + n_p [2] = 2 * exp (constants[0] + constants[1]) * + ((constants[4] + constants[6]) * cos (constants[3]) * cos (constants[2]) - + constants[5] * cos (constants[3]) * sin (constants[2]) - + constants[7] * cos (constants[2]) * sin (constants[3])) + + constants[6] * exp (2 * constants[0]) + + constants[4] * exp (2 * constants[1]); + n_p [3] = exp (constants[1] + 2 * constants[0]) * + (constants[7] * sin (constants[3]) - constants[6] * cos (constants[3])) + + exp (constants[0] + 2 * constants[1]) * + (constants[5] * sin (constants[2]) - constants[4] * cos (constants[2])); + n_p [4] = 0.0; + + d_p [0] = 0.0; + d_p [1] = -2 * exp (constants[1]) * cos (constants[3]) - + 2 * exp (constants[0]) * cos (constants[2]); + d_p [2] = 4 * cos (constants[3]) * cos (constants[2]) * exp (constants[0] + constants[1]) + + exp (2 * constants[1]) + exp (2 * constants[0]); + d_p [3] = -2 * cos (constants[2]) * exp (constants[0] + 2 * constants[1]) - + 2 * cos (constants[3]) * exp (constants[1] + 2 * constants[0]); + d_p [4] = exp (2 * constants[0] + 2 * constants[1]); + + for (i = 0; i <= 4; i++) + d_m [i] = d_p [i]; + + n_m[0] = 0.0; + for (i = 1; i <= 4; i++) + n_m [i] = n_p[i] - d_p[i] * n_p[0]; + + { + double sum_n_p, sum_n_m, sum_d; + double a, b; + + sum_n_p = 0.0; + sum_n_m = 0.0; + sum_d = 0.0; + for (i = 0; i <= 4; i++) + { + sum_n_p += n_p[i]; + sum_n_m += n_m[i]; + sum_d += d_p[i]; + } + + a = sum_n_p / (1.0 + sum_d); + b = sum_n_m / (1.0 + sum_d); + + for (i = 0; i <= 4; i++) + { + bd_p[i] = d_p[i] * a; + bd_m[i] = d_m[i] * b; + } + } +} + + +void KisDropshadow::transfer_pixels (double *src1, double *src2, TQ_UINT8 *dest, TQ_INT32 bytes, TQ_INT32 width) +{ + TQ_INT32 b; + TQ_INT32 bend = bytes * width; + double sum; + + for(b = 0; b < bend; b++) + { + sum = *src1++ + *src2++; + if (sum > 255) sum = 255; + else if(sum < 0) sum = 0; + + *dest++ = (TQ_UINT8) sum; + } +} + +//The equations: g(r) = exp (- r^2 / (2 * sigma^2)), r = sqrt (x^2 + y ^2) +TQ_INT32 * KisDropshadow::make_curve(double sigma, TQ_INT32 *length) +{ + int *curve; + double sigma2; + double l; + int temp; + int i, n; + + sigma2 = 2 * sigma * sigma; + l = sqrt (-sigma2 * log (1.0 / 255.0)); + + n = (int)(ceil (l) * 2); + if ((n % 2) == 0) + n += 1; + + curve = new TQ_INT32[n]; + + *length = n / 2; + curve += *length; + curve[0] = 255; + + for (i = 1; i <= *length; i++) + { + temp = (TQ_INT32) (exp (- (i * i) / sigma2) * 255); + curve[-i] = temp; + curve[i] = temp; + } + + return curve; +} + +void KisDropshadow::run_length_encode (TQ_UINT8 *src, TQ_INT32 *dest, TQ_INT32 bytes, TQ_INT32 width) +{ + TQ_INT32 start; + TQ_INT32 i; + TQ_INT32 j; + TQ_UINT8 last; + + last = *src; + src += bytes; + start = 0; + + for (i = 1; i < width; i++) + { + if (*src != last) + { + for (j = start; j < i; j++) + { + *dest++ = (i - j); + *dest++ = last; + } + start = i; + last = *src; + } + src += bytes; + } + + for (j = start; j < i; j++) + { + *dest++ = (i - j); + *dest++ = last; + } +} + +void KisDropshadow::multiply_alpha (TQ_UINT8 *buf, TQ_INT32 width, TQ_INT32 bytes) +{ + TQ_INT32 i, j; + double alpha; + + for (i = 0; i < width * bytes; i += bytes) + { + alpha = buf[i + bytes - 1] * (1.0 / 255.0); + for (j = 0; j < bytes - 1; j++) { + double a = (double)(buf[i + j]) * alpha; + buf[i + j] = (TQ_UINT8)a; + } + } +} + +void KisDropshadow::separate_alpha (TQ_UINT8 *buf, TQ_INT32 width, TQ_INT32 bytes) +{ + TQ_INT32 i, j; + TQ_UINT8 alpha; + double recip_alpha; + TQ_UINT32 new_val; + + for (i = 0; i < width * bytes; i += bytes) + { + alpha = buf[i + bytes - 1]; + if (alpha != 0 && alpha != 255) + { + recip_alpha = 255.0 / alpha; + for (j = 0; j < bytes - 1; j++) + { + new_val = (TQ_UINT32)(buf[i + j] * recip_alpha); + buf[i + j] = MIN (255, new_val); + } + } + } +} + +#include "kis_dropshadow.moc" diff --git a/chalk/plugins/viewplugins/dropshadow/kis_dropshadow.h b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow.h new file mode 100644 index 00000000..94c6decc --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow.h @@ -0,0 +1,72 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_DROPSHADOW_H_ +#define _KIS_DROPSHADOW_H_ + +#include <kis_progress_subject.h> +#include <kis_paint_device.h> + +typedef enum +{ + BLUR_IIR, + BLUR_RLE +} BlurMethod; + + +class TQColor; +class KisView; +class KisProgressDisplayInterface; + +class KisDropshadow : public KisProgressSubject { + + Q_OBJECT + TQ_OBJECT + +public: + + KisDropshadow(KisView * view); + virtual ~KisDropshadow() {}; + + void dropshadow(KisProgressDisplayInterface * progress, TQ_INT32 xoffset, TQ_INT32 yoffset, TQ_INT32 blurradius, TQColor color, TQ_UINT8 opacity, bool allowResize); + +public: // Implement KisProgressSubject + virtual void cancel() { m_cancelRequested = true; } + +private: + void gaussianblur (KisPaintDeviceSP src, KisPaintDeviceSP dst, + TQRect& rect, double horz, double vert, + BlurMethod method, + KisProgressDisplayInterface * progressDisplay); + //gaussian blur helper functions + void find_constants(double n_p[], double n_m[], double d_p[], double d_m[], double bd_p[], double bd_m[], double std_dev); + void transfer_pixels(double *src1, double *src2, TQ_UINT8 *dest, TQ_INT32 bytes, TQ_INT32 width); + TQ_INT32* make_curve(double sigma, TQ_INT32 *length); + void run_length_encode (TQ_UINT8 *src, TQ_INT32 *dest, TQ_INT32 bytes, TQ_INT32 width); + void multiply_alpha (TQ_UINT8 *buf, TQ_INT32 width, TQ_INT32 bytes); + void separate_alpha (TQ_UINT8 *buf, TQ_INT32 width, TQ_INT32 bytes); + +private: + KisView * m_view; + bool m_cancelRequested; + +}; + +#endif diff --git a/chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cc b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cc new file mode 100644 index 00000000..5dc190f1 --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cc @@ -0,0 +1,91 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> + +#include <kis_view.h> +#include <kis_types.h> +#include <kis_image.h> +#include <kis_paint_device.h> +#include <kis_layer.h> + +#include "kis_dropshadow_plugin.h" +#include "kis_dropshadow.h" +#include "dlg_dropshadow.h" + +K_EXPORT_COMPONENT_FACTORY( chalkdropshadow, KGenericFactory<KisDropshadowPlugin>( "chalk" ) ) + +KisDropshadowPlugin::KisDropshadowPlugin(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + if ( tqparent->inherits("KisView") ) { + + setInstance(KGenericFactory<KisDropshadowPlugin>::instance()); + setXMLFile(locate("data","chalkplugins/dropshadow.rc"), true); + + m_view = (KisView*) tqparent; + (void) new KAction(i18n("Add Drop Shadow..."), 0, 0, this, TQT_SLOT(slotDropshadow()), actionCollection(), "dropshadow"); + } +} + +KisDropshadowPlugin::~KisDropshadowPlugin() +{ +} + +void KisDropshadowPlugin::slotDropshadow() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + if (!image) return; + + KisPaintDeviceSP dev = image->activeDevice(); + if (!dev) return; + + DlgDropshadow * dlgDropshadow = new DlgDropshadow(dev->colorSpace()->id().name(), + image->colorSpace()->id().name(), + m_view, "Dropshadow"); + Q_CHECK_PTR(dlgDropshadow); + + dlgDropshadow->setCaption(i18n("Drop Shadow")); + + if (dlgDropshadow->exec() == TQDialog::Accepted) { + + KisDropshadow dropshadow(m_view); + dropshadow.dropshadow(m_view->canvasSubject()->progressDisplay(), + dlgDropshadow->getXOffset(), + dlgDropshadow->getYOffset(), + dlgDropshadow->getBlurRadius(), + dlgDropshadow->getShadowColor(), + dlgDropshadow->getShadowOpacity(), + dlgDropshadow->allowResizingChecked()); + + } + + delete dlgDropshadow; + +} + +#include "kis_dropshadow_plugin.moc" diff --git a/chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.h b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.h new file mode 100644 index 00000000..e2641ed2 --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.h @@ -0,0 +1,46 @@ +/* + * This file is part of Chalk + * + * Copyright (c) Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _KIS_DROPSHADOW_PLUGIN_H_ +#define _KIS_DROPSHADOW_PLUGIN_H_ + +#include <kparts/plugin.h> + +class KisView; + + + +class KisDropshadowPlugin : public KParts::Plugin +{ + Q_OBJECT + TQ_OBJECT +public: + KisDropshadowPlugin(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~KisDropshadowPlugin(); + +private slots: + + void slotDropshadow(); + +private: + + KisView * m_view; +}; + +#endif diff --git a/chalk/plugins/viewplugins/dropshadow/wdg_dropshadow.ui b/chalk/plugins/viewplugins/dropshadow/wdg_dropshadow.ui new file mode 100644 index 00000000..4bd2f38c --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/wdg_dropshadow.ui @@ -0,0 +1,235 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgDropshadow</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgDropshadow</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>403</width> + <height>258</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Offset X:</string> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>Offset Y:</string> + </property> + </widget> + <widget class="TQLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Blur radius:</string> + </property> + </widget> + <widget class="TQLabel" row="3" column="0"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>Color:</string> + </property> + </widget> + <widget class="TQLabel" row="4" column="0"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="text"> + <string>Opacity:</string> + </property> + </widget> + <widget class="TQSlider" row="4" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>opacitySlider</cstring> + </property> + <property name="maxValue"> + <number>100</number> + </property> + <property name="value"> + <number>80</number> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="TQSpinBox" row="4" column="3"> + <property name="name"> + <cstring>opacitySpinBox</cstring> + </property> + <property name="suffix"> + <string>%</string> + </property> + <property name="maxValue"> + <number>100</number> + </property> + <property name="value"> + <number>80</number> + </property> + </widget> + <widget class="TQCheckBox" row="5" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>allowResizingCheckBox</cstring> + </property> + <property name="text"> + <string>Allow resizing</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQSpinBox" row="0" column="1"> + <property name="name"> + <cstring>xOffsetSpinBox</cstring> + </property> + <property name="minValue"> + <number>-99</number> + </property> + <property name="value"> + <number>8</number> + </property> + </widget> + <spacer row="0" column="2" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer7</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>200</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQSpinBox" row="1" column="1"> + <property name="name"> + <cstring>yOffsetSpinBox</cstring> + </property> + <property name="minValue"> + <number>-99</number> + </property> + <property name="value"> + <number>8</number> + </property> + </widget> + <spacer row="1" column="2" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer8</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>200</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQSpinBox" row="2" column="1"> + <property name="name"> + <cstring>blurRadiusSpinBox</cstring> + </property> + <property name="value"> + <number>5</number> + </property> + </widget> + <spacer row="2" column="2" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer9</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>190</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KColorButton" row="3" column="1"> + <property name="name"> + <cstring>shadowColorButton</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <spacer row="3" column="2" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>120</width> + <height>31</height> + </size> + </property> + </spacer> + </grid> +</widget> +<customwidgets> +</customwidgets> +<connections> + <connection> + <sender>opacitySpinBox</sender> + <signal>valueChanged(int)</signal> + <receiver>opacitySlider</receiver> + <slot>setValue(int)</slot> + </connection> + <connection> + <sender>opacitySlider</sender> + <signal>valueChanged(int)</signal> + <receiver>opacitySpinBox</receiver> + <slot>setValue(int)</slot> + </connection> +</connections> +<tabstops> + <tabstop>xOffsetSpinBox</tabstop> + <tabstop>yOffsetSpinBox</tabstop> + <tabstop>blurRadiusSpinBox</tabstop> + <tabstop>shadowColorButton</tabstop> + <tabstop>opacitySlider</tabstop> + <tabstop>opacitySpinBox</tabstop> + <tabstop>allowResizingCheckBox</tabstop> +</tabstops> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kcolorbutton.h</includehint> +</includehints> +</UI> diff --git a/chalk/plugins/viewplugins/filtersgallery/Makefile.am b/chalk/plugins/viewplugins/filtersgallery/Makefile.am new file mode 100644 index 00000000..90ddcfc6 --- /dev/null +++ b/chalk/plugins/viewplugins/filtersgallery/Makefile.am @@ -0,0 +1,26 @@ +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = chalkfiltersgallery.rc + +EXTRA_DIST = $(chalkrc_DATA) + +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../ui \ + -I../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +chalkfiltersgallery_la_SOURCES = filters_gallery.cc \ + kis_dlg_filtersgallery.cc kis_wdg_filtersgallery.ui + +kde_module_LTLIBRARIES = chalkfiltersgallery.la +noinst_HEADERS = filters_gallery.h kis_dlg_filtersgallery.h + +kde_services_DATA = chalkfiltersgallery.desktop + +chalkfiltersgallery_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) chalkblurfilter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui +chalkfiltersgallery_la_LIBADD = ../../../libchalkcommon.la + +chalkfiltersgallery_la_METASOURCES = AUTO diff --git a/chalk/plugins/viewplugins/filtersgallery/chalkfiltersgallery.desktop b/chalk/plugins/viewplugins/filtersgallery/chalkfiltersgallery.desktop new file mode 100644 index 00000000..ed1bb5c9 --- /dev/null +++ b/chalk/plugins/viewplugins/filtersgallery/chalkfiltersgallery.desktop @@ -0,0 +1,45 @@ +[Desktop Entry] +Name=Filters Gallery +Name[bg]=Галерия с филтри +Name[ca]=Galeria de filtres +Name[da]=Filtergalleri +Name[de]=Filtergallerie +Name[el]=Συλλογή φίλτρων +Name[eo]=Filtrilgalerio +Name[es]=Galería de filtros +Name[et]=Filtrigalerii +Name[fa]=گالری پالایهها +Name[fr]=Galerie de filtres +Name[fy]=Filtergallerij +Name[ga]=Gailearaí na Scagairí +Name[gl]=Galería de Filtros +Name[he]=גלריית מסננים +Name[hu]=Szűrőgaléria +Name[is]=Síusafn +Name[it]=Galleria dei filtri +Name[ja]=フィルタギャラリー +Name[km]=វិចិត្រសាលតម្រង +Name[lv]=Filtru galerija +Name[nb]=Filtergalleri +Name[nds]=Filtersammeln +Name[ne]=फिल्टर ग्यालेरी +Name[nl]=Filtergalerij +Name[pl]=Galeria filtrów +Name[pt]=Galeria de Filtros +Name[pt_BR]=Galeria de Filtros +Name[ru]=Галерея фильтров +Name[se]=Sillegalleriija +Name[sk]=Zbierka filtrov +Name[sl]=Galerija filtrov +Name[sr]=Галерија филтера +Name[sr@Latn]=Galerija filtera +Name[sv]=Filtrergalleri +Name[uk]=Галерея фільтрів +Name[uz]=Filterlar toʻplami +Name[uz@cyrillic]=Филтерлар тўплами +Name[zh_CN]=滤镜库 +Name[zh_TW]=濾鏡畫廊 +ServiceTypes=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkfiltersgallery +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/filtersgallery/chalkfiltersgallery.rc b/chalk/plugins/viewplugins/filtersgallery/chalkfiltersgallery.rc new file mode 100644 index 00000000..e5fcfa43 --- /dev/null +++ b/chalk/plugins/viewplugins/filtersgallery/chalkfiltersgallery.rc @@ -0,0 +1,9 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkfiltersgallery" version="7"> +<MenuBar> +<Menu name="Filter"><text>&Filter</text> + <Seperator/> + <Action name="chalk_filters_gallery"/> +</Menu> +</MenuBar> +</kpartgui> diff --git a/chalk/plugins/viewplugins/filtersgallery/filters_gallery.cc b/chalk/plugins/viewplugins/filtersgallery/filters_gallery.cc new file mode 100644 index 00000000..8f70b8f7 --- /dev/null +++ b/chalk/plugins/viewplugins/filtersgallery/filters_gallery.cc @@ -0,0 +1,138 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "filters_gallery.h" + +#include <tqapplication.h> + +#include <kdebug.h> +#include <kgenericfactory.h> +#include <kstandarddirs.h> + +#include <kopalettemanager.h> + +#include <kis_colorspace_factory_registry.h> +#include "kis_progress_display_interface.h" +#include <kis_dlg_filtersgallery.h> +#include <kis_doc.h> +#include <kis_filter.h> +#include <kis_filters_listview.h> +#include <kis_meta_registry.h> +#include <kis_paint_device.h> +#include <kis_selection.h> +#include <kis_view.h> +#include <kis_transaction.h> + +namespace Chalk { +namespace Plugins { +namespace FiltersGallery { + +typedef KGenericFactory<ChalkFiltersGallery> ChalkFiltersGalleryFactory; +K_EXPORT_COMPONENT_FACTORY( chalkfiltersgallery, ChalkFiltersGalleryFactory( "chalk" ) ) + +ChalkFiltersGallery::ChalkFiltersGallery(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + + if ( tqparent->inherits("KisView") ) + { + setInstance(ChalkFiltersGallery::instance()); + setXMLFile(locate("data","chalkplugins/chalkfiltersgallery.rc"), true); + + m_view = (KisView*) tqparent; + + (void) new KAction(i18n("&Filters Gallery"), 0, 0, this, TQT_SLOT(showFiltersGalleryDialog()), actionCollection(), "chalk_filters_gallery"); + + // Add a docker with the list of filters +// TQImage img; +// if(img.load(locate("data","chalk/images/previewfilter.png"))) +// { +// KisPaintDeviceSP preview = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA",""),"")); +// preview->convertFromTQImage(img,""); +// m_view->canvasSubject()->paletteManager()->addWidget(new KisFiltersListView(preview,m_view),"filterslist",chalk::EFFECTSBOX, 0); +// } + + } + + +} + +ChalkFiltersGallery::~ChalkFiltersGallery() +{ +} + +void ChalkFiltersGallery::showFiltersGalleryDialog() +{ + KisDlgFiltersGallery dlg(m_view, m_view); + if (dlg.exec()) + { + TQApplication::setOverrideCursor( TQt::waitCursor ); + + KisFilter* filter = dlg.currentFilter(); + if(filter ) + { + KisImageSP img = m_view->canvasSubject()->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + TQRect r1 = dev->exactBounds(); + TQRect r2 = img->bounds(); + + TQRect rect = r1.intersect(r2); + + if (dev->hasSelection()) { + TQRect r3 = dev->selection()->selectedExactRect(); + rect = rect.intersect(r3); + } + KisFilterConfiguration* config = filter->configuration( dlg.currentConfigWidget()); + + filter->enableProgress(); + m_view->canvasSubject()->progressDisplay()->setSubject(filter, true, true); + filter->setProgressDisplay(m_view->canvasSubject()->progressDisplay()); + + KisTransaction * cmd = new KisTransaction(filter->id().name(), dev); + + filter->process(dev,dev, config, rect); + + delete config; + if (filter->cancelRequested()) { + cmd->unexecute(); + delete cmd; + } else { + dev->setDirty(rect); + if (img->undo()) + img->undoAdapter()->addCommand(cmd); + else + delete cmd; + } + filter->disableProgress(); + TQApplication::restoreOverrideCursor(); + + } + } +} + +} +} +} + +#include "filters_gallery.moc" diff --git a/chalk/plugins/viewplugins/filtersgallery/filters_gallery.h b/chalk/plugins/viewplugins/filtersgallery/filters_gallery.h new file mode 100644 index 00000000..89fed386 --- /dev/null +++ b/chalk/plugins/viewplugins/filtersgallery/filters_gallery.h @@ -0,0 +1,54 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _KRITA_FILTERS_PREVIEW_H_ +#define _KRITA_FILTERS_PREVIEW_H_ + +#include <kparts/plugin.h> + +class KisView; + +namespace Chalk { +namespace Plugins { +namespace FiltersGallery { + class ChalkFiltersGallery : public KParts::Plugin + { + Q_OBJECT + TQ_OBJECT + public: + ChalkFiltersGallery(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~ChalkFiltersGallery(); + public slots: + void showFiltersGalleryDialog(); + private: + + KisView * m_view; + + + }; + +} +} +} + + + +#endif diff --git a/chalk/plugins/viewplugins/filtersgallery/kis_dlg_filtersgallery.cc b/chalk/plugins/viewplugins/filtersgallery/kis_dlg_filtersgallery.cc new file mode 100644 index 00000000..76676177 --- /dev/null +++ b/chalk/plugins/viewplugins/filtersgallery/kis_dlg_filtersgallery.cc @@ -0,0 +1,133 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005-2006 Cyrille Berger <cberger@cberger.net> + * Copyright (c) 2007 Benjamin Schleimer <bensch128@yahoo.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#include "kis_dlg_filtersgallery.h" + +#include <tqgroupbox.h> +#include <tqlayout.h> +#include <tqlabel.h> +#include <tqdatetime.h> + +#include <kis_filter.h> +#include <kis_filter_config_widget.h> +#include <kis_filters_listview.h> +#include <kis_paint_device.h> +#include <kis_paint_layer.h> +#include <kis_previewwidget.h> +#include <kis_transaction.h> +#include <kis_types.h> +#include <kis_view.h> + +#include "kis_wdg_filtersgallery.h" + +namespace Chalk { +namespace Plugins { +namespace FiltersGallery { + + +KisDlgFiltersGallery::KisDlgFiltersGallery(KisView* view, TQWidget* tqparent,const char *name) + : KDialogBase(tqparent,name, true,i18n("Filters Gallery"), Ok | Cancel), m_view(view),m_currentConfigWidget(0), m_currentFilter(0) +{ + // Initialize main widget + m_widget = new KisWdgFiltersGallery(this); + m_widget->filtersList->setLayer(view->canvasSubject()->currentImg()->activeLayer()); + m_widget->filtersList->setProfile(view->canvasSubject()->monitorProfile()); + + setMainWidget(m_widget); + // Initialize filters list + connect(m_widget->filtersList , TQT_SIGNAL(selectionChanged(TQIconViewItem*)), this, TQT_SLOT(selectionHasChanged(TQIconViewItem* ))); + // Initialize configWidgetHolder + m_widget->configWidgetHolder->setColumnLayout ( 0, Qt::Horizontal ); + //m_widget->configWidgetHolder->tqsetSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Minimum); + // Initialize preview widget + + if (m_view->canvasSubject()->currentImg() && m_view->canvasSubject()->currentImg()->activeDevice()) + { + m_widget->previewWidget->slotSetDevice( m_view->canvasSubject()->currentImg()->activeDevice().data() ); + } + connect( m_widget->previewWidget, TQT_SIGNAL(updated()), this, TQT_SLOT(refreshPreview())); + resize( tqminimumSizeHint()); + m_widget->previewWidget->tqsetSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::MinimumExpanding); + m_labelNoCW = new TQLabel(i18n("No configuration options are available for this filter."), m_widget->configWidgetHolder); + m_widget->configWidgetHolder->tqlayout()->add(m_labelNoCW); + m_labelNoCW->hide(); +} + +KisDlgFiltersGallery::~KisDlgFiltersGallery() +{ +} + +void KisDlgFiltersGallery::selectionHasChanged ( TQIconViewItem * item ) +{ + KisFiltersIconViewItem* kisitem = (KisFiltersIconViewItem*) item; + m_currentFilter = kisitem->filter(); + if(m_currentConfigWidget != 0) + { + m_widget->configWidgetHolder->tqlayout()->remove(m_currentConfigWidget); + delete m_currentConfigWidget; + m_currentConfigWidget = 0; + } else { + m_labelNoCW->hide(); + } + KisImageSP img = m_view->canvasSubject()->currentImg(); + KisPaintLayerSP activeLayer = dynamic_cast<KisPaintLayer*>(img->activeLayer().data()); + + if (activeLayer) + m_currentConfigWidget = m_currentFilter->createConfigurationWidget(m_widget->configWidgetHolder, activeLayer->paintDevice()); + + if(m_currentConfigWidget != 0) { + //m_currentConfigWidget->tqsetSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed); + m_widget->configWidgetHolder->tqlayout()->add(m_currentConfigWidget); + m_currentConfigWidget->show(); + connect(m_currentConfigWidget, TQT_SIGNAL(sigPleaseUpdatePreview()), this, TQT_SLOT(slotConfigChanged())); + } + else { + m_labelNoCW->show(); + } + + refreshPreview(); +} + +void KisDlgFiltersGallery::slotConfigChanged() +{ + if(m_widget->previewWidget->getAutoUpdate()) + { + refreshPreview(); + } else { + m_widget->previewWidget->needUpdate(); + } +} + + +void KisDlgFiltersGallery::refreshPreview( ) +{ + if(!m_currentFilter) return; + + KisFilterConfiguration* config = m_currentFilter->configuration(m_currentConfigWidget); + + m_widget->previewWidget->runFilter(m_currentFilter, config); +} + +} +} +} + +#include "kis_dlg_filtersgallery.moc" diff --git a/chalk/plugins/viewplugins/filtersgallery/kis_dlg_filtersgallery.h b/chalk/plugins/viewplugins/filtersgallery/kis_dlg_filtersgallery.h new file mode 100644 index 00000000..09e5cb1f --- /dev/null +++ b/chalk/plugins/viewplugins/filtersgallery/kis_dlg_filtersgallery.h @@ -0,0 +1,69 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005-2006 Cyrille Berger <cberger@cberger.net> + * Copyright (c) 2007 Benjamin Schleimer <bensch128@yahoo.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef KISDLGFILTERSPREVIEW_H +#define KISDLGFILTERSPREVIEW_H + +#include <kdialogbase.h> + +class KisView; +class KisFilter; +class TQIconViewItem; +class TQLabel; +class TQHBoxLayout; +class KisPreviewWidget; +class KisWdgFiltersGallery; +class KisFiltersListView; + +namespace Chalk { +namespace Plugins { +namespace FiltersGallery { + +/** +@author Cyrille Berger +*/ +class KisDlgFiltersGallery : public KDialogBase +{ + Q_OBJECT + TQ_OBJECT + public: + KisDlgFiltersGallery(KisView* view, TQWidget* tqparent,const char *name = ""); + ~KisDlgFiltersGallery(); + public: + inline KisFilter* currentFilter() { return m_currentFilter; }; + inline TQWidget* currentConfigWidget() { return m_currentConfigWidget; } + private slots: + void slotConfigChanged(); + void refreshPreview(); + void selectionHasChanged ( TQIconViewItem * item ); + private: + KisWdgFiltersGallery* m_widget; + KisView* m_view; + TQWidget* m_currentConfigWidget; + KisFilter* m_currentFilter; + TQLabel* m_labelNoCW; +}; + +} +} +} + +#endif diff --git a/chalk/plugins/viewplugins/filtersgallery/kis_wdg_filtersgallery.ui b/chalk/plugins/viewplugins/filtersgallery/kis_wdg_filtersgallery.ui new file mode 100644 index 00000000..488c9564 --- /dev/null +++ b/chalk/plugins/viewplugins/filtersgallery/kis_wdg_filtersgallery.ui @@ -0,0 +1,123 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>KisWdgFiltersGallery</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>KisWdgFiltersGallery</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>763</width> + <height>296</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="KisPreviewWidget" row="0" column="1"> + <property name="name"> + <cstring>previewWidget</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <widget class="KisFiltersListView" row="0" column="0"> + <property name="name"> + <cstring>filtersList</cstring> + </property> + </widget> + <widget class="TQGroupBox" row="0" column="2"> + <property name="name"> + <cstring>configWidgetHolder</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="title"> + <string>Configuration</string> + </property> + </widget> + </grid> +</widget> +<customwidgets> + <customwidget> + <class>KisPreviewWidget</class> + <header location="local">kis_previewwidget.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + <signal>moved(QPoint)</signal> + <signal>moving(QPoint)</signal> + <signal>startMoving(QPoint)</signal> + <slot access="public" specifier="">zoomIn()</slot> + <slot access="public" specifier="">slot()</slot> + <slot access="public" specifier="">zoomOut()</slot> + <slot access="public" specifier="">slot()</slot> + <slot access="public" specifier="">slot()</slot> + <slot access="public" specifier="">slotMoving(QPoint)</slot> + <slot access="public" specifier="">slotMoved(QPoint)</slot> + <slot access="public" specifier="">slot()</slot> + <slot access="public" specifier="">slotStartMoving(QPoint)</slot> + </customwidget> + <customwidget> + <class>KisFiltersListView</class> + <header location="local">kis_filters_listview.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image1</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="1002">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b149444154388dad945f4c5b551cc73fe7dc4b7b4bcba0762d45c43114323599ee6192609c51d883892ce083f1718b3ebb185f8dc91e972cf39d2d2a2f1af664b6f1e0fe3863a0718969700eb0c52142da0242a1bd6d696f7bcff101585203ceb8fd9ece39f99dcff9fe7edf939f88c562ec465f5f9fe609442c161362173c3e3eae7b7a7ac8e7f36432196cdbfe4f907c3e4f2291201e8fe338cec3737357e9e8e828aded1e229d650e1f2d51754b082110124c13a4dc5ea341eb9dc284c0558a853f3ce8cb0677ef500fde7d39d2596679e326597b8e9abb85d7a770ab16ab6983ec5a05b487a70e36f0f4e10afe408d6a558310980108478dba4a1e8233990c5d474b64ed39aa3a8fe5f3317fbf81dbd70bccfeb205947632fd74f6589c1c6ea2f70d03a58ba0c1f2c9bdc1b66de3b8256a6e11cbe7e3ee1d181b590124fe2693aeee08d223c82c3a2c24b7b874bec8f26288774f7bd054504aef0dde6e99c0eb83f9fb266323cb80a27fb0958141836044605a2ee5523393371cc646fee2da37195aa35d0c0c5b4859ac03d7e91712dcaac5adab3650a3ff9d08ef7dd8404bb48869e5d958b5b87dadc4c9a1464e9f0d0326df7ebd86bd2e310cb1bf62d384d59441f2d70a070e1c60e09489929b988681bdd9cc97170bcc4c65595f71f8e0e3301337fc24a7732467831875a47f289652b0be5e4151e6d07316c1b0c0340d8ab92023e76d66a6b2840e36d2fb7a13fee632475e6edc367ea98a90fb98b7dd6310ca0328a44761582e1bab41befabcc0ec940d28bc5e93b68e064cab84e1d9beaeb48934eac1f53b01c1b000fca496aa54b61a99fcde61662a4b4b4b23d1680be9d426173e4df3602a48ea411989a4fd590f52a8fd156b05ed9d350e3defe3cfdf4b4c7ce770ea7d3fb9f520afbe1620daeee5c26735d20b9b9cfb6811a754a439e4e5c5639a4caa1e5caf586bfc0197b78702005cb9b4cae4cd3267ce8638fe964bd72b393e39d74928d242617303a756a37f284447770dcdbffc6384a05a85de1306e9a52057c7527c7131c3c42d3f475eb2303c82d4fc3276d6811db37efeb148723082d9b08f79f97c1e5729109a9a28307cc622d2d6cdf52b2b24efe548dedb00142009862cfa879ee1a71f6cec928353511472fbf4389148b0b0e0c108081412458dfe21c9f11351e67e7358595468246d1d1e5e38a6e9e851bc39d84ab502a669331dafec0d8ec7e3e8cb06e1a881d727d1ae40180a434a8c9db129a54126ad48a7358c2b4c5352c8c374bcccdab2bb37d8719cba79fab8211f9df218e0582c261e95f8bfc04f1a1e8bc5c4dfe0a190172af6a9690000000049454e44ae426082</data> + </image> + <image name="image1"> + <data format="PNG" length="1122">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000042949444154388db5954d6c545514c77ff7de37eff1a6a550da994e5ba798868f948fc847a2a2911816c436b0a02ed0083161a1981877ee10d90aa94656063491882c5cd4c4b8103f20cd806909a98604da8482341de80cb69de9bcd799799d79efba980f1da3a80b4f727273939bdff99f9b93f3175a6b6a21849080020c4002a29a8f0a5dcd002803bed63a1035f0d0d0504b6f6fef51d7758fa4d3e98d8ee3fc03af128ee3303939399548242eb8aefb09300f78464de9f0f0f0d148cc7caf3d5424de97a7ec17104220242805520a44557bbd4b21f083801d33e63a6d1bc7bf19c6064e0319a35a58b9ae7ba43d54e4d7c54b64dc097c7f09d30ef04b36736983cc7c11b4456b9b492c5e20dc54a6540e00896a8268a7017010f8bcae1830d2e9f4c69ebe3c197782b2ce60d94ddc9b30f9feeb45ae5d7181c5ead35636ef08d3ffe26a76ee3208b4031a56d80aa00768fda362e9380e25bf80ef3b587613d7afc099533380a4b5dda46fcb5aa42998b9eb7173dce5e6788e434763ec7fc942532008ea436003660d2caa7f8d69c3bd8910674e4d033e83877ad8d36fb0aa4d6058658ac5358c5df6383bf480f31fdda5a3632bbbfb6da4ccd5c00a10b2012cc12fd97cfb5516f0187c25cee0619396480ec3ca909d0f3372d1e5f9fe66de3ad605587c712ec55256a2540d5519d19ae24a29057329839f7ecc138944d833102290f3184ae1e6d6f0e98739c61229e6d21eafbed1c9c8c5558c8f3ee4ceed76946a1c43d97091828585223e2eebfbc295f60d45de89707628cb58224577bc85a79e5d4d786581cddb9b0148259711b20145836221400416e0232d1f6595c9ce4538773ac7b54406f0b15784e8e80aa1ac2594190220d021e49f2437960156b70ba095e95f96f18acd8c263cc6122962b1167a7ba34cdd7ec8c977a699bed546722a8fc2a02b6e2185fff78ab586ce78894ddb9ab9f5738ed14b1e030756929d8ff2e4ae5544632b38f96e89a99b298ebd6950cc2d12ed0eb3618b26f520788462ad09877df60db600f0f1fb49c646f21c7ebd836dcf94e9d9b4c0db27d6d3bd36c6426a96bce731703046d7da129a4670836284a054869d4f1b1c7e2dca67676ef3c1898091ef5ad8bc358c3205c93bf7c9a40ad4c660f4728edd7bbb3142ea2fc1da711cfc200011e08b45f6bd1c261adbce9717928c5f9d63fc6a19f0014567773303073790f8214bd6f5282dfbb8b9fa1f6b40d7c1939393533b92e63ad9240990484aec7e41b27d579cbb531e0f67023492d86316ebb768ba1e0f786e6f37e56550c62237aee7011e54abd7c1412291b8a06de378b4d3c0b215da9708e5a3a442192085404a83d4accfecac067c0c43e13a70e3fa12e96409e0325000966bbb354465339d04a6f9dd15fe6dde07ce030780278088d05ad72cc9a6b2f2daaaa74d75a1f0e8d0d5f60b40868a8364ead6248430000b0857a126ffcdf396abf03ce089ffcb4c7f033046c6b4a995e7a00000000049454e44ae426082</data> + </image> +</images> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kis_previewwidget.h</includehint> + <includehint>kis_filters_listview.h</includehint> +</includehints> +</UI> diff --git a/chalk/plugins/viewplugins/histogram/Makefile.am b/chalk/plugins/viewplugins/histogram/Makefile.am new file mode 100644 index 00000000..149a523b --- /dev/null +++ b/chalk/plugins/viewplugins/histogram/Makefile.am @@ -0,0 +1,25 @@ +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = histogram.rc + +EXTRA_DIST = $(chalkrc_DATA) + +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../ui \ + -I../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +kde_module_LTLIBRARIES = chalkhistogram.la + +chalkhistogram_la_SOURCES = histogram.cc dlg_histogram.cc wdghistogram.ui kis_histogram_widget.cc +noinst_HEADERS = dlg_histogram.h histogram.h wdghistogram.h kis_histogram_widget.h + +kde_services_DATA = chalkhistogram.desktop + +chalkhistogram_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) chalkblurfilter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui +chalkhistogram_la_LIBADD = ../../../libchalkcommon.la + +chalkhistogram_la_METASOURCES = AUTO diff --git a/chalk/plugins/viewplugins/histogram/chalkhistogram.desktop b/chalk/plugins/viewplugins/histogram/chalkhistogram.desktop new file mode 100644 index 00000000..b91e42b6 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram/chalkhistogram.desktop @@ -0,0 +1,43 @@ +[Desktop Entry] +Name=Histogram Plugin +Name[bg]=Приставка за Histogram +Name[ca]=Connector d'histograma +Name[da]=Plugin med histogram +Name[de]=Histogramm-Modul +Name[el]=Πρόσθετο ιστογράμματος +Name[eo]=Histograma kromaĵo +Name[es]=Complemento de histograma +Name[et]=Histogrammiplugin +Name[fa]=وصلۀ سابقهنما +Name[fr]=Module d'histogramme +Name[fy]=Histogramplugin +Name[gl]=Plugin de Histograma +Name[hu]=Hisztogram modul +Name[is]=Súluritssía +Name[it]=Plugin per gli istogrammi +Name[ja]=ヒストグラムプラグイン +Name[km]=កម្មវិធីជំនួយអ៊ីស្តូក្រាម +Name[lt]=Histogramos įskiepis +Name[nb]=Programtillegg for histogram +Name[nds]=Histogramm-Moduul +Name[ne]=हिस्टोग्राम प्लगइन +Name[nl]=Histogramplugin +Name[pl]=Wtyczka histogramu +Name[pt]='Plugin' do Histograma +Name[pt_BR]=Plugin do Histograma +Name[ru]=Модуль гистограммы +Name[se]=Histogram lassemoduvla +Name[sk]=Modul histogram +Name[sl]=Vstavek za histograme +Name[sr]=Хистограмски прикључак +Name[sr@Latn]=Histogramski priključak +Name[sv]=Insticksprogram med histogram +Name[uk]=Втулок гістограм +Name[uz]=Gistogramma plagini +Name[uz@cyrillic]=Гистограмма плагини +Name[zh_CN]=直方图插件 +Name[zh_TW]=直方圖外掛程式 +ServiceTypes=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkhistogram +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/histogram/dlg_histogram.cc b/chalk/plugins/viewplugins/histogram/dlg_histogram.cc new file mode 100644 index 00000000..4b781c17 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram/dlg_histogram.cc @@ -0,0 +1,68 @@ +/* + * dlg_histogram.cc - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <tqbuttongroup.h> +#include <tqpushbutton.h> +#include <tqcheckbox.h> +#include <tqslider.h> +#include <tqcombobox.h> +#include <tqpixmap.h> +#include <tqimage.h> +#include <tqlabel.h> + +#include <knuminput.h> +#include <klocale.h> +#include <kdebug.h> + +#include "kis_types.h" +#include "kis_histogram.h" +#include "kis_layer.h" +#include "kis_paint_device.h" + +#include "dlg_histogram.h" +#include "kis_histogram_widget.h" + + +DlgHistogram::DlgHistogram( TQWidget * tqparent, const char * name) + : super (tqparent, name, true, i18n("Histogram"), Ok | Cancel, Ok) +{ + m_page = new KisHistogramWidget(this, "histogram"); + Q_CHECK_PTR(m_page); + + setCaption(i18n("Histogram")); + setMainWidget(m_page); + resize(m_page->tqsizeHint()); +} + +DlgHistogram::~DlgHistogram() +{ + delete m_page; +} + +void DlgHistogram::setPaintDevice(KisPaintDeviceSP dev) +{ + m_page->setPaintDevice(dev); +} + +void DlgHistogram::okClicked() +{ + accept(); +} + +#include "dlg_histogram.moc" diff --git a/chalk/plugins/viewplugins/histogram/dlg_histogram.h b/chalk/plugins/viewplugins/histogram/dlg_histogram.h new file mode 100644 index 00000000..d2568f7a --- /dev/null +++ b/chalk/plugins/viewplugins/histogram/dlg_histogram.h @@ -0,0 +1,58 @@ +/* + * dlg_histogram.h -- part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef DLG_HISTOGRAM +#define DLG_HISTOGRAM + +#include <kdialogbase.h> + +#include "kis_types.h" + +class KisHistogramWidget; + +/** + * This dialog shows the histogram for the (selected) portion + * of the current layer. + * + * XXX: Also for complete image? + */ +class DlgHistogram: public KDialogBase { + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + + DlgHistogram(TQWidget * tqparent = 0, + const char* name = 0); + ~DlgHistogram(); + + void setPaintDevice(KisPaintDeviceSP dev); + +private slots: + void okClicked(); + +private: + + KisHistogramWidget * m_page; + KisHistogramSP m_histogram; + KisLayerSP m_layer; +}; + +#endif // DLG_HISTOGRAM diff --git a/chalk/plugins/viewplugins/histogram/histogram.cc b/chalk/plugins/viewplugins/histogram/histogram.cc new file mode 100644 index 00000000..8e6968b9 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram/histogram.cc @@ -0,0 +1,105 @@ +/* + * histogram.h -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include <math.h> + +#include <stdlib.h> + +#include <tqslider.h> +#include <tqpoint.h> + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> + +#include <kis_doc.h> +#include <kis_image.h> +#include <kis_layer.h> +#include <kis_paint_device.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_view.h> +#include <kis_selection.h> + +#include "histogram.h" +#include "dlg_histogram.h" +#include "kis_colorspace.h" +#include "kis_histogram.h" + +typedef KGenericFactory<Histogram> HistogramFactory; +K_EXPORT_COMPONENT_FACTORY( chalkhistogram, HistogramFactory( "chalk" ) ) + +Histogram::Histogram(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + + if ( tqparent->inherits("KisView") ) { + + setInstance(HistogramFactory::instance()); + setXMLFile(locate("data","chalkplugins/histogram.rc"), true); + + m_action = new KAction(i18n("&Histogram"), 0, 0, this, TQT_SLOT(slotActivated()), actionCollection(), "histogram"); + + m_view = (KisView*) tqparent; + if (KisImageSP img = m_view->canvasSubject()->currentImg()) { + connect(img, TQT_SIGNAL(sigLayersChanged(KisGroupLayerSP)), this, TQT_SLOT(slotLayersChanged())); + connect(img, TQT_SIGNAL(sigLayerAdded(KisLayerSP)), this, TQT_SLOT(slotLayersChanged())); + connect(img, TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayersChanged())); + connect(img, TQT_SIGNAL(sigLayerPropertiesChanged(KisLayerSP)), this, TQT_SLOT(slotLayersChanged())); + connect(img, TQT_SIGNAL(sigLayerRemoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)), + this, TQT_SLOT(slotLayersChanged())); + connect(img, TQT_SIGNAL(sigLayerMoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)), + this, TQT_SLOT(slotLayersChanged())); + m_img = img; + } + } +} + +Histogram::~Histogram() +{ +} + +void Histogram::slotLayersChanged() { + m_action->setEnabled(m_img && m_img->activeLayer() && m_img->activeLayer()->visible()); +} + +void Histogram::slotActivated() +{ + DlgHistogram * dlgHistogram = new DlgHistogram(m_view, "Histogram"); + Q_CHECK_PTR(dlgHistogram); + + KisPaintDeviceSP dev = m_view->canvasSubject()->currentImg()->activeDevice(); + if (dev) + dlgHistogram->setPaintDevice(dev); + + if (dlgHistogram->exec() == TQDialog::Accepted) { + // Do nothing; this is an informational dialog + } + delete dlgHistogram; +} + +#include "histogram.moc" + diff --git a/chalk/plugins/viewplugins/histogram/histogram.h b/chalk/plugins/viewplugins/histogram/histogram.h new file mode 100644 index 00000000..2425c0c6 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram/histogram.h @@ -0,0 +1,50 @@ +/* + * histogram.h -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef HISTOGRAM_H +#define HISTOGRAM_H + +#include <kparts/plugin.h> + +class KisView; +class KAction; +class KisImage; + +class Histogram : public KParts::Plugin +{ + Q_OBJECT + TQ_OBJECT + public: + Histogram(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~Histogram(); + + private slots: + void slotActivated(); + void slotLayersChanged(); + + private: + KisImage* m_img; + KisView * m_view; + KisPainter * m_painter; + KAction* m_action; + +}; + +#endif // HISTOGRAM_H diff --git a/chalk/plugins/viewplugins/histogram/histogram.rc b/chalk/plugins/viewplugins/histogram/histogram.rc new file mode 100644 index 00000000..db37b4b7 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram/histogram.rc @@ -0,0 +1,10 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkhistogram" version="6"> +<MenuBar> + <Menu name="Layer"><text>&Layer</text> + <Separator/> + <Action name="histogram"/> + <Separator/> + </Menu> +</MenuBar> +</kpartgui> diff --git a/chalk/plugins/viewplugins/histogram/kis_histogram_widget.cc b/chalk/plugins/viewplugins/histogram/kis_histogram_widget.cc new file mode 100644 index 00000000..12005e05 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram/kis_histogram_widget.cc @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2004 Boudewijn Rempt + * (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqpainter.h> +#include <tqpixmap.h> +#include <tqlabel.h> +#include <tqcombobox.h> +#include <tqbuttongroup.h> +#include <tqpushbutton.h> +#include <tqscrollbar.h> +#include <tqtooltip.h> + +#include <kdebug.h> + +#include "kis_channelinfo.h" +#include "kis_histogram_view.h" +#include "kis_histogram_widget.h" +#include "kis_histogram.h" +#include "kis_global.h" +#include "kis_types.h" +#include "kis_layer.h" +#include "kis_paint_device.h" +#include "kis_colorspace.h" + + +KisHistogramWidget::KisHistogramWidget(TQWidget *tqparent, const char *name) + : super(tqparent, name) +{ + m_from = 0.0; + m_width = 0.0; +} + +KisHistogramWidget::~KisHistogramWidget() +{ +} + +void KisHistogramWidget::setPaintDevice(KisPaintDeviceSP dev) +{ + grpType->disconnect(this); + cmbChannel->disconnect(this); + + m_histogramView->setPaintDevice(dev); + setActiveChannel(0); // So we have the colored one if there are colors + + // The channels + cmbChannel->clear(); + cmbChannel->insertStringList(m_histogramView->channelStrings()); + cmbChannel->setCurrentItem(0); + + // View display + currentView->setMinValue(0); + currentView->setMaxValue(100); + + updateEnabled(); + + m_from = m_histogramView->currentProducer()->viewFrom(); + m_width = m_histogramView->currentProducer()->viewWidth(); + + connect(grpType, TQT_SIGNAL(clicked(int)), this, TQT_SLOT(slotTypeSwitched(int))); + connect(cmbChannel, TQT_SIGNAL(activated(int)), this, TQT_SLOT(setActiveChannel(int))); + connect(zoomIn, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotZoomIn())); + connect(zoomOut, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotZoomOut())); + connect(currentView, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slide(int))); +} + +void KisHistogramWidget::setActiveChannel(int channel) +{ + m_histogramView->setActiveChannel(channel); + updateEnabled(); +} + +void KisHistogramWidget::slotTypeSwitched(int id) +{ + if (id == LINEAR) + m_histogramView->setHistogramType(LINEAR); + else if (id == LOGARITHMIC) + m_histogramView->setHistogramType(LOGARITHMIC); +} + +void KisHistogramWidget::setView(double from, double size) +{ + m_from = from; + m_width = size; + if (m_from + m_width > 1.0) + m_from = 1.0 - m_width; + m_histogramView->setView(m_from, m_width); + updateEnabled(); +} + +void KisHistogramWidget::slotZoomIn() { + if ((m_width / 2) >= m_histogramView->currentProducer()->maximalZoom()) { + setView(m_from, m_width / 2); + } +} + +void KisHistogramWidget::slotZoomOut() { + if (m_width * 2 <= 1.0) { + setView(m_from, m_width * 2); + } +} + +void KisHistogramWidget::slide(int val) { + // Beware: at the END (e.g. 100), we want to still view m_width: + setView((static_cast<double>(val) / 100.0) * (1.0 - m_width), m_width); +} + +void KisHistogramWidget::updateEnabled() { + if (m_histogramView->currentProducer()->maximalZoom() < 1.0) { + if ((m_width / 2) >= m_histogramView->currentProducer()->maximalZoom()) { + zoomIn->setEnabled(true); + } else { + zoomIn->setEnabled(false); + } + if (m_width * 2 <= 1.0) { + zoomOut->setEnabled(true); + } else { + zoomOut->setEnabled(false); + } + if (m_width < 1.0) + currentView->setEnabled(true); + else + currentView->setEnabled(false); + } else { + zoomIn->setEnabled(false); + zoomOut->setEnabled(false); + currentView->setEnabled(false); + } +} + +#include "kis_histogram_widget.moc" + diff --git a/chalk/plugins/viewplugins/histogram/kis_histogram_widget.h b/chalk/plugins/viewplugins/histogram/kis_histogram_widget.h new file mode 100644 index 00000000..f83394e7 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram/kis_histogram_widget.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2004 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_HISTOGRAM_WIDGET_ +#define KIS_HISTOGRAM_WIDGET_ + +#include "kis_types.h" +#include "wdghistogram.h" + +class KisColorSpace; + +/** + * The histogram widget takes a paint device or an image and + * draws a histogram for the given KisHistogram. + */ +class KisHistogramWidget : public WdgHistogram { + typedef WdgHistogram super; + Q_OBJECT + TQ_OBJECT + +public: + KisHistogramWidget(TQWidget *tqparent, const char *name); + virtual ~KisHistogramWidget(); + + void setPaintDevice(KisPaintDeviceSP dev); + +private slots: + void setActiveChannel(int channel); + void slotTypeSwitched(int id); + void slotZoomIn(); + void slotZoomOut(); + void slide(int val); + +private: + void setView(double from, double size); + void updateEnabled(); + double m_from, m_width; +}; + + +#endif // KIS_HISTOGRAM_WIDGET_ diff --git a/chalk/plugins/viewplugins/histogram/wdghistogram.ui b/chalk/plugins/viewplugins/histogram/wdghistogram.ui new file mode 100644 index 00000000..77c418ed --- /dev/null +++ b/chalk/plugins/viewplugins/histogram/wdghistogram.ui @@ -0,0 +1,229 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgHistogram</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgHistogram</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>450</width> + <height>380</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQButtonGroup"> + <property name="name"> + <cstring>grpType</cstring> + </property> + <property name="title"> + <string>Method</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQRadioButton" row="0" column="2"> + <property name="name"> + <cstring>radioLinear</cstring> + </property> + <property name="text"> + <string>&Linear</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQRadioButton" row="1" column="2" rowspan="2" colspan="1"> + <property name="name"> + <cstring>radioLog</cstring> + </property> + <property name="text"> + <string>&Logarithmic</string> + </property> + </widget> + <spacer row="2" column="1"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Preferred</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQComboBox" row="0" column="1" rowspan="2" colspan="1"> + <property name="name"> + <cstring>cmbChannel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>200</width> + <height>0</height> + </size> + </property> + </widget> + <widget class="TQLabel" row="0" column="0" rowspan="2" colspan="1"> + <property name="name"> + <cstring>lblChannel</cstring> + </property> + <property name="text"> + <string>&Channel:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cmbChannel</cstring> + </property> + </widget> + <spacer row="2" column="0"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Preferred</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>21</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="KisHistogramView"> + <property name="name"> + <cstring>m_histogramView</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>256</width> + <height>150</height> + </size> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>View:</string> + </property> + </widget> + <widget class="TQPushButton"> + <property name="name"> + <cstring>zoomIn</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>+</string> + </property> + </widget> + <widget class="TQPushButton"> + <property name="name"> + <cstring>zoomOut</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>-</string> + </property> + </widget> + <widget class="TQScrollBar"> + <property name="name"> + <cstring>currentView</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<customwidgets> + <customwidget> + <class>KisHistogramView</class> + <header location="local">kis_histogram_view.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="1002">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b149444154388dad945f4c5b551cc73fe7dc4b7b4bcba0762d45c43114323599ee6192609c51d883892ce083f1718b3ebb185f8dc91e972cf39d2d2a2f1af664b6f1e0fe3863a0718969700eb0c52142da0242a1bd6d696f7bcff101585203ceb8fd9ece39f99dcff9fe7edf939f88c562ec465f5f9fe609442c161362173c3e3eae7b7a7ac8e7f36432196cdbfe4f907c3e4f2291201e8fe338cec3737357e9e8e828aded1e229d650e1f2d51754b082110124c13a4dc5ea341eb9dc284c0558a853f3ce8cb0677ef500fde7d39d2596679e326597b8e9abb85d7a770ab16ab6983ec5a05b487a70e36f0f4e10afe408d6a558310980108478dba4a1e8233990c5d474b64ed39aa3a8fe5f3317fbf81dbd70bccfeb205947632fd74f6589c1c6ea2f70d03a58ba0c1f2c9bdc1b66de3b8256a6e11cbe7e3ee1d181b590124fe2693aeee08d223c82c3a2c24b7b874bec8f26288774f7bd054504aef0dde6e99c0eb83f9fb266323cb80a27fb0958141836044605a2ee5523393371cc646fee2da37195aa35d0c0c5b4859ac03d7e91712dcaac5adab3650a3ff9d08ef7dd8404bb48869e5d958b5b87dadc4c9a1464e9f0d0326df7ebd86bd2e310cb1bf62d384d59441f2d70a070e1c60e09489929b988681bdd9cc97170bcc4c65595f71f8e0e3301337fc24a7732467831875a47f289652b0be5e4151e6d07316c1b0c0340d8ab92023e76d66a6b2840e36d2fb7a13fee632475e6edc367ea98a90fb98b7dd6310ca0328a44761582e1bab41befabcc0ec940d28bc5e93b68e064cab84e1d9beaeb48934eac1f53b01c1b000fca496aa54b61a99fcde61662a4b4b4b23d1680be9d426173e4df3602a48ea411989a4fd590f52a8fd156b05ed9d350e3defe3cfdf4b4c7ce770ea7d3fb9f520afbe1620daeee5c26735d20b9b9cfb6811a754a439e4e5c5639a4caa1e5caf586bfc0197b78702005cb9b4cae4cd3267ce8638fe964bd72b393e39d74928d242617303a756a37f284447770dcdbffc6384a05a85de1306e9a52057c7527c7131c3c42d3f475eb2303c82d4fc3276d6811db37efeb148723082d9b08f79f97c1e5729109a9a28307cc622d2d6cdf52b2b24efe548dedb00142009862cfa879ee1a71f6cec928353511472fbf4389148b0b0e0c108081412458dfe21c9f11351e67e7358595468246d1d1e5e38a6e9e851bc39d84ab502a669331dafec0d8ec7e3e8cb06e1a881d727d1ae40180a434a8c9db129a54126ad48a7358c2b4c5352c8c374bcccdab2bb37d8719cba79fab8211f9df218e0582c261e95f8bfc04f1a1e8bc5c4dfe0a190172af6a9690000000049454e44ae426082</data> + </image> +</images> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kis_histogram_view.h</includehint> +</includehints> +</UI> diff --git a/chalk/plugins/viewplugins/histogram_docker/Makefile.am b/chalk/plugins/viewplugins/histogram_docker/Makefile.am new file mode 100644 index 00000000..64341755 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/Makefile.am @@ -0,0 +1,22 @@ +kde_services_DATA = chalkhistogramdocker.desktop +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = chalkhistogramdocker.rc + +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../ui \ + -I$/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +chalkhistogramdocker_la_SOURCES = histogramdocker.cc kis_imagerasteredcache.cc kis_cachedhistogram.cc kis_accumulating_producer.cc + +kde_module_LTLIBRARIES = chalkhistogramdocker.la +noinst_HEADERS = histogramdocker.h kis_imagerasteredcache.h kis_cachedhistogram.h kis_accumulating_producer.h + +chalkhistogramdocker_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) chalkblurfilter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui +chalkhistogramdocker_la_LIBADD = ../../../libchalkcommon.la + +chalkhistogramdocker_la_METASOURCES = AUTO diff --git a/chalk/plugins/viewplugins/histogram_docker/chalkhistogramdocker.desktop b/chalk/plugins/viewplugins/histogram_docker/chalkhistogramdocker.desktop new file mode 100644 index 00000000..aba9ded8 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/chalkhistogramdocker.desktop @@ -0,0 +1,40 @@ +[Desktop Entry] +Name=Histogram Docker +Name[ca]=Amarrador de l'histograma +Name[cy]=Bachydd Histogram +Name[da]=Histogramdokning +Name[de]=Histogramm-Docker +Name[el]=Προσάρτηση ιστογράμματος +Name[eo]=Histogramdokilo +Name[es]=Anclaje del histograma +Name[et]=Histogrammi dokk +Name[fa]=پیونددهندۀ سابقهنما +Name[fr]=Ancrage d'histogramme +Name[fy]=Histogramkomponint +Name[gl]=Acoplador de Histogramas +Name[hu]=Hisztogramdokkoló +Name[is]=Súluritsspjald +Name[it]=Aggancia-istogrammi +Name[ja]=ヒストグラムドッカー +Name[km]=កន្លែងចតអ៊ីស្តូក្រាម +Name[nb]=Histogramdokker +Name[nds]=Histogramm-Docker +Name[ne]=हिस्टोग्राम डकर +Name[nl]=Histogramcomponent +Name[pl]=Doker histogramu +Name[pt]=Acoplador de Histogramas +Name[pt_BR]=Acoplador de Histogramas +Name[ru]=Панель гистограммы +Name[sk]=Histogram +Name[sl]=Histogram +Name[sr]=Сидраш хистограма +Name[sr@Latn]=Sidraš histograma +Name[sv]=Histogramdockning +Name[uk]=Швартувальник гістограм +Name[uz]=Gistogramma paneli +Name[uz@cyrillic]=Гистограмма панели +Name[zh_TW]=直方圖停駐點 +ServiceTypes=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkhistogramdocker +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/histogram_docker/chalkhistogramdocker.rc b/chalk/plugins/viewplugins/histogram_docker/chalkhistogramdocker.rc new file mode 100644 index 00000000..2b6006b9 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/chalkhistogramdocker.rc @@ -0,0 +1,3 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkhistogramdocker" version="1"> +</kpartgui>
\ No newline at end of file diff --git a/chalk/plugins/viewplugins/histogram_docker/histogramdocker.cc b/chalk/plugins/viewplugins/histogram_docker/histogramdocker.cc new file mode 100644 index 00000000..df5de24a --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/histogramdocker.cc @@ -0,0 +1,192 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <tqtooltip.h> + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> + +#include <kopalettemanager.h> + +#include "kis_meta_registry.h" +#include <kis_doc.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_view.h> + +#include <kis_basic_histogram_producers.h> +#include <kis_colorspace_factory_registry.h> + +#include "histogramdocker.h" +#include "kis_imagerasteredcache.h" +#include "kis_accumulating_producer.h" + +typedef KGenericFactory<ChalkHistogramDocker> ChalkHistogramDockerFactory; +K_EXPORT_COMPONENT_FACTORY( chalkhistogramdocker, ChalkHistogramDockerFactory( "chalk" ) ) + +ChalkHistogramDocker::ChalkHistogramDocker(TQObject *tqparent, const char *name, const TQStringList&) + : KParts::Plugin(tqparent, name) +{ + + if ( tqparent->inherits("KisView") ) { + m_view = dynamic_cast<KisView*>(tqparent); + + setInstance(ChalkHistogramDockerFactory::instance()); + setXMLFile(locate("data","chalkplugins/chalkhistogramdocker.rc"), true); + + KisImageSP img = m_view->canvasSubject()->currentImg(); + if (!img) { + m_cache = 0; + return; + } + + m_hview = 0; // producerChanged wants to setCurrentChannels, prevent that here + m_cache = 0; // we try to delete it in producerChanged + colorSpaceChanged(img->colorSpace()); // calls producerChanged(0) + + + m_hview = new KisHistogramView(m_view); + TQToolTip::add(m_hview, i18n("Right-click to select histogram type")); + m_hview->setHistogram(m_histogram); + m_hview->setColor(true); + m_hview->setCurrentChannels(m_producer, m_producer->channels()); + m_hview->setFixedSize(256, 100); // XXX if not it keeps expanding + m_hview->setCaption(i18n("Histogram")); + + + connect(m_hview, TQT_SIGNAL(rightClicked(const TQPoint&)), + this, TQT_SLOT(popupMenu(const TQPoint&))); + connect(m_cache, TQT_SIGNAL(cacheUpdated()), + new HistogramDockerUpdater(this, m_histogram, m_hview, m_producer), TQT_SLOT(updated())); + connect(&m_popup, TQT_SIGNAL(activated(int)), + this, TQT_SLOT(producerChanged(int))); + connect(img, TQT_SIGNAL(sigColorSpaceChanged(KisColorSpace*)), + this, TQT_SLOT(colorSpaceChanged(KisColorSpace*))); // No need to force updates here + + // Add it to the control palette + m_view->canvasSubject()->paletteManager()->addWidget( + m_hview, "histodocker", chalk::CONTROL_PALETTE); + } else { + m_cache = 0; + } +} + +ChalkHistogramDocker::~ChalkHistogramDocker() +{ + uint count = m_producers . count(); + for (uint i = 0; i < count; i++) { + delete m_producers . at(i); + } + + if (m_cache) + m_cache->deleteLater(); +} + +void ChalkHistogramDocker::producerChanged(int pos) +{ + if (m_cache) + m_cache->deleteLater(); + m_cache = 0; + + if (m_currentProducerPos < m_popup.count()) + m_popup.setItemChecked(m_currentProducerPos, false); + m_currentProducerPos = pos; + m_popup.setItemChecked(m_currentProducerPos, true); + + uint count = m_producers . count(); + for (uint i = 0; i < count; i++) { + delete m_producers . at(i); + } + m_producers.clear(); + + KisIDList keys = KisHistogramProducerFactoryRegistry::instance() -> + listKeysCompatibleWith(m_cs); + + m_factory = KisHistogramProducerFactoryRegistry::instance()->get(*(keys.at(pos))); + + KisCachedHistogramObserver observer(&m_producers, m_factory, 0, 0, 0, 0, false); + + // We can reference observer because it will be only used as a factory to create new + // instances + m_cache = new KisImageRasteredCache(m_view, &observer); + + m_producer = new KisAccumulatingHistogramProducer(&m_producers); + + // use dummy layer as a source; we are not going to actually use or need it + // All of these are SP, no need to delete them afterwards + m_histogram = new KisHistogram( new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getAlpha8(), "dummy histogram"), m_producer, LOGARITHMIC); + + if (m_hview) { + m_hview->setHistogram(m_histogram); + m_hview->setColor(true); + m_hview->setCurrentChannels(m_producer, m_producer->channels()); + + connect(m_cache, TQT_SIGNAL(cacheUpdated()), + new HistogramDockerUpdater(this, m_histogram, m_hview, m_producer), TQT_SLOT(updated())); + } +} + +void ChalkHistogramDocker::popupMenu(const TQPoint& pos) +{ + m_popup.popup(pos, m_currentProducerPos); +} + +void ChalkHistogramDocker::colorSpaceChanged(KisColorSpace* cs) +{ + m_cs = cs; + + KisIDList keys = KisHistogramProducerFactoryRegistry::instance() -> + listKeysCompatibleWith(m_cs); + + m_popup.clear(); + m_currentProducerPos = 0; + + for (uint i = 0; i < keys.count(); i++) { + KisID id(*(keys.at(i))); + m_popup . insertItem(id.name(), static_cast<int>(i)); + } + + producerChanged(0); +} + +HistogramDockerUpdater::HistogramDockerUpdater(TQObject* /*tqparent*/, KisHistogramSP h, KisHistogramView* v, + KisAccumulatingHistogramProducer* p) + : m_histogram(h), m_view(v), m_producer(p) +{ + connect(p, TQT_SIGNAL(completed()), this, TQT_SLOT(completed())); +} + +void HistogramDockerUpdater::updated() { + // We don't [!] do m_histogram->updateHistogram();, because that will try to compute + // the histogram synchronously, while we want it asynchronously. + m_producer->addRegionsToBinAsync(); +} + +void HistogramDockerUpdater::completed() { + m_histogram->computeHistogram(); + m_view->updateHistogram(); +} + +#include "histogramdocker.moc" diff --git a/chalk/plugins/viewplugins/histogram_docker/histogramdocker.h b/chalk/plugins/viewplugins/histogram_docker/histogramdocker.h new file mode 100644 index 00000000..ade0650f --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/histogramdocker.h @@ -0,0 +1,81 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _HISTOGRAMDOCKER_H_ +#define _HISTOGRAMDOCKER_H_ + +#include <tqobject.h> +#include <tqpopupmenu.h> + +#include <kparts/plugin.h> +#include <kis_histogram_view.h> +#include <kis_histogram.h> + +#include "kis_cachedhistogram.h" + +class KisAccumulatingHistogramProducer; +class KisColorSpace; +class KisHistogramView; +class KisView; +class KisColorSpace; + +class ChalkHistogramDocker : public KParts::Plugin +{ +Q_OBJECT + TQ_OBJECT +public: + ChalkHistogramDocker(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~ChalkHistogramDocker(); +private slots: + void producerChanged(int pos); + void popupMenu(const TQPoint & pos); + void colorSpaceChanged(KisColorSpace* cs); +private: + KisHistogramProducerFactory* m_factory; + KisCachedHistogramObserver::Producers m_producers; + KisAccumulatingHistogramProducer* m_producer; + KisColorSpace* m_cs; + KisView* m_view; + KisHistogramView* m_hview; + KisImageRasteredCache* m_cache; + TQPopupMenu m_popup; + KisHistogramSP m_histogram; + uint m_currentProducerPos; +}; + +class KisGenericRGBHistogramProducerFactory; + +class HistogramDockerUpdater : public TQObject { +Q_OBJECT + TQ_OBJECT +public: + HistogramDockerUpdater(TQObject* tqparent, KisHistogramSP h, KisHistogramView* v, + KisAccumulatingHistogramProducer* p); +public slots: + void updated(); +private slots: + void completed(); +private: + KisHistogramSP m_histogram; + KisHistogramView* m_view; + KisAccumulatingHistogramProducer* m_producer; +}; + +#endif //_HISTOGRAMDOCKER_H_ diff --git a/chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cc b/chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cc new file mode 100644 index 00000000..217a36d9 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cc @@ -0,0 +1,102 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqthread.h> +#include <tqapplication.h> +#include <tqevent.h> + +#include "kis_accumulating_producer.h" + +static const int EmitCompletedType = TQEvent::User + 1; + +/** + * The threaded producer definition in c++ file because this is really an internal affair. + * Note that since we _know_ that we'll only have a single instance of it running, at most, + * we don't care too much about locking and synchronization + **/ +class KisAccumulatingHistogramProducer::ThreadedProducer : public TQThread { + KisAccumulatingHistogramProducer* m_source; + bool m_stop; +protected: + virtual void run(); +public: + ThreadedProducer(KisAccumulatingHistogramProducer* source) + : m_source(source), m_stop(false) {} + void cancel() { m_stop = true; } +}; + +KisAccumulatingHistogramProducer::KisAccumulatingHistogramProducer(KisCachedHistogramObserver::Producers* source) + : KisBasicHistogramProducer( + KisID("ACCHISTO", ""), + source->at(0)->channels().count(), + source->at(0)->numberOfBins(), + 0), + m_source(source) +{ + m_thread = new ThreadedProducer(this); +} + +KisAccumulatingHistogramProducer::~KisAccumulatingHistogramProducer() { + m_thread->cancel(); + m_thread->wait(); + delete m_thread; +} + +void KisAccumulatingHistogramProducer::addRegionsToBinAsync() { + m_thread->cancel(); + m_thread->wait(); + clear(); + m_thread->start(); +} + +void KisAccumulatingHistogramProducer::ThreadedProducer::run() { + m_stop = false; + + uint count = m_source->m_source->count(); // Talk about bad naming schemes... + KisCachedHistogramObserver::Producers* source = m_source->m_source; + TQValueVector<vBins>& bins = m_source->m_bins; + int channels = m_source->m_channels; + int nrOfBins = m_source->m_nrOfBins; + + for (uint i = 0; i < count && !m_stop; i++) { + KisHistogramProducer* p = source->at(i); + m_source->m_count += p->count(); + + for (int j = 0; j < channels && !m_stop; j++) { + for (int k = 0; k < nrOfBins; k++) { + bins.at(j).at(k) += p->getBinAt(j, k); + } + } + } + + if (!m_stop) { + // This function is thread-safe; and it takes ownership of the event + TQApplication::postEvent(m_source, new TQCustomEvent(EmitCompletedType)); + } +} + +void KisAccumulatingHistogramProducer::customEvent(TQCustomEvent* e) { + if (e->type() == EmitCompletedType) { + emit completed(); + } +} + +#include "kis_accumulating_producer.moc" + diff --git a/chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.h b/chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.h new file mode 100644 index 00000000..d74a3ec5 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.h @@ -0,0 +1,77 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_ACCUMULATING_PRODUCER_H_ +#define _KIS_ACCUMULATING_PRODUCER_H_ + +#include <tqobject.h> + +#include <kis_basic_histogram_producers.h> +#include "kis_cachedhistogram.h" + +/** + * Kept very minimalistic because all options would require much reiterating which we don't want. + * This class is multithreading! Don't expect it to contain the right data after an + * addRegionsToBinAsync call, but await it's completed() signal. Also beware! This function + * _does_ clear() before addRegionsToBinAsync! (hence not conforming to the regular semantics + * of HistogramProducers if you'd take addRegionsToBinAsync = addRegionToBin, but since that is + * already violated with the asynchronousity of it that is not really an issue anymore, I think) + **/ +class KisAccumulatingHistogramProducer : public TQObject, public KisBasicHistogramProducer { +Q_OBJECT + TQ_OBJECT +public: + KisAccumulatingHistogramProducer(KisCachedHistogramObserver::Producers* source); + ~KisAccumulatingHistogramProducer(); + /// Does _nothing_, use addRegionsToBinAsync + virtual void addRegionToBin(TQ_UINT8 *, TQ_UINT8*, TQ_UINT32, KisColorSpace *) {} + virtual void addRegionsToBinAsync(); + virtual TQString positionToString(double pos) const + { return m_source->at(0)->positionToString(pos); } + + virtual void setView(double, double) {} // No view support + virtual double maximalZoom() const { return 1.0; } + + virtual TQ_INT32 numberOfBins() { return m_source->at(0)->numberOfBins(); } + + virtual TQValueVector<KisChannelInfo *> channels() { return m_source->at(0)->channels(); } + + /// Call this when the 'source' list has changed colorspace + virtual void changedSourceProducer() { + m_count = m_source->at(0)->channels().count(); + m_external.clear(); + makeExternalToInternal(); + } + +signals: + void completed(); + +protected: + virtual void customEvent(TQCustomEvent* e); + /// source already converts external to internal + virtual int externalToInternal(int ext) { return ext; } + KisCachedHistogramObserver::Producers* m_source; + + class ThreadedProducer; + friend class ThreadedProducer; + ThreadedProducer* m_thread; +}; + +#endif // _KIS_ACCUMULATING_PRODUCER_H_ diff --git a/chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cc b/chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cc new file mode 100644 index 00000000..1ad197f9 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cc @@ -0,0 +1,37 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <kis_paint_device.h> +#include <kis_iterators_pixel.h> + +#include "kis_cachedhistogram.h" + +void KisCachedHistogramObserver::regionUpdated(KisPaintDeviceSP dev) { + m_producer->clear(); + KisRectIteratorPixel srcIt = dev->createRectIterator(m_x, m_y, m_w, m_h, false); + int i; + while ( !srcIt.isDone() ) { + i = srcIt.nConseqPixels(); + m_producer->addRegionToBin(srcIt.rawData(), srcIt.selectionMask(), i, dev->colorSpace()); + srcIt += i; + if (i == 0) + ++srcIt; + } +} diff --git a/chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.h b/chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.h new file mode 100644 index 00000000..084ff389 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.h @@ -0,0 +1,53 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _CACHED_HISTOGRAM_H_ +#define _CACHED_HISTOGRAM_H_ + +#include <tqvaluevector.h> +#include <kis_histogram_producer.h> + +#include "kis_imagerasteredcache.h" + +class KisCachedHistogramObserver : public KisImageRasteredCache::Observer { +public: + typedef TQValueVector<KisHistogramProducer*> Producers; + KisCachedHistogramObserver(Producers* p, KisHistogramProducerFactory* f, + int x, int y, int w, int h, bool add = true) + : m_producers(p), m_factory(f), m_x(x), m_y(y), m_w(w), m_h(h) + { + m_producer = m_factory->generate(); + if (add) + m_producers->append(m_producer); + } + virtual ~KisCachedHistogramObserver() {} + + virtual Observer* createNew(int x, int y, int w, int h) + { return new KisCachedHistogramObserver(m_producers, m_factory, x, y, w, h); } + + virtual void regionUpdated(KisPaintDeviceSP dev); +private: + Producers* m_producers; + KisHistogramProducerFactory* m_factory; + KisHistogramProducerSP m_producer; + int m_x, m_y, m_w, m_h; +}; + +#endif // _CACHED_HISTOGRAM_H_ diff --git a/chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cc b/chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cc new file mode 100644 index 00000000..19599cd9 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cc @@ -0,0 +1,162 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <cmath> + +#include <tqapplication.h> + +#include <kdebug.h> + +#include <kis_doc.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_view.h> + +#include "kis_imagerasteredcache.h" + +KisImageRasteredCache::KisImageRasteredCache(KisView* view, Observer* o) + : m_observer(o->createNew(0, 0, 0, 0)), m_view(view) +{ + m_busy = false; + m_imageProjection = 0; + m_rasterSize = 64*4; + m_timeOutMSec = 1000; + + KisImageSP img = view->canvasSubject()->currentImg(); + + if (!img) { + return; + } + + imageSizeChanged(img->width(), img->height()); + + connect(img, TQT_SIGNAL(sigImageUpdated(TQRect)), + this, TQT_SLOT(imageUpdated(TQRect))); + connect(img, TQT_SIGNAL(sigSizeChanged(TQ_INT32, TQ_INT32)), + this, TQT_SLOT(imageSizeChanged(TQ_INT32, TQ_INT32))); + connect(&m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(timeOut())); +} + +KisImageRasteredCache::~KisImageRasteredCache() { + cleanUpElements(); +} + +void KisImageRasteredCache::imageUpdated(TQRect rc) { + + if (rc.isValid()) { + TQRect r(0, 0, m_width * m_rasterSize, m_height * m_rasterSize); + r &= rc; + + uint x = static_cast<int>(r.x() / m_rasterSize); + uint y = static_cast<int>(r.y() / m_rasterSize); + uint x2 = static_cast<int>(ceil(float(r.x() + r.width()) / float(m_rasterSize))); + uint y2 = static_cast<int>(ceil(float(r.y() + r.height()) / float(m_rasterSize))); + + if (!m_raster.empty()) { + for ( ; x < x2; x++) { + for (uint i = y; i < y2; i++) { + if (x < m_raster.size()) { + if (i < m_raster.at(x).size()) { + Element* e = m_raster.at(x).at(i); + if (e && e->valid) { + e->valid = false; + m_queue.push_back(e); + } + } + } + } + } + } + } + + if (!m_busy) { + // If the timer is already started, this resets it. That way, we update always + // m_timeOutMSec milliseconds after the lastly monitored activity + m_timer.start(m_timeOutMSec, true); // true->singleshot + } +} + +void KisImageRasteredCache::imageSizeChanged(TQ_INT32 w, TQ_INT32 h) { + + KisImageSP image = m_view->canvasSubject()->currentImg(); + + cleanUpElements(); + m_busy = false; + + m_width = static_cast<int>(ceil(float(w) / float(m_rasterSize))); + m_height = static_cast<int>(ceil(float(h) / float(m_rasterSize))); + + m_raster.resize(m_width); + + int rasterX = 0; + + for (int i = 0; i < m_width * m_rasterSize; i += m_rasterSize) { + int rasterY = 0; + + m_raster.at(rasterX).resize(m_height + 1); + + for (int j = 0; j < m_height * m_rasterSize; j += m_rasterSize) { + Element* e = new Element(m_observer->createNew(i, j, m_rasterSize, m_rasterSize)); + m_raster.at(rasterX).at(rasterY) = e; + rasterY++; + } + rasterX++; + } + + imageUpdated(TQRect(0,0, image->width(), image->height())); +} + +void KisImageRasteredCache::timeOut() { + m_busy = true; + KisImageSP img = m_view->canvasSubject()->currentImg(); + + // Temporary cache: while we are busy, we won't get the mergeImage time and again. + if (!m_imageProjection) + m_imageProjection = img->mergedImage(); + + // Pick one element of the cache, and update it + if (!m_queue.isEmpty()) { + m_queue.front()->observer->regionUpdated(m_imageProjection); + m_queue.front()->valid = true; + m_queue.pop_front(); + } + + // If there are still elements, we need to be called again (this emulates processEvents) + if (!m_queue.isEmpty()) { + TQTimer::singleShot(0, this, TQT_SLOT(timeOut())); + } else { + emit cacheUpdated(); + m_imageProjection = 0; + m_busy = false; + } +} + +void KisImageRasteredCache::cleanUpElements() { + for (uint i = 0; i < m_raster.count(); i++) { + for (uint j = 0; j < m_raster.at(i).count(); j++) { + delete m_raster.at(i).at(j); + } + m_raster.at(i).clear(); + } + m_raster.clear(); + m_queue.clear(); +} + +#include "kis_imagerasteredcache.moc" diff --git a/chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.h b/chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.h new file mode 100644 index 00000000..7df7df8f --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.h @@ -0,0 +1,81 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_IMAGE_RASTERED_CACHE_H_ +#define _KIS_IMAGE_RASTERED_CACHE_H_ + +#include <tqobject.h> +#include <tqvaluevector.h> +#include <tqvaluelist.h> +#include <tqtimer.h> + +#include <kis_paint_device.h> + +class KisView; + +class KisImageRasteredCache : public TQObject { +Q_OBJECT + TQ_OBJECT + +public: + class Observer { + public: + virtual Observer* createNew(int x, int y, int w, int h) = 0; + virtual void regionUpdated(KisPaintDeviceSP dev) = 0; + virtual ~Observer() {} + }; + + KisImageRasteredCache(KisView* view, Observer* o); + virtual ~KisImageRasteredCache(); + +signals: + void cacheUpdated(); + +private slots: + void imageUpdated(TQRect rc); + void imageSizeChanged(TQ_INT32 w, TQ_INT32 h); + void timeOut(); + +private: + class Element { + public: + Element(Observer* o) : observer(o), valid(true) {} + Observer* observer; + bool valid; + }; + typedef TQValueVector< TQValueVector<Element*> > Raster; + typedef TQValueList<Element*> Queue; + + void cleanUpElements(); + + Observer* m_observer; + Raster m_raster; + Queue m_queue; + TQTimer m_timer; + int m_timeOutMSec; + int m_rasterSize; + int m_width, m_height; + KisView * m_view; + bool m_busy; + + KisPaintDeviceSP m_imageProjection; +}; + +#endif // _KIS_IMAGE_RASTERED_CACHE_H_ diff --git a/chalk/plugins/viewplugins/history_docker/Makefile.am b/chalk/plugins/viewplugins/history_docker/Makefile.am new file mode 100644 index 00000000..53511b3d --- /dev/null +++ b/chalk/plugins/viewplugins/history_docker/Makefile.am @@ -0,0 +1,18 @@ +#kde_services_DATA = chalkhistorydocker.desktop + +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +chalkhistorydocker_la_SOURCES = historydocker.cc + +kde_module_LTLIBRARIES = chalkhistorydocker.la +noinst_HEADERS = historydocker.h + +chalkhistorydocker_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +chalkhistorydocker_la_LIBADD = ../../../libchalkcommon.la + +chalkhistorydocker_la_METASOURCES = AUTO diff --git a/chalk/plugins/viewplugins/history_docker/chalkhistorydocker.desktop b/chalk/plugins/viewplugins/history_docker/chalkhistorydocker.desktop new file mode 100644 index 00000000..270393ce --- /dev/null +++ b/chalk/plugins/viewplugins/history_docker/chalkhistorydocker.desktop @@ -0,0 +1,73 @@ +[Desktop Entry] +Name=History Docker +Name[ca]=Amarrador d'història +Name[cy]=Bachydd Hanes +Name[da]=Historikdokning +Name[de]=Verlauf-Docker +Name[el]=Προσάρτηση ιστορικού +Name[eo]=Historidokilo +Name[es]=Anclaje del histórico +Name[et]=Ajaloo dokk +Name[fa]=پیونددهندۀ سابقهنما +Name[fr]=Ancrage d'historique +Name[fy]=Histoarjekomponint +Name[gl]=Acoplador de Histórico +Name[hu]=Előzménydokkoló +Name[is]=Söguspjald +Name[it]=Aggancia-cronologia +Name[ja]=履歴ドックパネル +Name[km]=កន្លែងចតប្រវត្តិ +Name[nb]=Hiastoriedokker +Name[nds]=Vörgeschicht-Docker +Name[ne]=इतिहास डकर +Name[nl]=Geschiedeniscomponent +Name[pl]=Doker historii +Name[pt]=Acoplador de Histórico +Name[pt_BR]=Acoplador de Histórico +Name[ru]=История команд +Name[sk]=História +Name[sl]=Zgodovina +Name[sr]=Сидраш историјата +Name[sr@Latn]=Sidraš istorijata +Name[sv]=Historikdockning +Name[uk]=Швартувальник історії +Name[zh_TW]=歷史紀錄停駐點 +Comment=Command history docker for Chalk +Comment[bg]=Основната функционалност на Chalk +Comment[ca]=Amarrador d'història d'ordres per a Chalk +Comment[cy]=Bachydd yr hanes gorchmynion ar gyfer Chalk +Comment[da]=Dokning af kommandohistorik for Chalk +Comment[de]=Befehlsverlauf-Docker für Chalk +Comment[el]=Άρθρωμα προσάρτησης ιστορικού εντολών για το Chalk +Comment[es]=Anclaje con el histórico de órdenes para Chalk +Comment[et]=Chalk käskude ajaloo dokk +Comment[fa]=پیونددهنده تاریخچۀ فرمان برای Chalk +Comment[fr]=Ancrage de l'historique des commandes pour Chalk +Comment[fy]=Komponint mei bewurkingshistoarje foar Chalk" +Comment[gl]=Un módulo acoplado co historial de comandos para Chalk +Comment[hu]=Chalk parancselőzmény-dokkoló +Comment[is]=Skipanasöguspjald fyrir Chalk +Comment[it]=Aggancia-cronologia dei comandi di Chalk +Comment[ja]=Chalk コマンド履歴ドックパネル +Comment[km]=កន្លែងចតប្រវត្តិពាក្យបញ្ជាសម្រាប់ Chalk +Comment[nb]=Kommandohistorie-dokker for Chalk +Comment[nds]=Befehlsvörgeschicht-Docker för Chalk +Comment[ne]=क्रिताका लागि आदेश इतिहास +Comment[nl]=Component met bewerkingsgeschiedenis voor Chalk +Comment[pl]=Doker historii poleceń dla Chalk +Comment[pt]=Um módulo acoplado de histórico de comandos do Chalk +Comment[pt_BR]=Um módulo acoplado de histórico de comandos do Chalk +Comment[ru]=Панель истории команд Chalk +Comment[sk]=História príkazov pre Chalk +Comment[sl]=Zgodovina ukazov za Krito +Comment[sr]=Сидраш историјата наредби за Chalk-у +Comment[sr@Latn]=Sidraš istorijata naredbi za Chalk-u +Comment[sv]=Dockning av kommandohistorik för Chalk +Comment[uk]=Швартувальник історії команд для Chalk +Comment[uz]=Chalk uchun buyruqlar tarixi paneli +Comment[uz@cyrillic]=Chalk учун буйруқлар тарихи панели +Comment[zh_TW]=Chalk 的指令紀錄停駐點 +ServiceTypes=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkhistorydocker +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/history_docker/historydocker.cc b/chalk/plugins/viewplugins/history_docker/historydocker.cc new file mode 100644 index 00000000..e4f36813 --- /dev/null +++ b/chalk/plugins/viewplugins/history_docker/historydocker.cc @@ -0,0 +1,58 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> + +#include <kis_doc.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_view.h> + +#include "historydocker.h" + +typedef KGenericFactory<ChalkHistoryDocker> ChalkHistoryDockerFactory; +K_EXPORT_COMPONENT_FACTORY( chalkhistorydocker, ChalkHistoryDockerFactory( "chalk" ) ) + +ChalkHistoryDocker::ChalkHistoryDocker(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + + + + if ( tqparent->inherits("KisView") ) + { + setInstance(ChalkHistoryDockerFactory::instance()); + // Create history docker + // Add the docker to the docker manager + // Connect the undo system to the docker + } + +} + +ChalkHistoryDocker::~ChalkHistoryDocker() +{ +} diff --git a/chalk/plugins/viewplugins/history_docker/historydocker.h b/chalk/plugins/viewplugins/history_docker/historydocker.h new file mode 100644 index 00000000..82aee9bf --- /dev/null +++ b/chalk/plugins/viewplugins/history_docker/historydocker.h @@ -0,0 +1,34 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _HISTORYDOCKER_H +#define _HISTORYDOCKER_H + +#include <kparts/plugin.h> + +class ChalkHistoryDocker : public KParts::Plugin +{ +public: + ChalkHistoryDocker(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~ChalkHistoryDocker(); +}; + + +#endif //_HISTORYDOCKER_H diff --git a/chalk/plugins/viewplugins/imagesize/Makefile.am b/chalk/plugins/viewplugins/imagesize/Makefile.am new file mode 100644 index 00000000..cf863888 --- /dev/null +++ b/chalk/plugins/viewplugins/imagesize/Makefile.am @@ -0,0 +1,25 @@ +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = imagesize.rc +EXTRA_DIST = $(chalkrc_DATA) + +kde_services_DATA = chalkimagesize.desktop + + +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +chalkimagesize_la_SOURCES = wdg_imagesize.ui wdg_layersize.ui imagesize.cc dlg_imagesize.cc dlg_layersize.cc wdg_resolution.ui + +noinst_HEADERS = wdg_imagesize.h dlg_imagesize.h imagesize.h dlg_layersize.h + +kde_module_LTLIBRARIES = chalkimagesize.la + +chalkimagesize_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) chalkblurfilter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui +chalkimagesize_la_LIBADD = ../../../libchalkcommon.la + +chalkimagesize_la_METASOURCES = AUTO diff --git a/chalk/plugins/viewplugins/imagesize/chalkimagesize.desktop b/chalk/plugins/viewplugins/imagesize/chalkimagesize.desktop new file mode 100644 index 00000000..8505b94e --- /dev/null +++ b/chalk/plugins/viewplugins/imagesize/chalkimagesize.desktop @@ -0,0 +1,39 @@ +[Desktop Entry] +Name=Image Resize and Scale Plugin +Name[bg]=Приставка за оразмеряване +Name[ca]=Connector de redimensionament i escala d'imatge +Name[da]=Plugin for størrelsesændring og skalering +Name[de]=Bildgrößenänderungs- und Skalierungsmodul +Name[el]=Πρόσθετο αλλαγής μεγέθους και κλιμάκωσης εικόνας +Name[es]=Complemento para cambiar de tamaño y para escalar la imagen +Name[et]=Pildi suuruse muutmise ja skaleerimise plugin +Name[fa]=تغییر اندازۀ تصویر و مقیاسبندی وصله +Name[fr]=Module de redimensionnement d'images +Name[fy]=Grutte wizigje en skale fan de ôfbylding +Name[gl]=Plugin de Redimensionamento e Escalado da Imaxe +Name[he]=תוסף לשינוי גודל וזוויות של תמונ +Name[hu]=Képátméretező és -nyújtó modul +Name[is]=Breytingar á stærð og skala mynda íforrit +Name[it]=Plugin di ridimensionamento e riscalamento delle immagini +Name[ja]=画像 リサイズ/スケール プラグイン +Name[km]=កម្មវិធីជំនួយដើម្បីប្ដូរទំហំ និងធ្វើមាត្រដ្ឋានរូបភាព +Name[nb]=Programtillegg for skalering og endring av bildestørrelse +Name[nds]=Moduul för't Ännern un Topassen vun de Bildgrött +Name[ne]=छवि रिसाइज र स्केल प्लगइन +Name[nl]=Grootte wijzigen en schalen van afbeelding +Name[pl]=Wtyczka skalowania i zmiany rozmiarów obrazków +Name[pt]='Plugin' de Dimensionamento e Escala da Imagem +Name[pt_BR]=Plugin de Redimensionamento e Escala da Imagem +Name[ru]=Модуль масштабирования и изменения размера +Name[se]=Lassemoduvla mii skále ja rievdada govvasturrodaga +Name[sk]=Modul na zmenu veľkosti a škály obrázkov +Name[sl]=Vstavek za spreminjanje velikosti in povečavo slike +Name[sr]=Прикључак за промену величине и скалирање слика +Name[sr@Latn]=Priključak za promenu veličine i skaliranje slika +Name[sv]=Insticksprogram för bildstorleksändring och skalning +Name[uk]=Втулок зміни розміру та масштабування зображень +Name[zh_TW]=圖片大小與縮放外掛程式 +ServiceTypes=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkimagesize +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/imagesize/configure.in.in b/chalk/plugins/viewplugins/imagesize/configure.in.in new file mode 100644 index 00000000..0875ce32 --- /dev/null +++ b/chalk/plugins/viewplugins/imagesize/configure.in.in @@ -0,0 +1 @@ +AC_CHECK_DECLS([round], [], [], [#include <math.h>]) diff --git a/chalk/plugins/viewplugins/imagesize/dlg_imagesize.cc b/chalk/plugins/viewplugins/imagesize/dlg_imagesize.cc new file mode 100644 index 00000000..a1eba4f3 --- /dev/null +++ b/chalk/plugins/viewplugins/imagesize/dlg_imagesize.cc @@ -0,0 +1,277 @@ +/* + * dlg_imagesize.cc - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <config.h> + +#include <math.h> + +#include <iostream> + +using namespace std; + +#include <tqradiobutton.h> +#include <tqcheckbox.h> +#include <tqbuttongroup.h> +#include <tqlabel.h> +#include <tqcombobox.h> + +#include <klocale.h> +#include <knuminput.h> +#include <kdebug.h> + +#include <kis_cmb_idlist.h> +#include <kis_filter_strategy.h> + +#include "dlg_imagesize.h" +#include "wdg_imagesize.h" + + +// XXX: I'm really real bad at arithmetic, let alone math. Here +// be rounding errors. (Boudewijn) +DlgImageSize::DlgImageSize( TQWidget * tqparent, + const char * name) + : super (tqparent, name, true, i18n("Image Size"), Ok | Cancel, Ok) +{ + m_lock = false; + + m_page = new WdgImageSize(this, "image_size"); + Q_CHECK_PTR(m_page); + + m_page->cmbFilterType->setIDList(KisFilterStrategyRegistry::instance()->listKeys()); + m_page->cmbFilterType->setCurrentText("Mitchell"); + + setMainWidget(m_page); + resize(m_page->tqsizeHint()); + + unblockAll(); + + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); + +} + +DlgImageSize::~DlgImageSize() +{ + delete m_page; +} + +void DlgImageSize::hideScaleBox() +{ + m_page->grpResizeScale->hide(); +} + +void DlgImageSize::setWidth(TQ_UINT32 w) +{ + blockAll(); + + m_page->lblWidthOriginal->setNum((int)w); + m_page->intWidth->setValue(w); + m_oldW = w; + m_origW = w; + + unblockAll(); +} + +void DlgImageSize::setWidthPercent(TQ_UINT32 w) +{ + blockAll(); + + m_page->intWidthPercent->setValue(w); + m_oldWPercent = w; + + unblockAll(); +} + + +void DlgImageSize::setMaximumWidth(TQ_UINT32 w) +{ + m_page->intWidth->setMaxValue(w); + m_maxW = w; +} + +TQ_INT32 DlgImageSize::width() +{ + //return (TQ_INT32)tqRound(m_oldW); + return (TQ_INT32)tqRound(m_page->intWidth->value()); +} + +void DlgImageSize::setHeight(TQ_UINT32 h) +{ + blockAll(); + + m_page->lblHeightOriginal->setNum((int)h); + m_page->intHeight->setValue(h); + m_oldH = h; + m_origH = h; + + unblockAll(); +} + + +void DlgImageSize::setHeightPercent(TQ_UINT32 h) +{ + blockAll(); + + m_page->intHeightPercent->setValue(h); + m_oldHPercent = h; + + unblockAll(); +} + + + +void DlgImageSize::setMaximumHeight(TQ_UINT32 h) +{ + m_page->intHeight->setMaxValue(h); + m_maxH = h; +} + + +TQ_INT32 DlgImageSize::height() +{ + //return (TQ_INT32)tqRound(m_oldH); + return (TQ_INT32)tqRound(m_page->intHeight->value()); +} + +bool DlgImageSize::scale() +{ + return m_page->radioScale->isChecked(); +} + +bool DlgImageSize::cropLayers() +{ + return m_page->chkCrop->isChecked(); +} + +KisFilterStrategy *DlgImageSize::filterType() +{ + KisID filterID = m_page->cmbFilterType->currentItem(); + KisFilterStrategy *filter = KisFilterStrategyRegistry::instance()->get(filterID); + return filter; +} + +// SLOTS + +void DlgImageSize::okClicked() +{ + accept(); +} + +void DlgImageSize::slotWidthPixelsChanged(int w) +{ + blockAll(); + + double wPercent = double(w) * 100 / double(m_origW); + + m_page->intWidthPercent->setValue(tqRound(wPercent)); + + // Set height in pixels and percent of necessary + if (m_page->chkConstrain->isChecked()) { + m_page->intHeightPercent->setValue(tqRound(wPercent)); + + m_oldH = tqRound(m_origH * wPercent / 100); + m_page->intHeight->setValue(tqRound(m_oldH)); + + } + m_oldW = w; + + unblockAll(); +} + +void DlgImageSize::slotHeightPixelsChanged(int h) +{ + blockAll(); + + double hPercent = double(h) * 100 / double(m_origH); + + m_page->intHeightPercent->setValue(tqRound(hPercent)); + + // Set width in pixels and percent of necessary + if (m_page->chkConstrain->isChecked()) { + m_page->intWidthPercent->setValue(tqRound(hPercent)); + + m_oldW = tqRound(m_origW * hPercent / 100); + m_page->intWidth->setValue(tqRound(m_oldW)); + + } + m_oldH = h; + + unblockAll(); +} + +void DlgImageSize::slotWidthPercentChanged(int w) +{ + blockAll(); + + m_page->intWidth->setValue(tqRound(w * m_origW / 100)); + + if (m_page->chkConstrain->isChecked()) { + m_page->intHeightPercent->setValue(w); + m_page->intHeight->setValue(tqRound( w * m_origH / 100)); + } + + unblockAll(); +} + +void DlgImageSize::slotHeightPercentChanged(int h) +{ + blockAll(); + + m_page->intHeight->setValue(tqRound(h * m_origH / 100)); + if (m_page->chkConstrain->isChecked()) { + m_page->intWidthPercent->setValue(h); + m_page->intWidth->setValue(tqRound( h * m_origW / 100)); + } + + unblockAll(); + +} + + +void DlgImageSize::blockAll() +{ + // XXX: more efficient to use blockSignals? + m_page->intWidth->disconnect(); + m_page->intHeight->disconnect(); + m_page->intWidthPercent->disconnect(); + m_page->intHeightPercent->disconnect(); + +} + +void DlgImageSize::unblockAll() +{ + // XXX: more efficient to use blockSignals? + connect (m_page->intWidth, TQT_SIGNAL(valueChanged(int)), + this, TQT_SLOT(slotWidthPixelsChanged(int))); + + connect (m_page->intHeight, TQT_SIGNAL(valueChanged(int)), + this, TQT_SLOT(slotHeightPixelsChanged(int))); + + connect (m_page->intWidthPercent, TQT_SIGNAL(valueChanged(int)), + this, TQT_SLOT(slotWidthPercentChanged(int))); + + connect (m_page->intHeightPercent, TQT_SIGNAL(valueChanged(int)), + this, TQT_SLOT(slotHeightPercentChanged(int))); + + +} + +#include "dlg_imagesize.moc" diff --git a/chalk/plugins/viewplugins/imagesize/dlg_imagesize.h b/chalk/plugins/viewplugins/imagesize/dlg_imagesize.h new file mode 100644 index 00000000..7983e112 --- /dev/null +++ b/chalk/plugins/viewplugins/imagesize/dlg_imagesize.h @@ -0,0 +1,83 @@ +/* + * dlg_imagesize.h -- part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef DLG_IMAGESIZE +#define DLG_IMAGESIZE + +#include <kdialogbase.h> + +class KisFilterStrategy; +class WdgImageSize; + +/** + * This dialog allows the user to create a selection tqmask based + * on a (range of) colors. + */ +class DlgImageSize: public KDialogBase { + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + + DlgImageSize(TQWidget * tqparent = 0, + const char* name = 0); + ~DlgImageSize(); + + void hideScaleBox(); + + void setWidth(TQ_UINT32 w); + void setWidthPercent(TQ_UINT32 w); + void setMaximumWidth(TQ_UINT32 w); + TQ_INT32 width(); + + void setHeight(TQ_UINT32 h); + void setHeightPercent(TQ_UINT32 h); + void setMaximumHeight(TQ_UINT32 h); + TQ_INT32 height(); + + bool scale(); + bool cropLayers(); + + KisFilterStrategy *filterType(); + +private slots: + + void okClicked(); + void slotWidthPixelsChanged(int w); + void slotHeightPixelsChanged(int h); + void slotWidthPercentChanged(int w); + void slotHeightPercentChanged(int h); + +private: + + void blockAll(); + void unblockAll(); + + WdgImageSize * m_page; + double m_oldW, m_oldH; + double m_oldWPercent, m_oldHPercent; + double m_origW, m_origH; + double m_maxW, m_maxH; + + bool m_lock; + +}; + +#endif // DLG_IMAGESIZE diff --git a/chalk/plugins/viewplugins/imagesize/dlg_layersize.cc b/chalk/plugins/viewplugins/imagesize/dlg_layersize.cc new file mode 100644 index 00000000..8289d693 --- /dev/null +++ b/chalk/plugins/viewplugins/imagesize/dlg_layersize.cc @@ -0,0 +1,261 @@ +/* + * dlg_layersize.cc - part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * Copyright (c) 2005 Sven Langkamp <longamp@reallygood.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <config.h> + +#include <math.h> + +#include <iostream> + +using namespace std; + +#include <tqradiobutton.h> +#include <tqcheckbox.h> +#include <tqbuttongroup.h> +#include <tqlabel.h> +#include <tqcombobox.h> + +#include <klocale.h> +#include <knuminput.h> +#include <kdebug.h> + +#include <kis_cmb_idlist.h> +#include <kis_filter_strategy.h> + +#include "dlg_layersize.h" +#include "wdg_layersize.h" + + +// XXX: I'm really real bad at arithmetic, let alone math. Here +// be rounding errors. (Boudewijn) +DlgLayerSize::DlgLayerSize( TQWidget * tqparent, + const char * name) + : super (tqparent, name, true, i18n("Scale Layer"), Ok | Cancel, Ok) +{ + m_lock = false; + + m_page = new WdgLayerSize(this, "layer_size"); + Q_CHECK_PTR(m_page); + + m_page->cmbFilterType->setIDList(KisFilterStrategyRegistry::instance()->listKeys()); + m_page->cmbFilterType->setCurrentText("Mitchell"); + + setMainWidget(m_page); + resize(m_page->tqsizeHint()); + + unblockAll(); + + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); + +} + +DlgLayerSize::~DlgLayerSize() +{ + delete m_page; +} + +void DlgLayerSize::setWidth(TQ_UINT32 w) +{ + blockAll(); + + m_page->lblWidthOriginal->setNum((int)w); + m_page->intWidth->setValue(w); + m_oldW = w; + m_origW = w; + + unblockAll(); +} + +void DlgLayerSize::setWidthPercent(TQ_UINT32 w) +{ + blockAll(); + + m_page->intWidthPercent->setValue(w); + m_oldWPercent = w; + + unblockAll(); +} + + +void DlgLayerSize::setMaximumWidth(TQ_UINT32 w) +{ + m_page->intWidth->setMaxValue(w); + m_maxW = w; +} + +TQ_INT32 DlgLayerSize::width() +{ + //return (TQ_INT32)tqRound(m_oldW); + return (TQ_INT32)tqRound(m_page->intWidth->value()); +} + +void DlgLayerSize::setHeight(TQ_UINT32 h) +{ + blockAll(); + + m_page->lblHeightOriginal->setNum((int)h); + m_page->intHeight->setValue(h); + m_oldH = h; + m_origH = h; + + unblockAll(); +} + + +void DlgLayerSize::setHeightPercent(TQ_UINT32 h) +{ + blockAll(); + + m_page->intHeightPercent->setValue(h); + m_oldHPercent = h; + + unblockAll(); +} + +void DlgLayerSize::setMaximumHeight(TQ_UINT32 h) +{ + m_page->intHeight->setMaxValue(h); + m_maxH = h; +} + +TQ_INT32 DlgLayerSize::height() +{ + //return (TQ_INT32)tqRound(m_oldH); + return (TQ_INT32)tqRound(m_page->intHeight->value()); +} + +KisFilterStrategy *DlgLayerSize::filterType() +{ + KisID filterID = m_page->cmbFilterType->currentItem(); + KisFilterStrategy *filter = KisFilterStrategyRegistry::instance()->get(filterID); + return filter; +} + + +// SLOTS + +void DlgLayerSize::okClicked() +{ + accept(); +} + +void DlgLayerSize::slotWidthPixelsChanged(int w) +{ + blockAll(); + + double wPercent = double(w) * 100 / double(m_origW); + + m_page->intWidthPercent->setValue(tqRound(wPercent)); + + // Set height in pixels and percent of necessary + if (m_page->chkConstrain->isChecked()) { + m_page->intHeightPercent->setValue(tqRound(wPercent)); + + m_oldH = tqRound(m_origH * wPercent / 100); + m_page->intHeight->setValue(tqRound(m_oldH)); + + } + m_oldW = w; + + unblockAll(); +} + +void DlgLayerSize::slotHeightPixelsChanged(int h) +{ + blockAll(); + + double hPercent = double(h) * 100 / double(m_origH); + + m_page->intHeightPercent->setValue(tqRound(hPercent)); + + // Set width in pixels and percent of necessary + if (m_page->chkConstrain->isChecked()) { + m_page->intWidthPercent->setValue(tqRound(hPercent)); + + m_oldW = tqRound(m_origW * hPercent / 100); + m_page->intWidth->setValue(tqRound(m_oldW)); + + } + m_oldH = h; + + unblockAll(); +} + +void DlgLayerSize::slotWidthPercentChanged(int w) +{ + blockAll(); + + m_page->intWidth->setValue(tqRound(w * m_origW / 100)); + + if (m_page->chkConstrain->isChecked()) { + m_page->intHeightPercent->setValue(w); + m_page->intHeight->setValue(tqRound( w * m_origH / 100)); + } + + unblockAll(); +} + +void DlgLayerSize::slotHeightPercentChanged(int h) +{ + blockAll(); + + m_page->intHeight->setValue(tqRound(h * m_origH / 100)); + if (m_page->chkConstrain->isChecked()) { + m_page->intWidthPercent->setValue(h); + m_page->intWidth->setValue(tqRound( h * m_origW / 100)); + } + + unblockAll(); + +} + + +void DlgLayerSize::blockAll() +{ + // XXX: more efficient to use blockSignals? + m_page->intWidth->disconnect(); + m_page->intHeight->disconnect(); + m_page->intWidthPercent->disconnect(); + m_page->intHeightPercent->disconnect(); + +} + +void DlgLayerSize::unblockAll() +{ + // XXX: more efficient to use blockSignals? + connect (m_page->intWidth, TQT_SIGNAL(valueChanged(int)), + this, TQT_SLOT(slotWidthPixelsChanged(int))); + + connect (m_page->intHeight, TQT_SIGNAL(valueChanged(int)), + this, TQT_SLOT(slotHeightPixelsChanged(int))); + + connect (m_page->intWidthPercent, TQT_SIGNAL(valueChanged(int)), + this, TQT_SLOT(slotWidthPercentChanged(int))); + + connect (m_page->intHeightPercent, TQT_SIGNAL(valueChanged(int)), + this, TQT_SLOT(slotHeightPercentChanged(int))); + + +} + +#include "dlg_layersize.moc" diff --git a/chalk/plugins/viewplugins/imagesize/dlg_layersize.h b/chalk/plugins/viewplugins/imagesize/dlg_layersize.h new file mode 100644 index 00000000..0aaf8445 --- /dev/null +++ b/chalk/plugins/viewplugins/imagesize/dlg_layersize.h @@ -0,0 +1,74 @@ +/* + * dlg_layersize.h -- part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * Copyright (c) 2005 Sven Langkamp <longamp@reallygood.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef DLG_LAYERSIZE +#define DLG_LAYERSIZE + +#include <kdialogbase.h> + +class WdgLayerSize; +class KisFilterStrategy; + +class DlgLayerSize: public KDialogBase { + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + + DlgLayerSize(TQWidget * tqparent = 0, + const char* name = 0); + ~DlgLayerSize(); + + void setWidth(TQ_UINT32 w); + void setWidthPercent(TQ_UINT32 w); + void setMaximumWidth(TQ_UINT32 w); + TQ_INT32 width(); + + void setHeight(TQ_UINT32 h); + void setHeightPercent(TQ_UINT32 h); + void setMaximumHeight(TQ_UINT32 h); + TQ_INT32 height(); + KisFilterStrategy *filterType(); + +private slots: + + void okClicked(); + void slotWidthPixelsChanged(int w); + void slotHeightPixelsChanged(int h); + void slotWidthPercentChanged(int w); + void slotHeightPercentChanged(int h); + +private: + + void blockAll(); + void unblockAll(); + + WdgLayerSize * m_page; + double m_oldW, m_oldH; + double m_oldWPercent, m_oldHPercent; + double m_origW, m_origH; + double m_maxW, m_maxH; + + bool m_lock; + +}; + +#endif // DLG_IMAGESIZE diff --git a/chalk/plugins/viewplugins/imagesize/imagesize.cc b/chalk/plugins/viewplugins/imagesize/imagesize.cc new file mode 100644 index 00000000..c23d2717 --- /dev/null +++ b/chalk/plugins/viewplugins/imagesize/imagesize.cc @@ -0,0 +1,190 @@ +/* + * imagesize.cc -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include <math.h> + +#include <stdlib.h> + +#include <tqslider.h> +#include <tqrect.h> +#include <tqpoint.h> + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> +#include <kstdaction.h> + +#include <kis_doc.h> +#include <kis_config.h> +#include <kis_image.h> +#include <kis_layer.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_view.h> +#include <kis_selection.h> +#include <kis_selection_manager.h> +#include <kis_transaction.h> +#include <kis_canvas_controller.h> +#include <kis_scale_visitor.h> + +#include "imagesize.h" +#include "dlg_imagesize.h" +#include "dlg_layersize.h" +#include "kis_filter_strategy.h" + +typedef KGenericFactory<ImageSize> ImageSizeFactory; +K_EXPORT_COMPONENT_FACTORY( chalkimagesize, ImageSizeFactory( "chalk" ) ) + +ImageSize::ImageSize(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + if ( tqparent->inherits("KisView") ) + { + setInstance(ImageSizeFactory::instance()); + setXMLFile(locate("data","chalkplugins/imagesize.rc"), true); + + (void) new KAction(i18n("Change &Image Size..."), 0, "Shift-s", this, TQT_SLOT(slotImageSize()), actionCollection(), "imagesize"); + (void) new KAction(i18n("&Scale Layer..."), 0, 0, this, TQT_SLOT(slotLayerSize()), actionCollection(), "layerscale"); + + + m_view = (KisView*) tqparent; + // Selection manager takes ownership? + KAction * a = new KAction(i18n("&Scale Selection..."), 0, 0, this, TQT_SLOT(slotSelectionScale()), actionCollection(), "selectionscale"); + Q_CHECK_PTR(a); + m_view ->canvasSubject()-> selectionManager()->addSelectionAction(a); + } +} + +ImageSize::~ImageSize() +{ + m_view = 0; +} + +void ImageSize::slotImageSize() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgImageSize * dlgImageSize = new DlgImageSize(m_view, "ImageSize"); + Q_CHECK_PTR(dlgImageSize); + + dlgImageSize->setCaption(i18n("Image Size")); + + KisConfig cfg; + + dlgImageSize->setWidth(image->width()); + dlgImageSize->setHeight(image->height()); + + if (dlgImageSize->exec() == TQDialog::Accepted) { + TQ_INT32 w = dlgImageSize->width(); + TQ_INT32 h = dlgImageSize->height(); + + if (dlgImageSize->scale()) { + m_view->scaleCurrentImage((double)w / ((double)(image->width())), + (double)h / ((double)(image->height())), + dlgImageSize->filterType()); + } + else { + m_view->resizeCurrentImage(w, h, dlgImageSize->cropLayers()); + } + } + + delete dlgImageSize; +} + +void ImageSize::slotLayerSize() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgLayerSize * dlgLayerSize = new DlgLayerSize(m_view, "LayerSize"); + Q_CHECK_PTR(dlgLayerSize); + + dlgLayerSize->setCaption(i18n("Layer Size")); + + KisConfig cfg; + KisPaintDeviceSP dev = image->activeDevice(); + + TQRect rc = dev->exactBounds(); + + dlgLayerSize->setWidth(rc.width()); + dlgLayerSize->setHeight(rc.height()); + + if (dlgLayerSize->exec() == TQDialog::Accepted) { + TQ_INT32 w = dlgLayerSize->width(); + TQ_INT32 h = dlgLayerSize->height(); + + m_view->scaleLayer((double)w / ((double)(rc.width())), + (double)h / ((double)(rc.height())), + dlgLayerSize->filterType()); + } + delete dlgLayerSize; +} + +void ImageSize::slotSelectionScale() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + KisPaintDeviceSP layer = image->activeDevice(); + + if (!layer) return; + + if (!layer->hasSelection()) return; + + + DlgLayerSize * dlgLayerSize = new DlgLayerSize(m_view, "SelectionScale"); + Q_CHECK_PTR(dlgLayerSize); + + dlgLayerSize->setCaption(i18n("Scale Selection")); + + KisConfig cfg; + TQRect rc = layer->selection()->selectedRect(); + + dlgLayerSize->setWidth(rc.width()); + dlgLayerSize->setHeight(rc.height()); + + if (dlgLayerSize->exec() == TQDialog::Accepted) { + TQ_INT32 w = dlgLayerSize->width(); + TQ_INT32 h = dlgLayerSize->height(); + + KisScaleWorker worker (layer->selection().data(), + (double)w / ((double)(rc.width())), + (double)h / ((double)(rc.height())), + dlgLayerSize->filterType()); + worker.run(); + + m_view->getCanvasController()->updateCanvas(); + + } + delete dlgLayerSize; +} + + +#include "imagesize.moc" diff --git a/chalk/plugins/viewplugins/imagesize/imagesize.h b/chalk/plugins/viewplugins/imagesize/imagesize.h new file mode 100644 index 00000000..989a603f --- /dev/null +++ b/chalk/plugins/viewplugins/imagesize/imagesize.h @@ -0,0 +1,49 @@ +/* + * imagesize.h -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef IMAGESIZE_H +#define IMAGESIZE_H + +#include <kparts/plugin.h> + +class KisView; +class KisPainter; + +class ImageSize : public KParts::Plugin +{ + Q_OBJECT + TQ_OBJECT +public: + ImageSize(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~ImageSize(); + +private slots: + + void slotImageSize(); + void slotLayerSize(); + void slotSelectionScale(); + +private: + + KisView * m_view; + KisPainter * m_painter; + +}; + +#endif // IMAGESIZE_H diff --git a/chalk/plugins/viewplugins/imagesize/imagesize.rc b/chalk/plugins/viewplugins/imagesize/imagesize.rc new file mode 100644 index 00000000..2efb4ed8 --- /dev/null +++ b/chalk/plugins/viewplugins/imagesize/imagesize.rc @@ -0,0 +1,15 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkimagesize" version="6"> +<MenuBar> + <Menu name="Image"><text>Image</text> + <Action name="imagesize"/> + <Action name="imageresolution"/> + </Menu> + <Menu name="Layer"><text>Layer</text> + <Action name="layerscale"/> + </Menu> + <Menu name="Select"><text>&Select</text> + <Action name="selectionscale"/> + </Menu> +</MenuBar> +</kpartgui> diff --git a/chalk/plugins/viewplugins/imagesize/wdg_imagesize.ui b/chalk/plugins/viewplugins/imagesize/wdg_imagesize.ui new file mode 100644 index 00000000..4cdd5c95 --- /dev/null +++ b/chalk/plugins/viewplugins/imagesize/wdg_imagesize.ui @@ -0,0 +1,365 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgImageSize</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgImageSize</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>397</width> + <height>382</height> + </rect> + </property> + <property name="caption"> + <string>Image Size</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQButtonGroup" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>grpResizeScale</cstring> + </property> + <property name="title"> + <string></string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>pixmapLabel1_2</cstring> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <spacer row="1" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer2_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>65</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="0" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer1_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>65</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQLabel" row="0" column="3"> + <property name="name"> + <cstring>pixmapLabel2_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="pixmap"> + <pixmap>image1</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <widget class="TQRadioButton" row="1" column="0"> + <property name="name"> + <cstring>radioResize</cstring> + </property> + <property name="text"> + <string>&Resize</string> + </property> + </widget> + <widget class="TQCheckBox" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>chkCrop</cstring> + </property> + <property name="text"> + <string>&Crop layers on image resize</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <spacer row="2" column="2" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>121</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQRadioButton" row="1" column="3"> + <property name="name"> + <cstring>radioScale</cstring> + </property> + <property name="text"> + <string>&Scale</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + <widget class="TQButtonGroup" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>grpPixelDimensions</cstring> + </property> + <property name="title"> + <string>&Pixel Dimensions</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="1"> + <property name="name"> + <cstring>lblWidth</cstring> + </property> + <property name="text"> + <string>&Width:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>intWidth</cstring> + </property> + </widget> + <widget class="KIntNumInput" row="2" column="2"> + <property name="name"> + <cstring>intHeight</cstring> + </property> + <property name="minValue"> + <number>0</number> + </property> + </widget> + <widget class="TQLabel" row="0" column="2"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>&Height:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>intHeight</cstring> + </property> + </widget> + <widget class="TQLabel" row="1" column="1"> + <property name="name"> + <cstring>lblWidthOriginal</cstring> + </property> + <property name="frameShape"> + <enum>WinPanel</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="tqalignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + <widget class="TQLabel" row="1" column="2"> + <property name="name"> + <cstring>lblHeightOriginal</cstring> + </property> + <property name="frameShape"> + <enum>WinPanel</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="tqalignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>lblOrignal</cstring> + </property> + <property name="text"> + <string>Original:</string> + </property> + </widget> + <widget class="TQLabel" row="2" column="0"> + <property name="name"> + <cstring>lblNew</cstring> + </property> + <property name="text"> + <string>&New:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>intWidth</cstring> + </property> + </widget> + <widget class="KIntNumInput" row="2" column="1"> + <property name="name"> + <cstring>intWidth</cstring> + </property> + <property name="minValue"> + <number>0</number> + </property> + </widget> + <widget class="KIntNumInput" row="3" column="1"> + <property name="name"> + <cstring>intWidthPercent</cstring> + </property> + <property name="value"> + <number>100</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="referencePoint"> + <number>100</number> + </property> + <property name="suffix"> + <string>%</string> + </property> + </widget> + <widget class="KIntNumInput" row="3" column="2"> + <property name="name"> + <cstring>intHeightPercent</cstring> + </property> + <property name="value"> + <number>100</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="suffix"> + <string>%</string> + </property> + </widget> + <widget class="TQLabel" row="3" column="0"> + <property name="name"> + <cstring>lblPercent</cstring> + </property> + <property name="text"> + <string>&Percent:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>intWidthPercent</cstring> + </property> + </widget> + <widget class="TQCheckBox" row="4" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>chkConstrain</cstring> + </property> + <property name="text"> + <string>&Constrain proportions</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + <widget class="TQLabel" row="2" column="0"> + <property name="name"> + <cstring>lblFilterType</cstring> + </property> + <property name="text"> + <string>Filter:</string> + </property> + <property name="tqalignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>cmbFilterType</cstring> + </property> + </widget> + <widget class="KisCmbIDList" row="2" column="1"> + <property name="name"> + <cstring>cmbFilterType</cstring> + </property> + </widget> + </grid> +</widget> +<customwidgets> + <customwidget> + <class>KisCmbIDList</class> + <header location="local">kis_cmb_idlist.h</header> + <sizehint> + <width>1</width> + <height>24</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image2</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="4407">89504e470d0a1a0a0000000d494844520000006e0000002e0806000000c9032c97000010fe49444154789ced9b79741455bec73f55bdd0d94893054212c32a10821064095b44458119c1618928038af8e61c78e3783cfee13bcfa7c020eaf00e1c90a3ce24f890454438a0cce8cc1b8808610f04599c17c0b0bcb0042421fbda55d575df1f9dea7477ba4967018ecefb9e53dd55f7debaf7d6ef5bbfe52e256566660aee31de78e38da4f2f2f26b0042dcf3e6bd2049120053a64c99f6d24b2fcda8abab76754880d0759001dd5556a7b1afba2b411702245759d0119ee58c0b570202dd558d68fcf14c6b2ce3be4f074c8de94e5709a70024937cf6ecf9a3595959996680050b1674a028ee8cacac2c2c164b8210e29a21b4fb0d21043367ce1c3b65ca53cf5b2cd6b6d6e2f11fe89c46428d73e17e7185e7b96ebc3b02a10bd7bf10d842ecfc61f97fc6039f995bd5b5c6ca8510e88d6f9defb9bfc3c88b8c8c0440922491959545972e5d5ad3fc5d8549128ef628bf10783cab679a77beeb5a6a2c2b79dc27f994c1230d9c4e1d4b278184e604ac72dbbbda7e582c96fbd9fc7dc5a64d9bda76a370a971ab34aeb2b2124d034992319bcd5cb97295ae5dedd8ed76005455e51fff384f48880db359263a3aaaf1dc7f33aaaab6adf3f719959595389d2049264c261357ae5c253e3ec66d415455e5cc997c424242b0584c74ed1a4b48880d93c9d442cdc12368e284101417979094d4039bcde507745da3aaaaca4d5c6e6e1e13274e70df535454cadebd393cf9e404b739f5447b346e6786940aec03ecc00660fef41d6db775cd7b171825252524262679c9a1babada4ddc9123b93cfef8a3eef24545a51c3efc2d93264d74a7bdf0c20b6dee2bb86226bff0f45d062449c2330ad434dd1d951d3f7e82f1e31ff52affd5573b193870406359ad591bed0c4ea645f64cb58ffab79d58c2ec2f02eb7766b4bd3e4df34f5d70727022cb2e511e3b96c7b871e95ee5fffad7bf909232b0cd7df384ea74fd0724eef0e1a3e4e4e472e2c477ee20c36432a1aa4d0408a1131616c6a54b97494979884e9d9a4cc1575fed2239b92f090909e8baee65163bca445ac2ec74ef7d86f4e72bb0d878917692e70f9e723060369bbde4a0eb82b0b0302e5ebc44fffe03b05a9be4f0f5d7bb193c3899c4c444af7a376ddae415bcf98367bed3e9f4caf34b5c4ece7e060c18c4e38f8fa173e7ae6cdcb88d8b170b5154d9cbbc454444b06fdf615455101d1de94e3f72e43bcaca7e64e8d0a10821d034edee8dd76a7388ec06e97331c83bb53343b2770481be72d8b0612b172ffe2f0d0ec94b0e9d3b87f3cd37fba9afd7888a6a92c3d1a327a9aa2a65d8b0615ef5fa93c59d481442347bd9fd1267b3d9282cbc0140bf7e0ff0e4939349ead58b7e7dba633635dd121e16c6238f3c4a6a6a8a3bede6cddbe4e61e64c68c1900e8ba8ed3d9644a3a1cbaeb888c85f467c1d209b7ef6b2f79fee490d8a3170ff68ef3924358681863c7a6336448b23bede6cddb9c387194679ec970a77912f3fcf3cffb6dd373f8042eb3acaa2abaae7bb916bfc1c9a85169ac5bb789f8f8ae444686939060a7fe87cd545cdc43f8843fba6f33994c8485857addfbe9a79b98376f8edb37a8aa8a2449adf2673b33a447815771051e81d0d3f5844d47642c4c7a090e6e27b5f236fb80c776664815c1042dbaae377be3db23872d5b36f39bdfcc7775d1673c6bc0dfe0db13469aa669cde41730aa9c356b3abb771f2423e397949fde4897ca3d848c7f0fc5d4d4c1eef1b15ef7e4e59da57bf738424242703a9d7e1bf444205f278469677cda54bbbd474f709ef622c7f3088ded09da69b7d6a183c502e9d3e0e04e522b4b5b479e3f3cfbec0c76ed3ad06a392426261212121290904f3ffd94b973e70624d280a669e8badecc620524aea2a29291a3d36828caa3cba53fc2137f42682ac2ac40e3b450e9ed4a6c61a18485b8ec7dbf7e7dd8bb771f0e87c35d4fdb2247c93eeaf5d5503b14d40a70025a80a38e66845a2c903e050e7e4d6a6519fb80e93b33a4c2b690d75639ecdf7f004dd3bc047e271fe69b67a419160b086c2a2b2baba9ad55282baba4b4b49c31e9c350774c064b0d2857118e4244a77877f9db37afa02b95f4199c8e5353e8d44966fcf8f1e4e49c202c2c045d57e9d7af07515151ad16187a21e8152e32749fc357fbfce45b2c903e190efe9dd4ca724ee1d2bcd3c190d7117218376e1cbb761d2222220c703270601fa2a2a2dc8418da168830c3b719e7be0ae0a57f870ee51217174d4a4a6f06a73e447dd975421d27c0741e6a73c079d12b2c359914ba687fa3f8da251c0a5455d592981847dfbe0f327a741afdfba7909777b2451f1730af1544f9cbb79821fd09888b97ed20ed734de5b78c8e9243af5ebd193efc617af6eccbd1a3c75b6cd793444f577347e25455c5643223cb20498dd1a0a31642711d35eb41ca4773368d5f1455c16e3b80f5e6124acbeb70284eeaea1a703a9d5cba7495babafaa08213bf26a40d44f9cb979189eb6e45088b5d88c033359ec1c9dd9083a2285e1ab679f366bfcf6f9c1bfebf45e26a6a6ab87af532efbfbf961d3bb2b978e93ad6d028549b09a281f02a74d39f716a0e340d1c0aa8ce320447e96afb8cba4b1f515ee5a4b6b61e4d7372fb76159b366d2639b95faba3ca2669e29fac2089742a3237ae59f9fe1408216d1022b83edcba7583356b3eee30396cdebc85e4e47ecddaf14718e0652203c14d9c2449cc9a3593a95327101bdb8983fb77610a8da53ee2510807ba8008ed82a2eaa8aac0a180a2e888082016faaa6f71bb20879a3a27d5d575984c269292fa60b158da4e5cb064f9e6e9e0545da49d3c0e9ac60690e6cbb21254b3f3e6cd61eedc19f4ee1dc3f1dc7ded96c3030ff4f29a6817423067ce9c663e4e0881d3e9748fd9fc1d06dcb51989313131c4c4c4d0ad5b37f24ee633a2d7121aae7d8bad0f5033829a6a1587e336d5d555a8ea752c76a01684650c515d92c9bf5c04ba46616121b76e5d253e3e843e7dfa0078459b2da1aea404ab2a7b47943ed1a58c4016a219914e55e6c6152b278f81a6893f03f31f1e2171ea44f093dad1d1d1444747131717c777a7ce31ac1d72282ebe46626238bd7bf7f622c91746e8efef250f388ef3cd50558d9a8a4aaafa8dc512b50dcefe165b3f33f6a8f398cd7d4888fb0eb335072aa1b6280547ff6d5c3dfd2385970b3199ca18336638c9c9bf222222c25da7b1ac11c4aa4045de87efd823a2ad4da4786a5ae37f648c469f215a73f378c5cac95c706ada6959d6e6037c7fca46b0a6d2130e8742754539550fb65e0e66733963c70e2739791ae1e1e14053d4b865cb1666cf9e0d34cd2ef95b41090437712693c96ba47ef9f20d9e7e7a2267ce5c24a6dbafb03184b2efdec71ef337cc09a3a1e67fa8bf7213a779314a8f57d97d209ff8b808626234a033050505141414f86d54b4204149d2a6979ecf7fb5f48e3327a267ec80213dfb8c125079daad6965c556ce9e72912649da6340852cdbd03498f96543c0dafccd9c689a467efe259e7a6a42abe53069523af9f9798c1c39d278e680ed1aa4dd695a30288ddbbbf70053a63c8d2441dfbe496cd9f2df24f54a62d8a095dcae3c8b282802691452e779dcaa0b277bcbdfe999d49dd4d4019c3f7f8ca953a762369bd175dd2d108bc582aeeb2c5dba34bbb8b8f872604260fa0e91f3e54c4bcee40fb760559ff36b2ebf7e47ff3de6c825987091a6c894ddb272f230d4567b9066b2a1a9e28ea405c2eedd7b983871b2971c7af44ee2e1944072d845cfa438525307a0eb3ac78e9de1cc99ef193cf821c09bbcd9b367a3ebba7bb9abb531805fe2c2c343d8b7ef2003060c64edda8f090f97e9da1532d7e5f0d0e03144dafba3282a47fff22d3555579930611c172efcc0f6ede500c4c6c6fa35874b962cd9939999f92f0d0d0dc51b366c68b173791fbe4340734923119ea41d84da2a6fd29c9a862c375f0b0c06e1e1a1e4e41ca27fff643efef8bf888cb4a0392cac5d7f809441a33ce4b097daeaab3cf1443a05052e398c1b379acb97cf9192e29a0ef39cce32b4aca5c8d11341695c7afa38f2f24eb0614316cf3cf34bfaf7ef0fc0a04137c8cfbfc6d0c1432829a9e49b5d452c5dfa1fc8b2cc638f491c3d7a948282db343434b807a856ab6b5a68d1a2457bde7befbdf9353535d783f17592a4517a3e9fd280f98090d11c50fea39593fba1b64a3d2d49cec7808ad0701bb5d51a92a411ec5497e7ac05c0f8f18f70ecd871366f5ec7af7f3d95010306208460d0a0419c3953c8d0c13d2929a964cfee22de7efb4d64d93573949b9bcbba75993cfdf404860f1fee55bf6116b76fdf4e464646fb89f3c58811c3193162b8575a42423cfbf7e761b78770e1c2351e78a09b975d1e397224050505ee7188c562415114962e5dba67f9f2e5f3333333af071a78faa22561efcc90a82a2aa4ac7c3ca7f61fa1ae5a392d49ba8bb4081bb555ad23cde84f4d4d0db22cd3a95327cc6633696923494b1be9b5129e9090c0b7dfe6bae5909414e7b52a9e9696465a5a9abb7ca0e0a33d3b0002469581101e6e66e5ca3f71eb5609191993bc26408d73d72c8c09455178f7dd77f7ac58b1627e5151d1751f5f477171719b3b0e6c70545c7df5d0dacfec92a49d86f691064d2f92c3e14051144c26d766205996ddff0622222cac5c994971b14b0e060c9f6e9842cfb19aa78c67cd9ad5aabe053d1c088469d3a606acd878305996a9abab63e5ca957b56ad5a355f0871ddb3ec92254bc8cccc6c55c77d317d8728dc9921758919f838a3a740f9b9239ccc81da2a154972b69a34dfe730846f987ccf41b02ccbfce21713dd323366f10dd2fc5992f66efe0d38e565369b3be400d72ea8575e7965c3aa55ab5eacafafbfded0d0e08e30df7cf34dde7efbed0edbcae032973d38b91feaaa953693e6cf8cf9ce58782e0eabaa8aa228288a82a6696e0df377af3fd2b66ddbd686a76d825be3eaebebdb254ccf0ebef6da6b6bb2b3b3ffbdb4b4b44151144f5fc7f2e5cb3b74ff89a3e22a87d67e86246980de664d332049925ba8cf3df71c005bb76ef5ba6e293fd8ebd668a16f59e96e7cf4b170e1c2ce999999d5d3a64dc366b301f0eebbefb262c50a2fd27cb7b9dd0f187d983c79f23b3b76ec78539224bf5b09ef372449a273e7ce2c5bb62c7bf1e2c573cc0b172e948410646565b160c102f7f2437b1a98376f1e1b376ef4f475ac5ab5ea9e9154121d4d6c69a081c49d21cbf2dddbd8e481400ba4069a6958e3b5d137b39168040b66b3b9ddc419fea2a4a484c58b17f3c5175ff8edcc3f33645946d3341c0e4750f23648d6755d0624b37153565616d0e1be8eececec7b6e0edba26dc6cbd6e625a856429665aaaaaa3877ee1c56abd53dce332259df0db02693899090100a0b0beb01cd6b006e90d751b81fa4b517f7923887c34174743483070f769b4e7ff2926519555559bd7af5f91d3b767c0054bb89bb1b1f37decb0f263dd11e1f772f2184409665ac56abd7e2a92f545565e3c68d17962d5bf63b87c371005f8dfb67474b014347c268c330d19edbf0dc0148e3b878cd9a353fbcf5d65b2f3b1c8e7d42085d92a4e03fb3fa29a13dda76af89337c9be78e2e5dd7b15aad343434f0c1071f9c5fba74e9ef1c0ec77e219a3e2cff5912d716b466f5b92360f8332320f124ce6c36535757c7faf5eb2f2c5ab4c820cd6b70795f3f25be5b28898ebedf5d080a9ec419e4812b82fce8a38f2ebcfefaebbf6d348fcd6604fe5fe37c702f4da5a7d6699a86c562c1e974f2f9e79fdf5cbd7af56287c371c8d33c7ae26749dc4fc5c719ed18df0fcab2cc975f7e59fcf2cb2fff6b7d7dfd2e2144c06d713f4be2da83fb419c2ccb288ac2279f7cf2c39a356b7edf1269f03325eea7328e03dc0bce5bb76e2d688c1e0fb5441adc07e28cc0c110ecddba6e2d244992434343dd03e27b81b0b030cacacad8b871e30f8b162d7ad9e170e408219c2ddf791f88f3d584bb7d1d2c144569c8ceceae976559ba1743035996a9a9a9e1d0a14317d6af5fff5a63c81f146900d24f6d2eb1a3e1e1cfecb83e4fb601f74a281250015c0682fbb0a111ff075b8fc771a1b0847a0000000049454e44ae426082</data> + </image> + <image name="image1"> + <data format="PNG" length="5498">89504e470d0a1a0a0000000d494844520000006e0000002e0806000000c9032c970000154149444154789ced9b797014d79dc73fdd3df7a19991348390408045c469a4981b1b13c026ae0427c626c956eda61cb27f381b672b9baaddd42665cc5249586fd965c7760ec9a9d8e0d871126393908a8d09e6306064c020620e21400c022124746b46337dbefd6334c38c90401cb6e38abf552df5bc7efddeebf77dbfb35f4b555555828f183ff8c10f4a3b3b3bcf0208f191779f0349920058ba74e97ddffce637efefebeb4d0d4880b02c90012b55d7a27fac56aac01202a4545db010d9f5d23f520508ac5433a2ff4f76597f9dcc7d16a0f4979ba91aa60024453e7ab46e4f757575950de0a1871eba8953716554575763b7db4b841067d393f6714308c1030f3c70fbd2a55ffcbaddeeb8de56b2fe0f754e3fa1e9739159b822fbdc4aaf1d81b044eabf10b8dc41fef7b1ff2b065eb65dd3d0fa1b174260f5afba81e7831de96b81400000499244757535a150e85abaff50a14842bd11e11782ac67cd2ecbbd9efa2df5d795b2ee9306d421ab0c4cd3c2ee14481826e090af7fa8370ebbddfe7176ffc9844889f135495c7777378601922463b3d93873a69148244830180440d7753ef8a00eb7db85cd26535090df7f3e7837baaedff073fca362d8c40921686dbd4869e9185cae941db02c839e9e9e0c713535fb58b26471e69ea6a676b66eddcedd772fcea8d36cdc88c46d582e5502db8020b01658b16cfdf5ebbacb47f7f78d215565b6ed4a439224b2bd40c3b0325ed9debdfb59b0e07339f5376edcc0e4c913fbeb1a97f57183cec97d81b195c139dfdf80dd1bfc06f0c286e5d7df9e617c78d4f5f6f6a169faa08bf75aa19ba9ff434adceedd7bd034c8cb73327dfa6d08215014055d3770bb9d000861e1f57a3975aa8129536ec5e95432f76fdcb8894993c6535252826559396af166a948bb37c8c85b0e31ffeb5dec5ccb37f4246c582edd90e45d0fb217732cd6475b5b179aa6e376bbb02c8b4442c56e87c2c2104ea713594ec98ba6e9ecdf7f0cbfdf4b3299c4e773130e07f1f93c993ae9b64dd3cce97350e2b66fdfc1d4a99fa5b0308ffafab3ac5bf77be6cd9b8525941cf5e6f7fbd9b66d3753a64ca6a02090297ff7ddf7e9e8b8c08205cb10426018c68717afc5b7131801f3ff0576bec437f424951b964b0b81ae8f92c0f4f3e9ba4e414190bc3c6fe65a47470fc78e1dc3e9b461b7db339ae6f0e10666cf9e86d7eb02e0c28576dadabaa9a9394a45c52d8c185198697be0621f5455ba5c2ea2d1f30094978fe6eebbefa174dc38cacb4662532edde2f37ab9f3cecf5159392553d6dcdc464dcd4eeebfff7e002ccbc234cdcc0abae9b05247200cf3bf06762719db7723aaf35a910e7d4cd3c2b22e5f30f1781c555533049f3c7996d2d29119d2008a8a0a0885fc184692eeee0e20654e743da566b34dcba0123767ce6c7efdeb17292e8e1008f82829099238fe125d27b7e05bfc8bcc6d8aa2e0f57a72eefdcd6f5ee4c107ff396323755d4792a46bb2671b964b9f03be4bcaf1180a63814b31ae4891f7f96fc2ce57a9ec6e631bb070c3726958926759d6756985ec5835fdfb52d09d2ebbd4b61082aeae5e34cd64d4a8484e3d55d578fbed3de4e7cb39fe84611897cddf9036eeab5f5dc65b6fed64f9f22fd059bb8e50f716dc0bd6a02997881a591cceb967dfbea38c1c5984dbedc634cd413bccc650b64e086543f1ec7b83c13163c1accd2127fbf084c782519b913a2cb0db61fe7db0730395ddedd746de7071faf479eaea4e138904993cf9961cf5971b40a790ed93e8bac1b16351162e9c99f5bc00828d1bb7e1f3598442051416a6d4a4611858967599c61a92b8aeae6e66cd9d4db2691fa153bf80bb7e893074844d83feb4507b5b372eaf07af3b65f7cacbcbd8ba751baaaa66dab93ecf510acef9afa720fe59d0bbc0048c218e3e2e23d46e87f94b61e79fa9ecee601bb06cc372297a33c86b68680260d1a299ecd9f301afbcb289850ba7337264049bcd4667672f91c8c0b49940557584101c3c788239736ebd74a59fe8b7dfde871071f2f3f3894422f87cbe8c6d4bcf61f65ce6d0d8ddddcbf9f3ed1c3edc4043430b23471660edfe36c83da0352262b588ace4695bf3191a8fd6a0e9904868389d320b162c60fbf6fdecdb7784f7deaba5b3b3f39a5525005614acae1419d68063a0f40d72dd6e87f9f7402044257010a8bc1936eff0e1939494847138ec2c58701bf3e74fe70f7fd8caae5d07397cf8d4a0c90621c0e1f070e8d019cacbc7e0f5bafbcb536af6e8d1d3343737120af9894422040201ec767bc6a91b6cfe7288dbb5ab86a2a202a64cb9856995b792e8388747dd0f4a1dc4b7837932c72d55148d90f1175acf9e42d5a0a727cea851458c1fff19e6ce9dcd840953d8b7efc055891bf2da351035d875bb0de6df0545c57210a46da954fe8da1a0208f9a9a2399df858521962c99c3fcf9d3a9a828efb74db9f15ada568d193392d1a347f4dbffd4d1dadac9c183870887bd84c36142a1100e8723c7d45c91385dd751141bb20c92d4ef0daa71f0903a622f807404c3bc14486bba46d0f50e8ee655b477f6a16a267d7d494cd3e4d4a946fafa12c3724e06750aae83a8c1aecbc8148d7420843d28c4d0999ae13a27b7dd3691fdfb3fa0b1f1025d5d31baba7aa8ac9c4047470f275ffd1ad21bf730589cadeb3073e694ace47b2abedbb2e55df2f2140a0a0a282828c0e572653c49e0eac4c562311a1b1bf8e94f9f63fdfacd9c3c750e87271fdda54001e0ebc152fe8869a81806a81ae86607823d445c2fd377eae774f698c4e3090cc3a4adad87175f7c894993caaf4f55c2d0640d93485393397fd6c1df0e8210d25a216e5ce29c4e270b174ee7f5d7b7d2d4d4cad8b1c51cfb5b2dd6efa730deefc07fdf1f19e85586427e962c999b1532080cc362e3c61db85c060505f984c3617c3e1fb22ca3eb7a46450e850c719224f1d5af3ec0bdf72e261c76b273c726144f9884ff73e00342203c2134dd42d705aa069a6621fc4018c6eb8fd056bf9d589f496f6f1f8aa2505a5a96f1b8ae8bb8e19235f09a05a69e22edc05e300cd682b44296b56b1fc3004892c4e4c96594978f66ca945b387daa8150ed7f503cf7df61d1cf11b2eb32afd26eb761b7dbb0ac14699665d2d5d54b6beb455a5a7ac9cbcbc3ebf522cb32a6696662b6c18e346cd90302282c2ca4b0b090112346b0efc011668e5b45f2ecdbb8ca80d84c62bd3aaada466f6f0fba7e0e7b108883b0cf233f3489230d4d601944a3515a5a1a292e765356560690e36d5e0d7d172fe2d0e55c8f72807729239085b88c485397397fc6c181f7c030c41f8115b7cd9438b8ffe6bc468ac51254544c2099d4481efe35e312e760dc17a1bb0111d720303e535708c1c58b5df4f4c4282d2dea4f4808dc6e27b7dd36852d5bf6108f27b02c2be3fa0fb6c8878ce3065ed075835857373de5b763cfff3d1cfd36ae721bc1fc3a6cb6324a8adec7e6d80edd106f9a823ae1f734d65e20da1045513a98376f0693267d19bfdf9f69535152b9cc61bc15e8daf7b31f07fd058e4ba4644b5affff40a141598571b97a3ce3e0400d9886512bcbc60a80bf1d7471a3aa5208414b4b3bcdcd6d54549473fce04e269daf8611b320d690da6e909411796599d8ccb204c9a4ca3b3bdee3fe07eec16653300c13d3b49830612c0d0de73870e00489844924924f4141004551aeaaa132c4298a9213a937349ce74b5f5ac2a14327291cf1655c54d0f1fe4f0916fe055bc95c881d2671a619d3f628da98eff2d63b47282ef25358680079d4d7d7535f5f3fd4045c715492642c6baf3bf2ddf62b664ec4d8f0c48ab165730474d76624ada3d5c1d18329d224c9580874c9b20bc380075e4f0ed9da50ce89ae1b1c39728ae6e68bb4b474e0f57a282a2a484d6ce36fa0b3038a7b403d033610ba3bd3961016a669611826e3020d6cddb293858befe827ce44d70de6ce9dc65b6fd5609a360e1d8ad2d6d6452492c71d77dc8ac77329d9312c89dbbaf51d962efd129204e3c797f2dbdfbe41e9b852a64f7d82b6eea388fa2690e620e53d484b9f8fcdbf7d93b1a523a9ac9c485ddd7bdc7befbdd86c362ccbca3c84dd6ec7b22c56af5ebdb9b5b5b5e14ac42d5b2fb6bffe807dfb3d3ffb2d0efd9f0655977ffeb1f53fd802ab504891a6c974b43838b01be2bd59a4292e0c5d5c91b42ba1a3a31b97cbc1a245b37038529ae2fdf78f01201adf49d9ff9e0360cc00c012a17e5b662184d5af022dfcce0b947863d4d6869930610c8691224e089832a58c8e8e1eeeba6b168661b2756b0d6d6d6d9496960e39ae4189f3f9dc6cdbb693891327f3dc73bfc2e7938944a0ead7dbb975da3c02c109689ace9e3fbd4daca791c58befe0c489e3bcfa6a2700e170785075b86ad5aa2d555555ff9a4c265bd7ae5d7bd549dbf7b31f33a4baa49f886cd27642bc279734d33090e5cbdf050e17ba6ee0f77b33a4c1a5fd237629095ec09584f657a1682ea0f62f5813cb4a798fa6698068a73cd2c8b1fd161de115381c0e745def6fdf43347a9ebaba28e3c615a3aa0962b1580e27c392b8f9f3ef60dfbefdac5d5bcd57bef205264c9800c0d4a9e73972e42c9f9d56c1c58bddfc755313ab57ff10599659b85062cf9e3dd4d7b7914c263381bac3914affac5cb972cb9a356b56c462b173c3b1759264d05e7784f621af0342c650a1f38283033b20dea3d74a92b910e8f2f85cc47b0d24c960b8a9aeb4bb9e3d17866170f8f069dadb7b2829091308f8323196092989f3034a33a86f20a4b91886d94f58ca96e9ba8910a7207188cf8fd8c8baed6398b76011baaea3693aaaaa535a3a929a9a0f3870e018f1782fe5e545c3236e2066ce9cc1cc993372ca4a4a8ad9b1631fc1a09b1327ce327af4889ce4e7ac59b3a8afafcfc42176bb1d4dd358bd7af596c71e7b6c455555d5b9975e7a2967a286c2d5267bc372899ea6281d9d0b38b8e35dfa7ab55a49b252a4f95dc47bae8db4f47862b118b22ce3743ab1d96c8c1a358296968becdd7b8053a79a48262deebcf3368400dd3f013c6753090a3fe04b226227310c0b5d37fadf8e182995289f01571c5700ee8eac66776d316565a35155ad9f3c8dd1a38b387ab49e193346e3743aaf38d621bdcaa1e0f3d978e2895fd2d27291e5cb3f9f93004d9fa7b2300a9aa6f1939ffc64cbe38f3fbea2a9a9e9dc005b476b6bebb0277510ac55bb1abfbbebb997839264d4c28d9106971692aaaa689a86a228c8b2ccf8f1a3894402cc9e3d894422c1e9d3eda8aa86145e8c2eb660f792923c1f08358069a6c84aa7ad745d47764aa93a26dc12394fedfb3fe382f7fb389d2995994c6ae8ba4e7e7e8868b483f1e3c75fbbaabc12eebbefde41cb2549ca489f2ccbf4f5f5f1c4134f6c79f2c927570821ce65d75db56a15555555c3ea6f282c5b2fa21b964ba1c2c98b98bb143a8fbdcb81ed10efd19124f39a491bf81ca90c879951f93e9f0fa7d389699ac4e32667cfb65072fbc39c5dff14b78c6b053760cf03a9045d33d1753de380689a8ec3e64bd55101274c0eaabc113d47696909aaaa914caa24931af17882e6e6362a2bbb183d7a74ceb8b29121ce66b3ddd0f6024992329b612e5ebcc8a38f3ebaf6b5d75e7b249148342593c96c5bc79a356bae9ad2192e06a84b24c9ba2ed206db189586a22828caa56d1b93268d63f7eec32c59328fbecf3c4b4fe3d7c88b48a0e423a40867cfb6108d9ea7a7bb1387a31b35719cb99536b02b6037397fc28967f61aa69e879a9a0f70b91cc46271ec764138ec63dab4a9b8dd578e7533c42512891b262efdb0dffbdef79edebc79f37fb7b7b727354dcbb6753cf6d8633775ff89dad5c8aee75e46920ce0fa48cbc670d27389848e65a5c2823973be4c74cb4a8c236bc89fee62444441b30e533062066ea70f97bd15cce65428a3cbb41eb3a14dde80e519454dcd9b4812381c0633668cc2e7f3e1f57af1783cf8fdfeababcaeaeaea1b7ad881d8bc79f3caaaaaaae4005bc7e38f3f7e5349fba87773413a208f72c71d951c3f1ee5fdf7ebf8eca21f12dd5bc1c53ffc276316b732fe9638d862a91b8c38584962d15e5a8f4ec236b90ad3338a975f7a83b2b252c2e1207bf71e22180c52545484cfe7c3e1700cb989380ddbb7bef52d4908417575350f3df4109aa6ddb0e43df8e083ac5bb72edbd6f1e4934f7eec5fe60c07b22c5f7163d3c993e7282d1d4928e467f6eca9ecde7d88b7dedac3bc790b51a61e205af322e6aefdb8f38ee00a87e96bacc73083d84b7e8cf3f6bb696ebec89b1b52a4cd993315d3141c3f7e86baba26c68e1d8bdfef4796e5cb242cfd3b3d365bba30ed2c7c08b68ed75e7b2da7f34f2ababa7a89c5542a2a2666623e97cbc9a64dbb3975aa91a9533fc3b8cfdc47b8e01b5896891002dfb8d4a6a933679a39f0a7ed44a38d949414535e3e3af3a6e0f6db2b79fef9d799366d5c7f9baecbfa4eab70cbb26440b2a5494aabcb9b6cebd8bc79f32742d2d28bed4a362e10f0a169492e5ce8c0eff7b07efd5f696838cdd4a9c5141515d0d6769ea347eb89c7351c0e278a22d1dd1da7bbbb07b75ba1ac2cc25d77dd8aaec3b66dfb2829194138ace0703858b66c16bdbdbd747575e578b369288a82dbed261a8d26002347917e08b6ee13415a36ae449c2ccb4c9f3e814d9bdee5f8f1b31417fb59b4e85682c120a15088f2723badad1d3435f5306fde342ccb4255759e79e6156ebfbd9cc2c242f2f3f3713a9d8c19338a37dfdccdc489d399366d5ac6cb1e6cbed22f579f7aeaa9baf5ebd73f0bf46688fb303e6efc283f98fc282049126eb79bc58b67525131ae7fdbb88f502884d7eb4551140281007bf7fe359364eee8e8c1b2343c1e0f914884c2c2421445213f3f9f050b2a90651987c391f3f27420745d67ddba75277ef4a31f7d4755d577182871ffe8186a4755366c361b81400097cb856118381c0e1c0e47c66970b95cc8f2a5d744a74f9f2714f2e076bbf17abd9978d6e17010080488c7e30039dbf0320e48bf67f9f4d34f1f7fe491471e5655759b10c2922469f89f59fda36038719ccd661bd25d972489bc3c2f7bf71e2114f2535f1f251209e0f1787236ce4a9284a22899ad0ad93bba2ccbc2e170904c2679f6d967eb56af5efd1d55557788aced631feb17a97f4fb8199f40a5b178f10cfc7e85d6d67394947899366d3c7ebf3f236d70e993b5f4b7158661640e21047d7d7dfcea57bf3ab172e5caefc4e3f11d42889c77539f4adc8780fcfc2077de39fbaaf5b2894b7b9176bb1d455178e699674eac5ab5eadb69f538f0de4f891b80ebde91769dfda4c9330c03bbdd8e699abcf2ca2bcd4f3df5d4a3aaaaee1a8c34f894b8cbf051130764d4a32ccbbcfefaebad0f3ffcf0bf2512894d428821b7c57d4adc007c1cc4c9b28ca6693cfffcf3c79f7efae9ffb91a69f029711f3bd249f8dffdee77f5fddee3aeab91069f1297812449b2c7e3c904c41f05bc5e2f1d1d1dac5bb7eef8ca952b1f565575bb10c2bcfa9d9f129781a669c9cd9b37276459966e66683014645926168bb16bd7ae132fbcf0c2f7fae3b4619106207dd27289371b59f62c48eaf3641703bfdaf810bb07ba8006e09a3e6cf87fd8857d4933e0288e0000000049454e44ae426082</data> + </image> + <image name="image2"> + <data format="PNG" length="1002">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b149444154388dad945f4c5b551cc73fe7dc4b7b4bcba0762d45c43114323599ee6192609c51d883892ce083f1718b3ebb185f8dc91e972cf39d2d2a2f1af664b6f1e0fe3863a0718969700eb0c52142da0242a1bd6d696f7bcff101585203ceb8fd9ece39f99dcff9fe7edf939f88c562ec465f5f9fe609442c161362173c3e3eae7b7a7ac8e7f36432196cdbfe4f907c3e4f2291201e8fe338cec3737357e9e8e828aded1e229d650e1f2d51754b082110124c13a4dc5ea341eb9dc284c0558a853f3ce8cb0677ef500fde7d39d2596679e326597b8e9abb85d7a770ab16ab6983ec5a05b487a70e36f0f4e10afe408d6a558310980108478dba4a1e8233990c5d474b64ed39aa3a8fe5f3317fbf81dbd70bccfeb205947632fd74f6589c1c6ea2f70d03a58ba0c1f2c9bdc1b66de3b8256a6e11cbe7e3ee1d181b590124fe2693aeee08d223c82c3a2c24b7b874bec8f26288774f7bd054504aef0dde6e99c0eb83f9fb266323cb80a27fb0958141836044605a2ee5523393371cc646fee2da37195aa35d0c0c5b4859ac03d7e91712dcaac5adab3650a3ff9d08ef7dd8404bb48869e5d958b5b87dadc4c9a1464e9f0d0326df7ebd86bd2e310cb1bf62d384d59441f2d70a070e1c60e09489929b988681bdd9cc97170bcc4c65595f71f8e0e3301337fc24a7732467831875a47f289652b0be5e4151e6d07316c1b0c0340d8ab92023e76d66a6b2840e36d2fb7a13fee632475e6edc367ea98a90fb98b7dd6310ca0328a44761582e1bab41befabcc0ec940d28bc5e93b68e064cab84e1d9beaeb48934eac1f53b01c1b000fca496aa54b61a99fcde61662a4b4b4b23d1680be9d426173e4df3602a48ea411989a4fd590f52a8fd156b05ed9d350e3defe3cfdf4b4c7ce770ea7d3fb9f520afbe1620daeee5c26735d20b9b9cfb6811a754a439e4e5c5639a4caa1e5caf586bfc0197b78702005cb9b4cae4cd3267ce8638fe964bd72b393e39d74928d242617303a756a37f284447770dcdbffc6384a05a85de1306e9a52057c7527c7131c3c42d3f475eb2303c82d4fc3276d6811db37efeb148723082d9b08f79f97c1e5729109a9a28307cc622d2d6cdf52b2b24efe548dedb00142009862cfa879ee1a71f6cec928353511472fbf4389148b0b0e0c108081412458dfe21c9f11351e67e7358595468246d1d1e5e38a6e9e851bc39d84ab502a669331dafec0d8ec7e3e8cb06e1a881d727d1ae40180a434a8c9db129a54126ad48a7358c2b4c5352c8c374bcccdab2bb37d8719cba79fab8211f9df218e0582c261e95f8bfc04f1a1e8bc5c4dfe0a190172af6a9690000000049454e44ae426082</data> + </image> +</images> +<tabstops> + <tabstop>intWidth</tabstop> + <tabstop>intHeight</tabstop> + <tabstop>intWidthPercent</tabstop> + <tabstop>intHeightPercent</tabstop> + <tabstop>chkConstrain</tabstop> + <tabstop>radioScale</tabstop> +</tabstops> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>knuminput.h</includehint> +</includehints> +</UI> diff --git a/chalk/plugins/viewplugins/imagesize/wdg_layersize.ui b/chalk/plugins/viewplugins/imagesize/wdg_layersize.ui new file mode 100644 index 00000000..fb7547d2 --- /dev/null +++ b/chalk/plugins/viewplugins/imagesize/wdg_layersize.ui @@ -0,0 +1,234 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgLayerSize</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgLayerSize</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>391</width> + <height>224</height> + </rect> + </property> + <property name="caption"> + <string>Image Size</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="TQButtonGroup" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>grpPixelDimensions</cstring> + </property> + <property name="title"> + <string>&Pixel Dimensions</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="1"> + <property name="name"> + <cstring>lblWidth</cstring> + </property> + <property name="text"> + <string>&Width:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>intWidth</cstring> + </property> + </widget> + <widget class="KIntNumInput" row="2" column="2"> + <property name="name"> + <cstring>intHeight</cstring> + </property> + <property name="minValue"> + <number>0</number> + </property> + </widget> + <widget class="TQLabel" row="0" column="2"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>&Height:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>intHeight</cstring> + </property> + </widget> + <widget class="TQLabel" row="1" column="1"> + <property name="name"> + <cstring>lblWidthOriginal</cstring> + </property> + <property name="frameShape"> + <enum>WinPanel</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="tqalignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + <widget class="TQLabel" row="1" column="2"> + <property name="name"> + <cstring>lblHeightOriginal</cstring> + </property> + <property name="frameShape"> + <enum>WinPanel</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="tqalignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>lblOrignal</cstring> + </property> + <property name="text"> + <string>Original:</string> + </property> + </widget> + <widget class="TQLabel" row="2" column="0"> + <property name="name"> + <cstring>lblNew</cstring> + </property> + <property name="text"> + <string>&New:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>intWidth</cstring> + </property> + </widget> + <widget class="KIntNumInput" row="2" column="1"> + <property name="name"> + <cstring>intWidth</cstring> + </property> + <property name="minValue"> + <number>0</number> + </property> + </widget> + <widget class="KIntNumInput" row="3" column="1"> + <property name="name"> + <cstring>intWidthPercent</cstring> + </property> + <property name="value"> + <number>100</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="referencePoint"> + <number>100</number> + </property> + <property name="suffix"> + <string>%</string> + </property> + </widget> + <widget class="KIntNumInput" row="3" column="2"> + <property name="name"> + <cstring>intHeightPercent</cstring> + </property> + <property name="value"> + <number>100</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="suffix"> + <string>%</string> + </property> + </widget> + <widget class="TQLabel" row="3" column="0"> + <property name="name"> + <cstring>lblPercent</cstring> + </property> + <property name="text"> + <string>&Percent:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>intWidthPercent</cstring> + </property> + </widget> + <widget class="TQCheckBox" row="4" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>chkConstrain</cstring> + </property> + <property name="text"> + <string>&Constrain proportions</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>lblFilterType</cstring> + </property> + <property name="text"> + <string>&Filter:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cmbFilterType</cstring> + </property> + </widget> + <widget class="KisCmbIDList" row="1" column="1"> + <property name="name"> + <cstring>cmbFilterType</cstring> + </property> + </widget> + </grid> +</widget> +<customwidgets> + <customwidget> + <class>KisCmbIDList</class> + <header location="local">kis_cmb_idlist.h</header> + <sizehint> + <width>1</width> + <height>24</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="1002">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b149444154388dad945f4c5b551cc73fe7dc4b7b4bcba0762d45c43114323599ee6192609c51d883892ce083f1718b3ebb185f8dc91e972cf39d2d2a2f1af664b6f1e0fe3863a0718969700eb0c52142da0242a1bd6d696f7bcff101585203ceb8fd9ece39f99dcff9fe7edf939f88c562ec465f5f9fe609442c161362173c3e3eae7b7a7ac8e7f36432196cdbfe4f907c3e4f2291201e8fe338cec3737357e9e8e828aded1e229d650e1f2d51754b082110124c13a4dc5ea341eb9dc284c0558a853f3ce8cb0677ef500fde7d39d2596679e326597b8e9abb85d7a770ab16ab6983ec5a05b487a70e36f0f4e10afe408d6a558310980108478dba4a1e8233990c5d474b64ed39aa3a8fe5f3317fbf81dbd70bccfeb205947632fd74f6589c1c6ea2f70d03a58ba0c1f2c9bdc1b66de3b8256a6e11cbe7e3ee1d181b590124fe2693aeee08d223c82c3a2c24b7b874bec8f26288774f7bd054504aef0dde6e99c0eb83f9fb266323cb80a27fb0958141836044605a2ee5523393371cc646fee2da37195aa35d0c0c5b4859ac03d7e91712dcaac5adab3650a3ff9d08ef7dd8404bb48869e5d958b5b87dadc4c9a1464e9f0d0326df7ebd86bd2e310cb1bf62d384d59441f2d70a070e1c60e09489929b988681bdd9cc97170bcc4c65595f71f8e0e3301337fc24a7732467831875a47f289652b0be5e4151e6d07316c1b0c0340d8ab92023e76d66a6b2840e36d2fb7a13fee632475e6edc367ea98a90fb98b7dd6310ca0328a44761582e1bab41befabcc0ec940d28bc5e93b68e064cab84e1d9beaeb48934eac1f53b01c1b000fca496aa54b61a99fcde61662a4b4b4b23d1680be9d426173e4df3602a48ea411989a4fd590f52a8fd156b05ed9d350e3defe3cfdf4b4c7ce770ea7d3fb9f520afbe1620daeee5c26735d20b9b9cfb6811a754a439e4e5c5639a4caa1e5caf586bfc0197b78702005cb9b4cae4cd3267ce8638fe964bd72b393e39d74928d242617303a756a37f284447770dcdbffc6384a05a85de1306e9a52057c7527c7131c3c42d3f475eb2303c82d4fc3276d6811db37efeb148723082d9b08f79f97c1e5729109a9a28307cc622d2d6cdf52b2b24efe548dedb00142009862cfa879ee1a71f6cec928353511472fbf4389148b0b0e0c108081412458dfe21c9f11351e67e7358595468246d1d1e5e38a6e9e851bc39d84ab502a669331dafec0d8ec7e3e8cb06e1a881d727d1ae40180a434a8c9db129a54126ad48a7358c2b4c5352c8c374bcccdab2bb37d8719cba79fab8211f9df218e0582c261e95f8bfc04f1a1e8bc5c4dfe0a190172af6a9690000000049454e44ae426082</data> + </image> +</images> +<tabstops> + <tabstop>intWidth</tabstop> + <tabstop>intHeight</tabstop> + <tabstop>intWidthPercent</tabstop> + <tabstop>intHeightPercent</tabstop> + <tabstop>chkConstrain</tabstop> +</tabstops> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>knuminput.h</includehint> +</includehints> +</UI> diff --git a/chalk/plugins/viewplugins/imagesize/wdg_resolution.ui b/chalk/plugins/viewplugins/imagesize/wdg_resolution.ui new file mode 100644 index 00000000..df0e010d --- /dev/null +++ b/chalk/plugins/viewplugins/imagesize/wdg_resolution.ui @@ -0,0 +1,152 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgResolution</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgResolution</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>487</width> + <height>265</height> + </rect> + </property> + <property name="caption"> + <string>Image Resolution</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQGroupBox" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>grpSize</cstring> + </property> + <property name="title"> + <string>Print Size</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>lblHeight</cstring> + </property> + <property name="text"> + <string>Height:</string> + </property> + </widget> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>lblWidth</cstring> + </property> + <property name="text"> + <string>Width:</string> + </property> + </widget> + <widget class="KIntNumInput" row="0" column="1"> + <property name="name"> + <cstring>intWidth</cstring> + </property> + <property name="suffix"> + <string> "</string> + </property> + </widget> + <widget class="KIntNumInput" row="1" column="1"> + <property name="name"> + <cstring>intHeight</cstring> + </property> + <property name="suffix"> + <string> "</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQGroupBox" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>grpResolution</cstring> + </property> + <property name="title"> + <string>Image Resolution</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>lblScreen</cstring> + </property> + <property name="text"> + <string>Screen resolution:</string> + </property> + </widget> + <widget class="TQLabel" row="0" column="1"> + <property name="name"> + <cstring>lblScreenResolution</cstring> + </property> + <property name="frameShape"> + <enum>Panel</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="text"> + <string>100</string> + </property> + <property name="tqalignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + <widget class="TQLabel" row="2" column="0"> + <property name="name"> + <cstring>lblYResolution</cstring> + </property> + <property name="text"> + <string>Image Y resolution:</string> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>lblImageXRes</cstring> + </property> + <property name="text"> + <string>Image X resolution:</string> + </property> + </widget> + <widget class="KIntNumInput" row="1" column="1"> + <property name="name"> + <cstring>intXRes</cstring> + </property> + <property name="suffix"> + <string> dpi</string> + </property> + </widget> + <widget class="KIntNumInput" row="2" column="1"> + <property name="name"> + <cstring>intYRes</cstring> + </property> + <property name="suffix"> + <string> dpi</string> + </property> + </widget> + </grid> + </widget> + </grid> +</widget> +<customwidgets> +</customwidgets> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> +</includehints> +</UI> diff --git a/chalk/plugins/viewplugins/modify_selection/Makefile.am b/chalk/plugins/viewplugins/modify_selection/Makefile.am new file mode 100644 index 00000000..6e0f14c5 --- /dev/null +++ b/chalk/plugins/viewplugins/modify_selection/Makefile.am @@ -0,0 +1,27 @@ +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = modify_selection.rc +EXTRA_DIST = $(chalkrc_DATA) + +kde_services_DATA = chalkmodifyselection.desktop + + +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +chalkmodifyselection_la_SOURCES = wdg_grow_selection.ui wdg_shrink_selection.ui wdg_border_selection.ui \ +dlg_grow_selection.cc dlg_shrink_selection.cc dlg_border_selection.cc modify_selection.cc + +noinst_HEADERS = wdg_grow_selection.h wdg_shrink_selection.h wdg_border_selection.h dlg_grow_selection.h \ +dlg_shrink_selection.h dlg_border_selection.h modify_selection.h + +kde_module_LTLIBRARIES = chalkmodifyselection.la + +chalkmodifyselection_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) chalkblurfilter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui +chalkmodifyselection_la_LIBADD = ../../../libchalkcommon.la + +chalkmodifyselection_la_METASOURCES = AUTO diff --git a/chalk/plugins/viewplugins/modify_selection/chalkmodifyselection.desktop b/chalk/plugins/viewplugins/modify_selection/chalkmodifyselection.desktop new file mode 100644 index 00000000..aa4a9d58 --- /dev/null +++ b/chalk/plugins/viewplugins/modify_selection/chalkmodifyselection.desktop @@ -0,0 +1,40 @@ +[Desktop Entry] +Name=Modify Selection +Name[bg]=Промяна на маркираното +Name[br]=Kemmañ an dibab +Name[ca]=Selecció de modificació +Name[da]=Ændr markering +Name[de]=Auswahl verändern +Name[el]=Τροποποίηση επιλογής +Name[eo]=Modifi elekton +Name[es]=Modificar selección +Name[et]=Valiku muutmine +Name[fa]=تغییر گزینش +Name[fr]=Modifier la sélection +Name[fy]=Seleksje oanpasse +Name[ga]=Athraigh an Roghnúchán +Name[gl]=Modificación da Selección +Name[hu]=A kijelölés módosítása +Name[it]=Modifica la selezione +Name[ja]=選択領域を変更 +Name[km]=កែប្រែការជ្រើស +Name[lv]=Mainīt izvēli +Name[nb]=Endre utvalg +Name[nds]=Utwahl ännern +Name[ne]=चयन परिमार्जन गर्नुहोस् +Name[nl]=Selectie aanpassen +Name[pl]=Zmiana wyboru +Name[pt]=Modificar a Selecção +Name[pt_BR]=Modificar a Seleção +Name[ru]=Выделение +Name[sk]=Zmeniť výber +Name[sl]=Spremeni izbiro +Name[sr]=Измена избора +Name[sr@Latn]=Izmena izbora +Name[sv]=Ändra markering +Name[uk]=Зміна виділення +Name[zh_TW]=變更選取 +ServiceTypes=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkmodifyselection +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/modify_selection/dlg_border_selection.cc b/chalk/plugins/viewplugins/modify_selection/dlg_border_selection.cc new file mode 100644 index 00000000..dcda5c7e --- /dev/null +++ b/chalk/plugins/viewplugins/modify_selection/dlg_border_selection.cc @@ -0,0 +1,76 @@ +/* + * dlg_border_selection.cc - part of Chalk + * + * Copyright (c) 2006 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <config.h> + +#include <math.h> + +#include <iostream> + +using namespace std; + +#include <tqradiobutton.h> +#include <tqcheckbox.h> +#include <tqbuttongroup.h> +#include <tqlabel.h> +#include <tqcombobox.h> + +#include <klocale.h> +#include <knuminput.h> +#include <kdebug.h> + +#include "dlg_border_selection.h" +#include "wdg_border_selection.h" + +DlgBorderSelection::DlgBorderSelection( TQWidget * tqparent, const char * name) : super (tqparent, name, true, i18n("Border Selection"), Ok | Cancel, Ok) +{ + m_page = new WdgBorderSelection(this, "border_selection"); + Q_CHECK_PTR(m_page); + + setMainWidget(m_page); + resize(m_page->tqsizeHint()); + + connect(this, TQT_SIGNAL(okClicked()), this, TQT_SLOT(okClicked())); +} + +DlgBorderSelection::~DlgBorderSelection() +{ + delete m_page; +} + +TQ_INT32 DlgBorderSelection::xradius() +{ + return m_page->radiusSpinBox->value(); +} + +TQ_INT32 DlgBorderSelection::yradius() +{ + return m_page->radiusSpinBox->value(); +} + + +// SLOTS + +void DlgBorderSelection::okClicked() +{ + accept(); +} + +#include "dlg_border_selection.moc" diff --git a/chalk/plugins/viewplugins/modify_selection/dlg_border_selection.h b/chalk/plugins/viewplugins/modify_selection/dlg_border_selection.h new file mode 100644 index 00000000..472f01ef --- /dev/null +++ b/chalk/plugins/viewplugins/modify_selection/dlg_border_selection.h @@ -0,0 +1,49 @@ +/* + * dlg_border_selection.h -- part of Chalk + * + * Copyright (c) 2006 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef DLG_BORDER_SELECTION_H +#define DLG_BORDER_SELECTION_H + +#include <kdialogbase.h> + +class WdgBorderSelection; + +class DlgBorderSelection: public KDialogBase { + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + + DlgBorderSelection(TQWidget * tqparent = 0, const char* name = 0); + ~DlgBorderSelection(); + + TQ_INT32 xradius(); + TQ_INT32 yradius(); + +private slots: + + void okClicked(); + +private: + + WdgBorderSelection * m_page; +}; + +#endif // DLG_BORDER_SELECTION_H diff --git a/chalk/plugins/viewplugins/modify_selection/dlg_grow_selection.cc b/chalk/plugins/viewplugins/modify_selection/dlg_grow_selection.cc new file mode 100644 index 00000000..b889ccde --- /dev/null +++ b/chalk/plugins/viewplugins/modify_selection/dlg_grow_selection.cc @@ -0,0 +1,76 @@ +/* + * dlg_grow_selection.cc - part of Chalk + * + * Copyright (c) 2006 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <config.h> + +#include <math.h> + +#include <iostream> + +using namespace std; + +#include <tqradiobutton.h> +#include <tqcheckbox.h> +#include <tqbuttongroup.h> +#include <tqlabel.h> +#include <tqcombobox.h> + +#include <klocale.h> +#include <knuminput.h> +#include <kdebug.h> + +#include "dlg_grow_selection.h" +#include "wdg_grow_selection.h" + +DlgGrowSelection::DlgGrowSelection( TQWidget * tqparent, const char * name) : super (tqparent, name, true, i18n("Grow Selection"), Ok | Cancel, Ok) +{ + m_page = new WdgGrowSelection(this, "grow_selection"); + Q_CHECK_PTR(m_page); + + setMainWidget(m_page); + resize(m_page->tqsizeHint()); + + connect(this, TQT_SIGNAL(okClicked()), this, TQT_SLOT(okClicked())); +} + +DlgGrowSelection::~DlgGrowSelection() +{ + delete m_page; +} + +TQ_INT32 DlgGrowSelection::xradius() +{ + return m_page->radiusSpinBox->value(); +} + +TQ_INT32 DlgGrowSelection::yradius() +{ + return m_page->radiusSpinBox->value(); +} + + +// SLOTS + +void DlgGrowSelection::okClicked() +{ + accept(); +} + +#include "dlg_grow_selection.moc" diff --git a/chalk/plugins/viewplugins/modify_selection/dlg_grow_selection.h b/chalk/plugins/viewplugins/modify_selection/dlg_grow_selection.h new file mode 100644 index 00000000..61785b20 --- /dev/null +++ b/chalk/plugins/viewplugins/modify_selection/dlg_grow_selection.h @@ -0,0 +1,49 @@ +/* + * dlg_grow_selection.h -- part of Chalk + * + * Copyright (c) 2006 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef DLG_GROW_SELECTION_H +#define DLG_GROW_SELECTION_H + +#include <kdialogbase.h> + +class WdgGrowSelection; + +class DlgGrowSelection: public KDialogBase { + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + + DlgGrowSelection(TQWidget * tqparent = 0, const char* name = 0); + ~DlgGrowSelection(); + + TQ_INT32 xradius(); + TQ_INT32 yradius(); + +private slots: + + void okClicked(); + +private: + + WdgGrowSelection * m_page; +}; + +#endif // DLG_GROW_SELECTION_H diff --git a/chalk/plugins/viewplugins/modify_selection/dlg_shrink_selection.cc b/chalk/plugins/viewplugins/modify_selection/dlg_shrink_selection.cc new file mode 100644 index 00000000..eb50c6cf --- /dev/null +++ b/chalk/plugins/viewplugins/modify_selection/dlg_shrink_selection.cc @@ -0,0 +1,81 @@ +/* + * dlg_shrink_selection.cc - part of Chalk + * + * Copyright (c) 2006 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <config.h> + +#include <math.h> + +#include <iostream> + +using namespace std; + +#include <tqradiobutton.h> +#include <tqcheckbox.h> +#include <tqbuttongroup.h> +#include <tqlabel.h> +#include <tqcombobox.h> + +#include <klocale.h> +#include <knuminput.h> +#include <kdebug.h> + +#include "dlg_shrink_selection.h" +#include "wdg_shrink_selection.h" + +DlgShrinkSelection::DlgShrinkSelection( TQWidget * tqparent, const char * name) : super (tqparent, name, true, i18n("Shrink Selection"), Ok | Cancel, Ok) +{ + m_page = new WdgShrinkSelection(this, "shrink_selection"); + Q_CHECK_PTR(m_page); + + setMainWidget(m_page); + resize(m_page->tqsizeHint()); + + connect(this, TQT_SIGNAL(okClicked()), this, TQT_SLOT(okClicked())); +} + +DlgShrinkSelection::~DlgShrinkSelection() +{ + delete m_page; +} + +TQ_INT32 DlgShrinkSelection::xradius() +{ + return m_page->radiusSpinBox->value(); +} + +TQ_INT32 DlgShrinkSelection::yradius() +{ + return m_page->radiusSpinBox->value(); +} + +bool DlgShrinkSelection::shrinkFromImageBorder() +{ + return m_page->shrinkFromImageBorderCheckBox->isChecked(); +} + + +// SLOTS + +void DlgShrinkSelection::okClicked() +{ + accept(); +} + +#include "dlg_shrink_selection.moc" diff --git a/chalk/plugins/viewplugins/modify_selection/dlg_shrink_selection.h b/chalk/plugins/viewplugins/modify_selection/dlg_shrink_selection.h new file mode 100644 index 00000000..53ce386b --- /dev/null +++ b/chalk/plugins/viewplugins/modify_selection/dlg_shrink_selection.h @@ -0,0 +1,50 @@ +/* + * dlg_shrink_selection.h -- part of Chalk + * + * Copyright (c) 2006 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef DLG_SHRINK_SELECTION_H +#define DLG_SHRINK_SELECTION_H + +#include <kdialogbase.h> + +class WdgShrinkSelection; + +class DlgShrinkSelection: public KDialogBase { + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + + DlgShrinkSelection(TQWidget * tqparent = 0, const char* name = 0); + ~DlgShrinkSelection(); + + TQ_INT32 xradius(); + TQ_INT32 yradius(); + bool shrinkFromImageBorder(); + +private slots: + + void okClicked(); + +private: + + WdgShrinkSelection * m_page; +}; + +#endif // DLG_SHRINK_SELECTION_H diff --git a/chalk/plugins/viewplugins/modify_selection/modify_selection.cc b/chalk/plugins/viewplugins/modify_selection/modify_selection.cc new file mode 100644 index 00000000..78a75778 --- /dev/null +++ b/chalk/plugins/viewplugins/modify_selection/modify_selection.cc @@ -0,0 +1,158 @@ +/* + * modify_selection.cc -- Part of Chalk + * + * Copyright (c) 2006 Michael Thaler (michael.thaler@physik.tu-muenchen.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include <math.h> + +#include <stdlib.h> + +#include <tqslider.h> +#include <tqpoint.h> + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> +#include <kstdaction.h> + +#include <kis_doc.h> +#include <kis_config.h> +#include <kis_image.h> +#include <kis_layer.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_view.h> +#include <kis_selection.h> +#include <kis_selection_manager.h> +#include <kis_transaction.h> + +#include "modify_selection.h" +#include "dlg_grow_selection.h" +#include "dlg_shrink_selection.h" +#include "dlg_border_selection.h" + +typedef KGenericFactory<ModifySelection> ModifySelectionFactory; +K_EXPORT_COMPONENT_FACTORY( chalkmodifyselection, ModifySelectionFactory( "chalk" ) ) + +ModifySelection::ModifySelection(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + if ( tqparent->inherits("KisView") ) + { + setInstance(ModifySelectionFactory::instance()); + setXMLFile(locate("data","chalkplugins/modify_selection.rc"), true); + + m_view = (KisView*) tqparent; + + // Selection manager takes ownership? + KAction* a = new KAction(i18n("Grow Selection..."), 0, 0, this, TQT_SLOT(slotGrowSelection()), actionCollection(), "growselection"); + KAction* b = new KAction(i18n("Shrink Selection..."), 0, 0, this, TQT_SLOT(slotShrinkSelection()), actionCollection(), "shrinkselection"); + KAction* c = new KAction(i18n("Border Selection..."), 0, 0, this, TQT_SLOT(slotBorderSelection()), actionCollection(), "borderselection"); + + Q_CHECK_PTR(a); + Q_CHECK_PTR(b); + Q_CHECK_PTR(c); + + m_view ->canvasSubject()-> selectionManager()->addSelectionAction(a); + m_view ->canvasSubject()-> selectionManager()->addSelectionAction(b); + m_view ->canvasSubject()-> selectionManager()->addSelectionAction(c); + } +} + +ModifySelection::~ModifySelection() +{ + m_view = 0; +} + +void ModifySelection::slotGrowSelection() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgGrowSelection * dlgGrowSelection = new DlgGrowSelection(m_view, "GrowSelection"); + Q_CHECK_PTR(dlgGrowSelection); + + dlgGrowSelection->setCaption(i18n("Grow Selection")); + + KisConfig cfg; + + if (dlgGrowSelection->exec() == TQDialog::Accepted) { + TQ_INT32 xradius = dlgGrowSelection->xradius(); + TQ_INT32 yradius = dlgGrowSelection->yradius(); + + m_view ->canvasSubject()-> selectionManager()->grow(xradius, yradius); + } + + delete dlgGrowSelection; +} + +void ModifySelection::slotShrinkSelection() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgShrinkSelection * dlgShrinkSelection = new DlgShrinkSelection(m_view, "ShrinkSelection"); + Q_CHECK_PTR(dlgShrinkSelection); + + dlgShrinkSelection->setCaption(i18n("Shrink Selection")); + + KisConfig cfg; + + if (dlgShrinkSelection->exec() == TQDialog::Accepted) { + TQ_INT32 xradius = dlgShrinkSelection->xradius(); + TQ_INT32 yradius = dlgShrinkSelection->yradius(); + bool shrinkFromImageBorder = dlgShrinkSelection->shrinkFromImageBorder(); + + m_view ->canvasSubject()-> selectionManager()->shrink(xradius, yradius, shrinkFromImageBorder); + } + + delete dlgShrinkSelection; +} + +void ModifySelection::slotBorderSelection() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgBorderSelection * dlgBorderSelection = new DlgBorderSelection(m_view, "BorderSelection"); + Q_CHECK_PTR(dlgBorderSelection); + + dlgBorderSelection->setCaption(i18n("Border Selection")); + + KisConfig cfg; + + if (dlgBorderSelection->exec() == TQDialog::Accepted) { + TQ_INT32 xradius = dlgBorderSelection->xradius(); + TQ_INT32 yradius = dlgBorderSelection->yradius(); + + m_view ->canvasSubject()-> selectionManager()->border(xradius, yradius); + } + + delete dlgBorderSelection; +} + +#include "modify_selection.moc" diff --git a/chalk/plugins/viewplugins/modify_selection/modify_selection.h b/chalk/plugins/viewplugins/modify_selection/modify_selection.h new file mode 100644 index 00000000..db5dd1b7 --- /dev/null +++ b/chalk/plugins/viewplugins/modify_selection/modify_selection.h @@ -0,0 +1,47 @@ +/* + * modify_selection.h -- Part of Chalk + * + * Copyright (c) 2006 Michael Thaler (michael.thaler@physik.tu-muenchen.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef MODIFY_SELECTION_H +#define MODIFY_SELECTION_H + +#include <kparts/plugin.h> + +class KisView; + +class ModifySelection : public KParts::Plugin +{ + Q_OBJECT + TQ_OBJECT +public: + ModifySelection(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~ModifySelection(); + +private slots: + + void slotGrowSelection(); + void slotShrinkSelection(); + void slotBorderSelection(); + +private: + + KisView * m_view; + +}; + +#endif // MODIFY_SELECTION_H diff --git a/chalk/plugins/viewplugins/modify_selection/modify_selection.rc b/chalk/plugins/viewplugins/modify_selection/modify_selection.rc new file mode 100644 index 00000000..999aaaaa --- /dev/null +++ b/chalk/plugins/viewplugins/modify_selection/modify_selection.rc @@ -0,0 +1,10 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkmodifyselection" version="6"> + <MenuBar> + <Menu name="Select"><text>&Select</text> + <Action name="growselection"/> + <Action name="shrinkselection"/> + <Action name="borderselection"/> + </Menu> + </MenuBar> +</kpartgui> diff --git a/chalk/plugins/viewplugins/modify_selection/wdg_border_selection.ui b/chalk/plugins/viewplugins/modify_selection/wdg_border_selection.ui new file mode 100644 index 00000000..06d01e9f --- /dev/null +++ b/chalk/plugins/viewplugins/modify_selection/wdg_border_selection.ui @@ -0,0 +1,57 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgBorderSelection</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgBorderSelection</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>255</width> + <height>101</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Border selection by</string> + </property> + </widget> + <widget class="TQSpinBox" row="1" column="0"> + <property name="name"> + <cstring>radiusSpinBox</cstring> + </property> + <property name="maxValue"> + <number>10000</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + <property name="value"> + <number>1</number> + </property> + </widget> + <widget class="TQComboBox" row="1" column="1"> + <item> + <property name="text"> + <string>pixels</string> + </property> + </item> + <property name="name"> + <cstring>comboBox1</cstring> + </property> + </widget> + </grid> +</widget> +<tabstops> + <tabstop>radiusSpinBox</tabstop> +</tabstops> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/plugins/viewplugins/modify_selection/wdg_grow_selection.ui b/chalk/plugins/viewplugins/modify_selection/wdg_grow_selection.ui new file mode 100644 index 00000000..d1180803 --- /dev/null +++ b/chalk/plugins/viewplugins/modify_selection/wdg_grow_selection.ui @@ -0,0 +1,57 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgGrowSelection</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgGrowSelection</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>255</width> + <height>101</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Grow selection by</string> + </property> + </widget> + <widget class="TQSpinBox" row="1" column="0"> + <property name="name"> + <cstring>radiusSpinBox</cstring> + </property> + <property name="maxValue"> + <number>10000</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + <property name="value"> + <number>1</number> + </property> + </widget> + <widget class="TQComboBox" row="1" column="1"> + <item> + <property name="text"> + <string>pixels</string> + </property> + </item> + <property name="name"> + <cstring>comboBox1</cstring> + </property> + </widget> + </grid> +</widget> +<tabstops> + <tabstop>radiusSpinBox</tabstop> +</tabstops> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/plugins/viewplugins/modify_selection/wdg_shrink_selection.ui b/chalk/plugins/viewplugins/modify_selection/wdg_shrink_selection.ui new file mode 100644 index 00000000..28429d72 --- /dev/null +++ b/chalk/plugins/viewplugins/modify_selection/wdg_shrink_selection.ui @@ -0,0 +1,68 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgShrinkSelection</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgShrinkSelection</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>255</width> + <height>117</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Shrink selection by</string> + </property> + </widget> + <widget class="TQSpinBox" row="1" column="0"> + <property name="name"> + <cstring>radiusSpinBox</cstring> + </property> + <property name="maxValue"> + <number>10000</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + <property name="value"> + <number>1</number> + </property> + </widget> + <widget class="TQComboBox" row="1" column="1"> + <item> + <property name="text"> + <string>pixels</string> + </property> + </item> + <property name="name"> + <cstring>comboBox1</cstring> + </property> + </widget> + <widget class="TQCheckBox" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>shrinkFromImageBorderCheckBox</cstring> + </property> + <property name="text"> + <string>Shrink from image border</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </grid> +</widget> +<tabstops> + <tabstop>radiusSpinBox</tabstop> +</tabstops> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/plugins/viewplugins/performancetest/Makefile.am b/chalk/plugins/viewplugins/performancetest/Makefile.am new file mode 100644 index 00000000..e2d7dfac --- /dev/null +++ b/chalk/plugins/viewplugins/performancetest/Makefile.am @@ -0,0 +1,25 @@ +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = perftest.rc + +EXTRA_DIST = $(chalkrc_DATA) + +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../ui \ + -I$/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +kde_module_LTLIBRARIES = chalkperftest.la + +chalkperftest_la_SOURCES = wdg_perftest.ui perftest.cc dlg_perftest.cc +noinst_HEADERS = wdg_perftest.h dlg_perftest.h perftest.h + +chalkperftest_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) chalkblurfilter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui +chalkperftest_la_LIBADD = ../../../libchalkcommon.la + +kde_services_DATA = chalkperftest.desktop + +chalkperftest_la_METASOURCES = AUTO diff --git a/chalk/plugins/viewplugins/performancetest/chalkperftest.desktop b/chalk/plugins/viewplugins/performancetest/chalkperftest.desktop new file mode 100644 index 00000000..74aee7ed --- /dev/null +++ b/chalk/plugins/viewplugins/performancetest/chalkperftest.desktop @@ -0,0 +1,41 @@ +[Desktop Entry] +Name=Performance Test +Name[bg]=Тест за производителност +Name[ca]=Prova d'execució +Name[da]=Ydelsestest +Name[de]=Leistungstest +Name[el]=Δοκιμή επίδοσης +Name[es]=Prueba de rendimiento +Name[et]=Jõudlustest +Name[fa]=آزمون کارایی +Name[fr]=Test de performances +Name[fy]=Prestaasjemjitting +Name[gl]=Probas de Rendemento +Name[he]=בדיקת ביצועים +Name[hu]=Teljesítményteszt +Name[is]=Afkastapróf +Name[it]=Prova delle prestazioni +Name[ja]=パフォーマンステスト +Name[km]=សាកល្បងការសម្ដែង +Name[lv]=Veiktspējas tests +Name[nb]=Ytelsestest +Name[nds]=Leistenprööv +Name[ne]=कार्य सम्पादन परीक्षण +Name[nl]=Prestatiemeting +Name[pl]=Test wydajności +Name[pt]=Teste de Performance +Name[pt_BR]=Teste de Desempenho +Name[ru]=Модуль производительности +Name[sk]=Test výkonnosti +Name[sl]=Preizkus zmogljivosti +Name[sr]=Проба перформанси +Name[sr@Latn]=Proba performansi +Name[sv]=Prestandatest +Name[uk]=Тест швидкодії +Name[uz]=Unumdorilkni tekshirish +Name[uz@cyrillic]=Унумдорилкни текшириш +Name[zh_TW]=效能測試 +ServiceTypes=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkperftest +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/performancetest/dlg_perftest.cc b/chalk/plugins/viewplugins/performancetest/dlg_perftest.cc new file mode 100644 index 00000000..12e3f42c --- /dev/null +++ b/chalk/plugins/viewplugins/performancetest/dlg_perftest.cc @@ -0,0 +1,110 @@ +/* + * dlg_perftest.cc - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <config.h> + +#include <math.h> + +#include <iostream> + +using namespace std; + +#include <tqradiobutton.h> +#include <tqpushbutton.h> +#include <tqcheckbox.h> +#include <tqlabel.h> + +#include <klocale.h> +#include <knuminput.h> +#include <kdebug.h> + +#include "dlg_perftest.h" +#include "wdg_perftest.h" + + +DlgPerfTest::DlgPerfTest( TQWidget * tqparent, + const char * name) + : super (tqparent, name, true, i18n("Performance Test"), Ok | Cancel, Ok) +{ + m_lock = false; + + m_page = new WdgPerfTest(this, "perf_test"); + Q_CHECK_PTR(m_page); + + setMainWidget(m_page); + resize(m_page->tqsizeHint()); + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); + + connect(m_page->btnSelectAll, TQT_SIGNAL(clicked()), this, TQT_SLOT(selectAllClicked())); + connect(m_page->btnDeselectAll, TQT_SIGNAL(clicked()), this, TQT_SLOT(deselectAllClicked())); +} + +DlgPerfTest::~DlgPerfTest() +{ + delete m_page; +} + +WdgPerfTest * DlgPerfTest::page() +{ + return m_page; +} + +// SLOTS + +void DlgPerfTest::okClicked() +{ + accept(); +} + +void DlgPerfTest::setAllTestCheckBoxes(bool checked) +{ + m_page->chkBitBlt->setChecked(checked); + m_page->chkFill->setChecked(checked); + m_page->chkGradient->setChecked(checked); + m_page->chkPixel->setChecked(checked); + m_page->chkShape->setChecked(checked); + m_page->chkLayer->setChecked(checked); + m_page->chkScale->setChecked(checked); + m_page->chkRotate->setChecked(checked); + m_page->chkRender->setChecked(checked); + m_page->chkSelection->setChecked(checked); + m_page->chkColorConversion->setChecked(checked); + m_page->chkFilter->setChecked(checked); + m_page->chkReadBytes->setChecked(checked); + m_page->chkWriteBytes->setChecked(checked); + m_page->chkIterators->setChecked(checked); + m_page->chkPaintView->setChecked(checked); + m_page->chkPaintViewFPS->setChecked(checked); +} + +void DlgPerfTest::selectAllClicked() +{ + setAllTestCheckBoxes(true); +} + +void DlgPerfTest::deselectAllClicked() +{ + setAllTestCheckBoxes(false); +} + + +#include "dlg_perftest.moc" diff --git a/chalk/plugins/viewplugins/performancetest/dlg_perftest.h b/chalk/plugins/viewplugins/performancetest/dlg_perftest.h new file mode 100644 index 00000000..aae398fa --- /dev/null +++ b/chalk/plugins/viewplugins/performancetest/dlg_perftest.h @@ -0,0 +1,56 @@ +/* + * dlg_perftest.h -- part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef DLG_PERFTEST_H_ +#define DLG_PERFTEST_H_ + +#include <kdialogbase.h> + +class WdgPerfTest; + +class DlgPerfTest: public KDialogBase { + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + + DlgPerfTest(TQWidget * tqparent = 0, + const char* name = 0); + ~DlgPerfTest(); + + WdgPerfTest * page(); + +private slots: + + void okClicked(); + void selectAllClicked(); + void deselectAllClicked(); + + void setAllTestCheckBoxes(bool checked); + +private: + + WdgPerfTest * m_page; + double m_oldAngle; + bool m_lock; + +}; + +#endif // DLG_PERFTEST_H diff --git a/chalk/plugins/viewplugins/performancetest/perftest.cc b/chalk/plugins/viewplugins/performancetest/perftest.cc new file mode 100644 index 00000000..88a50e85 --- /dev/null +++ b/chalk/plugins/viewplugins/performancetest/perftest.cc @@ -0,0 +1,1198 @@ +/* + * perftest.cc -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <math.h> + +#include <stdlib.h> + +#include <tqslider.h> +#include <tqpoint.h> +#include <tqradiobutton.h> +#include <tqcheckbox.h> +#include <tqlabel.h> +#include <tqtextedit.h> +#include <tqdatetime.h> + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kdialogbase.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> +#include <knuminput.h> + +#include <tqcolor.h> + +#include "kis_meta_registry.h" +#include <kis_resourceserver.h> +#include "kis_cursor.h" +#include <kis_doc.h> +#include <kis_config.h> +#include <kis_image.h> +#include <kis_layer.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_view.h> +#include <kis_selection.h> +#include <kis_colorspace_factory_registry.h> +#include <kis_colorspace.h> +#include <kis_painter.h> +#include <kis_fill_painter.h> +#include <kis_id.h> +#include <kis_paint_device.h> +#include <kis_iterators_pixel.h> +#include "perftest.h" +#include "kis_filter_config_widget.h" +#include "kis_factory.h" + +#include "dlg_perftest.h" +#include "wdg_perftest.h" + +#define USE_CALLGRIND 0 + +#if USE_CALLGRIND +#include <valgrind/callgrind.h> +#endif + + +typedef KGenericFactory<PerfTest> PerfTestFactory; +K_EXPORT_COMPONENT_FACTORY( chalkperftest, PerfTestFactory( "chalk" ) ) + +PerfTest::PerfTest(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + if ( tqparent->inherits("KisView") ) + { + setInstance(PerfTestFactory::instance()); + setXMLFile(locate("data","chalkplugins/perftest.rc"), true); + + (void) new KAction(i18n("&Performance Test..."), 0, 0, this, TQT_SLOT(slotPerfTest()), actionCollection(), "perf_test"); + + m_view = (KisView*) tqparent; + } +} + +PerfTest::~PerfTest() +{ + m_view = 0; +} + +void PerfTest::slotPerfTest() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgPerfTest * dlgPerfTest = new DlgPerfTest(m_view, "PerfTest"); + Q_CHECK_PTR(dlgPerfTest); + + dlgPerfTest->setCaption(i18n("Performance Test")); + + TQString report = TQString(""); + + if (dlgPerfTest->exec() == TQDialog::Accepted) { + + TQ_INT32 testCount = (TQ_INT32)tqRound(dlgPerfTest->page()->intTestCount->value()); + + if (dlgPerfTest->page()->chkBitBlt->isChecked()) { + kdDebug() << "bltTest:\n"; + TQString s = bltTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkFill->isChecked()) { + kdDebug() << "Filltest\n"; + TQString s= fillTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkGradient->isChecked()) { + kdDebug() << "Gradienttest\n"; + TQString s = gradientTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkPixel->isChecked()) { + kdDebug() << "Pixeltest\n"; + TQString s = pixelTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkShape->isChecked()) { + kdDebug() << "Shapetest\n"; + TQString s = tqshapeTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkLayer->isChecked()) { + kdDebug() << "LayerTest\n"; + TQString s = layerTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkScale->isChecked()) { + kdDebug() << "Scaletest\n"; + TQString s = scaleTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkRotate->isChecked()) { + kdDebug() << "Rotatetest\n"; + TQString s = rotateTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkRender->isChecked()) { + kdDebug() << "Rendertest\n"; + TQString s = renderTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkSelection->isChecked()) { + kdDebug() << "Selectiontest\n"; + TQString s = selectionTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkColorConversion->isChecked()) { + kdDebug() << "Colorconversiontest\n"; + TQString s = colorConversionTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkFilter-> isChecked()) { + kdDebug() << "filtertest\n"; + TQString s = filterTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkReadBytes->isChecked()) { + kdDebug() << "Readbytes test\n"; + TQString s = readBytesTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkWriteBytes-> isChecked()) { + kdDebug() << "Writebytes test\n"; + TQString s = writeBytesTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkIterators->isChecked()) { + kdDebug() << "Iterators test\n"; + TQString s = iteratorTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkPaintView->isChecked()) { + kdDebug() << "paintview test\n"; + TQString s = paintViewTest(testCount); + report = report.append(s); + kdDebug() << s << "\n"; + } + if (dlgPerfTest->page()->chkPaintViewFPS->isChecked()) { + kdDebug() << "paint current view (fps) test\n"; + TQString s = paintViewFPSTest(); + report = report.append(s); + kdDebug() << s << "\n"; + } + KDialogBase * d = new KDialogBase(m_view, "", true, "", KDialogBase::Ok); + Q_CHECK_PTR(d); + + d->setCaption("Performance test results"); + TQTextEdit * e = new TQTextEdit(d); + Q_CHECK_PTR(e); + d->setMainWidget(e); + e->setText(report); + e->setMinimumWidth(600); + e->setMinimumHeight(600); + d->exec(); + delete d; + + } + delete dlgPerfTest; +} + +TQString PerfTest::bltTest(TQ_UINT32 testCount) +{ + TQString report = TQString("* bitBlt test\n"); + + KisDoc * doc = m_view->canvasSubject()->document(); + KisIDList l = KisMetaRegistry::instance()->csRegistry()->listKeys(); + + for (KisIDList::Iterator it = l.begin(); it != l.end(); ++it) { + + kdDebug() << "Image->" << (*it).name() << "\n"; + + report = report.append( " Testing blitting on " + (*it).name() + "\n"); + + KisImageSP img = doc->newImage("blt-" + (*it).name(), 1000, 1000, + KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it,"")); + + report = report.append(doBlit(COMPOSITE_OVER, *it, OPACITY_OPAQUE, testCount, img)); + report = report.append( "\n"); + report = report.append(doBlit(COMPOSITE_OVER, *it, OPACITY_OPAQUE / 2, testCount, img)); + report = report.append( "\n"); + report = report.append(doBlit(COMPOSITE_COPY, *it, OPACITY_OPAQUE, testCount, img)); + report = report.append( "\n"); + report = report.append(doBlit(COMPOSITE_COPY, *it, OPACITY_OPAQUE / 2, testCount, img)); + report = report.append( "\n"); + } + + return report; + + +} + + +TQString PerfTest::doBlit(const KisCompositeOp& op, + KisID cspace, + TQ_UINT8 opacity, + TQ_UINT32 testCount, + KisImageSP img) +{ + + TQTime t; + TQString report; + + // ------------------------------------------------------------------------------ + // Small + + KisPaintDeviceSP small = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getColorSpace(cspace,""), "small blit"); + Q_CHECK_PTR(small); + + KisFillPainter pf(small.data()) ; + pf.fillRect(0, 0, 32, 32, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + pf.end(); + + t.restart(); + KisPainter p(img->activeDevice()); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.bitBlt(0, 0, op, small.data(),0,0,32, 32); + } + p.end(); + + report = report.append(TQString(" %1 blits of rectangles < tilesize with opacity %2 and composite op %3: %4ms\n") + .tqarg(testCount) + .tqarg(opacity) + .tqarg(op.id().name()) + .tqarg(t.elapsed())); + + + // ------------------------------------------------------------------------------ + // Medium + KisPaintDeviceSP medium = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getColorSpace(cspace,""), "medium blit"); + Q_CHECK_PTR(medium); + + pf.begin(medium.data()) ; + pf.fillRect(0, 0, 64 * 3, 64 * 3, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + pf.end(); + + t.restart(); + p.begin(img->activeDevice().data()); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.bitBlt(0, 0, op, medium.data(),0,0,96, 96); + } + p.end(); + + report = report.append(TQString(" %1 blits of rectangles 3 * tilesize with opacity %2 and composite op %3: %4ms\n") + .tqarg(testCount) + .tqarg(opacity) + .tqarg(op.id().name()) + .tqarg(t.elapsed())); + + + // ------------------------------------------------------------------------------ + // Big + KisPaintDeviceSP big = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getColorSpace(cspace,""), "big blit"); + Q_CHECK_PTR(big); + + pf.begin(big.data()) ; + pf.fillRect(0, 0, 800, 800, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + pf.end(); + + t.restart(); + p.begin(img->activeDevice().data()); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.bitBlt(0, 0, op, big.data(),0,0,800,800); + + } + p.end(); + report = report.append(TQString(" %1 blits of rectangles 800 x 800 with opacity %2 and composite op %3: %4ms\n") + .tqarg(testCount) + .tqarg(opacity) + .tqarg(op.id().name()) + .tqarg(t.elapsed())); + + + // ------------------------------------------------------------------------------ + // Outside + + KisPaintDeviceSP outside = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getColorSpace(cspace,""), "outside blit"); + Q_CHECK_PTR(outside); + pf.begin(outside.data()) ; + pf.fillRect(0, 0, 500, 500, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + pf.end(); + + t.restart(); + p.begin(img->activeDevice().data()); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.bitBlt(600, 600, op, outside.data(),0,0,500,500); + + } + p.end(); + report = report.append(TQString(" %1 blits of rectangles 500 x 500 at 600,600 with opacity %2 and composite op %3: %4ms\n") + .tqarg(testCount) + .tqarg(opacity) + .tqarg(op.id().name()) + .tqarg(t.elapsed())); + + // ------------------------------------------------------------------------------ + // Small with varied source opacity + + KisPaintDeviceSP small_with_alpha = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getColorSpace(cspace,""), "small blit with alpha"); + Q_CHECK_PTR(small_with_alpha); + + pf.begin(small_with_alpha.data()) ; + pf.fillRect(0, 0, 32, 32, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8()), OPACITY_TRANSPARENT); + pf.fillRect(4, 4, 24, 24, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8()), OPACITY_OPAQUE / 2); + pf.fillRect(8, 8, 16, 16, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8()), OPACITY_OPAQUE); + pf.end(); + + t.restart(); + p.begin(img->activeDevice().data()); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.bitBlt(0, 0, op, small_with_alpha.data(), 0, 0, 32, 32); + } + p.end(); + + report = report.append(TQString(" %1 blits of rectangles < tilesize with source alpha, with opacity %2 and composite op %3: %4ms\n") + .tqarg(testCount) + .tqarg(opacity) + .tqarg(op.id().name()) + .tqarg(t.elapsed())); + + return report; + +} + +TQString PerfTest::fillTest(TQ_UINT32 testCount) +{ + TQString report = TQString("* Fill test\n"); + + KisDoc * doc = m_view->canvasSubject()->document(); + KisIDList l = KisMetaRegistry::instance()->csRegistry()->listKeys(); + + for (KisIDList::Iterator it = l.begin(); it != l.end(); ++it) { + kdDebug() << "Filltest on " << (*it).name() + "\n"; + + report = report.append( " Testing blitting on " + (*it).name() + "\n"); + + KisImageSP img = doc->newImage("fill-" + (*it).name(), 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it,"")); + KisPaintDeviceSP l = img->activeDevice(); + + // Rect fill + KisFillPainter p(l.data()); + TQTime t; + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.eraseRect(0, 0, 1000, 1000); + } + report = report.append(TQString(" Erased 1000 x 1000 layer %1 times: %2\n").tqarg(testCount).tqarg(t.elapsed())); + + + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.eraseRect(50, 50, 500, 500); + } + report = report.append(TQString(" Erased 500 x 500 layer %1 times: %2\n").tqarg(testCount).tqarg(t.elapsed())); + + + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.eraseRect(-50, -50, 1100, 1100); + } + report = report.append(TQString(" Erased rect bigger than layer %1 times: %2\n").tqarg(testCount).tqarg(t.elapsed())); + + + // Opaque Rect fill + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + } + report = report.append(TQString(" Opaque fill 1000 x 1000 layer %1 times: %2\n").tqarg(testCount).tqarg(t.elapsed())); + + + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.fillRect(50, 50, 500, 500, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + } + report = report.append(TQString(" Opaque fill 500 x 500 layer %1 times: %2\n").tqarg(testCount).tqarg(t.elapsed())); + + + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.fillRect(-50, -50, 1100, 1100, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + } + report = report.append(TQString(" Opaque fill rect bigger than layer %1 times: %2\n").tqarg(testCount).tqarg(t.elapsed())); + + // Transparent rect fill + + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8()), OPACITY_OPAQUE / 2); + } + report = report.append(TQString(" Opaque fill 1000 x 1000 layer %1 times: %2\n").tqarg(testCount).tqarg(t.elapsed())); + + + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.fillRect(50, 50, 500, 500, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8()), OPACITY_OPAQUE / 2); + } + report = report.append(TQString(" Opaque fill 500 x 500 layer %1 times: %2\n").tqarg(testCount).tqarg(t.elapsed())); + + + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.fillRect(-50, -50, 1100, 1100, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8()), OPACITY_OPAQUE / 2); + } + report = report.append(TQString(" Opaque fill rect bigger than layer %1 times: %2\n").tqarg(testCount).tqarg(t.elapsed())); + + // Colour fill + + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.eraseRect(0, 0, 1000, 1000); +// p.paintEllipse(500, 1000, 100, 0, 0); + p.setPaintColor(KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.setFillThreshold(15); + p.setCompositeOp(COMPOSITE_OVER); + p.fillColor(0,0); + } + report = report.append(TQString(" Opaque floodfill of whole circle (incl. erase and painting of circle) %1 times: %2\n").tqarg(testCount).tqarg(t.elapsed())); + + + // Pattern fill + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + p.eraseRect(0, 0, 1000, 1000); +// p.paintEllipse(500, 1000, 100, 0, 0); + p.setPaintColor(KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + KisResourceServerBase* r = KisResourceServerRegistry::instance()->get("PatternServer"); + Q_CHECK_PTR(r); + p.setPattern((KisPattern*)r->resources().first()); + p.setFillThreshold(15); + p.setCompositeOp(COMPOSITE_OVER); + p.fillPattern(0,0); + } + report = report.append(TQString(" Opaque patternfill of whole circle (incl. erase and painting of circle) %1 times: %2\n").tqarg(testCount).tqarg(t.elapsed())); + + + + } + + + + return report; + +} + +TQString PerfTest::gradientTest(TQ_UINT32 testCount) +{ + return TQString("Gradient test\n"); +} + +TQString PerfTest::pixelTest(TQ_UINT32 testCount) +{ + TQString report = TQString("* pixel/setpixel test\n"); + + KisDoc * doc = m_view->canvasSubject()->document(); + KisIDList l = KisMetaRegistry::instance()->csRegistry()->listKeys(); + + + for (KisIDList::Iterator it = l.begin(); it != l.end(); ++it) { + report = report.append( " Testing pixel/setpixel on " + (*it).name() + "\n"); + + KisImageSP img = doc->newImage("fill-" + (*it).name(), 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it,"")); + + KisPaintDeviceSP l = img->activeDevice(); + + TQTime t; + t.restart(); + + TQColor c = TQt::black; + TQ_UINT8 opacity = OPACITY_OPAQUE; + for (TQ_UINT32 i = 0; i < testCount; ++i) { + for (TQ_UINT32 x = 0; x < 1000; ++x) { + for (TQ_UINT32 y = 0; y < 1000; ++y) { + l->pixel(x, y, &c, &opacity); + } + } + } + report = report.append(TQString(" read 1000 x 1000 pixels %1 times: %2\n").tqarg(testCount).tqarg(t.elapsed())); + + c= TQt::black; + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + for (TQ_UINT32 x = 0; x < 1000; ++x) { + for (TQ_UINT32 y = 0; y < 1000; ++y) { + l->setPixel(x, y, c, 128); + } + } + } + report = report.append(TQString(" written 1000 x 1000 pixels %1 times: %2\n").tqarg(testCount).tqarg(t.elapsed())); + + } + + + + + return report; + +} + +TQString PerfTest::tqshapeTest(TQ_UINT32 testCount) +{ + return TQString("Shape test\n"); +} + +TQString PerfTest::layerTest(TQ_UINT32 testCount) +{ + return TQString("Layer test\n"); +} + +TQString PerfTest::scaleTest(TQ_UINT32 testCount) +{ + return TQString("Scale test\n"); +} + +TQString PerfTest::rotateTest(TQ_UINT32 testCount) +{ + TQString report = TQString("* Rotate test\n"); + + KisDoc * doc = m_view->canvasSubject()->document(); + KisIDList l = KisMetaRegistry::instance()->csRegistry()->listKeys(); + for (KisIDList::Iterator it = l.begin(); it != l.end(); ++it) { + + doc->undoAdapter()->setUndo( false ); + TQTime t; + + for (uint i = 0; i < testCount; ++i) { + for (double angle = 0; angle < 360; ++angle) { + kdDebug() << "Rotating " << (*it).name() << " at " << angle << " degrees\n"; + KisImage * img = doc->newImage("cs-" + (*it).name(), 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it,"")); + img->rotate(angle, m_view->canvasSubject()->progressDisplay()); + kdDebug() << "Size: " << img->projection()->extent() << endl; + delete img; + } + } + report = report.append(TQString(" rotated 1000 x 1000 pixels over 360 degrees, degree by degree, %1 times: %2\n").tqarg(testCount).tqarg(t.elapsed())); + } + return report; +} + +TQString PerfTest::renderTest(TQ_UINT32 restCount) +{ + return TQString("Render test\n"); +} + +TQString PerfTest::selectionTest(TQ_UINT32 testCount) +{ + return TQString("Selection test\n"); +} + +TQString PerfTest::colorConversionTest(TQ_UINT32 testCount) +{ + TQString report = TQString("* Colorspace conversion test\n"); + + KisDoc * doc = m_view->canvasSubject()->document(); + KisIDList l = KisMetaRegistry::instance()->csRegistry()->listKeys(); + for (KisIDList::Iterator it = l.begin(); it != l.end(); ++it) { + + KisImage * img = doc->newImage("cs-" + (*it).name(), 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it,"")); + + TQTime t; + + KisIDList l2 = KisMetaRegistry::instance()->csRegistry()->listKeys(); + for (KisIDList::Iterator it2 = l2.begin(); it2 != l2.end(); ++it2) { + kdDebug() << "test conversion from " << (*it).name() << " to " << (*it2).name() << endl; + + t.restart(); + for (uint i = 0; i < testCount; ++i) { + KisImage * img2 = new KisImage(*img); + img2->convertTo(KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it2,"")); + delete img2; + } + report = report.append(TQString(" converted from " + (*it).name() + " to " + (*it2).name() + " 1000 x 1000 pixels %1 times: %2\n").tqarg(testCount).tqarg(t.elapsed())); + + } + + delete img; + + } + return report; + +} + +TQString PerfTest::filterTest(TQ_UINT32 testCount) +{ + + TQString report = TQString("* Filter test\n"); + + KisIDList filters = KisFilterRegistry::instance()->listKeys(); + KisDoc * doc = m_view->canvasSubject()->document(); + KisIDList l = KisMetaRegistry::instance()->csRegistry()->listKeys(); + + for (KisIDList::Iterator it = l.begin(); it != l.end(); ++it) { + report = report.append( " Testing filtering on " + (*it).name() + "\n"); + + KisImageSP img = doc->newImage("filter-" + (*it).name(), 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(*it,"")); + KisPaintDeviceSP l = img->activeDevice(); + + TQTime t; + + for (KisIDList::Iterator it = filters.begin(); it != filters.end(); ++it) { + + KisFilterSP f = KisFilterRegistry::instance()->get(*it); + t.restart(); + kdDebug() << "test filter " << f->id().name() << " on " << img->colorSpace()->id().name() << endl; + for (TQ_UINT32 i = 0; i < testCount; ++i) { + f->enableProgress(); + f->process(l.data(), l.data(), f->configuration(f->createConfigurationWidget(m_view, l.data())), TQRect(0, 0, 1000, 1000)); + f->disableProgress(); + } + report = report.append(TQString(" filtered " + (*it).name() + "1000 x 1000 pixels %1 times: %2\n").tqarg(testCount).tqarg(t.elapsed())); + + } + + } + return report; + +} + +TQString PerfTest::readBytesTest(TQ_UINT32 testCount) +{ + TQString report = TQString("* Read bytes test\n\n"); + + // On default tiles + KisDoc * doc = m_view->canvasSubject()->document(); + KisImageSP img = doc->newImage("Readbytes ", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA",""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + TQ_UINT8 * newData = new TQ_UINT8[1000 * 1000 * l->pixelSize()]; + Q_CHECK_PTR(newData); + l->readBytes(newData, 0, 0, 1000, 1000); + delete[] newData; + } + + report = report.append(TQString(" read 1000 x 1000 pixels %1 times from empty image: %2\n").tqarg(testCount).tqarg(t.elapsed())); + + // On tiles with data + + KisFillPainter p(l.data()); + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + TQ_UINT8 * newData = new TQ_UINT8[1000 * 1000 * l->pixelSize()]; + Q_CHECK_PTR(newData); + l->readBytes(newData, 0, 0, 1000, 1000); + delete[] newData; + } + + report = report.append(TQString(" read 1000 x 1000 pixels %1 times from filled image: %2\n").tqarg(testCount).tqarg(t.elapsed())); + + return report; +} + + +TQString PerfTest::writeBytesTest(TQ_UINT32 testCount) +{ + TQString report = TQString("* Write bytes test"); + + // On default tiles + KisDoc * doc = m_view->canvasSubject()->document(); + KisImageSP img = doc->newImage("Writebytes ", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + KisFillPainter p(l.data()); + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + + TQ_UINT8 * data = new TQ_UINT8[1000 * 1000 * l->pixelSize()]; + Q_CHECK_PTR(data); + l->readBytes(data, 0, 0, 1000, 1000); + + TQTime t; + t.restart(); + for (TQ_UINT32 i = 0; i < testCount; ++i) { + l->writeBytes(data, 0, 0, 1000, 1000); + } + delete[] data; + report = report.append(TQString(" written 1000 x 1000 pixels %1 times: %2\n").tqarg(testCount).tqarg(t.elapsed())); + return report; + + +} + +/////// Iterator tests + + +TQString hlineRODefault(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + TQTime t; + t.restart(); + + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + int adv; + + for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) + { + KisHLineIterator hiter = l->createHLineIterator(0, y2, 1000, false); + while(! hiter.isDone()) + { + adv = hiter.nConseqHPixels(); + hiter += adv; + } + } + + } + + return TQString(" hline iterated read-only 1000 x 1000 pixels %1 times over default tile: %2\n").tqarg(testCount).tqarg(t.elapsed()); + + +} + +TQString hlineRO(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + KisFillPainter p(l.data()); + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + int adv; + + for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) + { + KisHLineIterator hiter = l->createHLineIterator(0, y2, 1000, false); + while(! hiter.isDone()) + { + adv = hiter.nConseqHPixels(); + hiter += adv; + } + } + + } + + return TQString(" hline iterated read-only 1000 x 1000 pixels %1 times over existing tile: %2\n").tqarg(testCount).tqarg(t.elapsed()); + +} + +TQString hlineWRDefault(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + int adv; + + for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) + { + KisHLineIterator hiter = l->createHLineIterator(0, y2, 1000, true); + while(! hiter.isDone()) + { + adv = hiter.nConseqHPixels(); + hiter += adv; + } + } + + } + + return TQString(" hline iterated writable 1000 x 1000 pixels %1 times over default tile: %2\n").tqarg(testCount).tqarg(t.elapsed()); + +} + +TQString hlineWR(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + KisFillPainter p(l.data()); + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + int adv; + for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) + { + KisHLineIterator hiter = l->createHLineIterator(0, y2, 1000, true); + while(! hiter.isDone()) + { + adv = hiter.nConseqHPixels(); + hiter += adv; + } + } + + } + + return TQString(" hline iterated writable 1000 x 1000 pixels %1 times over existing tile: %2\n").tqarg(testCount).tqarg(t.elapsed()); + +} + + +TQString vlineRODefault(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) + { + KisVLineIterator hiter = l->createVLineIterator(y2, 0, 1000, true); + while(! hiter.isDone()) + { + ++hiter; + } + } + + } + + return TQString(" vline iterated read-only 1000 x 1000 pixels %1 times over default tile: %2\n").tqarg(testCount).tqarg(t.elapsed()); + +} + +TQString vlineRO(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + KisFillPainter p(l.data()); + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) + { + KisVLineIterator hiter = l->createVLineIterator(y2, 0, 1000, true); + while(! hiter.isDone()) + { + ++hiter; + } + } + + } + + return TQString(" vline iterated read-only 1000 x 1000 pixels %1 times over existing tile: %2\n").tqarg(testCount).tqarg(t.elapsed()); + +} + +TQString vlineWRDefault(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + + for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) + { + KisVLineIterator hiter = l->createVLineIterator(y2, 0, 1000, true); + while(! hiter.isDone()) + { + ++hiter; + } + } + + } + + return TQString(" vline iterated writable 1000 x 1000 pixels %1 times over default tile: %2\n").tqarg(testCount).tqarg(t.elapsed()); +} + +TQString vlineWR(KisDoc * doc, TQ_UINT32 testCount) +{ + + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + KisFillPainter p(l.data()); + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + for(TQ_INT32 y2 = 0; y2 < 0 + 1000; y2++) + { + KisHLineIterator hiter = l->createHLineIterator(y2, 0, 1000, true); + while(! hiter.isDone()) + { + ++hiter; + } + } + + } + + return TQString(" vline iterated writable 1000 x 1000 pixels %1 times over existing tile: %2\n").tqarg(testCount).tqarg(t.elapsed()); + +} + +TQString rectRODefault(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); +; + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + KisRectIterator r = l->createRectIterator(0, 0, 1000, 1000, false); + while(! r.isDone()) + { + ++r; + } + } + + return TQString(" rect iterated read-only 1000 x 1000 pixels %1 times over default tile: %2\n").tqarg(testCount).tqarg(t.elapsed()); + + +} + +TQString rectRO(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + KisFillPainter p(l.data()); + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + KisRectIterator r = l->createRectIterator(0, 0, 1000, 1000, false); + while(! r.isDone()) + { + ++r; + } + } + + return TQString(" rect iterated read-only 1000 x 1000 pixels %1 times over existing tile: %2\n").tqarg(testCount).tqarg(t.elapsed()); + +} + +TQString rectWRDefault(KisDoc * doc, TQ_UINT32 testCount) +{ + + + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + TQTime t; + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + KisRectIterator r = l->createRectIterator(0, 0, 1000, 1000, true); + while(! r.isDone()) + { + ++r; + } + } + + return TQString(" rect iterated writable 1000 x 1000 pixels %1 times over default tile: %2\n").tqarg(testCount).tqarg(t.elapsed()); + +} + +TQString rectWR(KisDoc * doc, TQ_UINT32 testCount) +{ + KisImageSP img = doc->newImage("", 1000, 1000, KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""),"")); + KisPaintDeviceSP l = img->activeDevice(); + + KisFillPainter p(l.data()); + p.fillRect(0, 0, 1000, 1000, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + + TQTime t; + t.restart(); + + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + KisRectIterator r = l->createRectIterator(0, 0, 1000, 1000, true); + while(! r.isDone()) + { + ++r; + } + } + + + return TQString(" rect iterated writable 1000 x 1000 pixels %1 times over existing tile: %2\n").tqarg(testCount).tqarg(t.elapsed()); + + +} +TQString PerfTest::iteratorTest(TQ_UINT32 testCount) +{ + TQString report = "Iterator test"; + + KisDoc * doc = m_view->canvasSubject()->document(); + + report = report.append(hlineRODefault(doc, testCount)); + report = report.append(hlineRO(doc, testCount)); + report = report.append(hlineWRDefault(doc, testCount)); + report = report.append(hlineWR(doc, testCount)); + + report = report.append(vlineRODefault(doc, testCount)); + report = report.append(vlineRO(doc, testCount)); + report = report.append(vlineWRDefault(doc, testCount)); + report = report.append(vlineWR(doc, testCount)); + + report = report.append(rectRODefault(doc, testCount)); + report = report.append(rectRO(doc, testCount)); + report = report.append(rectWRDefault(doc, testCount)); + report = report.append(rectWR(doc, testCount)); + + return report; + + +} + +TQString PerfTest::paintViewTest(TQ_UINT32 testCount) +{ + TQString report = TQString("* paintView test\n\n"); + + KisDoc * doc = m_view->canvasSubject()->document(); + + KisImageSP img = doc->currentImage(); + img->resize(512,512); + + + KisPaintDeviceSP l = img->activeDevice(); + + KisFillPainter p(l.data()); + p.fillRect(0, 0, 512, 512, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + TQTime t; + t.restart(); + +#if USE_CALLGRIND + CALLGRIND_ZERO_STATS(); +#endif + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + m_view->getCanvasController()->updateCanvas(TQRect(0, 0, 512, 512)); + } + +#if USE_CALLGRIND + CALLGRIND_DUMP_STATS(); +#endif + + report = report.append(TQString(" painted a 512 x 512 image %1 times: %2 ms\n").tqarg(testCount).tqarg(t.elapsed())); + + img->newLayer("layer 2", OPACITY_OPAQUE); + l = img->activeDevice(); + + p.begin(l.data()); + p.fillRect(0, 0, 512, 512, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + img->newLayer("layer 3", OPACITY_OPAQUE); + l = img->activeDevice(); + + p.begin(l.data()); + p.fillRect(0, 0, 512, 512, KisColor(TQt::black, KisMetaRegistry::instance()->csRegistry()->getRGB8())); + p.end(); + + t.restart(); + + for (TQ_UINT32 i = 0; i < testCount; ++i) { + m_view->getCanvasController()->updateCanvas(TQRect(0, 0, 512, 512)); + } + + report = report.append(TQString(" painted a 512 x 512 image with 3 layers %1 times: %2 ms\n").tqarg(testCount).tqarg(t.elapsed())); + + return report; +} + +TQString PerfTest::paintViewFPSTest() +{ + TQString report = TQString("* paintView (fps) test\n\n"); + + TQTime t; + t.restart(); + +#if USE_CALLGRIND + CALLGRIND_ZERO_STATS(); +#endif + + int numViewsPainted = 0; + const int millisecondsPerSecond = 1000; + + while (t.elapsed() < millisecondsPerSecond) { + m_view->getCanvasController()->updateCanvas(); + numViewsPainted++; + } + +#if USE_CALLGRIND + CALLGRIND_DUMP_STATS(); +#endif + + report = report.append(TQString(" painted current view at %1 frames per second\n").tqarg(numViewsPainted)); + + return report; +} + +#include "perftest.moc" diff --git a/chalk/plugins/viewplugins/performancetest/perftest.h b/chalk/plugins/viewplugins/performancetest/perftest.h new file mode 100644 index 00000000..5bae3c8c --- /dev/null +++ b/chalk/plugins/viewplugins/performancetest/perftest.h @@ -0,0 +1,76 @@ +/* + * perftest.h -- Part of Chalk + * + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PERFTEST_H_ +#define PERFTEST_H_ + +#include <kparts/plugin.h> +#include <kis_types.h> +#include <kis_global.h> + +class KisView; +class KisID; + +class PerfTest : public KParts::Plugin +{ + Q_OBJECT + TQ_OBJECT +public: + PerfTest(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~PerfTest(); + +private slots: + + void slotPerfTest(); + +private: + + TQString bltTest(TQ_UINT32 testCount); + TQString fillTest(TQ_UINT32 testCount); + TQString gradientTest(TQ_UINT32 testCount); + TQString pixelTest(TQ_UINT32 testCount); + TQString tqshapeTest(TQ_UINT32 testCount); + TQString layerTest(TQ_UINT32 testCount); + TQString scaleTest(TQ_UINT32 testCount); + TQString rotateTest(TQ_UINT32 testCount); + TQString renderTest(TQ_UINT32 restCount); + TQString selectionTest(TQ_UINT32 testCount); + TQString colorConversionTest(TQ_UINT32 testCount); + TQString filterTest(TQ_UINT32 testCount); + TQString readBytesTest(TQ_UINT32 testCount); + TQString writeBytesTest(TQ_UINT32 testCount); + TQString iteratorTest(TQ_UINT32 testCount); + TQString paintViewTest(TQ_UINT32 testCount); + TQString paintViewFPSTest(); + + TQString doBlit(const KisCompositeOp& op, + KisID cspace, + TQ_UINT8 opacity, + TQ_UINT32 testCount, + KisImageSP img); + +private: + + KisView * m_view; + KisPainter * m_painter; + +}; + +#endif // PERFTEST_H_ diff --git a/chalk/plugins/viewplugins/performancetest/perftest.rc b/chalk/plugins/viewplugins/performancetest/perftest.rc new file mode 100644 index 00000000..de404a34 --- /dev/null +++ b/chalk/plugins/viewplugins/performancetest/perftest.rc @@ -0,0 +1,9 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkperftest" version="1"> +<MenuBar> + <Menu name="Tools"><text>&Tools</text> + <Separator/> + <Action name="perf_test"/> + </Menu> +</MenuBar> +</kpartgui>
\ No newline at end of file diff --git a/chalk/plugins/viewplugins/performancetest/wdg_perftest.ui b/chalk/plugins/viewplugins/performancetest/wdg_perftest.ui new file mode 100644 index 00000000..7dc14f17 --- /dev/null +++ b/chalk/plugins/viewplugins/performancetest/wdg_perftest.ui @@ -0,0 +1,283 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>WdgPerfTest</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgPerfTest</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>377</width> + <height>566</height> + </rect> + </property> + <property name="caption"> + <string>Image Size</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQButtonGroup" row="0" column="0"> + <property name="name"> + <cstring>grpPerfTest</cstring> + </property> + <property name="title"> + <string>&Performance Test</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>lblTests</cstring> + </property> + <property name="text"> + <string>Number of tests:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>intWidth</cstring> + </property> + </widget> + <widget class="TQCheckBox" row="1" column="0"> + <property name="name"> + <cstring>chkBitBlt</cstring> + </property> + <property name="text"> + <string>bitBlt</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQCheckBox" row="2" column="0"> + <property name="name"> + <cstring>chkFill</cstring> + </property> + <property name="text"> + <string>Fill</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQCheckBox" row="3" column="0"> + <property name="name"> + <cstring>chkGradient</cstring> + </property> + <property name="text"> + <string>Gradients</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQCheckBox" row="4" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>chkPixel</cstring> + </property> + <property name="text"> + <string>setPixel/getPixel</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQCheckBox" row="5" column="0"> + <property name="name"> + <cstring>chkShape</cstring> + </property> + <property name="text"> + <string>Shapes</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQCheckBox" row="6" column="0"> + <property name="name"> + <cstring>chkLayer</cstring> + </property> + <property name="text"> + <string>Layers</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQCheckBox" row="7" column="0"> + <property name="name"> + <cstring>chkScale</cstring> + </property> + <property name="text"> + <string>Scaling</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQCheckBox" row="8" column="0"> + <property name="name"> + <cstring>chkRotate</cstring> + </property> + <property name="text"> + <string>Rotating</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQCheckBox" row="9" column="0"> + <property name="name"> + <cstring>chkRender</cstring> + </property> + <property name="text"> + <string>Rendering</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQCheckBox" row="10" column="0"> + <property name="name"> + <cstring>chkSelection</cstring> + </property> + <property name="text"> + <string>Selection</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQCheckBox" row="11" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>chkColorConversion</cstring> + </property> + <property name="text"> + <string>Color conversion</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQCheckBox" row="12" column="0"> + <property name="name"> + <cstring>chkFilter</cstring> + </property> + <property name="text"> + <string>Filters</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="KIntNumInput" row="0" column="1"> + <property name="name"> + <cstring>intTestCount</cstring> + </property> + <property name="value"> + <number>10</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="maxValue"> + <number>1000000</number> + </property> + </widget> + <widget class="TQCheckBox" row="13" column="0"> + <property name="name"> + <cstring>chkReadBytes</cstring> + </property> + <property name="text"> + <string>Read bytes</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQCheckBox" row="14" column="0"> + <property name="name"> + <cstring>chkWriteBytes</cstring> + </property> + <property name="text"> + <string>Write bytes</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQCheckBox" row="15" column="0"> + <property name="name"> + <cstring>chkIterators</cstring> + </property> + <property name="text"> + <string>Iterators</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQCheckBox" row="16" column="0"> + <property name="name"> + <cstring>chkPaintView</cstring> + </property> + <property name="text"> + <string>PaintView</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLayoutWidget" row="18" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>tqlayout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQPushButton"> + <property name="name"> + <cstring>btnSelectAll</cstring> + </property> + <property name="text"> + <string>&Select All</string> + </property> + </widget> + <widget class="TQPushButton"> + <property name="name"> + <cstring>btnDeselectAll</cstring> + </property> + <property name="text"> + <string>&Deselect All</string> + </property> + </widget> + </hbox> + </widget> + <widget class="TQCheckBox" row="17" column="0"> + <property name="name"> + <cstring>chkPaintViewFPS</cstring> + </property> + <property name="text"> + <string>PaintView (fps)</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + </grid> +</widget> +<tabstops> + <tabstop>intTestCount</tabstop> +</tabstops> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> +</includehints> +</UI> diff --git a/chalk/plugins/viewplugins/rotateimage/Makefile.am b/chalk/plugins/viewplugins/rotateimage/Makefile.am new file mode 100644 index 00000000..d4ff4e63 --- /dev/null +++ b/chalk/plugins/viewplugins/rotateimage/Makefile.am @@ -0,0 +1,25 @@ +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = rotateimage.rc + +EXTRA_DIST = $(chalkrc_DATA) + + +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +kde_module_LTLIBRARIES = chalkrotateimage.la + +chalkrotateimage_la_SOURCES = wdg_rotateimage.ui rotateimage.cc dlg_rotateimage.cc +noinst_HEADERS = wdg_rotateimage.h dlg_rotateimage.h rotateimage.h + +chalkrotateimage_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) chalkblurfilter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui +chalkrotateimage_la_LIBADD = ../../../libchalkcommon.la + +kde_services_DATA = chalkrotateimage.desktop + +chalkrotateimage_la_METASOURCES = AUTO diff --git a/chalk/plugins/viewplugins/rotateimage/chalkrotateimage.desktop b/chalk/plugins/viewplugins/rotateimage/chalkrotateimage.desktop new file mode 100644 index 00000000..e855492e --- /dev/null +++ b/chalk/plugins/viewplugins/rotateimage/chalkrotateimage.desktop @@ -0,0 +1,40 @@ +[Desktop Entry] +Name=Rotate Image Plugin +Name[bg]=Приставка за въртене на изображение +Name[ca]=Connector de rotació d'imatge +Name[da]=Plugin for rotering af billede +Name[de]="Bild rotieren"-Modul +Name[el]=Πρόσθετο περιστροφής εικόνας +Name[es]=Complemento para girar la imagen +Name[et]=Pildi pööramise plugin +Name[fa]=چرخش وصلۀ تصویر +Name[fr]=Module de rotation d'images +Name[fy]=Plugin foar ôfbyldingsrotaasje +Name[gl]=Plugin para Rodar a Imaxe +Name[he]=תוסף לשינוי גודל של תמונה +Name[hu]=Képelforgató modul +Name[is]=Snúa mynd íforrit +Name[it]=Plugin per ruotare le immagini +Name[ja]=画像回転プラグイン +Name[km]=កម្មវិធីត្រឡប់រូបភាព +Name[nb]=Programtillegg for bilderotering +Name[nds]=Moduul för't Bilddreihen +Name[ne]=छवि प्लगइन परिक्रमा गर्नुहोस् +Name[nl]=Plugin voor afbeeldingrotatie +Name[pl]=Wtyczka obrotu obrazków +Name[pt]='Plugin' para Rodar a Imagem +Name[pt_BR]=Plugin para Rodar a Imagem +Name[ru]=Модуль вращения +Name[sk]=Modul rotácia obrázkov +Name[sl]=Vstavek za vrtenje slike +Name[sr]=Прикључак за ротирање слике +Name[sr@Latn]=Priključak za rotiranje slike +Name[sv]=Insticksprogram för rotera bild +Name[uk]=Втулок обертання зображень +Name[uz]=Rasmni burish plagini +Name[uz@cyrillic]=Расмни буриш плагини +Name[zh_TW]=旋轉圖片外掛程式 +ServiceTypes=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkrotateimage +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/rotateimage/dlg_rotateimage.cc b/chalk/plugins/viewplugins/rotateimage/dlg_rotateimage.cc new file mode 100644 index 00000000..6e3cc9f7 --- /dev/null +++ b/chalk/plugins/viewplugins/rotateimage/dlg_rotateimage.cc @@ -0,0 +1,147 @@ +/* + * dlg_rotateimage.cc - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <config.h> + +#include <math.h> + +#include <iostream> + +using namespace std; + +#include <tqgroupbox.h> +#include <tqradiobutton.h> +#include <tqcheckbox.h> +#include <tqlabel.h> + +#include <klocale.h> +#include <knuminput.h> +#include <kdebug.h> + +#include "dlg_rotateimage.h" +#include "wdg_rotateimage.h" + + +DlgRotateImage::DlgRotateImage( TQWidget * tqparent, + const char * name) + : super (tqparent, name, true, i18n("Rotate Image"), Ok | Cancel, Ok) +{ + m_lock = false; + + m_page = new WdgRotateImage(this, "rotate_image"); + Q_CHECK_PTR(m_page); + + setMainWidget(m_page); + resize(m_page->tqsizeHint()); + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); + connect( m_page->doubleCustom, TQT_SIGNAL( valueChanged ( double ) ), + this, TQT_SLOT( slotAngleValueChanged( double ) ) ); + +} + +DlgRotateImage::~DlgRotateImage() +{ + delete m_page; +} + +void DlgRotateImage::slotAngleValueChanged( double ) +{ + m_page->radioCustom->setChecked(true); +} + +void DlgRotateImage::setAngle(double angle) +{ + if (angle == 90) { + m_page->radio90->setChecked(true); + } + else if (angle == 180) { + m_page->radio180->setChecked(true); + } + else if (angle == 270) { + m_page->radio270->setChecked(true); + } + else { + m_page->radioCustom->setChecked(true); + m_page->doubleCustom->setValue(angle); + } + + if (m_oldAngle != angle) + resetPreview(); + + m_oldAngle = angle; + +} + +double DlgRotateImage::angle() +{ + double angle = 0; + if (m_page->radio90->isChecked()) { + angle = 90; + } + else if (m_page->radio180->isChecked()) { + angle = 180; + } + else if (m_page->radio270->isChecked()) { + angle = 270; + } + else { + angle = tqRound(m_page->doubleCustom->value()); + } + if (m_page->radioCW->isChecked()) { + return angle; + } + else { + return -angle; + } +} + +void DlgRotateImage::setDirection (enumRotationDirection direction) +{ + if (direction == CLOCKWISE) { + m_page->radioCW->setChecked(true); + } + else if (direction== COUNTERCLOCKWISE) { + m_page->radioCCW->setChecked(true); + } +} + +enumRotationDirection DlgRotateImage::direction() +{ + if (m_page->radioCCW->isChecked()) { + return COUNTERCLOCKWISE; + } + else { + return CLOCKWISE; + } +} + +void DlgRotateImage::okClicked() +{ + accept(); +} + +void DlgRotateImage::resetPreview() +{ + // Code to update preview here. +} + +#include "dlg_rotateimage.moc" diff --git a/chalk/plugins/viewplugins/rotateimage/dlg_rotateimage.h b/chalk/plugins/viewplugins/rotateimage/dlg_rotateimage.h new file mode 100644 index 00000000..47ddd344 --- /dev/null +++ b/chalk/plugins/viewplugins/rotateimage/dlg_rotateimage.h @@ -0,0 +1,66 @@ +/* + * dlg_rotateimage.h -- part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef DLG_ROTATEIMAGE +#define DLG_ROTATEIMAGE + +#include <kdialogbase.h> + +#include <kis_global.h> + +class WdgRotateImage; + +enum enumRotationDirection { + CLOCKWISE, + COUNTERCLOCKWISE +}; + + +class DlgRotateImage: public KDialogBase { + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + + DlgRotateImage(TQWidget * tqparent = 0, + const char* name = 0); + ~DlgRotateImage(); + + void setAngle(double w); + double angle(); + + void setDirection (enumRotationDirection direction); + enumRotationDirection direction(); + +private slots: + + void okClicked(); + void resetPreview(); + void slotAngleValueChanged( double ); + +private: + + WdgRotateImage * m_page; + double m_oldAngle; + bool m_lock; + +}; + +#endif // DLG_ROTATEIMAGE diff --git a/chalk/plugins/viewplugins/rotateimage/rotateimage.cc b/chalk/plugins/viewplugins/rotateimage/rotateimage.cc new file mode 100644 index 00000000..e8961cec --- /dev/null +++ b/chalk/plugins/viewplugins/rotateimage/rotateimage.cc @@ -0,0 +1,134 @@ +/* + * rotateimage.cc -- Part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include <math.h> + +#include <stdlib.h> + +#include <tqslider.h> +#include <tqpoint.h> + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> + +#include <kis_doc.h> +#include <kis_config.h> +#include <kis_image.h> +#include <kis_layer.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_view.h> +#include <kis_selection.h> + +#include "rotateimage.h" +#include "dlg_rotateimage.h" + +typedef KGenericFactory<RotateImage> RotateImageFactory; +K_EXPORT_COMPONENT_FACTORY( chalkrotateimage, RotateImageFactory( "chalk" ) ) + +// XXX: this plugin could also provide layer scaling/resizing +RotateImage::RotateImage(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + + if ( tqparent->inherits("KisView") ) { + setInstance(RotateImageFactory::instance()); + setXMLFile(locate("data","chalkplugins/rotateimage.rc"), true); + m_view = (KisView*) tqparent; + (void) new KAction(i18n("&Rotate Image..."), 0, 0, TQT_TQOBJECT(this), TQT_SLOT(slotRotateImage()), actionCollection(), "rotateimage"); + (void) new KAction(i18n("Rotate Image CW"), "rotate_cw", 0, TQT_TQOBJECT(this), TQT_SLOT(slotRotateImage90()), actionCollection(), "rotateImageCW90"); + (void) new KAction(i18n("Rotate Image 1&80"), 0, 0, TQT_TQOBJECT(this), TQT_SLOT(slotRotateImage180()), actionCollection(), "rotateImage180"); + (void) new KAction(i18n("Rotate Image CCW"), "rotate_ccw", 0, TQT_TQOBJECT(this), TQT_SLOT(slotRotateImage270()), actionCollection(), "rotateImageCCW90"); + + (void) new KAction(i18n("&Rotate Layer..."), 0, 0, TQT_TQOBJECT(this), TQT_SLOT(slotRotateLayer()), actionCollection(), "rotatelayer"); + + (void)new KAction(i18n("Rotate 1&80"), 0, TQT_TQOBJECT(m_view), TQT_SLOT(rotateLayer180()), actionCollection(), "rotateLayer180"); + (void)new KAction(i18n("Rotate CCW"), "rotate_ccw", 0, TQT_TQOBJECT(m_view), TQT_SLOT(rotateLayerLeft90()), actionCollection(), "rotateLayerCCW90"); + (void)new KAction(i18n("Rotate CW"), "rotate_cw", 0, TQT_TQOBJECT(m_view), TQT_SLOT(rotateLayerRight90()), actionCollection(), "rotateLayerCW90"); + } +} + +RotateImage::~RotateImage() +{ + m_view = 0; +} + +void RotateImage::slotRotateImage() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgRotateImage * dlgRotateImage = new DlgRotateImage(m_view, "RotateImage"); + Q_CHECK_PTR(dlgRotateImage); + + dlgRotateImage->setCaption(i18n("Rotate Image")); + + if (dlgRotateImage->exec() == TQDialog::Accepted) { + double angle = dlgRotateImage->angle(); + angle *= M_PI/180; + m_view->rotateCurrentImage(angle); + } + delete dlgRotateImage; +} + +void RotateImage::slotRotateImage90() +{ + m_view->rotateCurrentImage( M_PI/2); +} + +void RotateImage::slotRotateImage180() +{ + m_view->rotateCurrentImage( M_PI ); +} + + +void RotateImage::slotRotateImage270() +{ + m_view->rotateCurrentImage( - M_PI/2 + M_PI*2 ); +} + +void RotateImage::slotRotateLayer() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgRotateImage * dlgRotateImage = new DlgRotateImage(m_view, "RotateLayer"); + Q_CHECK_PTR(dlgRotateImage); + + dlgRotateImage->setCaption(i18n("Rotate Layer")); + + if (dlgRotateImage->exec() == TQDialog::Accepted) { + double angle = dlgRotateImage->angle(); + angle *= M_PI/180; + m_view->rotateLayer(angle); + } + delete dlgRotateImage; +} + +#include "rotateimage.moc" diff --git a/chalk/plugins/viewplugins/rotateimage/rotateimage.h b/chalk/plugins/viewplugins/rotateimage/rotateimage.h new file mode 100644 index 00000000..6b262608 --- /dev/null +++ b/chalk/plugins/viewplugins/rotateimage/rotateimage.h @@ -0,0 +1,50 @@ +/* + * rotateimage.h -- Part of Chalk + * + * Copyright (c) 2004 Michael Thaler (michael.thaler@physik.tu-muenchen.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef ROTATEIMAGE_H +#define ROTATEIMAGE_H + +#include <kparts/plugin.h> + +class KisView; + +class RotateImage : public KParts::Plugin +{ + Q_OBJECT + TQ_OBJECT +public: + RotateImage(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~RotateImage(); + +private slots: + + void slotRotateImage(); + void slotRotateImage90(); + void slotRotateImage180(); + void slotRotateImage270(); + void slotRotateLayer(); + +private: + + KisView * m_view; + KisPainter * m_painter; + +}; + +#endif // ROTATEIMAGE_H diff --git a/chalk/plugins/viewplugins/rotateimage/rotateimage.rc b/chalk/plugins/viewplugins/rotateimage/rotateimage.rc new file mode 100644 index 00000000..78ae6f4f --- /dev/null +++ b/chalk/plugins/viewplugins/rotateimage/rotateimage.rc @@ -0,0 +1,25 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkrotateimage" version="7"> +<MenuBar> + <Menu name="Image"><text>&Image</text> + <Menu name="Rotate"><text>&Rotate</text> + <Action name="rotateimage"/> + <Separator /> + <Action name="rotateImageCW90"/> + <Action name="rotateImageCCW90"/> + <Action name="rotateImage180"/> + </Menu> + </Menu> + + <Menu name="Layer"><text>La&yer</text> + <Menu name="Rotate"><text>&Rotate</text> + <Action name="rotatelayer"/> + <Separator /> + <Action name="rotateLayerCW90"/> + <Action name="rotateLayerCCW90"/> + <Action name="rotateLayer180"/> + </Menu> + </Menu> +</MenuBar> + +</kpartgui> diff --git a/chalk/plugins/viewplugins/rotateimage/wdg_rotateimage.ui b/chalk/plugins/viewplugins/rotateimage/wdg_rotateimage.ui new file mode 100644 index 00000000..d58c458d --- /dev/null +++ b/chalk/plugins/viewplugins/rotateimage/wdg_rotateimage.ui @@ -0,0 +1,245 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgRotateImage</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgRotateImage</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>489</width> + <height>447</height> + </rect> + </property> + <property name="caption"> + <string>Rotate Image</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQButtonGroup" row="0" column="0"> + <property name="name"> + <cstring>grpDirection</cstring> + </property> + <property name="title"> + <string>Direction</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>tqlayout6</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQLabel"> + <property name="name"> + <cstring>pixmapLabel1</cstring> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>false</bool> + </property> + <property name="tqalignment"> + <set>AlignCenter</set> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>41</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQLabel"> + <property name="name"> + <cstring>pixmapLabel2</cstring> + </property> + <property name="pixmap"> + <pixmap>image1</pixmap> + </property> + <property name="scaledContents"> + <bool>false</bool> + </property> + <property name="tqalignment"> + <set>AlignCenter</set> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>31</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="TQRadioButton" row="1" column="1"> + <property name="name"> + <cstring>radioCW</cstring> + </property> + <property name="text"> + <string>C&lockwise</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQRadioButton" row="1" column="0"> + <property name="name"> + <cstring>radioCCW</cstring> + </property> + <property name="text"> + <string>Cou&nter-clockwise</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQButtonGroup" row="1" column="0"> + <property name="name"> + <cstring>grpAngle</cstring> + </property> + <property name="title"> + <string>Angle</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radio90</cstring> + </property> + <property name="text"> + <string>90 &degrees</string> + </property> + </widget> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radio180</cstring> + </property> + <property name="text"> + <string>180 d&egrees</string> + </property> + </widget> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radio270</cstring> + </property> + <property name="text"> + <string>270 de&grees</string> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radioCustom</cstring> + </property> + <property name="text"> + <string>&Custom:</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="KDoubleSpinBox"> + <property name="name"> + <cstring>doubleCustom</cstring> + </property> + <property name="maxValue"> + <number>360</number> + </property> + <property name="lineStep"> + <number>1</number> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <spacer row="2" column="0"> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>91</height> + </size> + </property> + </spacer> + </grid> +</widget> +<customwidgets> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="371">89504e470d0a1a0a0000000d494844520000002c0000002e0806000000534cfb0a0000013a494441545885ed994b0ec330084487aaf7bf32dd5689297f9b489d6d24fc3c02db106266a445c460a67c205daf7404a2821ddb9503de0c0b64800fc00251e043b00040eea28bc21615a50fb8cad904bc1db8230d02e0671cbeca01ee2bbaaecbc16184bfe8a405b4cd58a00c86c48eb588d3cc54b1a9f8c5114d0f0d5c81ce5dcd999c0e42e71f3f5dd0826245572dc9d1c586f20e57a8ed1cdead85f373808d2ecf01366a16f0cae54b5acc0236e80fdcadc701bfc52f99c77ae35065edf0c1ae58d31d78302c302d870d9dcc2c6083e4a2bbaa7b3a694cc5bbc39bc6a626a5dec39dc5e888bd06965cee8076741b40a4e82aa103b164e0442b6ed2af183fd6d69b500dce5ba4c978b6aeb962cc5434aa3a3b6efd56794fd7793e3b62d74d2f23da3ef939f0bfa36e54557d9a48cb8c98ad39f4b8e7e5e3803f91a1a32701eeec170000000049454e44ae426082</data> + </image> + <image name="image1"> + <data format="PNG" length="363">89504e470d0a1a0a0000000d494844520000002c0000002e0806000000534cfb0a00000132494441545885ed994b12032108449b54ee7f65b3cd5440f92a56a5f7326f5a11451a63608b8806c6a0689857068b5a446177f6020361e8fdc04008fa0c30e086a6b4a4f3ba664cc418704212013041fb80b340bfa5847e9b825680022687f549d70016d03aac815d7d988be1a87c6be015acb7dc3ac7cd8167b091734160acbc861bc2029e4a77101690f661c9dd840f46a577b8012cc00157edb749d239dcc45de0e4f1d2a927705235aad4e50e5fa03f70b56c0778ab227bba90ec7d1d167eb62f30c0423f81b9696856aa7b3bcc487fa7f3543ccb18e54cfe3adca914332ce7aff9c6d83cb0e47205b4f176634fba4c68472c1978b69633a09db7f2753330bb91128ca7eb5e56b5aaac316069b756573ce54cf5b8e65fd3d0769870e6c920305bfb1e659296541ef0265d77bcbc0ef803779f9c39421cd9b50000000049454e44ae426082</data> + </image> +</images> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>knuminput.h</includehint> +</includehints> +</UI> diff --git a/chalk/plugins/viewplugins/screenshot/Makefile.am b/chalk/plugins/viewplugins/screenshot/Makefile.am new file mode 100644 index 00000000..9887b7a2 --- /dev/null +++ b/chalk/plugins/viewplugins/screenshot/Makefile.am @@ -0,0 +1,27 @@ +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = screenshot-chalk.rc + +EXTRA_DIST = $(chalkrc_DATA) + +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +kde_module_LTLIBRARIES = chalkscreenshot.la + +chalkscreenshot_la_SOURCES = screenshot.cpp ksnapshot.cpp regiongrabber.cpp ksnapshotwidget.ui +noinst_HEADERS = screenshot.h ksnapshot.h regiongrabber.h ksnapshotwidget.h ksnapshotwidget.ui.h + +chalkscreenshot_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui -lkdeprint +chalkscreenshot_la_LIBADD = ../../../libchalkcommon.la + +kde_services_DATA = chalkscreenshot.desktop + +chalkscreenshot_la_METASOURCES = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kscreenshot_plugin.pot diff --git a/chalk/plugins/viewplugins/screenshot/chalkscreenshot.desktop b/chalk/plugins/viewplugins/screenshot/chalkscreenshot.desktop new file mode 100644 index 00000000..7b9b0d4b --- /dev/null +++ b/chalk/plugins/viewplugins/screenshot/chalkscreenshot.desktop @@ -0,0 +1,47 @@ +[Desktop Entry] +Name=Screenshot +Name[bg]=Снимка на екрана +Name[br]=Skrammpaker +Name[ca]=Captura de pantalla +Name[cy]=Sgrinlun +Name[da]=Skærmaftryk +Name[de]=Bildschirmphoto +Name[el]=Στιγμιότυπο οθόνης +Name[eo]=Ekrankopio +Name[es]=Captura de pantalla +Name[et]=Ekraanipilt +Name[fa]=تصویر پرده +Name[fr]=Capture d'écran +Name[fy]=Skermôfbylding +Name[ga]=Seat den Scáileán +Name[gl]=Captura de Pantalla +Name[he]=תמונת מסך +Name[hu]=Képernyőfelvétel +Name[is]=Skjámynd +Name[it]=Schermata +Name[ja]=スクリーンショット +Name[km]=រូបថតអេក្រង់ +Name[lv]=Ekrānattēls +Name[nb]=Skjermbilde +Name[nds]=Schirmbild +Name[ne]=स्क्रिनसट +Name[nl]=Schermafbeelding +Name[pl]=Zrzut ekranu +Name[pt]=Captura +Name[pt_BR]=Captura de Tela +Name[ru]=Снимок экрана +Name[se]=Šearbmagovva +Name[sk]=Snímač obrazovky +Name[sl]=Posnetek zaslona +Name[sr]=Снимак екрана +Name[sr@Latn]=Snimak ekrana +Name[sv]=Skärmdump +Name[uk]=Знімок екрана +Name[uz]=Skrinshot +Name[uz@cyrillic]=Скриншот +Name[zh_CN]=抓图 +Name[zh_TW]=螢幕快照 +ServiceTypes=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkscreenshot +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/screenshot/ksnapshot.cpp b/chalk/plugins/viewplugins/screenshot/ksnapshot.cpp new file mode 100644 index 00000000..f9887821 --- /dev/null +++ b/chalk/plugins/viewplugins/screenshot/ksnapshot.cpp @@ -0,0 +1,499 @@ +/* + * KSnapshot + * + * (c) Richard J. Moore 1997-2002 + * (c) Matthias Ettrich 2000 + * (c) Aaron J. Seigo 2002 + * (c) Nadeem Hasan 2003 + * This adaptation: (c) Boudewijn Rempt 2005 + * + * Released under the GPL see file LICENSE for details. + */ + +#include <kapplication.h> +#include <klocale.h> +#include <kimageio.h> +#include <kfiledialog.h> +#include <kimagefilepreview.h> +#include <kmessagebox.h> +#include <kdebug.h> +#include <kprinter.h> +#include <kio/netaccess.h> +#include <ksavefile.h> +#include <ktempfile.h> + +#include <tqbitmap.h> +#include <tqdragobject.h> +#include <tqimage.h> +#include <tqclipboard.h> +#include <tqvbox.h> + +#include <kaccel.h> +#include <knotifyclient.h> +#include <khelpmenu.h> +#include <kpopupmenu.h> +#include <kpushbutton.h> +#include <kstartupinfo.h> + +#include <tqcursor.h> +#include <tqregexp.h> +#include <tqpainter.h> +#include <tqpaintdevicemetrics.h> +#include <tqwhatsthis.h> + +#include <stdlib.h> + +#include "ksnapshot.h" +#include "regiongrabber.h" +#include "ksnapshotwidget.h" + +#include <X11/Xlib.h> +#include <X11/Xatom.h> + +#include <config.h> + +#ifdef HAVE_X11_EXTENSIONS_SHAPE_H +#include <X11/extensions/shape.h> +#endif + +#include <kglobal.h> + +KSnapshot::KSnapshot(TQWidget *tqparent, const char *name) + : super(tqparent, name, false, TQString(), Ok|Cancel) +{ + grabber = new TQWidget( 0, 0, WStyle_Customize | WX11BypassWM ); + Q_CHECK_PTR(grabber); + grabber->move( -1000, -1000 ); + grabber->installEventFilter( this ); + +#ifdef HAVE_X11_EXTENSIONS_SHAPE_H + int tmp1, tmp2; + //Check whether the extension is available + haveXShape = XShapeQueryExtension( qt_xdisplay(), &tmp1, &tmp2 ); +#endif + + TQVBox *vbox = makeVBoxMainWidget(); + mainWidget = new KSnapshotWidget( vbox, "mainWidget" ); + Q_CHECK_PTR(mainWidget); + + mainWidget->btnSave->hide(); + mainWidget->btnPrint->hide(); + connect(mainWidget, TQT_SIGNAL(startImageDrag()), TQT_SLOT(slotDragSnapshot())); + + connect( mainWidget, TQT_SIGNAL( newClicked() ), TQT_SLOT( slotGrab() ) ); + connect( mainWidget, TQT_SIGNAL( printClicked() ), TQT_SLOT( slotPrint() ) ); + + grabber->show(); + grabber->grabMouse( waitCursor ); + + snapshot = TQPixmap::grabWindow( qt_xrootwin() ); + updatePreview(); + grabber->releaseMouse(); + grabber->hide(); + + KConfig *conf=KGlobal::config(); + conf->setGroup("GENERAL"); + mainWidget->setDelay(conf->readNumEntry("delay",0)); + mainWidget->setMode( conf->readNumEntry( "mode", 0 ) ); + mainWidget->setIncludeDecorations(conf->readBoolEntry("includeDecorations",true)); + + connect( &grabTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( grabTimerDone() ) ); + + KAccel* accel = new KAccel(this); + Q_CHECK_PTR(accel); + accel->insert(KStdAccel::Print, TQT_TQOBJECT(this), TQT_SLOT(slotPrint())); + accel->insert(KStdAccel::New, TQT_TQOBJECT(this), TQT_SLOT(slotGrab())); + + accel->insert( "Print2", TQt::Key_P, TQT_TQOBJECT(this), TQT_SLOT(slotPrint())); + accel->insert( "New2", TQt::Key_N, TQT_TQOBJECT(this), TQT_SLOT(slotGrab())); + accel->insert( "New3", TQt::Key_Space, TQT_TQOBJECT(this), TQT_SLOT(slotGrab())); + + mainWidget->btnNew->setFocus(); + +} + +KSnapshot::~KSnapshot() +{ +} + +bool KSnapshot::save( const TQString &filename ) +{ + return save( KURL::fromPathOrURL( filename )); +} + +bool KSnapshot::save( const KURL& url ) +{ + TQString type( KImageIO::type(url.path()) ); + if ( type.isNull() ) + type = "PNG"; + + bool ok = false; + + if ( url.isLocalFile() ) { + KSaveFile saveFile( url.path() ); + if ( saveFile.status() == 0 ) { + if ( snapshot.save( saveFile.file(), type.latin1() ) ) + ok = saveFile.close(); + } + } + else { + KTempFile tmpFile; + tmpFile.setAutoDelete( true ); + if ( tmpFile.status() == 0 ) { + if ( snapshot.save( tmpFile.file(), type.latin1() ) ) { + if ( tmpFile.close() ) + ok = KIO::NetAccess::upload( tmpFile.name(), url, this ); + } + } + } + + TQApplication::restoreOverrideCursor(); + if ( !ok ) { + kdWarning() << "KSnapshot was unable to save the snapshot" << endl; + + TQString caption = i18n("Unable to Save Image"); + TQString text = i18n("KSnapshot was unable to save the image to\n%1.") + .tqarg(url.prettyURL()); + KMessageBox::error(this, text, caption); + } + + return ok; +} + +void KSnapshot::slotCopy() +{ + TQClipboard *cb = TQApplication::tqclipboard(); + cb->setPixmap( snapshot ); +} + +void KSnapshot::slotDragSnapshot() +{ + TQDragObject *drobj = new TQImageDrag(snapshot.convertToImage(), this); + Q_CHECK_PTR(drobj); + drobj->setPixmap(mainWidget->preview()); + drobj->dragCopy(); +} + +void KSnapshot::slotGrab() +{ + hide(); + if ( mainWidget->mode() == Region ) + { + rgnGrab = new RegionGrabber(); + Q_CHECK_PTR(rgnGrab); + connect( rgnGrab, TQT_SIGNAL( regionGrabbed( const TQPixmap & ) ), + TQT_SLOT( slotRegionGrabbed( const TQPixmap & ) ) ); + } + else + { + if ( mainWidget->delay() ) + grabTimer.start( mainWidget->delay() * 1000, true ); + else { + grabber->show(); + grabber->grabMouse( crossCursor ); + } + } +} + +void KSnapshot::slotPrint() +{ + KPrinter printer; + if (snapshot.width() > snapshot.height()) + printer.setOrientation(KPrinter::Landscape); + else + printer.setOrientation(KPrinter::Portrait); + + tqApp->processEvents(); + + if (printer.setup(this, i18n("Print Screenshot"))) + { + tqApp->processEvents(); + + TQPainter painter(&printer); + TQPaintDeviceMetrics metrics(painter.device()); + + float w = snapshot.width(); + float dw = w - metrics.width(); + float h = snapshot.height(); + float dh = h - metrics.height(); + bool scale = false; + + if ( (dw > 0.0) || (dh > 0.0) ) + scale = true; + + if ( scale ) { + + TQImage img = snapshot.convertToImage(); + tqApp->processEvents(); + + float newh, neww; + if ( dw > dh ) { + neww = w-dw; + newh = neww/w*h; + } + else { + newh = h-dh; + neww = newh/h*w; + } + + img = img.smoothScale( int(neww), int(newh), TQ_ScaleMin ); + tqApp->processEvents(); + + int x = (metrics.width()-img.width())/2; + int y = (metrics.height()-img.height())/2; + + painter.drawImage( x, y, img); + } + else { + int x = (metrics.width()-snapshot.width())/2; + int y = (metrics.height()-snapshot.height())/2; + painter.drawPixmap( x, y, snapshot ); + } + } + + tqApp->processEvents(); +} + +void KSnapshot::slotRegionGrabbed( const TQPixmap &pix ) +{ + if ( !pix.isNull() ) + { + snapshot = pix; + updatePreview(); + modified = true; + } + + delete rgnGrab; + TQApplication::restoreOverrideCursor(); + show(); +} + +bool KSnapshot::eventFilter( TQObject* o, TQEvent* e) +{ + if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(grabber) && e->type() == TQEvent::MouseButtonPress ) { + TQMouseEvent* me = (TQMouseEvent*) e; + if ( TQWidget::mouseGrabber() != grabber ) + return false; + if ( me->button() == Qt::LeftButton ) + performGrab(); + } + return false; +} + +void KSnapshot::updatePreview() +{ + TQImage img = snapshot.convertToImage(); + double r1 = ((double) snapshot.height() ) / snapshot.width(); + if ( r1 * mainWidget->previewWidth() < mainWidget->previewHeight() ) + img = img.smoothScale( mainWidget->previewWidth(), + int( mainWidget->previewWidth() * r1 )); + else + img = img.smoothScale( (int) (((double)mainWidget->previewHeight()) / r1), + (mainWidget->previewHeight() ) ); + + TQPixmap pm; + pm.convertFromImage( img ); + mainWidget->setPreview( pm ); +} + +void KSnapshot::grabTimerDone() +{ + performGrab(); + KNotifyClient::beep(i18n("The screen has been successfully grabbed.")); +} + +static +Window findRealWindow( Window w, int depth = 0 ) +{ + if( depth > 5 ) + return None; + static Atom wm_state = XInternAtom( qt_xdisplay(), "WM_STATE", False ); + Atom type; + int format; + unsigned long nitems, after; + unsigned char* prop; + if( XGetWindowProperty( qt_xdisplay(), w, wm_state, 0, 0, False, AnyPropertyType, + &type, &format, &nitems, &after, &prop ) == Success ) { + if( prop != NULL ) + XFree( prop ); + if( type != None ) + return w; + } + Window root, tqparent; + Window* tqchildren; + unsigned int ntqchildren; + Window ret = None; + if( XQueryTree( qt_xdisplay(), w, &root, &tqparent, &tqchildren, &ntqchildren ) != 0 ) { + for( unsigned int i = 0; + i < ntqchildren && ret == None; + ++i ) + ret = findRealWindow( tqchildren[ i ], depth + 1 ); + if( tqchildren != NULL ) + XFree( tqchildren ); + } + return ret; +} + +void KSnapshot::performGrab() +{ + grabber->releaseMouse(); + grabber->hide(); + grabTimer.stop(); + XGrabServer( qt_xdisplay()); + if ( mainWidget->mode() == WindowUnderCursor ) { + Window root; + Window child; + uint tqmask; + int rootX, rootY, winX, winY; + XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child, + &rootX, &rootY, &winX, &winY, + &tqmask); + if( child == None ) + child = qt_xrootwin(); + if( !mainWidget->includeDecorations()) { + Window real_child = findRealWindow( child ); + if( real_child != None ) // test just in case + child = real_child; + } + int x, y; + unsigned int w, h; + unsigned int border; + unsigned int depth; + XGetGeometry( qt_xdisplay(), child, &root, &x, &y, + &w, &h, &border, &depth ); + w += 2 * border; + h += 2 * border; + + Window tqparent; + Window* tqchildren; + unsigned int ntqchildren; + if( XQueryTree( qt_xdisplay(), child, &root, &tqparent, + &tqchildren, &ntqchildren ) != 0 ) { + if( tqchildren != NULL ) + XFree( tqchildren ); + int newx, newy; + Window dummy; + if( XTranslateCoordinates( qt_xdisplay(), tqparent, qt_xrootwin(), + x, y, &newx, &newy, &dummy )) { + x = newx; + y = newy; + } + } + + snapshot = TQPixmap::grabWindow( qt_xrootwin(), x, y, w, h ); + +#ifdef HAVE_X11_EXTENSIONS_SHAPE_H + //No XShape - no work. + if (haveXShape) { + TQBitmap tqmask(w, h); + //As the first step, get the tqmask from XShape. + int count, order; + XRectangle* rects = XShapeGetRectangles( qt_xdisplay(), child, + ShapeBounding, &count, &order); + //The ShapeBounding region is the outermost tqshape of the window; + //ShapeBounding - ShapeClipping is defined to be the border. + //Since the border area is part of the window, we use bounding + // to limit our work region + if (rects) { + //Create a TQRegion from the rectangles describing the bounding tqmask. + TQRegion contents; + for (int pos = 0; pos < count; pos++) + contents += TQRegion(rects[pos].x, rects[pos].y, + rects[pos].width, rects[pos].height); + XFree(rects); + + //Create the bounding box. + TQRegion bbox(0, 0, snapshot.width(), snapshot.height()); + + if( border > 0 ) { + contents.translate( border, border ); + contents += TQRegion( 0, 0, border, h ); + contents += TQRegion( 0, 0, w, border ); + contents += TQRegion( 0, h - border, w, border ); + contents += TQRegion( w - border, 0, border, h ); + } + + //Get the tqmasked away area. + TQRegion tqmaskedAway = bbox - contents; + TQMemArray<TQRect> tqmaskedAwayRects = tqmaskedAway.rects(); + + //Construct a bitmap tqmask from the rectangles + TQPainter p(&tqmask); + p.fillRect(0, 0, w, h, TQt::color1); + for (uint pos = 0; pos < tqmaskedAwayRects.count(); pos++) + p.fillRect(tqmaskedAwayRects[pos], TQt::color0); + p.end(); + + snapshot.setMask(tqmask); + } + } +#endif + } + else { + snapshot = TQPixmap::grabWindow( qt_xrootwin() ); + } + XUngrabServer( qt_xdisplay()); + updatePreview(); + TQApplication::restoreOverrideCursor(); + modified = true; +// show(); + slotOk(); +} + +void KSnapshot::setTime(int newTime) +{ + mainWidget->setDelay(newTime); +} + +void KSnapshot::setURL( const TQString &url ) +{ + KURL newURL = KURL::fromPathOrURL( url ); + if ( newURL == filename ) + return; + + filename = newURL; +} + +void KSnapshot::setGrabMode( int m ) +{ + mainWidget->setMode( m ); +} + +void KSnapshot::slotMovePointer(int x, int y) +{ + TQCursor::setPos( x, y ); +} + +void KSnapshot::exit() +{ + + KConfig *conf=KGlobal::config(); + conf->setGroup("GENERAL"); + conf->writeEntry("delay",mainWidget->delay()); + conf->writeEntry("mode",mainWidget->mode()); + conf->writeEntry("includeDecorations",mainWidget->includeDecorations()); + KURL url = filename; + url.setPass( TQString() ); + conf->writePathEntry("filename",url.url()); + + reject(); +} + +void KSnapshot::slotOk() +{ + + KConfig *conf=KGlobal::config(); + conf->setGroup("GENERAL"); + conf->writeEntry("delay",mainWidget->delay()); + conf->writeEntry("mode",mainWidget->mode()); + conf->writeEntry("includeDecorations",mainWidget->includeDecorations()); + KURL url = filename; + url.setPass( TQString() ); + conf->writePathEntry("filename",url.url()); + + emit screenGrabbed(); + + accept(); +} + +#include "ksnapshot.moc" diff --git a/chalk/plugins/viewplugins/screenshot/ksnapshot.h b/chalk/plugins/viewplugins/screenshot/ksnapshot.h new file mode 100644 index 00000000..030cad12 --- /dev/null +++ b/chalk/plugins/viewplugins/screenshot/ksnapshot.h @@ -0,0 +1,137 @@ +// -*- c++ -*- +/* + * (c) Richard J. Moore 1997-2002 + * (c) Matthias Ettrich 2000 + * (c) Aaron J. Seigo 2002 + * (c) Nadeem Hasan 2003 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KSNAPSHOT_H +#define KSNAPSHOT_H + +#include <tqlabel.h> +#include <tqpixmap.h> +#include <tqtimer.h> + +#include <dcopclient.h> +#include <kglobalsettings.h> +#include <kdialogbase.h> +#include <kurl.h> + +class RegionGrabber; +class KSnapshotWidget; + +class KSnapshotThumb : public TQLabel +{ + Q_OBJECT + TQ_OBJECT + +public: + KSnapshotThumb(TQWidget *tqparent, const char *name = 0) + : TQLabel(tqparent, name) + { + tqsetAlignment(AlignHCenter | AlignVCenter); + } + virtual ~KSnapshotThumb() {} + +signals: + void startDrag(); + +protected: + void mousePressEvent(TQMouseEvent * e) + { + mClickPt = e->pos(); + } + + void mouseMoveEvent(TQMouseEvent * e) + { + if (mClickPt != TQPoint(0, 0) && + (e->pos() - mClickPt).manhattanLength() > KGlobalSettings::dndEventDelay()) + { + mClickPt = TQPoint(0, 0); + emit startDrag(); + } + } + + void mouseReleaseEvent(TQMouseEvent * /*e*/) + { + mClickPt = TQPoint(0, 0); + } + + TQPoint mClickPt; +}; + +class KSnapshot : public KDialogBase +{ + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + KSnapshot(TQWidget *tqparent= 0, const char *name= 0); + ~KSnapshot(); + + enum CaptureMode { FullScreen=0, WindowUnderCursor=1, Region=2 }; + + bool save( const TQString &filename ); + bool save( const KURL& url ); + + TQString url() const { return filename.url(); } + +signals: + void screenGrabbed(); + +protected slots: + void slotGrab(); + void slotCopy(); + void slotPrint(); + void slotMovePointer( int x, int y ); + + void setTime(int newTime); + void setURL(const TQString &newURL); + void setGrabMode( int m ); + void exit(); + + void slotOk(); + + +protected: + void reject() { close(); } + bool eventFilter( TQObject*, TQEvent* ); + +private slots: + void grabTimerDone(); + void slotDragSnapshot(); + void slotRegionGrabbed( const TQPixmap & ); + +private: + void updatePreview(); + void performGrab(); + void autoincFilename(); + + TQPixmap snapshot; + TQTimer grabTimer; + TQWidget* grabber; + KURL filename; + KSnapshotWidget *mainWidget; + RegionGrabber *rgnGrab; + bool modified; + bool haveXShape; +}; + +#endif // KSNAPSHOT_H + diff --git a/chalk/plugins/viewplugins/screenshot/ksnapshotwidget.ui b/chalk/plugins/viewplugins/screenshot/ksnapshotwidget.ui new file mode 100644 index 00000000..0672215e --- /dev/null +++ b/chalk/plugins/viewplugins/screenshot/ksnapshotwidget.ui @@ -0,0 +1,335 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>KSnapshotWidget</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>KSnapshotWidget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>358</width> + <height>241</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="KSnapshotThumb" row="0" column="0" rowspan="4" colspan="3"> + <property name="name"> + <cstring>lblImage</cstring> + </property> + <property name="tqminimumSize"> + <size> + <width>200</width> + <height>130</height> + </size> + </property> + <property name="toolTip" stdset="0"> + <string>Thumbnail of the current snapshot</string> + </property> + <property name="whatsThis" stdset="0"> + <string>This is a thumbnail of the current snapshot. + +The image can be dragged to another application or document to copy the full screenshot there. Try it with the Konqueror file manager.</string> + </property> + </widget> + <widget class="KPushButton" row="0" column="3"> + <property name="name"> + <cstring>btnNew</cstring> + </property> + <property name="text"> + <string>&New Snapshot</string> + </property> + <property name="iconSet"> + <iconset>"tool_screenshot"</iconset> + </property> + <property name="whatsThis" stdset="0"> + <string>Click this button to take a new snapshot.</string> + </property> + </widget> + <widget class="KPushButton" row="2" column="3"> + <property name="name"> + <cstring>btnSave</cstring> + </property> + <property name="text"> + <string>&Save As...</string> + </property> + <property name="iconSet"> + <iconset>"filesave"</iconset> + </property> + <property name="whatsThis" stdset="0"> + <string>Click this button to save the current snapshot. To quickly save the snapshot without showing the file dialog, press Ctrl+Shift+S. The filename is automatically incremented after each save.</string> + </property> + </widget> + <spacer row="1" column="3"> + <property name="name"> + <cstring>Spacer6</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="KPushButton" row="3" column="3"> + <property name="name"> + <cstring>btnPrint</cstring> + </property> + <property name="text"> + <string>&Print...</string> + </property> + <property name="iconSet"> + <iconset>"fileprint"</iconset> + </property> + <property name="whatsThis" stdset="0"> + <string>Click this button to print the current screenshot.</string> + </property> + </widget> + <widget class="Line" row="4" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>line1</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="TQSpinBox" row="6" column="1"> + <property name="name"> + <cstring>spinDelay</cstring> + </property> + <property name="suffix"> + <string> sec</string> + </property> + <property name="specialValueText"> + <string>No delay</string> + </property> + <property name="toolTip" stdset="0"> + <string>Snapshot delay in seconds</string> + </property> + <property name="whatsThis" stdset="0"> + <string><qt> +This is the number of seconds to wait after clicking the <i>New Snapshot</i> button before taking the snapshot. +<p> +This is very useful for getting windows, menus and other items on the screen set up just the way you want. +<p> +If <i>no delay</i> is set, the program will wait for a mouse click before taking a snapshot. +</p> +</qt></string> + </property> + </widget> + <widget class="TQLabel" row="6" column="0"> + <property name="name"> + <cstring>lblDelay</cstring> + </property> + <property name="text"> + <string>Snapshot &delay:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>spinDelay</cstring> + </property> + </widget> + <widget class="TQLabel" row="5" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Cap&ture mode:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>comboMode</cstring> + </property> + </widget> + <spacer row="6" column="2" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>156</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="TQCheckBox" row="7" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>cbIncludeDecorations</cstring> + </property> + <property name="text"> + <string>Include &window decorations</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>When enabled, snapshot of a window will also include the window decorations</string> + </property> + </widget> + <widget class="TQComboBox" row="5" column="1" rowspan="1" colspan="3"> + <item> + <property name="text"> + <string>Full Screen</string> + </property> + </item> + <item> + <property name="text"> + <string>Window Under Cursor</string> + </property> + </item> + <item> + <property name="text"> + <string>Region</string> + </property> + </item> + <property name="name"> + <cstring>comboMode</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string><qt>Using this menu, you can select from the three following snapshot modes: +<p> +<b>Full Screen</b> - captures the entire desktop.<br> +<b>Window Under Cursor</b> - captures only the window (or menu) that is under the mouse cursor when the snapshot is taken.<br> +<b>Region</b> - captures only the region of the desktop that you specify. When taking a new snapshot in this mode you will be able to select any area of the screen by clicking and dragging the mouse.</p></qt></string> + </property> + </widget> + <spacer row="8" column="1"> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>31</height> + </size> + </property> + </spacer> + </grid> +</widget> +<customwidgets> + <customwidget> + <class>KSnapshotThumb</class> + <header location="local">ksnapshot.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + <signal>startDrag()</signal> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="XPM.GZ" length="5230">789c9597db4e1d4b0e86eff31428be8b46b5fb54dd551acd051020211c4320c0682eecaa5e9ccf90005bf3ee53cbbfe9d9c9c548a38ea27c2977b5cbfe6dd7fae3c3c2e1cee6c2873fde3d3cf2e3595a48a77cbff0213f5d5dbdfcf35ffff8f3ddfba65998fff161a179ffb777ef771f17d2c2d6cdf53807c705a889cdac6ee72c47736eebd637b5f2b672d70ecd30e744ca7d9b9a4ad7579587363433e527e5d072abefbb03636978ceb4a31c5bc13a91716ad41f89e0aec2fe74abcc6d6ad5f9e4945357375ef75f997357751dd61d19c71afb61bdef421b951f274ebaffb6716cb3f2b2f230f18d3183dd95b1b441d7d59f2e94757ccf1b27eceff69563618d0f5dcfd9d7beeb7a5dd7f3fac6fb4ee32b87c619f1168d976f7d6ff6df26d6ef4b301e1bac7f54f63e747a5e87f5c173276aff605c22a8fefc540e5e3af5972f956359577bf2c6d978cb78d6697edc9eb2f8b143fed7945359d778b0e6c3e7be81bf7465dce23cf4ac3c16567f19fecefaae53bd081b7baccbb131b7d05f679ca03f27c6b9d1f388c6bbaffab7f80dca4d1fed7bfafdbeedb9533d490f1e2ae8d5693ccacb83d77cd027e3d4416faa97beefa3d7f8f086f168f9d9020f43a3f5c5aa877e28eb88f74fe319becfaa873e0c15de775f95639f3dec37c143d361bf2be3cef4b76bdcb7d84ff5d2cbd0227facf1ecd360fa67d54b9f078ffcd10f636e11ff53e3847853ad3c1b668837e9fe43358c2df45a81430b3db2e6676842d368fd48abdc068b87e0fd2e788bf792b21f861e7afd0e0e5ce37dcdd7d0872218e5d789f57b3218a71ae7bb501eca3af67b510e21c05fd27a1b6218ac3ef17d0ed68fe8cb1be3fc6e5159863ca0bfed824340fe687d62c4838c23f677f0370de380fcdd2be7e03dfab1d6cf300bcd80fa80bfb358dbf9547fa18abe413d68fe421d63ade7737aded094cf63fdcc38f4d0bfee17dac2d08380a3a0dff24cb90bdc23ffaa87e0636c912fed87612e38d4df1e982bc4dbdd29872001f14aca319413eb793e83cbfbe8af27606e4c0f5f8d3bcb7763ec6b8da73b57e69083d61f9d82b9b5fada31f635fcaf8d7b7b5ffb41f16e34ff34fe214dfc0c8e1ef1a22330bfcdc345e31e4c33e3c1e6e181b1609e3ac43f8759803e8cd9f2e7e0ff18ab80ef5d8239e2fc0ef129f90ff0bf0773347fee8d13ce279bc6b34af5c61abf58157bf4b765b05435f4abfec726968c2b67e536fa80fe388279067f680d2c750dff75fe9766da07e44bc02521ba4e1d584c1fb261dcc23fd97f63f8c3af136bfc687362c4e76962ed8fac7a2ecdb7853f7c63ec6bf467bd3fc421c680780c60b6f9275fc045aea84fadaf18a2e0fc04ff0237bd9e8fefc0d236e8ef3f8d83c57fdd38daf94edeb886be74fec618b3ed7f3731e66b0fe67a403e76c0454ef8de9231dbfe9f8dc5fc47be38a6887ad2f950964d2fdc1a27d3c7b6710693f6ef9864b4fdb4ffc6cc5540fea0972c339c87afc1c9f4443a5fe2c84d40bd2f82cb3ae6c7b1716dbc37b1e68bf5be118b7e3dead78125d87d0bfa99bd7d8fb78c1bdb4fcfcfd51bcb9d716bebda3fb8966cf7cf57709103f2e327c6fe5a2fdc4ab4fb01deef5283fa65d50ffb54c13fd67ec37d61e845fb070f8571df7c341eec7e7a691c6ae453fb771937d1fa999ebfa43358bf573d3327c6fdd0a9de59b87414e59f60911ef3ff07380d16bf0b63b6fbb8ce0f4e523a80ee8ff8a5f21fe83f384f2e8cf9d419db7d4bb4bff32cb1dd871ae38c79417962dd9f8f2786bfaa3fa992ddbf68d5d8d6797d62dc27b4bf4a9bdeee5be7c619efbb169c2b9bb7aa67e972857a67d59bf8943cf4a6f5237dae3b9c3f4f8cef5713637e6a3c6548e546a7eb87e0b28e7cf7c68ddd2fb15f28acf166bd2f484c19f921f8cbc57de84ff52c397b8f7e178d7bbb7f7e9f18f743d593ccd210d12f9e8c05fd8417c1e5e704e2afefa7aa5cf850ff4fc6a1473debfc4d7561c4ebd3c48897f69fd4e4d8eb7e4efb736a0b23fe9adfd465bb3f388d6ff22933fa1df6f7597ad483c62371f6e6ff8671b6f89e198fb8cfb0ea3f49619c6f6562cc27d5474a7906e6b589d1df549f29e78479450fe0b1c2fc67d5731a0ba33ffc97a167fd7d92ebb1b1f9a87acdcdd8a23ff2e3c4a81fed0fb91bbb88f8e9f772f9b9c6b8bfac187bd41febbcc8c35831f4bb6edc227eeec8b847bc58ef0f398d91a1179d6f391746bdebfd60ac4716b0180bd8a97e473f8ea2dfdb7d9c3f8e1cff8f8760057b27e57f92cb6e743377e24efff29cb97377e12edd55b190c99eddb5bb71b7eeceddbb07f7e89edc0ff7d33dbb17f7ea16dd925b761fdd8a63d8174f52b15e756bee93fbecd6dd17b7e136dd96db763b6ed77d2dd67bee9bdb77078ed49e8b27b7c5fabb3b7447eed855ae768d6bcbd339ef7a37b8e022392a2734fbd1dd119350a24c23cde8844ee98ccee9c2f9c2977445d77443b793fd8ceee89e1ee8919ee807fdb4e7995ee8b5d82fd252b15ffe8bfd097da4155aa535fa34597fa6f5f2f717da28f69bb445dbb433d99fd22e7da53dfa3659efd3017da7c3f2af233aa68aeadfec1b6aa9236fd63d0d14ca15c0719913737b965fedcbf0c83cc29a677cc2a77cc6e77cc1977cc5d7c5fee637fbdbb2db9d5adff343b17ee427fec1737ee69762fffa9bfd222ff17259fdc82bbcca6bfc893ff33a7fe10ddee42ddee69ddfec77f92beff137dee703fece877cc4c7aee58a6b6ee8b8fc10ed7eb13f635f9a4bc5e54719477152ba671977a505c84845c57222a7bfd89fcb999ccb855cca955cbfc5546ee456ee68b14cf67b799047799aec2fdc92fc28999cef567224cff222afb2c85b32e36d599265f9282bb23ad95fba6559934f2593f3e798b74acc8fd5f6b3accb17d9904dd9926db3a7520d1fdd37d9915df95a72599e1291566df7e49beccb817c974339829eb55e56dc7e51ec0d2dcbb1545297a791563af1c5eff2d3beb4faf8562f568f0744745b9e9d5f1f7992d5e412a186ffef7afff7dfdffd077c99ae99</data> + </image> +</images> +<connections> + <connection> + <sender>comboMode</sender> + <signal>activated(int)</signal> + <receiver>KSnapshotWidget</receiver> + <slot>slotModeChanged(int)</slot> + </connection> + <connection> + <sender>btnNew</sender> + <signal>clicked()</signal> + <receiver>KSnapshotWidget</receiver> + <slot>slotNewClicked()</slot> + </connection> + <connection> + <sender>btnPrint</sender> + <signal>clicked()</signal> + <receiver>KSnapshotWidget</receiver> + <slot>slotPrintClicked()</slot> + </connection> + <connection> + <sender>btnSave</sender> + <signal>clicked()</signal> + <receiver>KSnapshotWidget</receiver> + <slot>slotSaveClicked()</slot> + </connection> + <connection> + <sender>lblImage</sender> + <signal>startDrag()</signal> + <receiver>KSnapshotWidget</receiver> + <slot>slotStartDrag()</slot> + </connection> +</connections> +<tabstops> + <tabstop>btnNew</tabstop> + <tabstop>btnSave</tabstop> + <tabstop>btnPrint</tabstop> + <tabstop>comboMode</tabstop> + <tabstop>spinDelay</tabstop> + <tabstop>cbIncludeDecorations</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> + <include location="global" impldecl="in implementation">kiconloader.h</include> + <include location="global" impldecl="in implementation">kglobalsettings.h</include> + <include location="local" impldecl="in implementation">ksnapshotwidget.ui.h</include> +</includes> +<Q_SIGNALS> + <signal>newClicked()</signal> + <signal>saveClicked()</signal> + <signal>printClicked()</signal> + <signal>startImageDrag()</signal> +</Q_SIGNALS> +<Q_SLOTS> + <slot access="protected" specifier="non virtual">slotModeChanged( int mode )</slot> + <slot access="protected" specifier="non virtual">slotNewClicked()</slot> + <slot access="protected" specifier="non virtual">slotSaveClicked()</slot> + <slot access="protected" specifier="non virtual">slotPrintClicked()</slot> + <slot access="protected" specifier="non virtual">slotStartDrag()</slot> + <slot specifier="non virtual" returnType="int">previewWidth()</slot> + <slot specifier="non virtual" returnType="int">previewHeight()</slot> +</Q_SLOTS> +<functions> + <function specifier="non virtual">setPreview( const TQPixmap & pm )</function> + <function specifier="non virtual">setDelay( int i )</function> + <function specifier="non virtual">setIncludeDecorations( bool b )</function> + <function specifier="non virtual">setMode( int mode )</function> + <function specifier="non virtual" returnType="int">delay()</function> + <function specifier="non virtual" returnType="bool">includeDecorations()</function> + <function specifier="non virtual" returnType="int">mode()</function> + <function specifier="non virtual" returnType="TQPixmap">preview()</function> +</functions> +<pixmapfunction>SmallIconSet</pixmapfunction> +<tqlayoutdefaults spacing="6" margin="11"/> +<tqlayoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +</UI> diff --git a/chalk/plugins/viewplugins/screenshot/ksnapshotwidget.ui.h b/chalk/plugins/viewplugins/screenshot/ksnapshotwidget.ui.h new file mode 100644 index 00000000..3c552868 --- /dev/null +++ b/chalk/plugins/viewplugins/screenshot/ksnapshotwidget.ui.h @@ -0,0 +1,118 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename functions or slots use +** TQt Designer which will update this file, preserving your code. Create an +** init() function in place of a constructor, and a destroy() function in +** place of a destructor. +*****************************************************************************/ + + +void KSnapshotWidget::slotModeChanged( int mode ) +{ + switch ( mode ) + { + case 0: + lblDelay->setEnabled(true); + spinDelay->setEnabled(true); + cbIncludeDecorations->setEnabled(false); + break; + case 1: + lblDelay->setEnabled(true); + spinDelay->setEnabled(true); + cbIncludeDecorations->setEnabled(true); + break; + case 2: + lblDelay->setEnabled(false); + spinDelay->setEnabled(false); + cbIncludeDecorations->setEnabled(false); + default: + break; + } +} + + +void KSnapshotWidget::setPreview( const TQPixmap &pm ) +{ + lblImage->setPixmap(pm); +} + + +void KSnapshotWidget::setDelay( int i ) +{ + spinDelay->setValue(i); +} + + +void KSnapshotWidget::setIncludeDecorations( bool b ) +{ + cbIncludeDecorations->setChecked(b); +} + + +void KSnapshotWidget::setMode( int mode ) +{ + comboMode->setCurrentItem(mode); + slotModeChanged(mode); +} + + +int KSnapshotWidget::delay() +{ + return spinDelay->value(); +} + + +bool KSnapshotWidget::includeDecorations() +{ + return cbIncludeDecorations->isChecked(); +} + + +int KSnapshotWidget::mode() +{ + return comboMode->currentItem(); +} + + +void KSnapshotWidget::slotNewClicked() +{ + emit newClicked(); +} + + +void KSnapshotWidget::slotSaveClicked() +{ + emit saveClicked(); +} + + +void KSnapshotWidget::slotPrintClicked() +{ + emit printClicked(); +} + + +void KSnapshotWidget::slotStartDrag() +{ + emit startImageDrag(); +} + + +TQPixmap KSnapshotWidget::preview() +{ + return *lblImage->pixmap(); +} + + +int KSnapshotWidget::previewWidth() +{ + return lblImage->width(); +} + + +int KSnapshotWidget::previewHeight() +{ + return lblImage->height(); +} + diff --git a/chalk/plugins/viewplugins/screenshot/main.cpp b/chalk/plugins/viewplugins/screenshot/main.cpp new file mode 100644 index 00000000..70f61349 --- /dev/null +++ b/chalk/plugins/viewplugins/screenshot/main.cpp @@ -0,0 +1,38 @@ +#include <kapplication.h> +#include "ksnapshot.h" +#include <kimageio.h> +#include <klocale.h> +#include <kcmdlineargs.h> +#include <kaboutdata.h> +#include <kiconloader.h> + +static const char description[] = + I18N_NOOP("KDE Screenshot Utility"); + +int main(int argc, char **argv) +{ + KAboutData aboutData( "ksnapshot", I18N_NOOP("KSnapshot"), + KSNAPVERSION, description, KAboutData::License_GPL, + "(c) 1997-2003, Richard J. Moore,\n(c) 2000, Matthias Ettrich,\n(c) 2002-2003 Aaron J. Seigo"); + aboutData.addAuthor("Richard J. Moore",0, "rich@kde.org"); + aboutData.addAuthor("Matthias Ettrich",0, "ettrich@kde.org"); + aboutData.addAuthor("Aaron J. Seigo", 0, "aseigo@kde.org"); + aboutData.addCredit( "Nadeem Hasan", "Region Grabbing\nReworked GUI", + "nhasan@kde.org" ); + KCmdLineArgs::init( argc, argv, &aboutData ); + + KApplication app; + + KImageIO::registerFormats(); + + // Create top level window + KSnapshot *toplevel= new KSnapshot(); + Q_CHECK_PTR(toplevel); + app.dcopClient()->setDefaultObject( toplevel->objId() ); + toplevel->setCaption( app.makeStdCaption("") ); + toplevel->setIcon(SmallIcon("tool_screenshot")); + app.setMainWidget(toplevel); + toplevel->show(); + return app.exec(); +} + diff --git a/chalk/plugins/viewplugins/screenshot/regiongrabber.cpp b/chalk/plugins/viewplugins/screenshot/regiongrabber.cpp new file mode 100644 index 00000000..1d3a451d --- /dev/null +++ b/chalk/plugins/viewplugins/screenshot/regiongrabber.cpp @@ -0,0 +1,170 @@ +/* + * This file was copied from ksnapshot + * + * Copyright (C) 2003 Nadeem Hasan <nhasan@kde.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "regiongrabber.h" + +#include <tqpainter.h> +#include <tqpalette.h> +#include <tqstyle.h> +#include <tqtimer.h> +#include <tqtooltip.h> + +#include <kglobalsettings.h> + +SizeTip::SizeTip( TQWidget *tqparent, const char *name ) + : TQLabel( tqparent, name, WStyle_Customize | WX11BypassWM | + WStyle_StaysOnTop | WStyle_NoBorder | WStyle_Tool ) +{ + setMargin( 2 ); + setIndent( 0 ); + setFrameStyle( TQFrame::Plain | TQFrame::Box ); + + setPalette( TQToolTip::palette() ); +} + +void SizeTip::setTip( const TQRect &rect ) +{ + TQString tip = TQString( "%1x%2" ).tqarg( rect.width() ) + .tqarg( rect.height() ); + + setText( tip ); + adjustSize(); + + positionTip( rect ); +} + +void SizeTip::positionTip( const TQRect &rect ) +{ + TQRect tipRect = tqgeometry(); + tipRect.moveTopLeft( TQPoint( 0, 0 ) ); + + if ( rect.intersects( tipRect ) ) + { + TQRect deskR = KGlobalSettings::desktopGeometry( TQPoint( 0, 0 ) ); + + tipRect.moveCenter( TQPoint( deskR.width()/2, deskR.height()/2 ) ); + if ( !rect.tqcontains( tipRect, true ) && rect.intersects( tipRect ) ) + tipRect.moveBottomRight( tqgeometry().bottomRight() ); + } + + move( tipRect.topLeft() ); +} + +RegionGrabber::RegionGrabber() + : TQWidget( 0, 0 ), + mouseDown( false ), sizeTip( 0L ) +{ + sizeTip = new SizeTip( ( TQWidget * )0L ); + + tipTimer = new TQTimer( this ); + Q_CHECK_PTR(tipTimer); + connect( tipTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( updateSizeTip() ) ); + + TQTimer::singleShot( 200, this, TQT_SLOT( initGrabber() ) ); +} + +RegionGrabber::~RegionGrabber() +{ + delete sizeTip; +} + +void RegionGrabber::initGrabber() +{ + pixmap = TQPixmap::grabWindow( qt_xrootwin() ); + setPaletteBackgroundPixmap( pixmap ); + + showFullScreen(); + + grabMouse( crossCursor ); +} + +void RegionGrabber::mousePressEvent( TQMouseEvent *e ) +{ + if ( e->button() == Qt::LeftButton ) + { + mouseDown = true; + grabRect = TQRect( e->pos(), e->pos() ); + } +} + +void RegionGrabber::mouseMoveEvent( TQMouseEvent *e ) +{ + if ( mouseDown ) + { + sizeTip->hide(); + tipTimer->start( 250, true ); + + drawRubber(); + grabRect.setBottomRight( e->pos() ); + drawRubber(); + } +} + +void RegionGrabber::mouseReleaseEvent( TQMouseEvent *e ) +{ + mouseDown = false; + drawRubber(); + sizeTip->hide(); + + grabRect.setBottomRight( e->pos() ); + grabRect = grabRect.normalize(); + + TQPixmap region = TQPixmap::grabWindow( winId(), grabRect.x(), grabRect.y(), + grabRect.width(), grabRect.height() ); + + releaseMouse(); + + emit regionGrabbed( region ); +} + +void RegionGrabber::keyPressEvent( TQKeyEvent *e ) +{ + if ( e->key() == TQt::Key_Escape ) + { + releaseMouse(); + emit regionGrabbed( TQPixmap() ); + } + else + e->ignore(); +} + +void RegionGrabber::updateSizeTip() +{ + TQRect rect = grabRect.normalize(); + + sizeTip->setTip( rect ); + sizeTip->show(); +} + +void RegionGrabber::drawRubber() +{ + TQPainter p; + p.begin( this ); + p.setRasterOp( NotROP ); + p.setPen( TQPen( color0, 1 ) ); + p.setBrush( NoBrush ); + + tqstyle().tqdrawPrimitive( TQStyle::PE_FocusRect, &p, grabRect, tqcolorGroup(), + TQStyle::Style_Default, TQStyleOption( tqcolorGroup().base() ) ); + + p.end(); +} + +#include "regiongrabber.moc" diff --git a/chalk/plugins/viewplugins/screenshot/regiongrabber.h b/chalk/plugins/viewplugins/screenshot/regiongrabber.h new file mode 100644 index 00000000..b1da1049 --- /dev/null +++ b/chalk/plugins/viewplugins/screenshot/regiongrabber.h @@ -0,0 +1,72 @@ +/* + * This file is copied from ksnapshot. + * + * Copyright (C) 2003 Nadeem Hasan <nhasan@kde.org> + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef REGIONGRABBER_H +#define REGIONGRABBER_H + +#include <tqlabel.h> +#include <tqpixmap.h> + +class TQTimer; + +class SizeTip : public TQLabel +{ +public: + SizeTip( TQWidget *tqparent, const char *name=0 ); + ~SizeTip() {} + + void setTip( const TQRect &rect ); + void positionTip( const TQRect &rect ); +}; + +class RegionGrabber : public TQWidget +{ + Q_OBJECT + TQ_OBJECT + +public: + RegionGrabber(); + ~RegionGrabber(); + +protected slots: + void initGrabber(); + void updateSizeTip(); + + signals: + void regionGrabbed( const TQPixmap & ); + +protected: + void mousePressEvent( TQMouseEvent *e ); + void mouseReleaseEvent( TQMouseEvent *e ); + void mouseMoveEvent( TQMouseEvent *e ); + void keyPressEvent( TQKeyEvent *e ); + + void drawRubber(); + + bool mouseDown; + TQRect grabRect; + TQPixmap pixmap; + + SizeTip *sizeTip; + TQTimer *tipTimer; +}; + +#endif // REGIONGRABBER_H + diff --git a/chalk/plugins/viewplugins/screenshot/screenshot-chalk.rc b/chalk/plugins/viewplugins/screenshot/screenshot-chalk.rc new file mode 100644 index 00000000..ec96bf11 --- /dev/null +++ b/chalk/plugins/viewplugins/screenshot/screenshot-chalk.rc @@ -0,0 +1,9 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkscreenshot" version="1"> +<MenuBar> + <Menu name="Tools"><text>&Tools</text> + <Seperator/> + <Action name="screenshot"/> + </Menu> +</MenuBar> +</kpartgui> diff --git a/chalk/plugins/viewplugins/screenshot/screenshot-kpresenter.rc b/chalk/plugins/viewplugins/screenshot/screenshot-kpresenter.rc new file mode 100644 index 00000000..8f1f2033 --- /dev/null +++ b/chalk/plugins/viewplugins/screenshot/screenshot-kpresenter.rc @@ -0,0 +1,9 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkscreenshot" version="1"> +<MenuBar> + <Menu name="Insert"><text>&Insert</text> + <Separator/> + <Action name="screenshot"/> + </Menu> +</MenuBar> +</kpartgui> diff --git a/chalk/plugins/viewplugins/screenshot/screenshot-kword.rc b/chalk/plugins/viewplugins/screenshot/screenshot-kword.rc new file mode 100644 index 00000000..f923f87f --- /dev/null +++ b/chalk/plugins/viewplugins/screenshot/screenshot-kword.rc @@ -0,0 +1,9 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkscreenshot" version="1"> +<MenuBar> + <Menu name="insert"><text>&Insert</text> + <Separator/> + <Action name="screenshot"/> + </Menu> +</MenuBar> +</kpartgui> diff --git a/chalk/plugins/viewplugins/screenshot/screenshot.cpp b/chalk/plugins/viewplugins/screenshot/screenshot.cpp new file mode 100644 index 00000000..ff762925 --- /dev/null +++ b/chalk/plugins/viewplugins/screenshot/screenshot.cpp @@ -0,0 +1,78 @@ +/* + * This file is part of the KDE project + * + * This file was copied from ksnapshot + * + * Copyright (C) 2001 Nikolas Zimmermann <wildfox@kde.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <KoView.h> +#include <KoDocument.h> +#include <kgenericfactory.h> +#include <klocale.h> + +#include "ksnapshot.h" +#include <kimageio.h> +#include <kis_view.h> +#include <kis_image.h> +#include "screenshot.moc" + + +K_EXPORT_COMPONENT_FACTORY( chalkscreenshot, KGenericFactory<Screenshot>( "chalk" ) ) + +Screenshot::Screenshot(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + KGlobal::locale()->insertCatalogue("kscreenshot_plugin"); + setInstance(KGenericFactory<Screenshot>::instance()); + setXMLFile(locate("data","chalkplugins/screenshot-chalk.rc"), true); + KImageIO::registerFormats(); + + snapshot = new KSnapshot(); + Q_CHECK_PTR(snapshot); + connect( snapshot, TQT_SIGNAL( screenGrabbed() ), TQT_SLOT( slotScreenGrabbed() ) ); + + (void) new KAction(i18n("&Screenshot..."), SmallIcon("tool_screenshot"), 0, this, TQT_SLOT(slotScreenshot()), actionCollection(), "screenshot"); + +} + +Screenshot::~Screenshot() +{ + delete snapshot; +} + +void Screenshot::slotScreenshot() +{ + snapshot->show(); +} + +void Screenshot::slotScreenGrabbed() +{ + KTempFile temp(locateLocal("tmp", "screenshot"), ".png"); + snapshot->save(temp.name()); + + KisView *view = dynamic_cast<KisView *>(tqparent()); + if(view) + view->importImage(temp.name()); +} diff --git a/chalk/plugins/viewplugins/screenshot/screenshot.h b/chalk/plugins/viewplugins/screenshot/screenshot.h new file mode 100644 index 00000000..d1100836 --- /dev/null +++ b/chalk/plugins/viewplugins/screenshot/screenshot.h @@ -0,0 +1,43 @@ +/* This file is part of the KDE project + * Copyright (C) 2001 Nikolas Zimmermann <wildfox@kde.org> + * Copyright (C) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef SCREENSHOT_H +#define SCREENSHOT_H + +#include <kparts/plugin.h> + +class KSnapshot; + +class Screenshot : public KParts::Plugin +{ + Q_OBJECT + TQ_OBJECT +public: + Screenshot(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~Screenshot(); + +private slots: + void slotScreenshot(); + void slotScreenGrabbed(); + +private: + KSnapshot * snapshot; +}; + +#endif diff --git a/chalk/plugins/viewplugins/scripting/Makefile.am b/chalk/plugins/viewplugins/scripting/Makefile.am new file mode 100644 index 00000000..2bc6c1fd --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/Makefile.am @@ -0,0 +1,29 @@ +SUBDIRS = chalkscripting chalkcore samples + +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = scripting.rc + +kde_services_DATA = chalkscripting.desktop + + +INCLUDES = -I$(top_srcdir)/chalk/sdk \ + -I$(top_srcdir)/chalk/core \ + -I$(top_srcdir)/chalk/chalkcolor/ \ + -I$(top_srcdir)/chalk/ui \ + -I$(top_builddir)/lib/kross/main \ + $(KROSS_INCLUDES) \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +chalkscripting_la_SOURCES = scripting.cc + +kde_module_LTLIBRARIES = chalkscripting.la +noinst_HEADERS = scripting.h + +chalkscripting_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) chalkblurfilter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui +chalkscripting_la_LIBADD = $(top_builddir)/chalk/libchalkcommon.la $(top_builddir)/lib/kross/main/libkrossmain.la ./chalkscripting/libchalkscripting.la + +KDE_CXXFLAGS = $(USE_EXCEPTIONS) + +chalkscripting_la_METASOURCES = AUTO diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/Makefile.am b/chalk/plugins/viewplugins/scripting/chalkcore/Makefile.am new file mode 100644 index 00000000..448c7c59 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/Makefile.am @@ -0,0 +1,30 @@ + +INCLUDES = -I$(top_srcdir)/core -I$(top_srcdir)/chalk/plugins/viewplugins/scripting/chalkscripting \ + -I$(top_srcdir)/chalk $(KOFFICECORE_INCLUDES) $(KROSS_INCLUDES) \ + -I$(top_srcdir)/chalk/ui -I$(top_srcdir)/chalk/core -I$(top_srcdir)/chalk/sdk \ + -I$(top_srcdir)/chalk/chalkcolor $(all_includes) + +kde_module_LTLIBRARIES = krosschalkcore.la + +krosschalkcore_la_SOURCES = chalkcoremodule.cpp krs_doc.cpp krs_paint_layer.cpp \ + krs_image.cpp krs_histogram.cpp krs_script_progress.cpp krs_painter.cpp krs_color.cpp \ + krs_brush.cpp krs_pattern.cpp krs_filter.cpp krs_filter_configuration.cpp \ + krs_wavelet.cpp + +krosschalkcore_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../../chalk/core/.libs -lchalkimage \ + -L../../../../../chalk/ui/.libs -lchalkui -L../../../../../lib/kofficeui/.libs -lkofficeui -L../../../../../lib/kofficecore/.libs -lkofficecore +krosschalkcore_la_LIBADD = \ + $(LIB_QT) \ + $(LIB_KDECORE) \ + $(top_builddir)/lib/kross/api/libkrossapi.la \ + $(top_builddir)/lib/kross/main/libkrossmain.la \ + $(top_builddir)/chalk/libchalkcommon.la \ + $(top_builddir)/chalk/plugins/viewplugins/scripting/chalkscripting/libchalkscripting.la + +METASOURCES = AUTO +SUBDIRS = . + +KDE_CXXFLAGS = $(USE_EXCEPTIONS) + +noinst_HEADERS = krs_doc.h krs_iterator.h krs_painter.h krs_color.h krs_brush.h \ + krs_filter.h krs_filter_configuration.h krs_wavelet.h diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/chalkcoremodule.cpp b/chalk/plugins/viewplugins/scripting/chalkcore/chalkcoremodule.cpp new file mode 100644 index 00000000..04f7b653 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/chalkcoremodule.cpp @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "chalkcoremodule.h" + +#include <kdebug.h> + +//#include <api/variant.h> +#include <api/qtobject.h> +#include <main/manager.h> + +#include <kis_autobrush_resource.h> +#include <kis_brush.h> +#include <kis_colorspace_factory_registry.h> +#include <kis_doc.h> +#include <kis_filter.h> +#include <kis_filter_registry.h> +#include <kis_image.h> +#include <kis_meta_registry.h> +#include <kis_pattern.h> +#include <kis_resourceserver.h> + +#include "kis_script_progress.h" + +#include "krs_brush.h" +#include "krs_color.h" +#include "krs_doc.h" +#include "krs_filter.h" +#include "krs_image.h" +#include "krs_pattern.h" +#include "krs_script_progress.h" + +extern "C" +{ + /** + * Exported an loadable function as entry point to use + * the \a KexiAppModule. + */ + Kross::Api::Object* KDE_EXPORT init_module(Kross::Api::Manager* manager) + { + return new Kross::ChalkCore::ChalkCoreModule(manager); + } +} + + +using namespace Kross::ChalkCore; + +ChalkCoreFactory::ChalkCoreFactory(TQString packagePath) : Kross::Api::Event<ChalkCoreFactory>("ChalkCoreFactory"), m_packagePath(packagePath) +{ + addFunction("newRGBColor", &ChalkCoreFactory::newRGBColor); + addFunction("newHSVColor", &ChalkCoreFactory::newHSVColor); + addFunction("getPattern", &ChalkCoreFactory::getPattern); + addFunction("loadPattern", &ChalkCoreFactory::loadPattern); + addFunction("getBrush", &ChalkCoreFactory::getBrush); + addFunction("loadBrush", &ChalkCoreFactory::loadBrush); + addFunction("getFilter", &ChalkCoreFactory::getFilter); + addFunction("newCircleBrush", &ChalkCoreFactory::newCircleBrush); + addFunction("newRectBrush", &ChalkCoreFactory::newRectBrush); + addFunction("newImage", &ChalkCoreFactory::newImage); + addFunction("getPackagePath", &ChalkCoreFactory::getPackagePath); +} + +Kross::Api::Object::Ptr ChalkCoreFactory::newRGBColor(Kross::Api::List::Ptr args) +{ + Color* c = new Color(Kross::Api::Variant::toUInt(args->item(0)), Kross::Api::Variant::toUInt(args->item(1)), Kross::Api::Variant::toUInt(args->item(2)), TQColor::Rgb); + return c; +} +Kross::Api::Object::Ptr ChalkCoreFactory::newHSVColor(Kross::Api::List::Ptr args) +{ + return new Color(Kross::Api::Variant::toUInt(args->item(0)), Kross::Api::Variant::toUInt(args->item(1)), Kross::Api::Variant::toUInt(args->item(2)), TQColor::Hsv); +} + +Kross::Api::Object::Ptr ChalkCoreFactory::getPattern(Kross::Api::List::Ptr args) +{ + KisResourceServerBase* rServer = KisResourceServerRegistry::instance()->get("PatternServer"); + TQValueList<KisResource*> resources = rServer->resources(); + + TQString name = Kross::Api::Variant::toString(args->item(0)); + + for (TQValueList<KisResource*>::iterator it = resources.begin(); it != resources.end(); ++it ) + { + if((*it)->name() == name) + { + return new Pattern(dynamic_cast<KisPattern*>(*it), true); + } + } + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception( i18n("Unknown pattern") ) ); + return 0; + +} + +Kross::Api::Object::Ptr ChalkCoreFactory::loadPattern(Kross::Api::List::Ptr args) +{ + TQString filename = Kross::Api::Variant::toString(args->item(0)); + KisPattern* pattern = new KisPattern(filename); + if(pattern->load()) + { + return new Pattern( pattern, false ); + } else { + delete pattern; + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception( i18n("Unknown pattern") ) ); + return 0; + } +} + +Kross::Api::Object::Ptr ChalkCoreFactory::getBrush(Kross::Api::List::Ptr args) +{ + KisResourceServerBase* rServer = KisResourceServerRegistry::instance()->get("BrushServer"); + TQValueList<KisResource*> resources = rServer->resources(); + + TQString name = Kross::Api::Variant::toString(args->item(0)); + + for (TQValueList<KisResource*>::iterator it = resources.begin(); it != resources.end(); ++it ) + { + if((*it)->name() == name) + { + return new Brush(dynamic_cast<KisBrush*>(*it), true); + } + } + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception( i18n("Unknown brush") ) ); + return 0; +} + +Kross::Api::Object::Ptr ChalkCoreFactory::loadBrush(Kross::Api::List::Ptr args) +{ + TQString filename = Kross::Api::Variant::toString(args->item(0)); + KisBrush* brush = new KisBrush(filename); + if(brush->load()) + { + return new Brush( brush, false ); + } else { + delete brush; + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception( i18n("Unknown brush") ) ); + return 0; + } +} + +Kross::Api::Object::Ptr ChalkCoreFactory::getFilter(Kross::Api::List::Ptr args) +{ + TQString name = Kross::Api::Variant::toString(args->item(0)); + KisFilter* filter = KisFilterRegistry::instance()->get(name); + if(filter) + { + return new Filter(filter); + } else { + return 0; + } +} + +Kross::Api::Object::Ptr ChalkCoreFactory::newCircleBrush(Kross::Api::List::Ptr args) +{ + uint w = TQMAX(1, Kross::Api::Variant::toUInt(args->item(0))); + uint h = TQMAX(1, Kross::Api::Variant::toUInt(args->item(1))); + uint hf = 0; + uint vf = 0; + if( args.count() > 2) + { + hf = Kross::Api::Variant::toUInt(args->item(2)); + vf = Kross::Api::Variant::toUInt(args->item(3)); + } + KisAutobrushShape* kas = new KisAutobrushCircleShape(w, h, hf, vf); + TQImage* brsh = new TQImage(); + kas->createBrush(brsh); + return new Brush(new KisAutobrushResource(*brsh), false); +} +Kross::Api::Object::Ptr ChalkCoreFactory::newRectBrush(Kross::Api::List::Ptr args) +{ + uint w = TQMAX(1, Kross::Api::Variant::toUInt(args->item(0))); + uint h = TQMAX(1, Kross::Api::Variant::toUInt(args->item(1))); + uint hf = 0; + uint vf = 0; + if( args.count() > 2) + { + hf = Kross::Api::Variant::toUInt(args->item(2)); + vf = Kross::Api::Variant::toUInt(args->item(3)); + } + KisAutobrushShape* kas = new KisAutobrushRectShape(w, h, hf, vf); + TQImage* brsh = new TQImage(); + kas->createBrush(brsh); + return new Brush(new KisAutobrushResource(*brsh), false);; +} + +Kross::Api::Object::Ptr ChalkCoreFactory::newImage(Kross::Api::List::Ptr args) +{ + int w = Kross::Api::Variant::toInt(args->item(0)); + int h = Kross::Api::Variant::toInt(args->item(1)); + TQString csname = Kross::Api::Variant::toString(args->item(2)); + TQString name = Kross::Api::Variant::toString(args->item(3)); + if( w < 0 || h < 0) + { + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception( i18n("Invalid image size") ) ); + return 0; + } + KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID(csname, ""), ""); + if(!cs) + { + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception( i18n("Colorspace %0 is not available, please check your installation.").tqarg(csname ) ) ); + return 0; + } + + return new Image(new KisImage(0,w,h, cs, name)); +} + +Kross::Api::Object::Ptr ChalkCoreFactory::getPackagePath(Kross::Api::List::Ptr) +{ + return new Kross::Api::Variant(m_packagePath); +} + +ChalkCoreModule::ChalkCoreModule(Kross::Api::Manager* manager) + : Kross::Api::Module("chalkcore") , m_manager(manager), m_factory(0) +{ + + TQMap<TQString, Object::Ptr> tqchildren = manager->getChildren(); + kdDebug(41011) << " there are " << tqchildren.size() << endl; + for(TQMap<TQString, Object::Ptr>::const_iterator it = tqchildren.begin(); it != tqchildren.end(); it++) + { + kdDebug(41011) << it.key() << " " << it.data() << endl; + } + + // Wrap doc + Kross::Api::Object::Ptr chalkdocument = manager->getChild("ChalkDocument"); + if(chalkdocument) { + Kross::Api::QtObject* chalkdocumentqt = (Kross::Api::QtObject*)( chalkdocument.data() ); + if(chalkdocumentqt) { + ::KisDoc* document = (::KisDoc*)( chalkdocumentqt->getObject() ); + if(document) { + addChild( new Doc(document) ); + } else { + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception("There was no 'ChalkDocument' published.") ); + } + } + } + // Wrap ChalkScriptProgress + TQString packagePath; + Kross::Api::Object::Ptr chalkscriptprogress = manager->getChild("ChalkScriptProgress"); + if(chalkdocument) { + Kross::Api::QtObject* chalkscriptprogressqt = (Kross::Api::QtObject*)( chalkscriptprogress.data() ); + if(chalkscriptprogressqt) { + ::KisScriptProgress* scriptprogress = (::KisScriptProgress*)( chalkscriptprogressqt->getObject() ); + scriptprogress->activateAsSubject(); + packagePath = scriptprogress->packagePath(); + if(scriptprogress) { + addChild( new ScriptProgress(scriptprogress) ); + } else { + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception("There was no 'ChalkScriptProgress' published.") ); + } + } + } + m_factory = new ChalkCoreFactory(packagePath); +} + +ChalkCoreModule::~ChalkCoreModule() +{ + if(m_factory) + delete m_factory; +} + + +const TQString ChalkCoreModule::getClassName() const +{ + return "Kross::ChalkCore::ChalkCoreModule"; +} + +Kross::Api::Object::Ptr ChalkCoreModule::call(const TQString& name, Kross::Api::List::Ptr arguments) +{ + kdDebug(41011) << "ChalkCoreModule::call = " << name << endl; + if( m_factory->isAFunction(name)) + { + return m_factory->call(name, arguments); + } else { + return Kross::Api::Module::call(name, arguments); + } +} diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/chalkcoremodule.h b/chalk/plugins/viewplugins/scripting/chalkcore/chalkcoremodule.h new file mode 100644 index 00000000..d719edd6 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/chalkcoremodule.h @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KRITA_KROSS_KRITACOREMODULE_H +#define KRITA_KROSS_KRITACOREMODULE_H + +#include <tqstring.h> +#include <tqvariant.h> + +#define KROSS_MAIN_EXPORT KDE_EXPORT + +#include <api/module.h> +#include <api/event.h> + +namespace Kross { namespace Api { + class Manager; +}} + +namespace Kross { namespace ChalkCore { + /** + * This class contains functions use to create new Kross object in a script + */ + class ChalkCoreFactory : public Kross::Api::Event<ChalkCoreFactory> + { + public: + ChalkCoreFactory(TQString packagePath); + private: + /** + * This function return a new Image. + * It takes four arguments : + * - width + * - height + * - colorspace id + * - name of the image + * + * And in return you get an Image object. + * + * For example (in ruby) : + * @code + * Krosschalkcore::newImage(10,20, "RGBA", "kikoo") + * @endcode + */ + Kross::Api::Object::Ptr newImage(Kross::Api::List::Ptr); + /** + * This function return a new Color with the given RGB triplet + * It takes three arguments : + * - red color (0 to 255) + * - blue color (0 to 255) + * - green color (0 to 255) + * + * For example (in ruby) : + * @code + * Krosschalkcore::newRGBColor(255,0,0) # create a red color + * Krosschalkcore::newRGBColor(255,255,255) # create a white color + * @endcode + */ + Kross::Api::Object::Ptr newRGBColor(Kross::Api::List::Ptr); + /** + * This function return a new Color with the given HSV triplet + * It takes three arguments : + * - hue color (0 to 255) + * - saturation color (0 to 255) + * - value color (0 to 255) + * + * For example (in ruby) : + * @code + * Krosschalkcore::newRGBColor(255,125,0) + * @endcode + */ + Kross::Api::Object::Ptr newHSVColor(Kross::Api::List::Ptr); + /** + * This function return a Pattern taken from the list of ressources + * of chalk + * It takes one argument : + * - the name of the pattern + * + * For example (in ruby) : + * @code + * Krosschalkcore::getPattern("Bricks") + * @endcode + */ + Kross::Api::Object::Ptr getPattern(Kross::Api::List::Ptr); + /** + * This function return a Brush taken from the list of ressources + * of chalk + * It takes one argument : + * - the name of the pattern + * + * For example (in ruby) : + * @code + * Krosschalkcore::getBrush("Circle (05)") + * @endcode + */ + Kross::Api::Object::Ptr getBrush(Kross::Api::List::Ptr); + /** + * This function return a Brush with a circular tqshape + * It takes at least two arguments : + * - width + * - height + * + * It can takes two other arguments : + * - width of the shading + * - height of the shading + * + * If the shading isn't specified, no shading will be used. + * + * For example (in ruby) : + * @code + * Krosschalkcore::newCircleBrush(10,20) # create a plain circle + * Krosschalkcore::newCircleBrush(10,20,5,10) # create a gradient + * @endcode + */ + Kross::Api::Object::Ptr newCircleBrush(Kross::Api::List::Ptr); + /** + * This function return a Brush with a rectangular tqshape + * It takes at least two arguments : + * - width + * - height + * + * It can takes two other arguments : + * - width of the shading + * - height of the shading + * + * If the shading isn't specified, no shading will be used. + * + * For example (in ruby) : + * @code + * Krosschalkcore::newRectBrush(10,20) # create a plain rectangle + * Krosschalkcore::newRectBrush(10,20,5,10) # create a gradient + * @endcode + */ + Kross::Api::Object::Ptr newRectBrush(Kross::Api::List::Ptr); + /** + * This function return a Filter taken from the list of ressources + * of chalk + * It takes one argument : + * - the name of the filter + * + * For example (in ruby) : + * @code + * Krosschalkcore::getFilter("invert") + * @endcode + */ + Kross::Api::Object::Ptr getFilter(Kross::Api::List::Ptr); + /** + * This function loads a Brush and then returns it. + * It takes one argument: the filename of the brush. + */ + Kross::Api::Object::Ptr loadBrush(Kross::Api::List::Ptr); + /** + * This function loads a Pattern and then returns it. + * It takes one argument: the filename of the pattern. + */ + Kross::Api::Object::Ptr loadPattern(Kross::Api::List::Ptr); + /** + * This function return the directory where the script is located. + */ + Kross::Api::Object::Ptr getPackagePath(Kross::Api::List::Ptr); + private: + TQString m_packagePath; + }; + /** + * + */ + class ChalkCoreModule : public Kross::Api::Module + { + public: + /** + * Constructor. + */ + ChalkCoreModule(Kross::Api::Manager* manager); + + /** + * Destructor. + */ + virtual ~ChalkCoreModule(); + + /// \see Kross::Api::Object::getClassName + virtual const TQString getClassName() const; + virtual Kross::Api::Object::Ptr call(const TQString& name, Kross::Api::List::Ptr arguments); + private: + Kross::Api::Manager* m_manager; + ChalkCoreFactory* m_factory; + }; + + +}} + +#endif + diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_brush.cpp b/chalk/plugins/viewplugins/scripting/chalkcore/krs_brush.cpp new file mode 100644 index 00000000..d3f1cb8a --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_brush.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "krs_brush.h" + +#include <kis_brush.h> + +namespace Kross { + +namespace ChalkCore { + +Brush::Brush(KisBrush* brush, bool sharedBrush) : Kross::Api::Class<Brush>("ChalkBrush"), m_brush(brush), m_sharedBrush(sharedBrush) +{ +} + +Brush::~Brush() +{ + if(!m_sharedBrush) + { + delete m_brush; + } +} + +} + +} diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_brush.h b/chalk/plugins/viewplugins/scripting/chalkcore/krs_brush.h new file mode 100644 index 00000000..7a6bdef5 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_brush.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KROSS_KRITACOREKRS_BRUSH_H +#define KROSS_KRITACOREKRS_BRUSH_H + +#include <api/class.h> + +class KisBrush; + +namespace Kross { + +namespace ChalkCore { + +class Brush : public Kross::Api::Class<Brush>{ + public: + /** + * @param sharedBrush tell if the brush should be deleted or not when this object is deleted + */ + Brush(KisBrush*, bool sharedBrush ); + ~Brush(); + public: + inline KisBrush* getBrush() { return m_brush; } + private: + KisBrush* m_brush; + bool m_sharedBrush; +}; + +} + +} + +#endif diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_color.cpp b/chalk/plugins/viewplugins/scripting/chalkcore/krs_color.cpp new file mode 100644 index 00000000..b02a36f0 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_color.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "krs_color.h" + +namespace Kross { + +namespace ChalkCore { + +Color::Color ( int x, int y, int z, TQColor::Spec colorSpec ) + : Kross::Api::Class<Color>("ChalkColor"), m_color(x,y,z,colorSpec) +{ +} + +Color::Color() + : Kross::Api::Class<Color>("ChalkColor") +{ +} + +Color::~Color() +{ +} + + +} + +} diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_color.h b/chalk/plugins/viewplugins/scripting/chalkcore/krs_color.h new file mode 100644 index 00000000..7955dc92 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_color.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KROSS_APIKRS_COLOR_H +#define KROSS_APIKRS_COLOR_H + +#include <tqcolor.h> + +#include <api/class.h> + +namespace Kross { + +namespace ChalkCore { + +class Color : public Kross::Api::Class<Color> +{ + public: + Color ( int x, int y, int z, TQColor::Spec colorSpec ); + Color (); + + ~Color(); + public: + inline const TQString getClassName() const + { return "Kross::Chalk::Color"; }; + inline TQColor toTQColor() { return m_color; }; + private: + TQColor m_color; +}; + +} + +} + +#endif diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_doc.cpp b/chalk/plugins/viewplugins/scripting/chalkcore/krs_doc.cpp new file mode 100644 index 00000000..4fc37fab --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_doc.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "krs_doc.h" + +#include <kis_doc.h> +#include <kis_image.h> + +#include "krs_image.h" + +namespace Kross { namespace ChalkCore { + +Doc::Doc(::KisDoc* doc) : Kross::Api::Class<Doc>("ChalkDocument"), m_doc(doc) { + addFunction("getImage", &Doc::getImage); +} + +Doc::~Doc() { + +} + +const TQString Doc::getClassName() const { + return "Kross::ChalkCore::Doc"; +} + +Kross::Api::Object::Ptr Doc::getImage(Kross::Api::List::Ptr) +{ + return new Image(m_doc->currentImage(), m_doc); +} + +} +} diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_doc.h b/chalk/plugins/viewplugins/scripting/chalkcore/krs_doc.h new file mode 100644 index 00000000..c06e530a --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_doc.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _KROSS_KRS_DOC_H_ +#define _KROSS_KRS_DOC_H_ + +class KisDoc; + +#include <api/class.h> + +namespace Kross { namespace ChalkCore { + +class Doc : public Kross::Api::Class<Doc> +{ + public: + explicit Doc(::KisDoc* doc); + virtual ~Doc(); + virtual const TQString getClassName() const; + private: + /** + * This function return the Image associated with this Doc. + * + * Example (in Ruby) : + * @code + * doc = krosschalkcore::get("ChalkDocument") + * image = doc.getImage() + * @endcode + */ + Kross::Api::Object::Ptr getImage(Kross::Api::List::Ptr); + private: + KisDoc* m_doc; + +}; +} +} + + +#endif diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_filter.cpp b/chalk/plugins/viewplugins/scripting/chalkcore/krs_filter.cpp new file mode 100644 index 00000000..ecac5501 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_filter.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "krs_filter.h" + +#include <kis_filter.h> +#include <kis_paint_layer.h> + +#include "krs_filter_configuration.h" +#include "krs_paint_layer.h" + +namespace Kross { +namespace ChalkCore { + +Filter::Filter(KisFilter* filter) + : Kross::Api::Class<Filter>("ChalkFilter"), m_filter(filter), m_config( new FilterConfiguration(filter->configuration()) ) +{ + addFunction("process", &Filter::process); + addFunction("getFilterConfiguration", &Filter::getFilterConfiguration); + +} + +Filter::~Filter() +{ +} + +const TQString Filter::getClassName() const { + return "Kross::ChalkCore::Filter"; +} + +Kross::Api::Object::Ptr Filter::getFilterConfiguration(Kross::Api::List::Ptr ) +{ + return m_config; +} + +Kross::Api::Object::Ptr Filter::process(Kross::Api::List::Ptr args) +{ + PaintLayer* src = (PaintLayer*)args->item(0).data(); + if(!m_filter->workWith( src->paintLayer()->paintDevice()->colorSpace())) + { + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception( i18n("An error has occured in %1").tqarg("process") ) ); + } + TQRect rect; + if( args->count() >1) + { + uint x = Kross::Api::Variant::toVariant(args->item(1)).toUInt(); + uint y = Kross::Api::Variant::toVariant(args->item(2)).toUInt(); + uint w = Kross::Api::Variant::toVariant(args->item(3)).toUInt(); + uint h = Kross::Api::Variant::toVariant(args->item(4)).toUInt(); + rect = TQRect(x, y, w, h); + } else { + TQRect r1 = src->paintLayer()->paintDevice()->extent(); + TQRect r2 = src->paintLayer()->image()->bounds(); + rect = r1.intersect(r2); + } + m_filter->process( src->paintLayer()->paintDevice(), src->paintLayer()->paintDevice(), m_config->filterConfiguration(), rect ); + return 0; +} + +} +} diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_filter.h b/chalk/plugins/viewplugins/scripting/chalkcore/krs_filter.h new file mode 100644 index 00000000..1576574b --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_filter.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KROSS_KRITACOREKRS_FILTER_H +#define KROSS_KRITACOREKRS_FILTER_H + +#include <api/class.h> + +class KisFilter; + +namespace Kross { +namespace ChalkCore { + class FilterConfiguration; + +class Filter : public Kross::Api::Class<Filter> +{ + public: + Filter(KisFilter*); + ~Filter(); + private: + /** + * This function return the FilterConfiguration associated with this filter. + */ + Kross::Api::Object::Ptr getFilterConfiguration(Kross::Api::List::Ptr args); + /** + * This function will apply the filter. + * It takes one argument : + * - the source layer + * You can also use this four aguments : + * - x + * - y + * - width + * - height + * + * (x,y, width, height) defines the rectangular area on which the filter will be computed. + * If the rectangle is not defined, then the filter will be apply on alll the source layer. + * + * For example (in ruby) + * @code + * doc = Krosschalkcore::get("ChalkDocument") + * image = doc.getImage() + * layer = image.getActivePaintLayer() + * width = layer.getWidth() + * height = layer.getHeight() + * filter = Krosschalkcore::getFilter("invert") + * filter.process(layer, layer) + * filter.process(layer, layer, 10, 10, 20, 20 ) + * @endcode + */ + Kross::Api::Object::Ptr process(Kross::Api::List::Ptr args); + public: + virtual const TQString getClassName() const; + private: + KisFilter* m_filter; + FilterConfiguration* m_config; +}; + +} +} + +#endif diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_filter_configuration.cpp b/chalk/plugins/viewplugins/scripting/chalkcore/krs_filter_configuration.cpp new file mode 100644 index 00000000..976af321 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_filter_configuration.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "krs_filter_configuration.h" + +#include <api/variant.h> + +#include <kis_filter_configuration.h> + +namespace Kross { +namespace ChalkCore { + + FilterConfiguration::FilterConfiguration(KisFilterConfiguration* fConfig) + : Kross::Api::Class<FilterConfiguration>("ChalkFilterConfiguration"), m_fConfig(fConfig) +{ + addFunction("setProperty", &FilterConfiguration::setProperty); + addFunction("getProperty", &FilterConfiguration::getProperty); + addFunction("fromXML", &FilterConfiguration::fromXML); +} + +FilterConfiguration::~FilterConfiguration() +{ +} + +const TQString FilterConfiguration::getClassName() const { + return "Kross::ChalkCore::FilterConfiguration"; +} + + +Kross::Api::Object::Ptr FilterConfiguration::setProperty(Kross::Api::List::Ptr args) +{ + TQString name = Kross::Api::Variant::toString(args->item(0)); + TQVariant value = Kross::Api::Variant::toVariant(args->item(1)); + m_fConfig->setProperty(name, value); + return 0; +} +Kross::Api::Object::Ptr FilterConfiguration::getProperty(Kross::Api::List::Ptr args) +{ + TQString name = Kross::Api::Variant::toString(args->item(0)); + TQVariant value; + if(m_fConfig->getProperty( name, value)) + { + return new Kross::Api::Variant(value); + } else { + return 0; + } +} + +Kross::Api::Object::Ptr FilterConfiguration::fromXML(Kross::Api::List::Ptr args) +{ + TQString xml = Kross::Api::Variant::toString(args->item(0)); + m_fConfig->fromXML( xml ); + return 0; +} + +} +} diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_filter_configuration.h b/chalk/plugins/viewplugins/scripting/chalkcore/krs_filter_configuration.h new file mode 100644 index 00000000..61378cf4 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_filter_configuration.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KROSS_KRITACOREKRS_FILTER_CONFIGURATION_H +#define KROSS_KRITACOREKRS_FILTER_CONFIGURATION_H + +#include <api/class.h> + +class KisFilterConfiguration; + +namespace Kross { +namespace ChalkCore { + +/** + @author Cyrille Berger <cberger@cberger.net> +*/ +class FilterConfiguration : public Kross::Api::Class<FilterConfiguration> +{ + public: + FilterConfiguration(KisFilterConfiguration*); + ~FilterConfiguration(); + public: + virtual const TQString getClassName() const; + inline KisFilterConfiguration* filterConfiguration() { return m_fConfig; }; + private: + /** + * This function define a parameter of the associated Filter. + * It takes two arguments : + * - the name of the parameter + * - the value, whose type depends of the Filter + */ + Kross::Api::Object::Ptr setProperty(Kross::Api::List::Ptr args); + /** + * This function return the value of a parameter of the associated Filter. + * It takes one argument : + * - the name of the parameter + */ + Kross::Api::Object::Ptr getProperty(Kross::Api::List::Ptr args); + /** + * Deserialize + */ + Kross::Api::Object::Ptr fromXML(Kross::Api::List::Ptr args); + private: + KisFilterConfiguration* m_fConfig; +}; + +} +} + +#endif diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_histogram.cpp b/chalk/plugins/viewplugins/scripting/chalkcore/krs_histogram.cpp new file mode 100644 index 00000000..ea121d7c --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_histogram.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "krs_histogram.h" + +#include <kis_paint_layer.h> + +namespace Kross { + +namespace ChalkCore { + +Histogram::Histogram(KisPaintLayerSP layer, + KisHistogramProducerSP producer, + const enumHistogramType type) + : Kross::Api::Class<Histogram>("ChalkHistogram") +{ + m_histogram = new KisHistogram(layer, producer, type); + addFunction("getMax", &Histogram::getMax); + addFunction("getMin", &Histogram::getMin); + addFunction("getHighest", &Histogram::getHighest); + addFunction("getLowest", &Histogram::getLowest); + addFunction("getMean", &Histogram::getMean); + addFunction("getCount", &Histogram::getCount); + addFunction("getTotal", &Histogram::getTotal); + addFunction("setChannel", &Histogram::setChannel); + addFunction("getChannel", &Histogram::getChannel); + addFunction("getValue", &Histogram::getValue); + addFunction("getNumberOfBins", &Histogram::getNumberOfBins); +} + +Histogram::~Histogram() +{ +} + +const TQString Histogram::getClassName() const { + return "Kross::ChalkCore::Histogram"; +} + +Kross::Api::Object::Ptr Histogram::setChannel(Kross::Api::List::Ptr args) +{ + m_histogram->setChannel(Kross::Api::Variant::toUInt(args->item(0))); + return 0; +} +Kross::Api::Object::Ptr Histogram::getChannel(Kross::Api::List::Ptr) +{ + return new Kross::Api::Variant( m_histogram->channel()); +} +Kross::Api::Object::Ptr Histogram::getMax(Kross::Api::List::Ptr) +{ + return new Kross::Api::Variant( m_histogram->calculations().getMax()); +} +Kross::Api::Object::Ptr Histogram::getMin(Kross::Api::List::Ptr) +{ + return new Kross::Api::Variant( m_histogram->calculations().getMin() ); +} +Kross::Api::Object::Ptr Histogram::getHighest(Kross::Api::List::Ptr) +{ + return new Kross::Api::Variant( m_histogram->calculations().getHighest() ); +} +Kross::Api::Object::Ptr Histogram::getLowest(Kross::Api::List::Ptr) +{ + return new Kross::Api::Variant( m_histogram->calculations().getLowest() ); +} +Kross::Api::Object::Ptr Histogram::getMean(Kross::Api::List::Ptr) +{ + return new Kross::Api::Variant( m_histogram->calculations().getMean() ); +} +Kross::Api::Object::Ptr Histogram::getCount(Kross::Api::List::Ptr) +{ + return new Kross::Api::Variant( m_histogram->calculations().getCount() ); +} +Kross::Api::Object::Ptr Histogram::getTotal(Kross::Api::List::Ptr) +{ + return new Kross::Api::Variant( m_histogram->calculations().getTotal() ); +} +Kross::Api::Object::Ptr Histogram::getValue(Kross::Api::List::Ptr args) +{ + return new Kross::Api::Variant( m_histogram->getValue( Kross::Api::Variant::toUInt(args->item(0)) ) ); +} + +Kross::Api::Object::Ptr Histogram::getNumberOfBins(Kross::Api::List::Ptr) +{ + return new Kross::Api::Variant( m_histogram->producer()->numberOfBins() ); +} + + +} + +} diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_histogram.h b/chalk/plugins/viewplugins/scripting/chalkcore/krs_histogram.h new file mode 100644 index 00000000..50b66ca4 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_histogram.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KROSS_KRITACOREHISTOGRAM_H +#define KROSS_KRITACOREHISTOGRAM_H + +#include <api/class.h> + +#include <kis_types.h> +#include <kis_histogram.h> + +namespace Kross { + +namespace ChalkCore { + +/** + * This class allow to access the histogram of a PaintLayer. + * + * Example (in Ruby) : + * @code + * doc = krosschalkcore::get("ChalkDocument") + * image = doc.getImage() + * layer = image.getActiveLayer() + * histo = layer.createHistogram("RGB8HISTO",0) + * min = layer.getMin() * 255 + * max = layer.getMax() * 255 + * for i in min..max + * print layer.getValue(i) + * print "\n" + * end + * @endcode + */ +class Histogram : public Kross::Api::Class<Histogram> +{ + public: + Histogram(KisPaintLayerSP layer, KisHistogramProducerSP producer, const enumHistogramType type); + ~Histogram(); + virtual const TQString getClassName() const; + private: + /** + * This function return the maximum bound of the histogram + * (values at greater position than the maximum are null). + * The value is in the range 0.0 - 1.0. + */ + Kross::Api::Object::Ptr getMax(Kross::Api::List::Ptr); + /** + * This function return the minimum bound of the histogram + * (values at smaller position than the minimum are null) + * The value is in the range 0.0 - 1.0. + */ + Kross::Api::Object::Ptr getMin(Kross::Api::List::Ptr); + /** + * This function return the highest value of the histogram + */ + Kross::Api::Object::Ptr getHighest(Kross::Api::List::Ptr); + /** + * This function return the lowest value of the histogram + */ + Kross::Api::Object::Ptr getLowest(Kross::Api::List::Ptr); + /** + * This function return the mean of the histogram + */ + Kross::Api::Object::Ptr getMean(Kross::Api::List::Ptr); + /** + * This function return the number of pixels used by the histogram + */ + Kross::Api::Object::Ptr getCount(Kross::Api::List::Ptr); + /** + * This function return the sum of all values of the histogram + */ + Kross::Api::Object::Ptr getTotal(Kross::Api::List::Ptr); + /** + * Select the channel of the layer on which to get the result of the histogram. + * This function takes one argument : + * - channel number + */ + Kross::Api::Object::Ptr setChannel(Kross::Api::List::Ptr); + /** + * Return the selected channel + */ + Kross::Api::Object::Ptr getChannel(Kross::Api::List::Ptr); + /** + * Return the value of a bin of the histogram. + * This function takes one argument : + * - index, in the range [0..255], + */ + Kross::Api::Object::Ptr getValue(Kross::Api::List::Ptr); + /** + * Return the number of bins of this histogram. + */ + Kross::Api::Object::Ptr getNumberOfBins(Kross::Api::List::Ptr); + private: + KisHistogram* m_histogram; +}; + +} + +} + +#endif diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_image.cpp b/chalk/plugins/viewplugins/scripting/chalkcore/krs_image.cpp new file mode 100644 index 00000000..c93d6e88 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_image.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "krs_image.h" + +#include <klocale.h> + +#include <kis_colorspace_factory_registry.h> +#include <kis_image.h> +#include <kis_filter_strategy.h> +#include <kis_group_layer.h> +#include <kis_paint_layer.h> +#include <kis_meta_registry.h> + + +#include "krs_paint_layer.h" + +namespace Kross { + +namespace ChalkCore { + + Image::Image(KisImageSP image, KisDoc* doc) + : Kross::Api::Class<Image>("ChalkImage"), m_image(image), m_doc(doc) +{ + addFunction("getActivePaintLayer", &Image::getActivePaintLayer); + addFunction("getWidth", &Image::getWidth); + addFunction("getHeight", &Image::getHeight); + addFunction("convertToColorspace", &Image::convertToColorspace); + addFunction("createPaintLayer", &Image::createPaintLayer); + addFunction("colorSpaceId", &Image::colorSpaceId); + addFunction("scale", &Image::scale); + addFunction("resize", &Image::resize); +} + + +Image::~Image() +{ +} + +const TQString Image::getClassName() const { + return "Kross::ChalkCore::Image"; +} + +Kross::Api::Object::Ptr Image::getActivePaintLayer(Kross::Api::List::Ptr) +{ + KisPaintLayer* activePaintLayer = dynamic_cast<KisPaintLayer*>(m_image->activeLayer().data()); + if(activePaintLayer ) + { + return new PaintLayer(activePaintLayer, m_doc); + } else { + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception("The active layer is not paintable.") ); + return 0; + } +} +Kross::Api::Object::Ptr Image::getWidth(Kross::Api::List::Ptr) +{ + return new Kross::Api::Variant(m_image->width()); +} +Kross::Api::Object::Ptr Image::getHeight(Kross::Api::List::Ptr) +{ + return new Kross::Api::Variant(m_image->height()); +} +Kross::Api::Object::Ptr Image::convertToColorspace(Kross::Api::List::Ptr args) +{ + KisColorSpace * dstCS = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID(Kross::Api::Variant::toString(args->item(0)), ""), ""); + if(!dstCS) + { + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception( i18n("Colorspace %0 is not available, please check your installation.").tqarg(Kross::Api::Variant::toString(args->item(0))) ) ); + return 0; + } + m_image->convertTo(dstCS); + return 0; +} + +Kross::Api::Object::Ptr Image::colorSpaceId(Kross::Api::List::Ptr ) +{ + return new Kross::Api::Variant( m_image->colorSpace()->id().id() ); +} + + +Kross::Api::Object::Ptr Image::createPaintLayer(Kross::Api::List::Ptr args) +{ + TQString name = Kross::Api::Variant::toString(args->item(0)); + int opacity = Kross::Api::Variant::toInt(args->item(1)); + opacity = CLAMP(opacity, 0, 255); + TQString csname; + if(args->count() > 2) + { + csname = Kross::Api::Variant::toString(args->item(2)); + } else { + csname = m_image->colorSpace()->id().id(); + } + KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID(csname, ""), ""); + KisPaintLayer* layer; + if(cs) + { + layer = new KisPaintLayer(m_image, name, opacity, cs); + } else { + layer = new KisPaintLayer(m_image, name, opacity); + } + layer->setVisible(true); + + m_image->addLayer(layer, m_image->rootLayer(), 0); + return new PaintLayer(layer); + +} + +Kross::Api::Object::Ptr Image::scale(Kross::Api::List::Ptr args) +{ + double cw = Kross::Api::Variant::toDouble(args->item(0)); + double ch = Kross::Api::Variant::toDouble(args->item(1)); + m_image->scale( cw, ch, 0, KisFilterStrategyRegistry::instance()->get( "Mitchell") ); + return 0; +} +Kross::Api::Object::Ptr Image::resize(Kross::Api::List::Ptr args) +{ + int nw = Kross::Api::Variant::toInt(args->item(0)); + int nh = Kross::Api::Variant::toInt(args->item(1)); + int x = 0; + int y = 0; + if(args->count() > 2) + { + x = Kross::Api::Variant::toInt(args->item(2)); + y = Kross::Api::Variant::toInt(args->item(3)); + } + m_image->resize( nw, nh, x, y ); + return 0; +} + + +} + +} diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_image.h b/chalk/plugins/viewplugins/scripting/chalkcore/krs_image.h new file mode 100644 index 00000000..91314f3f --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_image.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KROSS_KRITACOREKRSIMAGE_H +#define KROSS_KRITACOREKRSIMAGE_H + +#include <api/class.h> + +#include <kis_types.h> + +class KisDoc; + +namespace Kross { + +namespace ChalkCore { + +class Image : public Kross::Api::Class<Image> +{ + public: + Image(KisImageSP image, KisDoc* doc = 0); + ~Image(); + virtual const TQString getClassName() const; + private: + /** + * Return the active PaintLayer, if any. + */ + Kross::Api::Object::Ptr getActivePaintLayer(Kross::Api::List::Ptr); + /** + * Return the width of the image. + */ + Kross::Api::Object::Ptr getWidth(Kross::Api::List::Ptr); + /** + * Return the height of the image. + */ + Kross::Api::Object::Ptr getHeight(Kross::Api::List::Ptr); + /** + * Resize an image + */ + Kross::Api::Object::Ptr resize(Kross::Api::List::Ptr); + /** + * Scale an image + */ + Kross::Api::Object::Ptr scale(Kross::Api::List::Ptr); + /** + * Convert the image to a colorspace. + * This function takes one argument : + * - the name of the destination colorspace + * + * For example (in Ruby) : + * @code + * image.convertToColorspace("CMYK") + * @endcode + */ + Kross::Api::Object::Ptr convertToColorspace(Kross::Api::List::Ptr args); + /** + * Return the id of the colorspace of this image. + */ + Kross::Api::Object::Ptr colorSpaceId(Kross::Api::List::Ptr ); + /** + * Create a new PaintLayer for this image, and return it. + * This function takes at least two arguments : + * - the name of the layer + * - the opacity of the layer (between 0 and 255) + * + * This function can take one optional argument : + * - the id of the colorSpace (if this is not specified, the new PaintLayer + * will have the same colorspace as the image) + */ + Kross::Api::Object::Ptr createPaintLayer(Kross::Api::List::Ptr args); + private: + KisImageSP m_image; + KisDoc* m_doc; +}; + +} + +} + +#endif diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_iterator.h b/chalk/plugins/viewplugins/scripting/chalkcore/krs_iterator.h new file mode 100644 index 00000000..2e17ed98 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_iterator.h @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KROSS_KRITACOREKRS_ITERATOR_H +#define KROSS_KRITACOREKRS_ITERATOR_H + +#include <tqobject.h> +#include <api/class.h> +//#include <api/proxy.h> +//#include <api/variant.h> + +#include <klocale.h> + +#include <kis_paint_layer.h> +#include <kis_paint_device.h> +#include <kis_types.h> + +#include <kis_script_monitor.h> + +namespace Kross { + +namespace ChalkCore { + +//<beurk> stupid TQt which doesn't support templated TQObject +class IteratorMemoryManaged { + public: + virtual void tqinvalidateIterator() = 0; +}; + +class IteratorMemoryManager : public TQObject { + Q_OBJECT + TQ_OBJECT + public: + IteratorMemoryManager(IteratorMemoryManaged* it) : m_it(it) + { + // Connect the Monitor to know when the invalidating of iterator is needed + connect(KisScriptMonitor::instance(), TQT_SIGNAL(executionFinished(const Kross::Api::ScriptAction* )), this, TQT_SLOT(tqinvalidateIterator())); + + } + public slots: + void tqinvalidateIterator() + { + m_it->tqinvalidateIterator(); + } + private: + IteratorMemoryManaged* m_it; +}; +//</beurk> +/** + * This object allow to change the value of pixel one by one. + * The name of some function depends of the colorspace, for instance, if + * the colorspace of the layer is RGB, you will have setR, setG, setB... and for CMYK, + * setC, setM, setY, setK. In the doc bellow we will consider the colorspace is called ABC with + * three channels : A, B and C. + * + * Function: setA setB setC + * Those functions take one argument: + * - the new value of one of the channel of this pixel + * + * Function: setABC + * Set the value of all channels. + * This function take one argument: + * - an array with the new value for all channels + */ +template<class _T_It> +class Iterator : public Kross::Api::Class<Iterator<_T_It> >, private IteratorMemoryManaged +{ + public: + Iterator(_T_It it, KisPaintLayerSP layer) : Kross::Api::Class<Iterator<_T_It> >("ChalkIterator"), m_itmm (new IteratorMemoryManager(this)), m_it(new _T_It(it)), nchannels(layer->paintDevice()->nChannels()), m_layer(layer) + { + // navigate in the iterator + this->addFunction("next", + new Kross::Api::ProxyFunction< + Iterator<_T_It>, // instance + bool (Iterator<_T_It>::*)(), // method + Kross::Api::Variant // return-value + >(this, &Iterator<_T_It>::next)); + this->addFunction("isDone", + new Kross::Api::ProxyFunction< + Iterator<_T_It>, // instance + bool (Iterator<_T_It>::*)(), // method + Kross::Api::Variant // return-value + >(this, &Iterator<_T_It>::isDone)); + + // get/set value + TQValueVector<KisChannelInfo *> channels = layer->paintDevice()->colorSpace()->channels(); + TQString initiales = ""; + for(TQValueVector<KisChannelInfo *>::iterator itC = channels.begin(); itC != channels.end(); itC++) + { + KisChannelInfo * ci = *itC; + initiales += ci->name().left(1); + switch(ci->channelValueType()) + { + case KisChannelInfo::UINT8: + this->addFunction("get"+ci->name(), + new Kross::Api::Function1< Iterator<_T_It> , uint >( + this, &Iterator<_T_It>::getChannelUINT8, ci->pos() ) ); + this->addFunction("set"+ci->name(), + new Kross::Api::Function1< Iterator<_T_It> , uint >( + this, &Iterator<_T_It>::setChannelUINT8, ci->pos() ) ); + break; + case KisChannelInfo::UINT16: + this->addFunction("get"+ci->name(), + new Kross::Api::Function1< Iterator<_T_It> , uint >( + this, &Iterator<_T_It>::getChannelUINT16, ci->pos() ) ); + this->addFunction("set"+ci->name(), + new Kross::Api::Function1< Iterator<_T_It> , uint >( + this, &Iterator<_T_It>::setChannelUINT16, ci->pos() ) ); + break; + case KisChannelInfo::FLOAT32: + this->addFunction("get"+ci->name(), + new Kross::Api::Function1< Iterator<_T_It> , uint >( + this, &Iterator<_T_It>::getChannelFLOAT, ci->pos() ) ); + this->addFunction("set"+ci->name(), + new Kross::Api::Function1< Iterator<_T_It> , uint >( + this, &Iterator<_T_It>::setChannelFLOAT, ci->pos() ) ); + break; + default: + kdDebug(41011) << "unsupported data format in scripts" << endl; + break; + } + } + initiales = initiales.upper(); + // set/get general + addFunction("set" + initiales, &Iterator::setPixel); + addFunction("get" + initiales, &Iterator::getPixel); + kdDebug(41011) << ( "get" + initiales ) << endl; + // Various colorSpace + addFunction("invertColor", &Iterator::invertColor); + addFunction("darken", &Iterator::darken); + } + + ~Iterator() + { + tqinvalidateIterator(); + delete m_itmm; + } + virtual const TQString getClassName() const { + return "Kross::ChalkCore::KrsDoc"; + }; + private: + /** + * Darken a pixel. + * This functions at least one argument: + * - shade amount use to darken all color channels + * + * This function can take the following optional argument: + * - compensation to limit the darkening + */ + Kross::Api::Object::Ptr darken(Kross::Api::List::Ptr args) + { + TQ_INT32 shade = Kross::Api::Variant::toUInt( args->item(0) ); + bool compensate = (args->count() == 2); + double compensation = compensate ? Kross::Api::Variant::toDouble( args->item(2) ) : 0.; + m_layer->paintDevice()->colorSpace()->darken(m_it->rawData(), m_it->rawData(), shade, compensate, compensation, 1); + return 0; + } + /** + * Invert the color of a pixel. + */ + Kross::Api::Object::Ptr invertColor(Kross::Api::List::Ptr ) + { + m_layer->paintDevice()->colorSpace()->invertColor(m_it->rawData(), 1); + return 0; + } + /** + * Increment the positon, and go to the next pixel. + */ + bool next() + { + ++(*m_it); + return m_it->isDone(); + } + /** + * Return true if the iterator is at the end, and that no more pixels are available. + */ + bool isDone() + { + return m_it->isDone(); + } + Kross::Api::Object::Ptr getChannelUINT8(Kross::Api::List::Ptr, uint channelpos) + { + TQ_UINT8* data = (TQ_UINT8*)(m_it->rawData() + channelpos); + return new Kross::Api::Variant( * data); + } + Kross::Api::Object::Ptr setChannelUINT8(Kross::Api::List::Ptr args, uint channelpos) + { + TQ_UINT8* data = (TQ_UINT8*)(m_it->rawData() + channelpos); //*(uint*)channelpos); + *data = Kross::Api::Variant::toUInt( args->item(0) ); + return 0; + } + Kross::Api::Object::Ptr getChannelUINT16(Kross::Api::List::Ptr, uint channelpos) + { + TQ_UINT16* data = (TQ_UINT16*)(m_it->rawData() + channelpos); + return new Kross::Api::Variant( * data); + } + Kross::Api::Object::Ptr setChannelUINT16(Kross::Api::List::Ptr args, uint channelpos) + { + TQ_UINT16* data = (TQ_UINT16*)(m_it->rawData() + channelpos); + *data = Kross::Api::Variant::toUInt( args->item(0) ); + return 0; + } + Kross::Api::Object::Ptr getChannelFLOAT(Kross::Api::List::Ptr, uint channelpos) + { + float* data = (float*)(m_it->rawData() + channelpos); + return new Kross::Api::Variant( * data); + } + Kross::Api::Object::Ptr setChannelFLOAT(Kross::Api::List::Ptr args, uint channelpos) + { + float* data = (float*)(m_it->rawData() + channelpos); + *data = Kross::Api::Variant::toUInt( args->item(0) ); + return 0; + } + Kross::Api::Object::Ptr getPixel(Kross::Api::List::Ptr) + { + TQValueVector<KisChannelInfo *> channels = m_layer->paintDevice()->colorSpace()->channels(); + TQValueList<TQVariant> pixel; + for(TQValueVector<KisChannelInfo *>::iterator itC = channels.begin(); itC != channels.end(); itC++) + { + KisChannelInfo * ci = *itC; + TQ_UINT8* data = (TQ_UINT8*)(m_it->rawData() + ci->pos()); + switch(ci->channelValueType()) + { + case KisChannelInfo::UINT8: + pixel.push_back( *data); + break; + case KisChannelInfo::UINT16: + pixel.push_back( *((TQ_UINT16*) data) ); + break; + case KisChannelInfo::FLOAT32: + pixel.push_back( *((float*) data) ); + break; + default: + kdDebug(41011) << i18n("An error has occurred in %1").tqarg("getPixel") << endl; + kdDebug(41011) << i18n("unsupported data format in scripts") << endl; + break; + } + } + return new Kross::Api::Variant( pixel); + } + Kross::Api::Object::Ptr setPixel(Kross::Api::List::Ptr args) + { + TQValueList<TQVariant> pixel = Kross::Api::Variant::toList( args->item(0) ); + TQValueVector<KisChannelInfo *> channels = m_layer->paintDevice()->colorSpace()->channels(); + uint i = 0; + for(TQValueVector<KisChannelInfo *>::iterator itC = channels.begin(); itC != channels.end(); itC++, i++) + { + KisChannelInfo * ci = *itC; + TQ_UINT8* data = (TQ_UINT8*)(m_it->rawData() + ci->pos()); + switch(ci->channelValueType()) + { + case KisChannelInfo::UINT8: + *data = pixel[i].toUInt(); + break; + case KisChannelInfo::UINT16: + *((TQ_UINT16*) data) = pixel[i].toUInt(); + break; + case KisChannelInfo::FLOAT32: + *((float*) data) = pixel[i].toDouble(); + break; + default: + kdDebug(41011) << i18n("An error has occurred in %1").tqarg("setPixel") << endl; + kdDebug(41011) << i18n("unsupported data format in scripts") << endl; + break; + } + } + return 0; + } + private: + virtual void tqinvalidateIterator() + { + kdDebug(41011) << "invalidating iterator" << endl; + if(m_it) + { + kdDebug(41011) << "deleting iterator" << endl; + delete m_it; + } + m_it = 0; + kdDebug() << " Iterator = " << m_it << endl; + } + private: + IteratorMemoryManager* m_itmm; + _T_It* m_it; + int nchannels; + KisPaintLayerSP m_layer; +}; + +} + +} + +#endif diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_paint_layer.cpp b/chalk/plugins/viewplugins/scripting/chalkcore/krs_paint_layer.cpp new file mode 100644 index 00000000..5f800f6a --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_paint_layer.cpp @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "krs_paint_layer.h" + +#include <klocale.h> + +#include <kis_colorspace_factory_registry.h> +#include <kis_doc.h> +#include <kis_layer.h> +#include <kis_meta_registry.h> +#include <kis_iterators_pixel.h> +#include <kis_transaction.h> +#include <kis_math_toolbox.h> + +#include "krs_iterator.h" +#include "krs_histogram.h" +#include "krs_painter.h" +#include "krs_wavelet.h" + +namespace Kross { + +namespace ChalkCore { + +PaintLayer::PaintLayer(KisPaintLayerSP layer, KisDoc* doc) + : Kross::Api::Class<PaintLayer>("ChalkLayer"), m_layer(layer), m_doc(doc), m_cmd(0) +{ + addFunction("createRectIterator", &PaintLayer::createRectIterator); + addFunction("createHLineIterator", &PaintLayer::createHLineIterator); + addFunction("createVLineIterator", &PaintLayer::createVLineIterator); + addFunction("getWidth", &PaintLayer::getWidth); + addFunction("getHeight", &PaintLayer::getHeight); + addFunction("createHistogram", &PaintLayer::createHistogram); + addFunction("createPainter", &PaintLayer::createPainter); + addFunction("beginPainting", &PaintLayer::beginPainting); + addFunction("endPainting", &PaintLayer::endPainting); + addFunction("convertToColorspace", &PaintLayer::convertToColorspace); + addFunction("fastWaveletTransformation", &PaintLayer::fastWaveletTransformation); + addFunction("fastWaveletUntransformation", &PaintLayer::fastWaveletUntransformation); + addFunction("colorSpaceId", &PaintLayer::colorSpaceId); +} + + +PaintLayer::~PaintLayer() +{ +} + +const TQString PaintLayer::getClassName() const { + return "Kross::ChalkCore::PaintLayer"; +} + +Kross::Api::Object::Ptr PaintLayer::createRectIterator(Kross::Api::List::Ptr args) +{ + return new Iterator<KisRectIteratorPixel>( + paintLayer()->paintDevice()->createRectIterator(Kross::Api::Variant::toUInt(args->item(0)), + Kross::Api::Variant::toUInt(args->item(1)), + Kross::Api::Variant::toUInt(args->item(2)), + Kross::Api::Variant::toUInt(args->item(3)), true), + paintLayer()); +} +Kross::Api::Object::Ptr PaintLayer::createHLineIterator(Kross::Api::List::Ptr args) +{ + return new Iterator<KisHLineIteratorPixel>( + paintLayer()->paintDevice()->createHLineIterator(Kross::Api::Variant::toUInt(args->item(0)), + Kross::Api::Variant::toUInt(args->item(1)), + Kross::Api::Variant::toUInt(args->item(2)), true), + paintLayer()); +} +Kross::Api::Object::Ptr PaintLayer::createVLineIterator(Kross::Api::List::Ptr args) +{ + return new Iterator<KisVLineIteratorPixel>( + paintLayer()->paintDevice()->createVLineIterator(Kross::Api::Variant::toUInt(args->item(0)), + Kross::Api::Variant::toUInt(args->item(1)), + Kross::Api::Variant::toUInt(args->item(2)), true), + paintLayer()); +} +Kross::Api::Object::Ptr PaintLayer::getWidth(Kross::Api::List::Ptr) +{ + TQRect r1 = paintLayer()->extent(); + TQRect r2 = paintLayer()->image()->bounds(); + TQRect rect = r1.intersect(r2); + return new Kross::Api::Variant(rect.width()); +} +Kross::Api::Object::Ptr PaintLayer::getHeight(Kross::Api::List::Ptr) +{ + TQRect r1 = paintLayer()->extent(); + TQRect r2 = paintLayer()->image()->bounds(); + TQRect rect = r1.intersect(r2); + return new Kross::Api::Variant(rect.height()); +} + +Kross::Api::Object::Ptr PaintLayer::createHistogram(Kross::Api::List::Ptr args) +{ + TQString histoname = Kross::Api::Variant::toString(args->item(0)); + KisHistogramProducerFactory* factory = KisHistogramProducerFactoryRegistry::instance()->get(histoname); + +/* KisIDList listID = KisHistogramProducerFactoryRegistry::instance()->listKeys(); + for(KisIDList::iterator it = listID.begin(); it != listID.end(); it++) + { + kdDebug(41011) << (*it).name() << " " << (*it).id() << endl; + }*/ + + enumHistogramType type ; + switch( Kross::Api::Variant::toUInt(args->item(1)) ) + { + case 1: + type = LOGARITHMIC; + break; + case 0: + default: + type = LINEAR; + break; + } + if(factory && factory->isCompatibleWith( paintLayer()->paintDevice()->colorSpace() )) + { + return new Histogram( paintLayer().data(), factory->generate() , type); + } else { + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception( i18n("An error has occured in %1").tqarg("createHistogram") + "\n" + i18n("The histogram %1 is not available").tqarg(histoname) ) ); + } + return 0; +} + +Kross::Api::Object::Ptr PaintLayer::createPainter(Kross::Api::List::Ptr ) +{ + return new Painter(paintLayer()); +} + +Kross::Api::Object::Ptr PaintLayer::beginPainting(Kross::Api::List::Ptr args) +{ + TQString name = Kross::Api::Variant::toString(args->item(0)); + if(m_cmd != 0) + { + delete m_cmd; + } + m_cmd = new KisTransaction(name, paintLayer()->paintDevice()); + Q_CHECK_PTR(m_cmd); + return 0; +} + +Kross::Api::Object::Ptr PaintLayer::endPainting(Kross::Api::List::Ptr) +{ + if(doc() !=0) + { + doc()->setModified(true); + doc()->currentImage()->activeLayer()->setDirty(); + } + if(m_cmd != 0) + { + paintLayer()->image()->undoAdapter()->addCommand(m_cmd); + } + return 0; +} + +Kross::Api::Object::Ptr PaintLayer::convertToColorspace(Kross::Api::List::Ptr args) +{ + KisColorSpace * dstCS = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID(Kross::Api::Variant::toString(args->item(0)), ""), ""); + if(!dstCS) + { + // FIXME: inform user + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception( i18n("An error has occured in %1").tqarg("convertToColorspace") + "\n" + i18n("Colorspace %1 is not available, please check your installation.").tqarg(Kross::Api::Variant::toString(args->item(0))) ) ); + return 0; + } + paintLayer()->paintDevice()->convertTo(dstCS); + return 0; +} + +Kross::Api::Object::Ptr PaintLayer::colorSpaceId(Kross::Api::List::Ptr ) +{ + return new Kross::Api::Variant( paintLayer()->paintDevice()->colorSpace()->id().id() ); +} + + +Kross::Api::Object::Ptr PaintLayer::fastWaveletTransformation(Kross::Api::List::Ptr ) +{ + KisMathToolbox* mathToolbox = KisMetaRegistry::instance()->mtRegistry()->get( paintLayer()->paintDevice()->colorSpace()->mathToolboxID() ); + TQRect rect = paintLayer()->exactBounds(); + KisMathToolbox::KisWavelet* wav = mathToolbox->fastWaveletTransformation(paintLayer()->paintDevice(), rect); + return new Wavelet(wav); +} +Kross::Api::Object::Ptr PaintLayer::fastWaveletUntransformation(Kross::Api::List::Ptr args) +{ + Wavelet* wav = (Wavelet*)args->item(0).data(); + KisMathToolbox* mathToolbox = KisMetaRegistry::instance()->mtRegistry()->get( paintLayer()->paintDevice()->colorSpace()->mathToolboxID() ); + TQRect rect = paintLayer()->exactBounds(); + mathToolbox->fastWaveletUntransformation( paintLayer()->paintDevice(), rect, wav->wavelet() ); + return 0; +} + + +} + +} diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_paint_layer.h b/chalk/plugins/viewplugins/scripting/chalkcore/krs_paint_layer.h new file mode 100644 index 00000000..18ac5088 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_paint_layer.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KROSS_KRITACOREKRSLAYER_H +#define KROSS_KRITACOREKRSLAYER_H + +#include <api/class.h> + +#include <kis_types.h> +#include <kis_paint_layer.h> + +class KisDoc; +class KisTransaction; + +namespace Kross { + +namespace ChalkCore { + +/** +@author Cyrille Berger +*/ +class PaintLayer : public Kross::Api::Class<PaintLayer> +{ + public: + explicit PaintLayer(KisPaintLayerSP layer, KisDoc* doc = 0); + virtual ~PaintLayer(); + virtual const TQString getClassName() const; + private: + /** + * Create an iterator over a layer, it will iterate on a rectangle area. + * This function takes four arguments : + * - x + * - y + * - width of the rectangle + * - height of the rectangle + */ + Kross::Api::Object::Ptr createRectIterator(Kross::Api::List::Ptr); + /** + * Create an iterator over a layer, it will iterate on a row. + * This function takes three arguments : + * - x start in the row + * - y vertical position of the row + * - width of the row + */ + Kross::Api::Object::Ptr createHLineIterator(Kross::Api::List::Ptr); + /** + * Create an iterator over a layer, it will iterate on a column. + * This function takes three arguments : + * - x horizontal position of the column + * - y start in the column + * - height of the column + */ + Kross::Api::Object::Ptr createVLineIterator(Kross::Api::List::Ptr); + /** + * Return the width of the layer + */ + Kross::Api::Object::Ptr getWidth(Kross::Api::List::Ptr); + /** + * Return the height of the layer + */ + Kross::Api::Object::Ptr getHeight(Kross::Api::List::Ptr); + /** + * This function creates an Histogram for this layer. + * It takes two arguments : + * - the type of the histogram ("RGB8HISTO") + * - 0 if the histogram is linear, or 1 if it is logarithmic + */ + Kross::Api::Object::Ptr createHistogram(Kross::Api::List::Ptr); + /** + * This function create a Painter which will allow you to some painting on the layer. + */ + Kross::Api::Object::Ptr createPainter(Kross::Api::List::Ptr); + /** + * Uses this function to create a new undo entry. + */ + Kross::Api::Object::Ptr beginPainting(Kross::Api::List::Ptr args); + /** + * Uses this function to close the current undo entry and add it to the history. + */ + Kross::Api::Object::Ptr endPainting(Kross::Api::List::Ptr args); + /** + * Convert the image to a colorspace. + * This function takes one argument : + * - the name of the destination colorspace + * + * For example (in Ruby) : + * @code + * image.convertToColorspace("CMYK") + * @endcode + */ + Kross::Api::Object::Ptr convertToColorspace(Kross::Api::List::Ptr args); + /** + * Return the id of the colorspace of this paint layer. + */ + Kross::Api::Object::Ptr colorSpaceId(Kross::Api::List::Ptr ); + /** + * Return the fast wavelet transformed of the layer + */ + Kross::Api::Object::Ptr fastWaveletTransformation(Kross::Api::List::Ptr args); + /** + * Untransform a fast wavelet into this layer + * It takes one argument : + * - a wavelet object + * + * For example (in Ruby) : + * @code + * wavelet = layer.fastWaveletTransformation() + * layer.fastWaveletUntransformation(wavelet) + * @endcode + */ + Kross::Api::Object::Ptr fastWaveletUntransformation(Kross::Api::List::Ptr args); + public: + inline KisPaintLayerSP paintLayer() { return m_layer; } + inline KisDoc* doc() { return m_doc; } + private: + KisPaintLayerSP m_layer; + KisDoc* m_doc; + KisTransaction* m_cmd; +}; + +} + +} + +#endif diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_painter.cpp b/chalk/plugins/viewplugins/scripting/chalkcore/krs_painter.cpp new file mode 100644 index 00000000..44991303 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_painter.cpp @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2005-2006 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "krs_painter.h" + +#include <kis_convolution_painter.h> +#include <kis_fill_painter.h> +#include <kis_paint_layer.h> +#include <kis_paintop_registry.h> +#include <kis_painter.h> + +#include "krs_brush.h" +#include "krs_color.h" +#include "krs_pattern.h" + +namespace Kross { + +namespace ChalkCore { + +Painter::Painter(KisPaintLayerSP layer) + : Kross::Api::Class<Painter>("ChalkPainter"), m_layer(layer),m_painter(new KisPainter(layer->paintDevice())),m_threshold(1) +{ + // convolution + addFunction("convolve", &Painter::convolve); + // Fill specific + addFunction("setFillThreshold", &Painter::setFillThreshold); + addFunction("fillColor", &Painter::fillColor); + addFunction("fillPattern", &Painter::fillPattern); + + // Painting operations + addFunction("paintPolyline", &Painter::paintPolyline); + addFunction("paintLine", &Painter::paintLine); + addFunction("paintBezierCurve", &Painter::paintBezierCurve); + addFunction("paintEllipse", &Painter::paintEllipse); + addFunction("paintPolygon", &Painter::paintPolygon); + addFunction("paintRect", &Painter::paintRect); + addFunction("paintAt", &Painter::paintAt); + addFunction("setBackgroundColor", &Painter::setBackgroundColor); + addFunction("setPaintColor", &Painter::setPaintColor); + + // Color operations + addFunction("setPattern", &Painter::setPattern); + addFunction("setBrush", &Painter::setBrush); + + // How is painting done operations + addFunction("setPaintOp", &Painter::setPaintOp); + // Special settings + addFunction("setDuplicateOffset", &Painter::setDuplicateOffset); + + // Style operation + addFunction("setOpacity", &Painter::setOpacity); + addFunction("setStrokeStyle", &Painter::setStrokeStyle); + addFunction("setFillStyle", &Painter::setFillStyle); +} + + +Painter::~Painter() +{ + delete m_painter; +} + +Kross::Api::Object::Ptr Painter::convolve(Kross::Api::List::Ptr args) +{ + KisConvolutionPainter* cp = new KisConvolutionPainter(m_painter->device()); + TQRect rect; + KisKernel kernel; + kernel.factor = Kross::Api::Variant::toInt(args->item(1)); + kernel.offset = Kross::Api::Variant::toInt(args->item(2)); + + uint borderop = 3; + if( args.count() > 3 ) + { + borderop = Kross::Api::Variant::toUInt(args->item(3)); + } + uint channelsFlag = KisChannelInfo::FLAG_COLOR; + if( args.count() > 4 ) + { + channelsFlag = Kross::Api::Variant::toUInt(args->item(4)); + } + if( args.count() > 5) + { + uint x = Kross::Api::Variant::toUInt(args->item(5)); + uint y = Kross::Api::Variant::toUInt(args->item(6)); + uint w = Kross::Api::Variant::toUInt(args->item(7)); + uint h = Kross::Api::Variant::toUInt(args->item(8)); + rect = TQRect(x,y,w,h); + } else { + TQRect r1 = paintLayer()->paintDevice()->extent(); + TQRect r2 = paintLayer()->image()->bounds(); + rect = r1.intersect(r2); + } + + TQValueList<TQVariant> kernelH = Kross::Api::Variant::toList( args->item(0) ); + + TQVariant firstlineVariant = *kernelH.begin(); + if(firstlineVariant.type() != TQVariant::List) + { + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(i18n("An error has occured in %1").tqarg("applyConvolution")) ); + } + + TQValueList<TQVariant> firstline = firstlineVariant.toList(); + + kernel.height = kernelH.size(); + kernel.width = firstline.size(); + + kernel.data = new TQ_INT32[kernel.height * kernel.width]; + + uint i = 0; + for(TQValueList<TQVariant>::iterator itK = kernelH.begin(); itK != kernelH.end(); itK++, i ++ ) + { + TQVariant lineVariant = *kernelH.begin(); + if(lineVariant.type() != TQVariant::List) + { + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(i18n("An error has occured in %1").tqarg("applyConvolution")) ); + } + TQValueList<TQVariant> line = firstlineVariant.toList(); + if(line.size() != kernel.width) + { + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(i18n("An error has occured in %1").tqarg("applyConvolution")) ); + } + uint j = 0; + for(TQValueList<TQVariant>::iterator itLine = line.begin(); itLine != line.end(); itLine++, j ++ ) + { + kernel.data[ j + i * kernel.width ] = (*itLine).toInt(); + } + } + cp->applyMatrix(&kernel, rect.x(), rect.y(), rect.width(), rect.height(), (KisConvolutionBorderOp)borderop, (KisChannelInfo::enumChannelFlags) channelsFlag); + + delete[] kernel.data; + return 0; +} + + +KisFillPainter* Painter::createFillPainter() +{ + KisFillPainter* fp = new KisFillPainter(m_painter->device()); + fp->setBrush( m_painter->brush() ); + fp->setFillColor( m_painter->fillColor() ); + fp->setPaintColor( m_painter->paintColor() ); + fp->setFillStyle( m_painter->fillStyle() ); + fp->setOpacity( m_painter->opacity() ); + fp->setPattern( m_painter->pattern() ); + return fp; +} + +Kross::Api::Object::Ptr Painter::setFillThreshold(Kross::Api::List::Ptr args) +{ + m_threshold = Kross::Api::Variant::toInt(args->item(0)); + return 0; +} +Kross::Api::Object::Ptr Painter::fillColor(Kross::Api::List::Ptr args) +{ + KisFillPainter* fp = createFillPainter(); + uint x = Kross::Api::Variant::toUInt(args->item(0)); + uint y = Kross::Api::Variant::toUInt(args->item(1)); + + fp->fillColor( x, y ); + return 0; +} +Kross::Api::Object::Ptr Painter::fillPattern(Kross::Api::List::Ptr args) +{ + KisFillPainter* fp = createFillPainter(); + uint x = Kross::Api::Variant::toUInt(args->item(0)); + uint y = Kross::Api::Variant::toUInt(args->item(1)); + fp->fillPattern(x, y); + return 0; +} + +Kross::Api::Object::Ptr Painter::setStrokeStyle(Kross::Api::List::Ptr args) +{ + uint style = Kross::Api::Variant::toVariant(args->item(0)).toUInt(); + KisPainter::StrokeStyle strokestyle; + switch(style) + { + case 1: + strokestyle = KisPainter::StrokeStyleBrush; + break; + default: + strokestyle = KisPainter::StrokeStyleNone; + } + m_painter->setStrokeStyle(strokestyle); + return 0; +} + +Kross::Api::Object::Ptr Painter::setFillStyle(Kross::Api::List::Ptr args) +{ + uint style = Kross::Api::Variant::toVariant(args->item(0)).toUInt(); + KisPainter::FillStyle fillstyle; + switch(style) + { + case 1: + fillstyle = KisPainter::FillStyleForegroundColor; + break; + case 2: + fillstyle = KisPainter::FillStyleBackgroundColor; + break; + case 3: + fillstyle = KisPainter::FillStylePattern; + break; + default: + fillstyle = KisPainter::FillStyleNone; + } + m_painter->setFillStyle(fillstyle); + return 0; +} + +Kross::Api::Object::Ptr Painter::setOpacity(Kross::Api::List::Ptr args) +{ + TQ_UINT8 opacity = Kross::Api::Variant::toVariant(args->item(0)).toUInt(); + m_painter->setOpacity(opacity); + return 0; +} + +Kross::Api::Object::Ptr Painter::setDuplicateOffset(Kross::Api::List::Ptr args) +{ + double x1 = Kross::Api::Variant::toVariant(args->item(0)).toDouble(); + double y1 = Kross::Api::Variant::toVariant(args->item(1)).toDouble(); + m_painter->setDuplicateOffset(KisPoint(x1,y1)); + return 0; +} + +Kross::Api::Object::Ptr Painter::paintPolyline(Kross::Api::List::Ptr args) +{ + TQValueList<TQVariant> pointsX = Kross::Api::Variant::toList( args->item(0) ); + TQValueList<TQVariant> pointsY = Kross::Api::Variant::toList( args->item(1) ); + if(pointsX.size() != pointsY.size()) + { + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception("the two lists should have the same size.") ); + } + m_painter->paintPolyline( createPointsVector( pointsX, pointsY)); + return 0; +} + +Kross::Api::Object::Ptr Painter::paintLine(Kross::Api::List::Ptr args) +{ + double x1 = Kross::Api::Variant::toVariant(args->item(0)).toDouble(); + double y1 = Kross::Api::Variant::toVariant(args->item(1)).toDouble(); + double p1 = Kross::Api::Variant::toVariant(args->item(2)).toDouble(); + double x2 = Kross::Api::Variant::toVariant(args->item(3)).toDouble(); + double y2 = Kross::Api::Variant::toVariant(args->item(4)).toDouble(); + double p2 = Kross::Api::Variant::toVariant(args->item(5)).toDouble(); + m_painter->paintLine(KisPoint( x1, y1), p1, 0.0, 0.0, KisPoint( x2, y2 ), p2, 0.0, 0.0 ); + return 0; +} + +Kross::Api::Object::Ptr Painter::paintBezierCurve(Kross::Api::List::Ptr args) +{ + double x1 = Kross::Api::Variant::toVariant(args->item(0)).toDouble(); + double y1 = Kross::Api::Variant::toVariant(args->item(1)).toDouble(); + double p1 = Kross::Api::Variant::toVariant(args->item(2)).toDouble(); + double cx1 = Kross::Api::Variant::toVariant(args->item(3)).toDouble(); + double cy1 = Kross::Api::Variant::toVariant(args->item(4)).toDouble(); + double cx2 = Kross::Api::Variant::toVariant(args->item(5)).toDouble(); + double cy2 = Kross::Api::Variant::toVariant(args->item(6)).toDouble(); + double x2 = Kross::Api::Variant::toVariant(args->item(7)).toDouble(); + double y2 = Kross::Api::Variant::toVariant(args->item(8)).toDouble(); + double p2 = Kross::Api::Variant::toVariant(args->item(9)).toDouble(); + m_painter->paintBezierCurve( KisPoint(x1,y1), p1, 0.0, 0.0, KisPoint(cx1,cy1), KisPoint(cx2,cy2), KisPoint(x2,y2), p2, 0.0, 0.0); + return 0; +} + +Kross::Api::Object::Ptr Painter::paintEllipse(Kross::Api::List::Ptr args) +{ + double x1 = Kross::Api::Variant::toVariant(args->item(0)).toDouble(); + double y1 = Kross::Api::Variant::toVariant(args->item(1)).toDouble(); + double x2 = Kross::Api::Variant::toVariant(args->item(2)).toDouble(); + double y2 = Kross::Api::Variant::toVariant(args->item(3)).toDouble(); + double p1 = Kross::Api::Variant::toVariant(args->item(4)).toDouble(); + m_painter->paintEllipse( KisPoint(x1,y1), KisPoint(x2,y2), p1, 0.0, 0.0 ); + return 0; +} + +Kross::Api::Object::Ptr Painter::paintPolygon(Kross::Api::List::Ptr args) +{ + TQValueList<TQVariant> pointsX = Kross::Api::Variant::toList( args->item(0) ); + TQValueList<TQVariant> pointsY = Kross::Api::Variant::toList( args->item(1) ); + if(pointsX.size() != pointsY.size()) + { + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception("the two lists should have the same size.") ); + } + m_painter->paintPolygon( createPointsVector(pointsX, pointsY)); + return 0; +} + +Kross::Api::Object::Ptr Painter::paintRect(Kross::Api::List::Ptr args) +{ + double x1 = Kross::Api::Variant::toVariant(args->item(0)).toDouble(); + double y1 = Kross::Api::Variant::toVariant(args->item(1)).toDouble(); + double x2 = Kross::Api::Variant::toVariant(args->item(2)).toDouble(); + double y2 = Kross::Api::Variant::toVariant(args->item(3)).toDouble(); + double p1 = Kross::Api::Variant::toVariant(args->item(4)).toDouble(); + m_painter->paintRect( KisPoint(x1, y1), KisPoint(x2,y2), p1, 0, 0); + return 0; +} + +Kross::Api::Object::Ptr Painter::paintAt(Kross::Api::List::Ptr args) +{ + double x1 = Kross::Api::Variant::toVariant(args->item(0)).toDouble(); + double y1 = Kross::Api::Variant::toVariant(args->item(1)).toDouble(); + double p1 = Kross::Api::Variant::toVariant(args->item(2)).toDouble(); + m_painter->paintAt( KisPoint( x1, y1 ), p1, 0.0, 0.0); + return 0; +} + +Kross::Api::Object::Ptr Painter::setBackgroundColor(Kross::Api::List::Ptr args) +{ + Color* c = (Color*)args->item(0).data(); + m_painter->setBackgroundColor( KisColor(c->toTQColor(), paintLayer()->paintDevice()->colorSpace() )); + return 0; +} + +Kross::Api::Object::Ptr Painter::setPaintColor(Kross::Api::List::Ptr args) +{ + Color* c = (Color*)args->item(0).data(); + m_painter->setPaintColor( KisColor(c->toTQColor(), paintLayer()->paintDevice()->colorSpace() )); + return 0; +} + +Kross::Api::Object::Ptr Painter::setPattern(Kross::Api::List::Ptr args) +{ + Pattern* p = (Pattern*)args->item(0).data(); + m_painter->setPattern( p->getPattern()); + return 0; +} + + +Kross::Api::Object::Ptr Painter::setBrush(Kross::Api::List::Ptr args) +{ + Brush* b = (Brush*)args->item(0).data(); + m_painter->setBrush( b->getBrush()); + return 0; +} +Kross::Api::Object::Ptr Painter::setPaintOp(Kross::Api::List::Ptr args) +{ + TQString id = Kross::Api::Variant::toString(args->item(0)); + KisPaintOp* op = KisPaintOpRegistry::instance()->paintOp( id, 0, m_painter ); + m_painter->setPaintOp( op ); + return 0; +} + +} + +} diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_painter.h b/chalk/plugins/viewplugins/scripting/chalkcore/krs_painter.h new file mode 100644 index 00000000..f4e2c06a --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_painter.h @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2005-2006 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KROSS_KRITACOREKRS_PAINTER_H +#define KROSS_KRITACOREKRS_PAINTER_H + +#include <api/class.h> + +#include <kis_point.h> +#include <kis_types.h> +#include <kis_paint_layer.h> + +class KisPainter; +class KisFillPainter; + +namespace Kross { + +namespace ChalkCore { + +class Painter : public Kross::Api::Class<Painter> +{ + public: + explicit Painter(KisPaintLayerSP layer); + ~Painter(); + private: + // Convolution + /** + * This function apply a convolution kernel to an image. + * It takes at least three arguments : + * - a list of a list with the kernel (all lists need to have the same size) + * - factor + * - offset + * + * The value of a pixel will be given by the following function K*P/factor + offset, + * where K is the kernel and P is the neighbourhood. + * + * It can takes the following optional arguments : + * - borderOp control how to convolve the pixels on the border of an image ( 0 use the default color + * 1 use the pixel on the opposite side of the image 2 use the border pixel 3 avoid border pixels) + * - channel ( 1 for color 2 for alpha 3 for both) + * - x + * - y + * - width + * - height + */ + Kross::Api::Object::Ptr convolve(Kross::Api::List::Ptr args); + // Fill specific + /** + * Set the threshold the fill threshold. + * It takes one argument : + * - threshold + */ + Kross::Api::Object::Ptr setFillThreshold(Kross::Api::List::Ptr args); + /** + * Start filling color. + * It takes two argument : + * - x + * - y + */ + Kross::Api::Object::Ptr fillColor(Kross::Api::List::Ptr args); + /** + * start filling a pattern + * It takes two argument : + * - x + * - y + */ + Kross::Api::Object::Ptr fillPattern(Kross::Api::List::Ptr args); + // Painting operations + /** + * This function will paint a polyline. + * It takes two arguments : + * - a list of x position + * - a list of y position + */ + Kross::Api::Object::Ptr paintPolyline(Kross::Api::List::Ptr args); + /** + * This function will paint a line. + * It takes five arguments : + * - x1 + * - y1 + * - x2 + * - y2 + * - pressure + */ + Kross::Api::Object::Ptr paintLine(Kross::Api::List::Ptr args); + /** + * This function will paint a Bezier curve. + * It takes ten arguments : + * - x1 + * - y1 + * - p1 + * - cx1 + * - cy1 + * - cx2 + * - cx2 + * - x2 + * - y2 + * - p2 + * + * Where (x1,y1) is the start position, p1 is the pressure at the start, + * (x2,y2) is the ending position, p2 is the pressure at the end. (cx1,cy1) and (cx2,cy2) + * are the position of the control points. + */ + Kross::Api::Object::Ptr paintBezierCurve(Kross::Api::List::Ptr args); + /** + * This function will paint an ellipse. + * It takes five arguments : + * - x1 + * - y1 + * - x2 + * - y2 + * - pressure + * + * Where (x1,y1) and (x2,y2) are the position of the two centers. + */ + Kross::Api::Object::Ptr paintEllipse(Kross::Api::List::Ptr args); + /** + * This function will paint a polygon. + * It takes two arguments : + * - a list of x position + * - a list of y position + */ + Kross::Api::Object::Ptr paintPolygon(Kross::Api::List::Ptr args); + /** + * This function will paint a rectangle. + * It takes five arguments : + * - x + * - y + * - width + * - height + * - pressure + */ + Kross::Api::Object::Ptr paintRect(Kross::Api::List::Ptr args); + /** + * This function will paint at a given position. + * It takes three arguments : + * - x + * - y + * - pressure + */ + Kross::Api::Object::Ptr paintAt(Kross::Api::List::Ptr args); + // Color operations + /** + * This functions set the paint color (also called foreground color). + * It takes one argument : + * - a Color + */ + Kross::Api::Object::Ptr setPaintColor(Kross::Api::List::Ptr args); + /** + * This functions set the background color. + * It takes one argument : + * - a Color + */ + Kross::Api::Object::Ptr setBackgroundColor(Kross::Api::List::Ptr args); + // How is painting done operations + /** + * This functions set the pattern used for filling. + * It takes one argument : + * - a Pattern object + */ + Kross::Api::Object::Ptr setPattern(Kross::Api::List::Ptr args); + /** + * This functions set the brush used for painting. + * It takes one argument : + * - a Brush object + */ + Kross::Api::Object::Ptr setBrush(Kross::Api::List::Ptr args); + /** + * This function define the paint operation. + * It takes one argument : + * - the name of the paint operation + */ + Kross::Api::Object::Ptr setPaintOp(Kross::Api::List::Ptr args); + // Special settings + /** + * This function define the duplicate offset. + * It takes two arguments : + * - horizontal offset + * - vertical offset + */ + Kross::Api::Object::Ptr setDuplicateOffset(Kross::Api::List::Ptr args); + // Style operation + /** + * This function set the opacity of the painting + * It takes one argument : + * - opacity in the range 0 to 255 + */ + Kross::Api::Object::Ptr setOpacity(Kross::Api::List::Ptr args); + /** + * This function set the style of the stroke. + * It takes one argument : + * - 0 for none 1 for brush + */ + Kross::Api::Object::Ptr setStrokeStyle(Kross::Api::List::Ptr args); + /** + * This function set the fill style of the Painter. + * It takes one argument : + * - 0 for none 1 for fill with foreground color 2 for fill with background color + * 3 for fill with a pattern + */ + Kross::Api::Object::Ptr setFillStyle(Kross::Api::List::Ptr args); + protected: + inline KisPaintLayerSP paintLayer() { return m_layer; } + private: + inline vKisPoint createPointsVector( TQValueList<TQVariant> xs, TQValueList<TQVariant> ys) + { + vKisPoint a; + TQValueList<TQVariant>::iterator itx = xs.begin(); + TQValueList<TQVariant>::iterator ity = ys.begin(); + for(; itx != xs.end(); ++itx, ++ity) + { + a.push_back(KisPoint( (*itx).toDouble(), (*ity).toDouble())); + } + return a; + } + inline KisFillPainter* createFillPainter(); + private: + KisPaintLayerSP m_layer; + KisPainter* m_painter; + int m_threshold; +}; + +} + +} + +#endif diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_pattern.cpp b/chalk/plugins/viewplugins/scripting/chalkcore/krs_pattern.cpp new file mode 100644 index 00000000..8ee4f909 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_pattern.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "krs_pattern.h" + +#include <kis_pattern.h> + +namespace Kross { + +namespace ChalkCore { + +Pattern::Pattern(KisPattern* pattern, bool sharedPattern) : Kross::Api::Class<Pattern>("ChalkPattern"), m_pattern(pattern), m_sharedPattern(sharedPattern) +{ +} + +Pattern::~Pattern() +{ + if(!m_sharedPattern) + delete m_pattern; +} + +} + +} diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_pattern.h b/chalk/plugins/viewplugins/scripting/chalkcore/krs_pattern.h new file mode 100644 index 00000000..be39cf31 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_pattern.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KROSS_KRITACOREKRS_PATTERN_H +#define KROSS_KRITACOREKRS_PATTERN_H + +#include <api/class.h> + +class KisPattern; + +namespace Kross { + +namespace ChalkCore { + +class Pattern : public Kross::Api::Class<Pattern>{ + public: + /** + * @param sharedPattern tell if the pattern should be deleted or not when this object is deleted + */ + Pattern(KisPattern*, bool sharedPattern); + ~Pattern(); + public: + inline KisPattern* getPattern() { return m_pattern; } + private: + KisPattern* m_pattern; + bool m_sharedPattern; +}; + +} + +} + +#endif diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_script_progress.cpp b/chalk/plugins/viewplugins/scripting/chalkcore/krs_script_progress.cpp new file mode 100644 index 00000000..b36076c4 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_script_progress.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "krs_script_progress.h" + +#include "kis_script_progress.h" + +namespace Kross { + +namespace ChalkCore { + +ScriptProgress::ScriptProgress(KisScriptProgress* script): Kross::Api::Class<ScriptProgress>("ChalkScript"), m_script(script) +{ + addFunction("setProgressTotalSteps", &ScriptProgress::setProgressTotalSteps); + addFunction("setProgressTotalSteps", &ScriptProgress::setProgressTotalSteps); + addFunction("setProgress", &ScriptProgress::setProgress); + addFunction("incProgress", &ScriptProgress::incProgress); + addFunction("setProgressStage", &ScriptProgress::setProgressStage); +} + + +ScriptProgress::~ScriptProgress() +{ +} + +Kross::Api::Object::Ptr ScriptProgress::setProgressTotalSteps(Kross::Api::List::Ptr args) +{ + m_script->setProgressTotalSteps( Kross::Api::Variant::toUInt(args->item(0)) ); + return 0; +} + +Kross::Api::Object::Ptr ScriptProgress::setProgress(Kross::Api::List::Ptr args) +{ + m_script->setProgress( Kross::Api::Variant::toUInt(args->item(0)) ); + return 0; +} + +Kross::Api::Object::Ptr ScriptProgress::incProgress(Kross::Api::List::Ptr) +{ + m_script->incProgress(); + return 0; +} + +Kross::Api::Object::Ptr ScriptProgress::setProgressStage(Kross::Api::List::Ptr args) +{ + m_script->setProgressStage( Kross::Api::Variant::toString(args->item(0)), Kross::Api::Variant::toUInt(args->item(1)) ); + return 0; +} + +} + +} diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_script_progress.h b/chalk/plugins/viewplugins/scripting/chalkcore/krs_script_progress.h new file mode 100644 index 00000000..b2ae7e44 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_script_progress.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KROSS_KRITACOREKRS_SCRIPTPROGRESS_H +#define KROSS_KRITACOREKRS_SCRIPTPROGRESS_H + +#include <api/class.h> + +class KisScriptProgress; + +namespace Kross { + +namespace ChalkCore { + +/** + * ScriptProgress is used to manage the progress bar of the status bar in chalk + * + * For example (in ruby) : + * @code + * script = Krosschalkcore::get("ChalkScript") + * script.setProgressTotalSteps(1000) + * script.setProgressStage("progressive", 0) + * for i in 1..900 + * script.incProgress() + * end + * script.setProgressStage("brutal", 1000) + * @endcode + */ +class ScriptProgress : public Kross::Api::Class<ScriptProgress> { + public: + ScriptProgress(KisScriptProgress* Script); + ~ScriptProgress(); + private: + /** + * This function set the number of steps that the script will require. + * It takes one argument : + * - maximum value of the progress + */ + Kross::Api::Object::Ptr setProgressTotalSteps(Kross::Api::List::Ptr); + /** + * This function set the value of progress. + * It takes one argument : + * - value of the progress + */ + Kross::Api::Object::Ptr setProgress(Kross::Api::List::Ptr); + /** + * This function increment of one step the position of the progress. + */ + Kross::Api::Object::Ptr incProgress(Kross::Api::List::Ptr); + /** + * This function set the value of the progress and display the text + */ + Kross::Api::Object::Ptr setProgressStage(Kross::Api::List::Ptr); + private: + KisScriptProgress* m_script; +}; + +} + +} + +#endif diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_wavelet.cpp b/chalk/plugins/viewplugins/scripting/chalkcore/krs_wavelet.cpp new file mode 100644 index 00000000..e166de7c --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_wavelet.cpp @@ -0,0 +1,114 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "krs_wavelet.h" + +#include <klocale.h> + +#include <kis_math_toolbox.h> + +namespace Kross { + +namespace ChalkCore { + +Wavelet::Wavelet(KisMathToolbox::KisWavelet* kwl) + : Kross::Api::Class<Wavelet>("ChalkWavelet"), m_wavelet(kwl) +{ + addFunction("getNCoeff", &Wavelet::getNCoeff); + addFunction("setNCoeff", &Wavelet::setNCoeff); + addFunction("getXYCoeff", &Wavelet::getXYCoeff); + addFunction("setXYCoeff", &Wavelet::setXYCoeff); + addFunction("getDepth", &Wavelet::getDepth); + addFunction("getSize", &Wavelet::getSize); + addFunction("getNumCoeffs", &Wavelet::getNumCoeffs); + m_numCoeff = m_wavelet->size*m_wavelet->size*m_wavelet->depth; +} + + +Wavelet::~Wavelet() +{ +} + + +Kross::Api::Object::Ptr Wavelet::getNCoeff(Kross::Api::List::Ptr args) +{ + TQ_UINT32 n = Kross::Api::Variant::toUInt(args->item(0)); + if( n > m_numCoeff) + { + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception( i18n("An error has occured in %1").tqarg("getNCoeff") + "\n" + i18n("Index out of bound") ) ); + } + return new Kross::Api::Variant(*(m_wavelet->coeffs + n )); +} + +Kross::Api::Object::Ptr Wavelet::setNCoeff(Kross::Api::List::Ptr args) +{ + TQ_UINT32 n = Kross::Api::Variant::toUInt(args->item(0)); + double v = Kross::Api::Variant::toDouble(args->item(1)); + if( n > m_numCoeff) + { + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception( i18n("An error has occured in %1").tqarg("setNCoeff") + "\n" + i18n("Index out of bound") ) ); + } + *(m_wavelet->coeffs + n ) = v; + return 0; +} + +Kross::Api::Object::Ptr Wavelet::getXYCoeff(Kross::Api::List::Ptr args) +{ + TQ_UINT32 x = Kross::Api::Variant::toUInt(args->item(0)); + TQ_UINT32 y = Kross::Api::Variant::toUInt(args->item(1)); + if( x > m_wavelet->size && y > m_wavelet->size) + { + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception( i18n("An error has occured in %1").tqarg("getXYCoeff") + "\n" + i18n("Index out of bound") ) ); + } + return new Kross::Api::Variant(*(m_wavelet->coeffs + (x + y * m_wavelet->size ) * m_wavelet->depth )); +} + +Kross::Api::Object::Ptr Wavelet::setXYCoeff(Kross::Api::List::Ptr args) +{ + TQ_UINT32 x = Kross::Api::Variant::toUInt(args->item(0)); + TQ_UINT32 y = Kross::Api::Variant::toUInt(args->item(1)); + double v = Kross::Api::Variant::toDouble(args->item(2)); + if( x > m_wavelet->size && y > m_wavelet->size) + { + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception( i18n("An error has occured in %1").tqarg("setXYCoeff") + "\n" + i18n("Index out of bound") )); + } + *(m_wavelet->coeffs + (x + y * m_wavelet->size ) * m_wavelet->depth ) = v; + return 0; +} + +Kross::Api::Object::Ptr Wavelet::getDepth(Kross::Api::List::Ptr /*args*/) +{ + return new Kross::Api::Variant(m_wavelet->depth); +} + +Kross::Api::Object::Ptr Wavelet::getSize(Kross::Api::List::Ptr) +{ + return new Kross::Api::Variant(m_wavelet->size); +} + +Kross::Api::Object::Ptr Wavelet::getNumCoeffs(Kross::Api::List::Ptr) +{ + return new Kross::Api::Variant(m_numCoeff); +} + + +} + +} diff --git a/chalk/plugins/viewplugins/scripting/chalkcore/krs_wavelet.h b/chalk/plugins/viewplugins/scripting/chalkcore/krs_wavelet.h new file mode 100644 index 00000000..8a9a0889 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkcore/krs_wavelet.h @@ -0,0 +1,92 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KROSS_KRITACOREKRS_WAVELET_H +#define KROSS_KRITACOREKRS_WAVELET_H + +#include <api/class.h> + +#include <kis_math_toolbox.h> + +namespace Kross { + +namespace ChalkCore { + +/** + @author Cyrille Berger <cberger@cberger.net> +*/ +class Wavelet : public Kross::Api::Class<Wavelet> +{ + public: + Wavelet(KisMathToolbox::KisWavelet* wavelet); + ~Wavelet(); + private: + /** + * Return the value of the Nth coefficient + * The function takes one argument : + * - the index of the coefficient + */ + Kross::Api::Object::Ptr getNCoeff(Kross::Api::List::Ptr); + /** + * Set the value of the Nth coefficient + * The function takes two arguments : + * - the index of the coefficient + * - the new value of the coefficient + */ + Kross::Api::Object::Ptr setNCoeff(Kross::Api::List::Ptr); + /** + * Return the value of a coefficient + * The function takes two arguments : + * - x + * - y + */ + Kross::Api::Object::Ptr getXYCoeff(Kross::Api::List::Ptr); + /** + * Set the value of a coefficient + * The function takes three arguments : + * - x + * - y + * - the new value of the coefficient + */ + Kross::Api::Object::Ptr setXYCoeff(Kross::Api::List::Ptr); + /** + * Return the depth of the layer + */ + Kross::Api::Object::Ptr getDepth(Kross::Api::List::Ptr); + /** + * Return the size of the wavelet (size = width = height) + */ + Kross::Api::Object::Ptr getSize(Kross::Api::List::Ptr); + /** + * Return the number of coefficients in this wavelet (= size * size * depth) + */ + Kross::Api::Object::Ptr getNumCoeffs(Kross::Api::List::Ptr); + public: + KisMathToolbox::KisWavelet* wavelet() { return m_wavelet; } + private: + KisMathToolbox::KisWavelet* m_wavelet; + uint m_numCoeff; +}; + +} + +} + +#endif diff --git a/chalk/plugins/viewplugins/scripting/chalkscripting.desktop b/chalk/plugins/viewplugins/scripting/chalkscripting.desktop new file mode 100644 index 00000000..511e76a0 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkscripting.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Name=Scripting plugin +Name[bg]=Приставка за скриптове +Name[ca]=Connector de seqüenciació +Name[da]=Scriptplugin +Name[de]=Skripting-Modul +Name[el]=Πρόσθετο γραφής σεναρίων +Name[eo]=Skriptad-kromaĵo +Name[es]=Complemento para guiones +Name[et]=Skriptiplugin +Name[fa]=وصلۀ دستنوشته +Name[fr]=Module de scriptage +Name[fy]=Skriptplugin +Name[ga]=Breiseán scriptithe +Name[gl]=Plugin de programación +Name[he]=תוסף לתסריטים +Name[hu]=Szkript modul +Name[is]=Skriftu íforrit +Name[it]=Plugin di scripting +Name[ja]=スクリプトプラグイン +Name[km]=កម្មវិធីជំនួយសម្រាប់ស្គ្រីប +Name[nb]=Programtillegg for skripting +Name[nds]=Skriptmoduul +Name[ne]=प्लगइन स्क्रिप्ट गर्दै +Name[nl]=Scriptplugin +Name[pl]=Wtyczka obsługi języków skryptowych +Name[pt]='Plugin' de programação +Name[pt_BR]=Plugin de programação +Name[ru]=Модуль поддержки сценариев +Name[sk]=Modul pre skripty +Name[sl]=Vstavek za skripte +Name[sr]=Прикључак за скриптовање +Name[sr@Latn]=Priključak za skriptovanje +Name[sv]=Skriptinsticksprogram +Name[uk]=Втулок для скриптів +Name[uz]=Skriptlash plagini +Name[uz@cyrillic]=Скриптлаш плагини +Name[zh_CN]=脚本插件 +Name[zh_TW]=命令稿外掛程式 +Comment=Allow execution of scripts +Comment[bg]=Изпълнение на скриптове +Comment[ca]=Permet l'execució de seqüències +Comment[da]=Tillad kørsel af script +Comment[de]=Ermöglicht das Ausführen von Skripten +Comment[el]=Επιτρέπει την εκτέλεση σεναρίων +Comment[eo]=Permesi ruligon de skriptoj +Comment[es]=Permite la ejecución de guiones +Comment[et]=Võimaldab skriptide käivitamist +Comment[fa]=اجازۀ اجرای دستنوشتهها +Comment[fr]=Permet d'exécuter des scripts +Comment[fy]=Hjirmei kinne skripts útfierd wurde +Comment[gl]=Permite executar guións +Comment[he]=אפשרות להרצת תסריטים +Comment[hu]=Lehetővé teszi szkriptek végrehajtását +Comment[is]=Leyfa að skriftur séu keyrðar +Comment[it]=Permette di eseguire script +Comment[ja]=スクリプトの実行を可能にします +Comment[km]=អនុញ្ញាតឲ្យប្រតិបត្តិស្គ្រីប +Comment[lv]=Atļaut skriptu izpildi +Comment[nb]=Tillater skriptkjøring +Comment[nds]=Skripten utföhren +Comment[ne]=स्क्रिप्टको कार्यान्वयनलाई अनुमति दिनुहोस् +Comment[nl]=Hiermee kunnen scripts uitgevoerd worden +Comment[pl]=Zezwala na wykonywanie skryptów +Comment[pt]=Permitir executar programas ou 'scripts' +Comment[pt_BR]=Permitir executar programas ou 'scripts' +Comment[ru]=Возможность выполнения сценариев +Comment[sk]=Povoliť vykonávanie skriptov +Comment[sl]=Dovoli izvedbo skriptov +Comment[sr]=Омогући извршавање скрипти +Comment[sr@Latn]=Omogući izvršavanje skripti +Comment[sv]=Tillåt körning av skript +Comment[uk]=Дає змогу виконувати скрипти +Comment[uz]=Skriptlarni ishga tushirishga ruxsat berish +Comment[uz@cyrillic]=Скриптларни ишга туширишга рухсат бериш +Comment[zh_CN]=允许执行脚本 +Comment[zh_TW]=允許執行命令稿 +ServiceTypes=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkscripting +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/scripting/chalkscripting/Makefile.am b/chalk/plugins/viewplugins/scripting/chalkscripting/Makefile.am new file mode 100644 index 00000000..b805ef18 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkscripting/Makefile.am @@ -0,0 +1,19 @@ +INCLUDES = -I$(top_srcdir)/chalk/sdk \ + -I$(top_srcdir)/chalk/core \ + -I$(top_srcdir)/chalk/chalkcolor/ \ + -I$(top_srcdir)/chalk/ui \ + $(KROSS_INCLUDES) \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + + +lib_LTLIBRARIES = libchalkscripting.la +libchalkscripting_la_SOURCES = kis_script_progress.cpp kis_script_monitor.cpp +noinst_HEADERS = kis_script_progress.h + +libchalkscripting_la_LDFLAGS = -no-undefined $(all_libraries) +libchalkscripting_la_LIBADD = $(top_builddir)/chalk/libchalkcommon.la $(top_builddir)/lib/kross/main/libkrossmain.la + +KDE_CXXFLAGS = $(USE_EXCEPTIONS) + +libchalkscripting_la_METASOURCES = AUTO diff --git a/chalk/plugins/viewplugins/scripting/chalkscripting/kis_script_monitor.cpp b/chalk/plugins/viewplugins/scripting/chalkscripting/kis_script_monitor.cpp new file mode 100644 index 00000000..3967ffe7 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkscripting/kis_script_monitor.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_script_monitor.h" + +#include <main/scriptaction.h> +#include <main/scriptguiclient.h> + + +KisScriptMonitor::KisScriptMonitor() +{ +} + + +KisScriptMonitor::~KisScriptMonitor() +{ + s_instance = 0; +} + +void KisScriptMonitor::monitor(Kross::Api::ScriptGUIClient* guiClient) +{ + connect(guiClient, TQT_SIGNAL(executionFinished( const Kross::Api::ScriptAction* )), TQT_SIGNAL(executionFinished( const Kross::Api::ScriptAction* ))); + connect(guiClient, TQT_SIGNAL(executionStarted( const Kross::Api::ScriptAction* )), TQT_SIGNAL(executionStarted( const Kross::Api::ScriptAction* ))); +} + +KisScriptMonitor* KisScriptMonitor::s_instance = 0; + +KisScriptMonitor* KisScriptMonitor::instance() +{ + if(s_instance == 0) + s_instance = new KisScriptMonitor(); + return s_instance; +} + +#include "kis_script_monitor.moc" + diff --git a/chalk/plugins/viewplugins/scripting/chalkscripting/kis_script_monitor.h b/chalk/plugins/viewplugins/scripting/chalkscripting/kis_script_monitor.h new file mode 100644 index 00000000..c1ee64c0 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkscripting/kis_script_monitor.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_SCRIPT_MONITOR_H +#define KIS_SCRIPT_MONITOR_H + +#include <tqobject.h> + +namespace Kross { + namespace Api { + class ScriptGUIClient; + class ScriptAction; + } +} + +/** + @author Cyrille Berger <cberger@cberger.net> +*/ +class KisScriptMonitor : public TQObject { + Q_OBJECT + TQ_OBJECT + private: + KisScriptMonitor(); + ~KisScriptMonitor(); + public: + static KisScriptMonitor* instance(); + void monitor(Kross::Api::ScriptGUIClient* guiClient); + signals: + void executionFinished(const Kross::Api::ScriptAction* ); + void executionStarted(const Kross::Api::ScriptAction* ); + private: + static KisScriptMonitor* s_instance; + +}; + +#endif diff --git a/chalk/plugins/viewplugins/scripting/chalkscripting/kis_script_progress.cpp b/chalk/plugins/viewplugins/scripting/chalkscripting/kis_script_progress.cpp new file mode 100644 index 00000000..d7af4eb4 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkscripting/kis_script_progress.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_script_progress.h" + +#include <kis_progress_display_interface.h> +#include <kis_view.h> + +void KisScriptProgress::activateAsSubject() +{ + m_view->canvasSubject()->progressDisplay()->setSubject( this, true, false /* TODO: how to cancel a script ? */ ); +} + +void KisScriptProgress::setProgressTotalSteps(TQ_INT32 totalSteps) +{ + m_progressTotalSteps = totalSteps; + m_progressSteps = 0; + m_lastProgressPerCent = 0; + emit notifyProgress(0); +} + +void KisScriptProgress::setProgress(TQ_INT32 progress) +{ + m_progressSteps = progress; + TQ_INT32 progressPerCent = (m_progressSteps * 100) / (m_progressTotalSteps > 0 ? m_progressTotalSteps : 1); + + if (progressPerCent != m_lastProgressPerCent) { + + m_lastProgressPerCent = progressPerCent; + emit notifyProgress(progressPerCent); + } +} + +void KisScriptProgress::incProgress() +{ + setProgress( ++m_progressSteps ); +} + +void KisScriptProgress::setProgressStage(const TQString& stage, TQ_INT32 progress) +{ + TQ_INT32 progressPerCent = (progress * 100) / (m_progressTotalSteps > 0 ? m_progressTotalSteps : 1); + m_lastProgressPerCent = progress; + emit notifyProgressStage( stage, progressPerCent); +} + +void KisScriptProgress::progressDone() +{ + emit notifyProgressDone(); +} diff --git a/chalk/plugins/viewplugins/scripting/chalkscripting/kis_script_progress.h b/chalk/plugins/viewplugins/scripting/chalkscripting/kis_script_progress.h new file mode 100644 index 00000000..48af433c --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/chalkscripting/kis_script_progress.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_SCRIPT_PROGRESS_H_ +#define _KIS_SCRIPT_PROGRESS_H_ + +#include <kis_progress_subject.h> + +class KisView; + +/** + * TODO: clarify the situation, while, in the future, multiple scripts could be running at a same time, + * some of the functions are global to all script and some aren't. + */ +class KisScriptProgress : public KisProgressSubject +{ + public: + KisScriptProgress(KisView* view) : m_view(view) {}; + public: + /** + * This function will set this class as the KisProgressSubject in view + */ + void activateAsSubject(); + virtual void cancel() {}; + public: + void setProgressTotalSteps(TQ_INT32 totalSteps); + void setProgress(TQ_INT32 progress); + void incProgress(); + void setProgressStage(const TQString& stage, TQ_INT32 progress); + void progressDone(); + inline void setPackagePath(TQString path) { m_packagePath = path; }; + inline TQString packagePath() { return m_packagePath; } + private: + TQ_INT32 m_progressSteps, m_progressTotalSteps, m_lastProgressPerCent; + KisView * m_view; + TQString m_packagePath; +}; + +#endif diff --git a/chalk/plugins/viewplugins/scripting/samples/Makefile.am b/chalk/plugins/viewplugins/scripting/samples/Makefile.am new file mode 100644 index 00000000..0f0c383d --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(srcdir)/../../../sdk -I$(srcdir)/../../../core -I$(srcdir)/../../../chalkcolor/ -I$(srcdir)/../../../ui -I$(top_srcdir)/kexi/scriptingcore/main $(KOFFICE_INCLUDES) $(all_includes) +METASOURCES = AUTO +SUBDIRS = python ruby diff --git a/chalk/plugins/viewplugins/scripting/samples/python/Makefile.am b/chalk/plugins/viewplugins/scripting/samples/python/Makefile.am new file mode 100644 index 00000000..c15a3b3b --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/python/Makefile.am @@ -0,0 +1,5 @@ +scriptinvertdir = $(kde_datadir)/chalk/scripts/invertpython +scriptinvert_SCRIPTS = invert.py invertpython.rc + +scriptreshapedir = $(kde_datadir)/chalk/scripts/reshapehisto +scriptreshape_SCRIPTS = reshapehisto.py reshapehisto.rc diff --git a/chalk/plugins/viewplugins/scripting/samples/python/invert.py b/chalk/plugins/viewplugins/scripting/samples/python/invert.py new file mode 100644 index 00000000..7a642760 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/python/invert.py @@ -0,0 +1,48 @@ +# This file is part of Chalk +# +# Copyright (c) 2005-2006 Cyrille Berger <cberger@cberger.net> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +class Inverter: + def __init__(self): + try: + import krosschalkcore + except: + raise "Import of the ChalkCore module failed." + doc = krosschalkcore.get("ChalkDocument") + script = krosschalkcore.get("ChalkScript") + image = doc.getImage() + layer = image.getActivePaintLayer() + if(layer.colorSpaceId() != "RGBA" ): + raise("This script works only for 8bit RGBA layers") + width = layer.getWidth() + height = layer.getHeight() + script.setProgressTotalSteps(width * height) + layer.beginPainting("invert") + it = layer.createRectIterator( 0, 0, width, height ) + print "kikoo\n" + finesh = it.isDone() + while (not finesh) : + p = it.getRGBA() + p[0] = 255 - p[0] + p[1] = 255 - p[1] + p[2] = 255 - p[2] + it.setRGBA(p) + script.incProgress() + finesh = it.next() + layer.endPainting() + +Inverter() diff --git a/chalk/plugins/viewplugins/scripting/samples/python/invertpython.rc b/chalk/plugins/viewplugins/scripting/samples/python/invertpython.rc new file mode 100644 index 00000000..d2224311 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/python/invertpython.rc @@ -0,0 +1,9 @@ +<KrossScripting> + <ScriptAction + name="InvertPython" + text="Invert (python)" + description="Invert the pixel of an image (python)" + icon="" + interpreter="python" + file="invert.py" /> +</KrossScripting> diff --git a/chalk/plugins/viewplugins/scripting/samples/python/reshapehisto.py b/chalk/plugins/viewplugins/scripting/samples/python/reshapehisto.py new file mode 100644 index 00000000..4ef66965 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/python/reshapehisto.py @@ -0,0 +1,300 @@ +# This file is part of Chalk +# +# Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +import math + +# it's an experimental script to try to reshape.histogram, while the results are far to be convincing yet +# it is still an example on how to use histogram in a script + +def sign(a): + if a < 0: + return -1 + else: + return 1 +#def abs(a): + #if a < + +def computeDiff(histo, histoTarget): + diff = [ ] + histoMax = histo.getHighest() + count = 0 + while( count < 256 ) : + v = histo.getValue(count) + diff.append( v / histoMax - histoTarget[count]) + count += 1 + derivdiff = [ ] + derivdiff.append(diff[1] - diff[0] ) + count = 1 + while( count < 255 ) : + derivdiff.append((diff[count+1] - diff[count - 1])/2.0) + print count + print " " + print derivdiff[count] + print " " + count += 1 + derivdiff.append(diff[255] - diff[254] ) + return diff + +try: + import krosschalkcore +except: + raise "Import of the ChalkCore module failed." + +#histoTarget = [ 0.0, 0.01226531745085, 0.024528789662323, 0.0367885716726463, 0.049042819075215, 0.0612896882960706, 0.0735273368712555, 0.0857539237239997, 0.0979676094416996, 0.110166556552646, 0.122348929802458, 0.13451289643019, 0.146656626444054, 0.158778292896733, 0.170876072160234, 0.18294814420024, 0.194992692849922, 0.207007906083172, 0.218991976287209, 0.230943100534525, 0.242859480854121, 0.254739324502003, 0.266580844230888, 0.278382258559083, 0.290141792038499, 0.301857675521758, 0.313528146428344, 0.325151449009778, 0.336725834613756, 0.348249561947225, 0.359720897338346, 0.371138114997318, 0.38249949727601, 0.393803334926368, 0.405047927357568, 0.416231582891849, 0.427352619019025, 0.4384093626496, 0.449400150366478, 0.460323328675215, 0.471177254252771, 0.481960294194744, 0.492670826261026, 0.50330723911986, 0.513867932590253, 0.524351317882718, 0.534755817838293, 0.545079867165813, 0.555321912677404, 0.565480413522147, 0.575553841417885, 0.585540680881154, 0.595439429455167, 0.605248597935856, 0.614966710595909, 0.624592305406788, 0.634123934258679, 0.643560163178352, 0.652899572544893, 0.662140757303275, 0.671282327175744, 0.680322906870975, 0.689261136290974, 0.698095670735701, 0.706825181105366, 0.715448354100387, 0.723963892418968, 0.732370514952268, 0.740666956977137, 0.748851970346384, 0.756924323676554, 0.764882802533185, 0.772726209613504, 0.780453364926561, 0.788063105970749, 0.795554287908693, 0.802925783739486, 0.810176484468239, 0.817305299272921, 0.824311155668464, 0.83119299966812, 0.837949795942015, 0.84458052797292, 0.851084198209167, 0.857459828214736, 0.863706458816447, 0.869823150248263, 0.875808982292675, 0.881663054419139, 0.887384485919556, 0.892972416040772, 0.898426004114068, 0.903744429681637, 0.908926892620016, 0.913972613260457, 0.918880832506229, 0.923650811946811, 0.928281833968988, 0.93277320186481, 0.937124239936404, 0.941334293597632, 0.945402729472569, 0.949328935490789, 0.953112320979447, 0.956752316752142, 0.960248375194552, 0.963599970346811, 0.966806597982642, 0.969867775685214, 0.972783042919718, 0.97555196110265, 0.978174113667795, 0.980649106128898, 0.982976566139007, 0.985156143546496, 0.987187510447739, 0.989070361236445, 0.990804412649628, 0.99238940381023, 0.993825096266363, 0.995111274027184, 0.99624774359539, 0.997234333996328, 0.998070896803715, 0.998757306161974, 0.99929345880516, 0.999679274072503, 0.999914693920536, 0.999999682931835, 0.99993422832034, 0.999718339933283, 0.999352050249705, 0.998835414375572, 0.998168510035481, 0.997351437560967, 0.996384319875413, 0.995267302475555, 0.994000553409588, 0.992584263251893, 0.991018645074359, 0.989303934414332, 0.987440389239176, 0.985428289907469, 0.983267939126818, 0.980959661908326, 0.978503805517689, 0.975900739422957, 0.973150855238948, 0.970254566668332, 0.967212309439392, 0.964024541240472, 0.960691741651122, 0.957214412069943, 0.953593075639162, 0.949828277165924, 0.945920583040329, 0.941870581150226, 0.937678880792763, 0.933346112582728, 0.928872928357675, 0.924260001079857, 0.919508024734984, 0.914617714227821, 0.909589805274631, 0.90442505429249, 0.899124238285494, 0.89368815472786, 0.888117621443952, 0.882413476485242, 0.876576578004235, 0.870607804125365, 0.86450805281288, 0.858278241735758, 0.851919308129644, 0.845432208655849, 0.83881791925743, 0.832077435012361, 0.825211769983833, 0.818221957067693, 0.811109047837053, 0.803874112384084, 0.796518239159033, 0.789042534806467, 0.781448123998789, 0.773736149267035, 0.76590777082899, 0.757964166414642, 0.749906531088995, 0.741736077072283, 0.733454033557598, 0.725061646525966, 0.716560178558895, 0.707950908648432, 0.699235132004742, 0.690414159861254, 0.681489319277395, 0.672461952938941, 0.663333418956019, 0.654105090658787, 0.644778356390828, 0.635354619300277, 0.625835297128734, 0.616221821997965, 0.606515640194456, 0.596718211951823, 0.586831011231134, 0.576855525499155, 0.566793255504575, 0.556645715052225, 0.546414430775338, 0.536100941905873, 0.525706800042952, 0.515233568919429, 0.504682824166636, 0.49405615307734, 0.483355154366944, 0.472581437932973, 0.461736624612871, 0.450822345940161, 0.439840243898986, 0.428791970677089, 0.417679188417244, 0.406503568967204, 0.39526679362818, 0.383970552901897, 0.372616546236274, 0.361206481769749, 0.349742076074299, 0.338225053897198, 0.326657147901536, 0.315040098405551, 0.303375653120808, 0.291665566889271, 0.279911601419294, 0.268115525020586, 0.256279112338177, 0.244404144085436, 0.232492406776176, 0.220545692455878, 0.208565798432095, 0.196554527004056, 0.184513685191523, 0.172445084462932, 0.160350540462877, 0.148231872738948, 0.136090904468, 0.123929462181863, 0.111749375492553, 0.0995524768170189, 0.0873406011014653, 0.0751155855452987, 0.0628792693247314, 0.0506334933160884, 0.0383800998188613, 0.0261209322785436, 0.0138578350092972 ] + +histoTarget = [ 0.0, 0.00392156862745098, 0.00784313725490196, 0.0117647058823529, 0.0156862745098039, 0.0196078431372549, 0.0235294117647059, 0.0274509803921569, 0.0313725490196078, 0.0352941176470588, 0.0392156862745098, 0.0431372549019608, 0.0470588235294118, 0.0509803921568627, 0.0549019607843137, 0.0588235294117647, 0.0627450980392157, 0.0666666666666667, 0.0705882352941176, 0.0745098039215686, 0.0784313725490196, 0.0823529411764706, 0.0862745098039216, 0.0901960784313725, 0.0941176470588235, 0.0980392156862745, 0.101960784313725, 0.105882352941176, 0.109803921568627, 0.113725490196078, 0.117647058823529, 0.12156862745098, 0.125490196078431, 0.129411764705882, 0.133333333333333, 0.137254901960784, 0.141176470588235, 0.145098039215686, 0.149019607843137, 0.152941176470588, 0.156862745098039, 0.16078431372549, 0.164705882352941, 0.168627450980392, 0.172549019607843, 0.176470588235294, 0.180392156862745, 0.184313725490196, 0.188235294117647, 0.192156862745098, 0.196078431372549, 0.2, 0.203921568627451, 0.207843137254902, 0.211764705882353, 0.215686274509804, 0.219607843137255, 0.223529411764706, 0.227450980392157, 0.231372549019608, 0.235294117647059, 0.23921568627451, 0.243137254901961, 0.247058823529412, 0.250980392156863, 0.254901960784314, 0.258823529411765, 0.262745098039216, 0.266666666666667, 0.270588235294118, 0.274509803921569, 0.27843137254902, 0.282352941176471, 0.286274509803922, 0.290196078431373, 0.294117647058824, 0.298039215686275, 0.301960784313725, 0.305882352941176, 0.309803921568627, 0.313725490196078, 0.317647058823529, 0.32156862745098, 0.325490196078431, 0.329411764705882, 0.333333333333333, 0.337254901960784, 0.341176470588235, 0.345098039215686, 0.349019607843137, 0.352941176470588, 0.356862745098039, 0.36078431372549, 0.364705882352941, 0.368627450980392, 0.372549019607843, 0.376470588235294, 0.380392156862745, 0.384313725490196, 0.388235294117647, 0.392156862745098, 0.396078431372549, 0.4, 0.403921568627451, 0.407843137254902, 0.411764705882353, 0.415686274509804, 0.419607843137255, 0.423529411764706, 0.427450980392157, 0.431372549019608, 0.435294117647059, 0.43921568627451, 0.443137254901961, 0.447058823529412, 0.450980392156863, 0.454901960784314, 0.458823529411765, 0.462745098039216, 0.466666666666667, 0.470588235294118, 0.474509803921569, 0.47843137254902, 0.482352941176471, 0.486274509803922, 0.490196078431373, 0.494117647058824, 0.498039215686275, 0.501960784313725, 0.505882352941176, 0.509803921568627, 0.513725490196078, 0.517647058823529, 0.52156862745098, 0.525490196078431, 0.529411764705882, 0.533333333333333, 0.537254901960784, 0.541176470588235, 0.545098039215686, 0.549019607843137, 0.552941176470588, 0.556862745098039, 0.56078431372549, 0.564705882352941, 0.568627450980392, 0.572549019607843, 0.576470588235294, 0.580392156862745, 0.584313725490196, 0.588235294117647, 0.592156862745098, 0.596078431372549, 0.6, 0.603921568627451, 0.607843137254902, 0.611764705882353, 0.615686274509804, 0.619607843137255, 0.623529411764706, 0.627450980392157, 0.631372549019608, 0.635294117647059, 0.63921568627451, 0.643137254901961, 0.647058823529412, 0.650980392156863, 0.654901960784314, 0.658823529411765, 0.662745098039216, 0.666666666666667, 0.670588235294118, 0.674509803921569, 0.67843137254902, 0.682352941176471, 0.686274509803922, 0.690196078431373, 0.694117647058824, 0.698039215686274, 0.701960784313725, 0.705882352941177, 0.709803921568627, 0.713725490196078, 0.717647058823529, 0.72156862745098, 0.725490196078431, 0.729411764705882, 0.733333333333333, 0.737254901960784, 0.741176470588235, 0.745098039215686, 0.749019607843137, 0.752941176470588, 0.756862745098039, 0.76078431372549, 0.764705882352941, 0.768627450980392, 0.772549019607843, 0.776470588235294, 0.780392156862745, 0.784313725490196, 0.788235294117647, 0.792156862745098, 0.796078431372549, 0.8, 0.803921568627451, 0.807843137254902, 0.811764705882353, 0.815686274509804, 0.819607843137255, 0.823529411764706, 0.827450980392157, 0.831372549019608, 0.835294117647059, 0.83921568627451, 0.843137254901961, 0.847058823529412, 0.850980392156863, 0.854901960784314, 0.858823529411765, 0.862745098039216, 0.866666666666667, 0.870588235294118, 0.874509803921569, 0.87843137254902, 0.882352941176471, 0.886274509803922, 0.890196078431372, 0.894117647058824, 0.898039215686275, 0.901960784313726, 0.905882352941176, 0.909803921568627, 0.913725490196078, 0.917647058823529, 0.92156862745098, 0.925490196078431, 0.929411764705882, 0.933333333333333, 0.937254901960784, 0.941176470588235, 0.945098039215686, 0.949019607843137, 0.952941176470588, 0.956862745098039, 0.96078431372549, 0.964705882352941, 0.968627450980392, 0.972549019607843, 0.976470588235294, 0.980392156862745, 0.984313725490196, 0.988235294117647, 0.992156862745098, 0.996078431372549, 1.0 ] + +doc = krosschalkcore.get("ChalkDocument") +image = doc.getImage() +layer = image.getActivePaintLayer() +if (layer.colorSpaceId() != "RGBA" ): + raise("This script works only for 8bit RGBA layers") + +width = layer.getWidth() +height = layer.getHeight() + +countreshaping = 0 +while countreshaping < 1: + histo = layer.createHistogram("RGB8HISTO",0) + print "################################### histogram reshaping ##################################################" + if histo == 0: + raise "Uncompatible histogram\n" + print "Max : " + str( histo.getMax() ) + " Min : " + str( histo.getMin() ) + + #Compute the area of the target histogram + aireHistoTarget = 0.0 + count = 0 + while( count < 256 ) : + aireHistoTarget += histoTarget[count] + count += 1 + + #compute the table for the blue channel + histo.setChannel(0) + tableb = [ ] + histoMax = histo.getHighest() + aireHisto = width * height + coeff = aireHistoTarget / aireHisto + count = 0 + position = 0 + residu = 0. + while( count < 256 ) : + residu += histo.getValue(count) * coeff + while residu > 0.0: + residu -= histoTarget[position] + position += 1 + tableb.append( position ) + count += 1 + #compute the table for the green channel + histo.setChannel(1) + tableg = [ ] + histoMax = histo.getHighest() + aireHisto = width * height + coeff = aireHistoTarget / aireHisto + count = 0 + position = 0 + residu = 0. + while( count < 256 ) : + residu += histo.getValue(count) * coeff + while residu > 0.0: + residu -= histoTarget[position] + position += 1 + tableg.append( position ) + count += 1 + #compute the table for the red channel + histo.setChannel(2) + tabler = [ ] + histoMax = histo.getHighest() + aireHisto = width * height + coeff = aireHistoTarget / aireHisto + count = 0 + position = 0 + residu = 0. + while( count < 256 ) : + residu += histo.getValue(count) * coeff + while residu > 0.0: + residu -= histoTarget[position] + position += 1 + tabler.append( position ) + count += 1 + + it = layer.createRectIterator( 0, 0, width, height ) + print "kikoo : " + str(countreshaping) + while (not it.isDone()) : + r = it.getRed() + g = it.getGreen() + b = it.getBlue() + #var = ( tabler[r] - r + tableg[g] - g + tableb[b] - b ) / 3 + #ng = g + var + #nr = r + var + #nb = b + var + it.setRed(tabler[r]) + it.setGreen(tableg[g]) + it.setBlue(tableb[b]) + it.next() + + #histo.setChannel(0) + #diff = [ ] + #histoMax = histo.getHighest() + #count = 0 + #while( count < 256 ) : + #v = histo.getValue(count) + #diff.append( v / histoMax - histoTarget[count]) + #count += 1 + #diffb = [ ] + #diffb.append(diff[1] - diff[0] ) + #count = 1 + #while( count < 255 ) : + #diffb.append((diff[count+1] - diff[count - 1])/2.0) + #count += 1 + #diffb.append(diff[255] - diff[254] ) + + #histo.setChannel(1) + #diff = [ ] + #histoMax = histo.getHighest() + #count = 0 + #while( count < 256 ) : + #v = histo.getValue(count) + #diff.append( v / histoMax - histoTarget[count]) + #count += 1 + #diffg = [ ] + #diffg.append(diff[1] - diff[0] ) + #count = 1 + #while( count < 255 ) : + #diffg.append((diff[count+1] - diff[count - 1])/2.0) + #count += 1 + #diffg.append(diff[255] - diff[254] ) + + #histo.setChannel(2) + #diff = [ ] + #histoMax = histo.getHighest() + #count = 0 + #while( count < 256 ) : + #v = histo.getValue(count) + #diff.append( v / histoMax - histoTarget[count]) + #count += 1 + #diffr = [ ] + #diffr.append(diff[1] - diff[0] ) + #count = 1 + #while( count < 255 ) : + #diffr.append((diff[count+1] - diff[count - 1])/2.0) + #count += 1 + #diffr.append(diff[255] - diff[254] ) + + + #histo.setChannel(0) + #diff = [ ] + #histoMax = histo.getHighest() + #count = 0 + #while( count < 256 ) : + #v = histo.getValue(count) + #diff.append( v / histoMax - histoTarget[count]) + #count += 1 + #diffb = [ ] + #diffb.append( sign(diff[1] - diff[0] ) * abs(diff[0]) ) + #count = 1 + #while( count < 255 ) : + #diffb.append( sign(diff[count+1] - diff[count - 1]) * abs(diff[count]) ) + #count += 1 + #diffb.append( sign(diff[255] - diff[254] ) * abs(diff[255]) ) + + #histo.setChannel(1) + #diff = [ ] + #histoMax = histo.getHighest() + #count = 0 + #while( count < 256 ) : + #v = histo.getValue(count) + #diff.append( v / histoMax - histoTarget[count]) + #count += 1 + #diffg = [ ] + #diffg.append( sign(diff[1] - diff[0] ) * abs(diff[0]) ) + #count = 1 + #while( count < 255 ) : + #diffg.append( sign(diff[count+1] - diff[count - 1]) * abs(diff[count]) ) + #count += 1 + #diffg.append( sign(diff[255] - diff[254] ) * abs(diff[255]) ) + + #histo.setChannel(2) + #diff = [ ] + #histoMax = histo.getHighest() + #count = 0 + #while( count < 256 ) : + #v = histo.getValue(count) + #diff.append( v / histoMax - histoTarget[count]) + #count += 1 + #diffr = [ ] + #diffr.append( sign(diff[1] - diff[0] ) * abs(diff[0]) ) + #count = 1 + #while( count < 255 ) : + #diffr.append( sign(diff[count+1] - diff[count - 1]) * abs(diff[count]) ) + #count += 1 + #diffr.append( sign(diff[255] - diff[254] ) * abs(diff[255]) ) + + + #print str(diffr) + " " + str(diff[count+1]) + " " + str(diff[count-1]) + + #histo.setChannel(0) + #diffb = computeDiff(histo, histoTarget) + #print "##########################" + #count = 0 + #while( count < 256 ) : + #print count + #print " " + #print diffb[count] + #print "\n" + #count += 1 + + #histo.setChannel(1) + #diffg = computeDiff(histo, histoTarget) + #print "##########################" + #count = 0 + #while( count < 256 ) : + #print count + #print " " + #print diffg[count] + #print "\n" + #count += 1 + + #histo.setChannel(2) + #diffr = computeDiff(histo, histoTarget) + #print "##########################" + #count = 0 + #while( count < 256 ) : + #print count + #print " " + #print diffr[count] + #print "\n" + #count += 1 + + #it = layer.createRectIterator( 0, 0, width, height ) + #print "kikoo : " + str(countreshaping) + #while (not it.isDone()) : + #r = it.getRed() + #g = it.getGreen() + #b = it.getBlue() + #coeff = 1.0 - ( diffr[r] + diffg[g] + diffb[b] ) / 3.0 + ##print str(r) + " = " + str(diffr[r]) + " " + str(g) + " = " + str(diffg[g]) + " " + str(b) + " = " + str(diffb[b]) + " coeff = " + str(coeff) + #ng = g * coeff + #nr = r * coeff + #nb = b * coeff + #it.setRed(nr) + #it.setGreen(ng) + #it.setBlue(nb) + #it.next() + countreshaping += 1 + +doc.notifyModification() diff --git a/chalk/plugins/viewplugins/scripting/samples/python/reshapehisto.rc b/chalk/plugins/viewplugins/scripting/samples/python/reshapehisto.rc new file mode 100644 index 00000000..481f5764 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/python/reshapehisto.rc @@ -0,0 +1,9 @@ +<KrossScripting> + <ScriptAction + name="ReshapeHistogramPython" + text="Reshape Histogram (python)" + description="It's an experimental approach to improve color of image, it doesn't work as it, but it show how to use an histogram in a script :)" + icon="" + interpreter="python" + file="reshapehisto.py" /> +</KrossScripting> diff --git a/chalk/plugins/viewplugins/scripting/samples/ruby/Makefile.am b/chalk/plugins/viewplugins/scripting/samples/ruby/Makefile.am new file mode 100644 index 00000000..bebd4a71 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/ruby/Makefile.am @@ -0,0 +1,18 @@ +scriptsinvertdir = $(kde_datadir)/chalk/scripts/invertruby +scriptsinvert_SCRIPTS = invert.rb invertruby.rc + +scriptschangecsdir = $(kde_datadir)/chalk/scripts/changecs +scriptschangecs_SCRIPTS = changecs.rb changecs.rc + +scriptsrandompaintdir = $(kde_datadir)/chalk/scripts/randompaint +scriptsrandompaint_SCRIPTS = randompaint.rb randompaint.rc + +scriptsfilterstestdir = $(kde_datadir)/chalk/scripts/filterstest +scriptsfilterstest_SCRIPTS = filterstest.rb filterstest.rc + +scriptstorturefiltersdir = $(kde_datadir)/chalk/scripts/torturefilters +scriptstorturefilters_SCRIPTS = torture-filters.rb torture-filters.rc + +scriptstorturepaintingdir = $(kde_datadir)/chalk/scripts/torturepainting +scriptstorturepainting_SCRIPTS = torture-painting.rb torture-painting.rc + diff --git a/chalk/plugins/viewplugins/scripting/samples/ruby/changecs.rb b/chalk/plugins/viewplugins/scripting/samples/ruby/changecs.rb new file mode 100644 index 00000000..be7c0d89 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/ruby/changecs.rb @@ -0,0 +1,5 @@ +require "krosschalkcore" + +doc = Krosschalkcore::get("ChalkDocument") +image = doc.getImage() +image.convertToColorspace("LABA") diff --git a/chalk/plugins/viewplugins/scripting/samples/ruby/changecs.rc b/chalk/plugins/viewplugins/scripting/samples/ruby/changecs.rc new file mode 100644 index 00000000..4121693d --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/ruby/changecs.rc @@ -0,0 +1,9 @@ +<KrossScripting> + <ScriptAction + name="ChangeColorspaceRuby" + text="Change Colorspace" + description="Demonstrate how to change the colorspace in a script" + icon="" + interpreter="ruby" + file="changecs.rb" /> +</KrossScripting> diff --git a/chalk/plugins/viewplugins/scripting/samples/ruby/filterstest.rb b/chalk/plugins/viewplugins/scripting/samples/ruby/filterstest.rb new file mode 100644 index 00000000..bf76b018 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/ruby/filterstest.rb @@ -0,0 +1,31 @@ +# This file is part of Chalk +# +# Copyright (c) 2005-2006 Cyrille Berger <cberger@cberger.net> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +require "krosschalkcore" + +doc = Krosschalkcore::get("ChalkDocument") + +image = doc.getImage() +layer = image.getActivePaintLayer() +width = layer.getWidth() +height = layer.getHeight() + +filter = Krosschalkcore::getFilter("invert") + +filter.process(layer ) +filter.process(layer, 10, 10, 20, 20 ) diff --git a/chalk/plugins/viewplugins/scripting/samples/ruby/filterstest.rc b/chalk/plugins/viewplugins/scripting/samples/ruby/filterstest.rc new file mode 100644 index 00000000..2f8dfb98 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/ruby/filterstest.rc @@ -0,0 +1,9 @@ +<KrossScripting> + <ScriptAction + name="FiltersTestRuby" + text="Filters Test" + description="Test of filters in scripting (ruby)" + icon="" + interpreter="ruby" + file="filterstest.rb" /> +</KrossScripting> diff --git a/chalk/plugins/viewplugins/scripting/samples/ruby/invert.rb b/chalk/plugins/viewplugins/scripting/samples/ruby/invert.rb new file mode 100644 index 00000000..d9ad32f7 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/ruby/invert.rb @@ -0,0 +1,45 @@ +# This file is part of Chalk +# +# Copyright (c) 2005-2006 Cyrille Berger <cberger@cberger.net> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +require "krosschalkcore" + +doc = Krosschalkcore::get("ChalkDocument") +script = Krosschalkcore::get("ChalkScript") +image = doc.getImage() +layer = image.getActivePaintLayer() + +if(layer.colorSpaceId() != "RGBA" ) + raise("This script works only for 8bit RGBA layers") +end + +width = layer.getWidth() +height = layer.getHeight() +script.setProgressTotalSteps(width * height) +layer.beginPainting("invert") +it = layer.createRectIterator( 0, 0, width, height ) +while (it.isDone() == 0) + p = it.getRGBA() + p[0] = 255 - p[0] + p[1] = 255 - p[1] + p[2] = 255 - p[2] + it.setRGBA(p) + script.incProgress() + it.next() +end + +layer.endPainting() diff --git a/chalk/plugins/viewplugins/scripting/samples/ruby/invertruby.rc b/chalk/plugins/viewplugins/scripting/samples/ruby/invertruby.rc new file mode 100644 index 00000000..9cc7bd6a --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/ruby/invertruby.rc @@ -0,0 +1,9 @@ +<KrossScripting> + <ScriptAction + name="InvertRuby" + text="Invert (ruby)" + description="Invert the pixel of an image (ruby)" + icon="" + interpreter="ruby" + file="invert.rb" /> +</KrossScripting> diff --git a/chalk/plugins/viewplugins/scripting/samples/ruby/randompaint.rb b/chalk/plugins/viewplugins/scripting/samples/ruby/randompaint.rb new file mode 100644 index 00000000..1ec25dcd --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/ruby/randompaint.rb @@ -0,0 +1,98 @@ +def randomizeStyle(painter) + painter.setFillStyle(4 *rand) + painter.setStrokeStyle(2 *rand) +end + +require "krosschalkcore" + +doc = Krosschalkcore::get("ChalkDocument") +script = Krosschalkcore::get("ChalkScript") + +image = doc.getImage() +layer = image.getActivePaintLayer() +width = layer.getWidth() +height = layer.getHeight() + +script.setProgressTotalSteps(110) +layer.beginPainting("random paint") + +painter = layer.createPainter() + +# create painting color +blackcolor = Krosschalkcore::newRGBColor(0,0,0) + +# set painting color +painter.setPaintColor( blackcolor ) + +# get the brush +brush = Krosschalkcore::getBrush("Circle (05)") + +# define the brush +painter.setBrush(brush) + +# get the pattern +pattern = Krosschalkcore::getPattern("Bricks") + +# set the pattern +painter.setPattern(pattern) + +# define the paint operation +painter.setPaintOp("paintbrush") + +# randomly paint +for i in 1..10 + # set painting color + painter.setPaintColor( Krosschalkcore::newRGBColor(rand*255,rand*255,rand*255) ) + painter.paintAt(rand * width , rand * height,1.1) + script.incProgress() +end + +# randomly rect or circle paint +for i in 1..100 + # set painting color + painter.setPaintColor( Krosschalkcore::newRGBColor(rand*255,rand*255,rand*255) ) + painter.setBackgroundColor( Krosschalkcore::newRGBColor(rand*255,rand*255,rand*255) ) + painter.setOpacity( rand*255 ) +# set the brush + if(rand < 0.5) + painter.setBrush( Krosschalkcore::newRectBrush(rand*20,rand*20,rand*10,rand*10) ) + else + painter.setBrush( Krosschalkcore::newCircleBrush(rand*20,rand*20,rand*10,rand*10) ) + end + # paint a point + tqshape = rand * 7 + painter.setStrokeStyle(1) + if( tqshape < 1 ) + painter.paintAt(rand * width , rand * height,1.1) + elsif(tqshape < 2 ) + xs = Array.new + ys = Array.new + for i in 0..6 + xs[i] = rand*width + ys[i] = rand*height + end + painter.paintPolyline(xs,ys) + elsif(tqshape < 3) + painter.paintLine(rand * width, rand * height, 1.1, rand * width, rand * height,1.1) + elsif(tqshape < 4) + painter.paintBezierCurve(rand * width, rand * height, 1.1, rand * width, rand * height, rand * width , rand * height, rand * width, rand * height, 1.1) + elsif(tqshape < 5) + randomizeStyle(painter) + painter.paintEllipse(rand * width, rand * height, rand * width, rand * height, 1.1) + elsif(tqshape < 6) + xs = Array.new + ys = Array.new + for i in 0..6 + xs[i] = rand*width + ys[i] = rand*height + end + randomizeStyle(painter) + painter.paintPolygon(xs, ys) + elsif(tqshape < 7) + randomizeStyle(painter) + painter.paintRect(rand * width, rand * height, rand * width, rand * height, 1.1) + end + script.incProgress() +end + +layer.endPainting() diff --git a/chalk/plugins/viewplugins/scripting/samples/ruby/randompaint.rc b/chalk/plugins/viewplugins/scripting/samples/ruby/randompaint.rc new file mode 100644 index 00000000..3697f700 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/ruby/randompaint.rc @@ -0,0 +1,9 @@ +<KrossScripting> + <ScriptAction + name="RandomPaintRuby" + text="Random Paint" + description="Demonstrate how to use the Painter script API and paint random shape on screen" + icon="" + interpreter="ruby" + file="randompaint.rb" /> +</KrossScripting> diff --git a/chalk/plugins/viewplugins/scripting/samples/ruby/torture-filters.rb b/chalk/plugins/viewplugins/scripting/samples/ruby/torture-filters.rb new file mode 100644 index 00000000..b92a67e0 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/ruby/torture-filters.rb @@ -0,0 +1,70 @@ +# This file is part of Chalk +# +# Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +require "krosschalkcore" + +doc = Krosschalkcore::get("ChalkDocument") + +image = doc.getImage() +layer = image.getActivePaintLayer() + +def testFilter(layer, filterid) + print " applying filter ", filterid, "\n" + begin + filter = Krosschalkcore::getFilter(filterid) + filter.process(layer) + rescue + print " WARNING: this filter is incompatible with this colorspace\n" + end +end + + +def testColorspace(layer, colorspaceid) + print "Testing for ", colorspaceid, "\n" + if (layer.colorSpaceId() != colorspaceid) + layer.convertToColorspace(colorspaceid) + end + testFilter(layer, "invert") + testFilter(layer, "bumpmap") + testFilter(layer, "cimg") + testFilter(layer, "desaturate") + testFilter(layer, "autocontrast") + testFilter(layer, "brightnesscontrast") + testFilter(layer, "gaussian blur") + testFilter(layer, "cubism") + testFilter(layer, "emboss") + testFilter(layer, "simplenoisereducer") + testFilter(layer, "waveletnoisereducer") + testFilter(layer, "oilpaint") + testFilter(layer, "pixelize") + testFilter(layer, "raindrops") + testFilter(layer, "roundcorners") + testFilter(layer, "smalltiles") + testFilter(layer, "sobel") +end + +testColorspace(layer, "RGBA") +testColorspace(layer, "RGBA16") +testColorspace(layer, "RGBAF16HALF") +testColorspace(layer, "RGBAF32") +testColorspace(layer, "CMYK") +testColorspace(layer, "CMYKA16") +testColorspace(layer, "CMYK") +testColorspace(layer, "CMYKA16") +testColorspace(layer, "LABA") +testColorspace(layer, "LMSAF32") diff --git a/chalk/plugins/viewplugins/scripting/samples/ruby/torture-filters.rc b/chalk/plugins/viewplugins/scripting/samples/ruby/torture-filters.rc new file mode 100644 index 00000000..b3abde5b --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/ruby/torture-filters.rc @@ -0,0 +1,9 @@ +<KrossScripting> + <ScriptAction + name="TortureFiltersRuby" + text="Torture Chalk with Filters" + description="Test all filters with all colorspaces (ruby)" + icon="" + interpreter="ruby" + file="torture-filters.rb" /> +</KrossScripting> diff --git a/chalk/plugins/viewplugins/scripting/samples/ruby/torture-painting.rb b/chalk/plugins/viewplugins/scripting/samples/ruby/torture-painting.rb new file mode 100644 index 00000000..b7c784fc --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/ruby/torture-painting.rb @@ -0,0 +1,133 @@ +# This file is part of Chalk +# +# Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +require "krosschalkcore" + +class TorturePainting + + def initialize() + + doc = Krosschalkcore::get("ChalkDocument") + @script = Krosschalkcore::get("ChalkScript") + + @image = doc.getImage() + @width = @image.getWidth() + @height = @image.getHeight() + + @script.setProgressTotalSteps(30 * 10) + + testColorspace("RGBA") + testColorspace("RGBA16") + testColorspace("RGBAF16HALF") + testColorspace("RGBAF32") + testColorspace("CMYK") + testColorspace("CMYKA16") + testColorspace("CMYK") + testColorspace("CMYKA16") + testColorspace("LABA") + testColorspace("LMSAF32") + + + end + + def randomizeStyle(painter) + painter.setFillStyle(4 *rand) + painter.setStrokeStyle(2 *rand) + end + + + def testColorspace(cs) + print "Torturing for ", cs, "\n" + layer = @image.createPaintLayer("torture", 255 * rand, "RGBA" ); + torture(layer) + end + + + def torture(layer) + layer.beginPainting("torture painting") + + painter = layer.createPainter() + + # create painting color + blackcolor = Krosschalkcore::newRGBColor(0,0,0) + + # set painting color + painter.setPaintColor( blackcolor ) + + # get the pattern + pattern = Krosschalkcore::getPattern("Bricks") + + # set the pattern + painter.setPattern(pattern) + + # define the paint operation + painter.setPaintOp("paintbrush") + + # randomly rect or circle paint + for i in 1..30 + # set painting color + painter.setPaintColor( Krosschalkcore::newRGBColor(rand*255,rand*255,rand*255) ) + painter.setBackgroundColor( Krosschalkcore::newRGBColor(rand*255,rand*255,rand*255) ) + painter.setOpacity( rand*255 ) + # set the brush + if(rand < 0.5) + painter.setBrush( Krosschalkcore::newRectBrush(rand*20,rand*20,rand*10,rand*10) ) + else + painter.setBrush( Krosschalkcore::newCircleBrush(rand*20,rand*20,rand*10,rand*10) ) + end + # paint a point + tqshape = rand * 7 + painter.setStrokeStyle(1) + if( tqshape < 1 ) + painter.paintAt(rand * @width , rand * @height,1.1) + elsif(tqshape < 2 ) + xs = Array.new + ys = Array.new + for i in 0..6 + xs[i] = rand*@width + ys[i] = rand*@height + end + painter.paintPolyline(xs,ys) + elsif(tqshape < 3) + painter.paintLine(rand * @width, rand * @height, 1.1, rand * @width, rand * @height,1.1) + elsif(tqshape < 4) + painter.paintBezierCurve(rand * @width, rand * @height, 1.1, rand * @width, rand * @height, rand * @width , rand * @height, rand * @width, rand * @height, 1.1) + elsif(tqshape < 5) + randomizeStyle(painter) + painter.paintEllipse(rand * @width, rand * @height, rand * @width, rand * @height, 1.1) + elsif(tqshape < 6) + xs = Array.new + ys = Array.new + for i in 0..6 + xs[i] = rand*@width + ys[i] = rand*@height + end + randomizeStyle(painter) + painter.paintPolygon(xs, ys) + elsif(tqshape < 7) + randomizeStyle(painter) + painter.paintRect(rand * @width, rand * @height, rand * @width, rand * @height, 1.1) + end + @script.incProgress() + end + layer.endPainting() + end + +end + +TorturePainting.new()
\ No newline at end of file diff --git a/chalk/plugins/viewplugins/scripting/samples/ruby/torture-painting.rc b/chalk/plugins/viewplugins/scripting/samples/ruby/torture-painting.rc new file mode 100644 index 00000000..51f2eee4 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/samples/ruby/torture-painting.rc @@ -0,0 +1,9 @@ +<KrossScripting> + <ScriptAction + name="TorturePainting" + text="Torture Chalk with Painting" + description="Paint on an image and create multiple layers" + icon="" + interpreter="ruby" + file="torture-painting.rb" /> +</KrossScripting> diff --git a/chalk/plugins/viewplugins/scripting/scripting.cc b/chalk/plugins/viewplugins/scripting/scripting.cc new file mode 100644 index 00000000..34b4d1d8 --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/scripting.cc @@ -0,0 +1,111 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "scripting.h" + +#include <stdlib.h> +#include <vector> + +#include <tqapplication.h> +#include <tqpoint.h> + +#include <kdebug.h> +#include <kfiledialog.h> +#include <kgenericfactory.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> + +#define KROSS_MAIN_EXPORT KDE_EXPORT +#include <main/manager.h> +#include <main/scriptguiclient.h> +#include <main/wdgscriptsmanager.h> + +#include <kopalettemanager.h> + +#include <kis_doc.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_view.h> +#include <kis_image.h> +#include <kis_layer.h> + +#include "chalkscripting/kis_script_progress.h" +#include "chalkscripting/kis_script_monitor.h" + +typedef KGenericFactory<Scripting> ChalkScriptingFactory; +K_EXPORT_COMPONENT_FACTORY( chalkscripting, ChalkScriptingFactory( "chalk" ) ) + +Scripting::Scripting(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + setInstance(ChalkScriptingFactory::instance()); + + + if ( tqparent->inherits("KisView") ) + { + setInstance(Scripting::instance()); + m_view = (KisView*) tqparent; + m_scriptguiclient = new Kross::Api::ScriptGUIClient( m_view, m_view ); +// m_scriptguiclient ->setXMLFile(locate("data","chalkplugins/scripting.rc"), true); + //BEGIN TODO: understand why the ScriptGUIClient doesn't "link" its actions to the menu + setXMLFile(locate("data","chalkplugins/scripting.rc"), true); + new KAction(i18n("Execute Script File..."), 0, 0, m_scriptguiclient, TQT_SLOT(executeScriptFile()), actionCollection(), "executescriptfile"); + new KAction(i18n("Script Manager..."), 0, 0, m_scriptguiclient, TQT_SLOT(showScriptManager()), actionCollection(), "configurescripts"); + //END TODO + + TQWidget * w = new Kross::Api::WdgScriptsManager(m_scriptguiclient, m_view); + + m_view->canvasSubject()->paletteManager()->addWidget(w, "Scripts Manager", chalk::LAYERBOX, 10, PALETTE_DOCKER, false); + + connect(m_scriptguiclient, TQT_SIGNAL(executionFinished( const Kross::Api::ScriptAction* )), this, TQT_SLOT(executionFinished(const Kross::Api::ScriptAction*))); + connect(m_scriptguiclient, TQT_SIGNAL(executionStarted( const Kross::Api::ScriptAction* )), this, TQT_SLOT(executionStarted(const Kross::Api::ScriptAction*))); + KisScriptMonitor::instance()->monitor( m_scriptguiclient ); + + Kross::Api::Manager::scriptManager()->addTQObject(m_view->canvasSubject()->document(), "ChalkDocument"); + Kross::Api::Manager::scriptManager()->addTQObject(TQT_TQOBJECT(m_view), "ChalkView"); + m_scriptProgress = new KisScriptProgress(m_view); + Kross::Api::Manager::scriptManager()->addTQObject(m_scriptProgress, "ChalkScriptProgress"); + + } + +} + +Scripting::~Scripting() +{ +} + +void Scripting::executionFinished(const Kross::Api::ScriptAction*) +{ + m_view->canvasSubject()->document()->setModified(true); + m_view->canvasSubject()->document()->currentImage()->activeLayer()->setDirty(); + m_scriptProgress->progressDone(); + TQApplication::restoreOverrideCursor(); +} + +void Scripting::executionStarted(const Kross::Api::ScriptAction* act) +{ + kdDebug(41011) << act->getPackagePath() << endl; + m_scriptProgress->setPackagePath( act->getPackagePath() ); +} + + +#include "scripting.moc" diff --git a/chalk/plugins/viewplugins/scripting/scripting.h b/chalk/plugins/viewplugins/scripting/scripting.h new file mode 100644 index 00000000..a981175d --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/scripting.h @@ -0,0 +1,54 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SCRIPTING_H +#define SCRIPTING_H + +#include <kparts/plugin.h> + +class KisView; +class KisScript; +class KisScriptProgress; + +namespace Kross { + namespace Api { + class ScriptGUIClient; + class ScriptAction; + } +} + +class Scripting : public KParts::Plugin +{ + Q_OBJECT + TQ_OBJECT + public: + Scripting(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~Scripting(); + private slots: + void executionFinished(const Kross::Api::ScriptAction*); + void executionStarted(const Kross::Api::ScriptAction*); + private: + KisView * m_view; + Kross::Api::ScriptGUIClient* m_scriptguiclient; + KisScriptProgress* m_scriptProgress; +}; + + +#endif diff --git a/chalk/plugins/viewplugins/scripting/scripting.rc b/chalk/plugins/viewplugins/scripting/scripting.rc new file mode 100644 index 00000000..1b4999df --- /dev/null +++ b/chalk/plugins/viewplugins/scripting/scripting.rc @@ -0,0 +1,10 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkscripting" version="3"> + <MenuBar> + <Menu name="Scripts"><text>S&cripts</text> + <Separator/> + <Action name="executescriptfile"/> + <Action name="configurescripts"/> + </Menu> + </MenuBar> +</kpartgui> diff --git a/chalk/plugins/viewplugins/selectopaque/Makefile.am b/chalk/plugins/viewplugins/selectopaque/Makefile.am new file mode 100644 index 00000000..7f83e3c6 --- /dev/null +++ b/chalk/plugins/viewplugins/selectopaque/Makefile.am @@ -0,0 +1,25 @@ +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +kde_module_LTLIBRARIES = chalkselectopaque.la + +chalkselectopaque_la_SOURCES = selectopaque.cc +noinst_HEADERS = selectopaque.h + +chalkselectopaque_la_LIBADD = ../../../libchalkcommon.la +chalkselectopaque_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) chalkblurfilter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui + +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = selectopaque.rc +EXTRA_DIST = $(chalkrc_DATA) + +kde_services_DATA = chalkselectopaque.desktop + +chalkselectopaque_la_METASOURCES = AUTO + +KDE_OPTIONS = nofinal diff --git a/chalk/plugins/viewplugins/selectopaque/chalkselectopaque.desktop b/chalk/plugins/viewplugins/selectopaque/chalkselectopaque.desktop new file mode 100644 index 00000000..049c6a40 --- /dev/null +++ b/chalk/plugins/viewplugins/selectopaque/chalkselectopaque.desktop @@ -0,0 +1,26 @@ +[Desktop Entry] +Name=SelectOpaque +Name[bg]=Негатив +Name[da]=Markér ugennemsigtig +Name[de]=UndurchsichtigeAuswählen +Name[et]=Läbipaistmatute pikslite valik +Name[fy]=Untrochsichtige selektearje +Name[it]=Seleziona i pixel opachi +Name[km]=ជ្រើសស្រអាប់ +Name[nds]=Decken utsöken +Name[ne]=अपारदर्शी चयन +Name[nl]=Ondoorzichtige selecteren +Name[pl]=Zaznaczanie nieprzezroczystości +Name[pt]=Selecção Opaca +Name[pt_BR]=Seleção Opaca +Name[ru]=Выделение непрозрачных областей +Name[sk]=Invertovať Výber +Name[sr]=Избор непрозирног +Name[sr@Latn]=Izbor neprozirnog +Name[sv]=Markera ogenomskinliga +Name[uk]=Виділення непрозорих ділянок +Name[zh_TW]=選擇不透明 +ServiceTypes=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkselectopaque +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/selectopaque/selectopaque.cc b/chalk/plugins/viewplugins/selectopaque/selectopaque.cc new file mode 100644 index 00000000..a5717a97 --- /dev/null +++ b/chalk/plugins/viewplugins/selectopaque/selectopaque.cc @@ -0,0 +1,116 @@ +/* + * selectopague.h -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include <math.h> + +#include <stdlib.h> + +#include <tqcursor.h> +#include <tqapplication.h> + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> + +#include <kis_selected_transaction.h> +#include <kis_cursor.h> +#include <kis_doc.h> +#include <kis_image.h> +#include <kis_layer.h> +#include <kis_paint_device.h> +#include <kis_iterator.h> +#include <kis_iterators_pixel.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_view.h> +#include <kis_selection.h> +#include <kis_selection_manager.h> +#include "selectopaque.h" + +typedef KGenericFactory<SelectOpaque> SelectOpaqueFactory; +K_EXPORT_COMPONENT_FACTORY( chalkselectopaque, SelectOpaqueFactory( "chalk" ) ) + +SelectOpaque::SelectOpaque(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + + if (tqparent->inherits("KisView")) { + setInstance(SelectOpaqueFactory::instance()); + setXMLFile(locate("data","chalkplugins/selectopaque.rc"), true); + m_view = dynamic_cast<KisView*>(tqparent); + m_view->canvasSubject()->selectionManager()->addSelectionAction( new KAction(i18n("&Select All Opaque Pixels..."), 0, 0, this, TQT_SLOT(slotActivated()), actionCollection(), "selectopaque") ); + + } +} + +SelectOpaque::~SelectOpaque() +{ +} + +void SelectOpaque::slotActivated() +{ + KisSelectedTransaction *transaction; + + KisPaintDeviceSP layer = m_view->canvasSubject()->currentImg()->activeDevice(); + if (!layer) return; + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + + if (layer->image()->undo()) transaction = new KisSelectedTransaction(i18n("Select Opaque Pixels"), layer); + // XXX: Multithread this! + TQ_INT32 x, y, w, h; + layer->exactBounds(x, y, w, h); + + KisColorSpace * cs = layer->colorSpace(); + + if(! layer->hasSelection()) + layer->selection()->clear(); + KisSelectionSP selection = layer->selection(); + + KisHLineIterator hiter = layer->createHLineIterator(x, y, w, false); + KisHLineIterator selIter = selection ->createHLineIterator(x, y, w, true); + + for (int row = 0; row < h; ++row) { + while (!hiter.isDone()) { + // Don't try to select transparent pixels. + if (cs->getAlpha( hiter.rawData() ) > OPACITY_TRANSPARENT) { + *(selIter.rawData()) = MAX_SELECTED; + } + ++hiter; + ++selIter; + } + hiter.nextRow(); + selIter.nextRow(); + } + TQApplication::restoreOverrideCursor(); + layer->setDirty(); + layer->emitSelectionChanged(); + + if (layer->image()->undo()) m_view->canvasSubject()->undoAdapter()->addCommand(transaction); + +} + +#include "selectopaque.moc" + diff --git a/chalk/plugins/viewplugins/selectopaque/selectopaque.h b/chalk/plugins/viewplugins/selectopaque/selectopaque.h new file mode 100644 index 00000000..47614e30 --- /dev/null +++ b/chalk/plugins/viewplugins/selectopaque/selectopaque.h @@ -0,0 +1,45 @@ +/* + * selectopaque.h -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SELECTOPAQUE_H +#define SELECTOPAQUE_H + +#include <kparts/plugin.h> + +class KisView; + +class SelectOpaque : public KParts::Plugin +{ + Q_OBJECT + TQ_OBJECT + public: + SelectOpaque(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~SelectOpaque(); + + private slots: + void slotActivated(); + + private: + KisView * m_view; + KisPainter * m_painter; + +}; + +#endif // SELECTOPAQUE_H diff --git a/chalk/plugins/viewplugins/selectopaque/selectopaque.rc b/chalk/plugins/viewplugins/selectopaque/selectopaque.rc new file mode 100644 index 00000000..a4809d59 --- /dev/null +++ b/chalk/plugins/viewplugins/selectopaque/selectopaque.rc @@ -0,0 +1,10 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkselectopaque" version="1"> +<MenuBar> + <Menu name="Select"><text>Select</text> + <Separator/> + <Action name="selectopaque"/> + <Separator/> + </Menu> +</MenuBar> +</kpartgui> diff --git a/chalk/plugins/viewplugins/separate_channels/Makefile.am b/chalk/plugins/viewplugins/separate_channels/Makefile.am new file mode 100644 index 00000000..9b28a89d --- /dev/null +++ b/chalk/plugins/viewplugins/separate_channels/Makefile.am @@ -0,0 +1,27 @@ +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = imageseparate.rc +EXTRA_DIST = $(chalkrc_DATA) + +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +kde_module_LTLIBRARIES = chalkseparatechannels.la + +chalkseparatechannels_la_SOURCES = wdg_separations.ui \ + kis_channel_separator.cc dlg_separate.cc \ + kis_separate_channels_plugin.cc + +noinst_HEADERS = wdg_separations.h kis_separate_channels_plugin.h \ + kis_channel_separator.h dlg_separate.h + +kde_services_DATA = chalkseparatechannels.desktop + +chalkseparatechannels_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui -L../../../../lib/kofficecore/.libs -lkofficecore +chalkseparatechannels_la_LIBADD = ../../../libchalkcommon.la + +chalkseparatechannels_la_METASOURCES = AUTO diff --git a/chalk/plugins/viewplugins/separate_channels/chalkseparatechannels.desktop b/chalk/plugins/viewplugins/separate_channels/chalkseparatechannels.desktop new file mode 100644 index 00000000..efb596b8 --- /dev/null +++ b/chalk/plugins/viewplugins/separate_channels/chalkseparatechannels.desktop @@ -0,0 +1,42 @@ +[Desktop Entry] +Name=Separate Channels Plugin +Name[bg]=Приставка за отделен канал +Name[ca]=Connector de canals separats +Name[da]=Plugin for separate kanaler +Name[de]="Kanäle trennen"-Modul +Name[el]=Πρόσθετο διαχωρισμού καναλιών +Name[eo]=Apartkanal-kromaĵo +Name[es]=Complemento para canales separados +Name[et]=Kanalite lahutamise plugin +Name[fa]=جدا کردن وصلۀ مجراها +Name[fr]=Module de séparation des canaux +Name[fy]=Plugin foar aparte kanalen +Name[gl]=Plugin de Separación de Canais +Name[he]=תוסף לריבוי ערוצים +Name[hu]=Csatornaszétválasztó modul +Name[is]=Aðgreindar rásir íforrit +Name[it]=Plugin per la separazione dei canali +Name[ja]=チャンネル分離プラグイン +Name[km]=កម្មវិធីជំនួយដើម្បីបំបែកឆានែល +Name[nb]=Programtillegg for atskilte kanaler +Name[nds]=Kanaaltrenn-Moduul +Name[ne]=च्यानल प्लगइन छुट्याउनुहोस् +Name[nl]=Plugin voor aparte kanalen +Name[pl]=Wtyczka oddzielania kanałów +Name[pt]='Plugin' de Separação de Canais +Name[pt_BR]=Plugin de Separação de Canais +Name[ru]=Разбор изображения по каналам +Name[sk]=Modul oddelenie kanálov +Name[sl]=Vstavek za ločevanje kanalov +Name[sr]=Прикључак за раздвајање канала +Name[sr@Latn]=Priključak za razdvajanje kanala +Name[sv]=Insticksprogram för separata kanaler +Name[uk]=Втулок розділення каналів +Name[uz]=Kanallarni ajratish uchun plagin +Name[uz@cyrillic]=Каналларни ажратиш учун плагин +Name[zh_CN]=独立通道插件 +Name[zh_TW]=分離色頻外掛程式 +ServiceTypes=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkseparatechannels +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/separate_channels/dlg_separate.cc b/chalk/plugins/viewplugins/separate_channels/dlg_separate.cc new file mode 100644 index 00000000..e6124046 --- /dev/null +++ b/chalk/plugins/viewplugins/separate_channels/dlg_separate.cc @@ -0,0 +1,110 @@ +/* + * dlg_separate.cc - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqradiobutton.h> +#include <tqcheckbox.h> +#include <tqbuttongroup.h> +#include <tqlabel.h> +#include <tqcombobox.h> +#include <tqbutton.h> + +#include <klocale.h> +#include <knuminput.h> +#include <kdebug.h> + +#include "dlg_separate.h" +#include "wdg_separations.h" + +DlgSeparate::DlgSeparate( const TQString & imageCS, + const TQString & layerCS, + TQWidget * tqparent, + const char * name) + : super (tqparent, name, true, i18n("Separate Image"), Ok | Cancel, Ok), + m_imageCS(imageCS), + m_layerCS(layerCS) +{ + m_page = new WdgSeparations(this, "separate_image"); + Q_CHECK_PTR(m_page); + setMainWidget(m_page); + resize(m_page->tqsizeHint()); + + m_page->lblColormodel->setText(layerCS); + m_page->grpOutput->hide(); + connect(m_page->grpSource, TQT_SIGNAL(clicked(int)), this, TQT_SLOT(slotSetColorSpaceLabel(int))); + connect(m_page->chkColors, TQT_SIGNAL(toggled(bool)), m_page->chkDownscale, TQT_SLOT(setDisabled(bool))); + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); +} + +DlgSeparate::~DlgSeparate() +{ + delete m_page; +} + + + +enumSepAlphaOptions DlgSeparate::getAlphaOptions() +{ + return (enumSepAlphaOptions)m_page->grpAlpha->selectedId(); +} + +enumSepSource DlgSeparate::getSource() +{ + return (enumSepSource)m_page->grpSource->selectedId(); +} + +enumSepOutput DlgSeparate::getOutput() +{ + return (enumSepOutput)m_page->grpOutput->selectedId(); +} + + +bool DlgSeparate::getDownscale() +{ + return m_page->chkDownscale->isChecked(); +} + +bool DlgSeparate::getToColor() +{ + return m_page->chkColors->isChecked(); +} + +// SLOTS + +void DlgSeparate::okClicked() +{ + accept(); +} + +void DlgSeparate::slotSetColorSpaceLabel(int buttonid) +{ + if (buttonid == 0) { + m_page->lblColormodel->setText(m_layerCS); + } + else { + m_page->lblColormodel->setText(m_imageCS); + } +} +void DlgSeparate::enableDownscale(bool enable) { + m_page->chkDownscale->setEnabled(enable); +} + +#include "dlg_separate.moc" diff --git a/chalk/plugins/viewplugins/separate_channels/dlg_separate.h b/chalk/plugins/viewplugins/separate_channels/dlg_separate.h new file mode 100644 index 00000000..d3536dda --- /dev/null +++ b/chalk/plugins/viewplugins/separate_channels/dlg_separate.h @@ -0,0 +1,68 @@ +/* + * dlg_imagesize.h -- part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef DLG_SEPARATE +#define DLG_SEPARATE + +#include <kdialogbase.h> +#include <kis_channel_separator.h> + +class WdgSeparations; + +/** + * This dialog allows the user to configure the decomposition of an image + * into layers: one layer for each color channel. + */ +class DlgSeparate: public KDialogBase { + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + + DlgSeparate(const TQString & imageCS, const TQString & layerCS, TQWidget * tqparent = 0, + const char* name = 0); + ~DlgSeparate(); + +public: + + enumSepAlphaOptions getAlphaOptions(); + enumSepSource getSource(); + enumSepOutput getOutput(); + + bool getDownscale(); + void enableDownscale(bool enable); + + bool getToColor(); + + +private slots: + + void slotSetColorSpaceLabel(int buttonid); + void okClicked(); + +private: + + WdgSeparations * m_page; + TQString m_imageCS; + TQString m_layerCS; + +}; + +#endif // DLG_SEPARATE diff --git a/chalk/plugins/viewplugins/separate_channels/imageseparate.rc b/chalk/plugins/viewplugins/separate_channels/imageseparate.rc new file mode 100644 index 00000000..b0518510 --- /dev/null +++ b/chalk/plugins/viewplugins/separate_channels/imageseparate.rc @@ -0,0 +1,9 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkseparatechannels" version="6"> +<MenuBar> + <Menu name="Image"><text>Image</text> + <Separator/> + <Action name="separate"/> + </Menu> +</MenuBar> +</kpartgui> diff --git a/chalk/plugins/viewplugins/separate_channels/kis_channel_separator.cc b/chalk/plugins/viewplugins/separate_channels/kis_channel_separator.cc new file mode 100644 index 00000000..3315177c --- /dev/null +++ b/chalk/plugins/viewplugins/separate_channels/kis_channel_separator.cc @@ -0,0 +1,301 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * ported from Gimp, Copyright (C) 1997 Eiichi Takamori <taka@ma1.seikyou.ne.jp> + * original pixelize.c for GIMP 0.54 by Tracy Scott + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <limits.h> + +#include <stdlib.h> +#include <vector> + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> +#include <knuminput.h> +#include <kfiledialog.h> + + +#include <KoFilterManager.h> + +#include <kis_doc.h> +#include <kis_image.h> +#include "kis_meta_registry.h" +#include <kis_iterators_pixel.h> +#include <kis_layer.h> +#include <kis_paint_layer.h> +#include <kis_group_layer.h> +#include <kis_transaction.h> +#include <kis_undo_adapter.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_progress_subject.h> +#include <kis_progress_display_interface.h> +#include <kis_colorspace.h> +#include <kis_colorspace_factory_registry.h> +#include <kis_view.h> +#include <kis_paint_device.h> +#include <kis_channelinfo.h> + +#include "kis_channel_separator.h" + +KisChannelSeparator::KisChannelSeparator(KisView * view) + : m_view(view) +{ +} + +void KisChannelSeparator::separate(KisProgressDisplayInterface * progress, enumSepAlphaOptions alphaOps, enumSepSource sourceOps, enumSepOutput outputOps, bool downscale, bool toColor) +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + if (!image) return; + + KisLayerSP layer = image->activeLayer(); + if (!layer) return; + + KisPaintDeviceSP src = image->activeDevice(); + if (!src) return; + + m_cancelRequested = false; + if ( progress ) + progress->setSubject(this, true, true); + emit notifyProgressStage(i18n("Separating image..."), 0); + + KisColorSpace * dstCs = 0; + + TQ_UINT32 numberOfChannels = src->nChannels(); + KisColorSpace * srcCs = src->colorSpace(); + TQValueVector<KisChannelInfo *> channels = srcCs->channels(); + + // Use the flattened image, if required + switch(sourceOps) { + + case(ALL_LAYERS): + src = image->mergedImage(); + break; + default: + break; + } + + vKisPaintDeviceSP layers; + + TQValueVector<KisChannelInfo *>::const_iterator begin = channels.begin(); + TQValueVector<KisChannelInfo *>::const_iterator end = channels.end(); + + + TQRect rect = src->exactBounds(); + + int i = 0; + TQ_UINT32 channelIndex = 0; + for (TQValueVector<KisChannelInfo *>::const_iterator it = begin; it != end; ++it, ++channelIndex) + { + + KisChannelInfo * ch = (*it); + + if (ch->channelType() == KisChannelInfo::ALPHA && alphaOps != CREATE_ALPHA_SEPARATION) { + continue; + } + + TQ_INT32 channelSize = ch->size(); + TQ_INT32 channelPos = ch->pos(); + TQ_INT32 destSize = 1; + + KisPaintDeviceSP dev; + if (toColor) { + // We don't downscale if we separate to color channels + dev = new KisPaintDevice(srcCs, "color separations"); + } + else { + if (channelSize == 1 || downscale) { + dev = new KisPaintDevice( KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("GRAYA",""),"" ), "8 bit grayscale sep"); + } + else { + dev = new KisPaintDevice( KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("GRAYA16",""),"" ), "16 bit grayscale sep"); + destSize = 2; + } + } + + dstCs = dev->colorSpace(); + + layers.push_back(dev); + + for (TQ_INT32 row = 0; row < rect.height(); ++row) { + + KisHLineIteratorPixel srcIt = src->createHLineIterator(rect.x(), rect.y() + row, rect.width(), false); + KisHLineIteratorPixel dstIt = dev->createHLineIterator(rect.x(), rect.y() + row, rect.width(), true); + + while( ! srcIt.isDone() ) + { + if (srcIt.isSelected()) + { + if (toColor) { + dstCs->getSingleChannelPixel(dstIt.rawData(), srcIt.rawData(), channelIndex); + + if (alphaOps == COPY_ALPHA_TO_SEPARATIONS) { + //dstCs->setAlpha(dstIt.rawData(), srcIt.rawData()[srcAlphaPos], 1); + dstCs->setAlpha(dstIt.rawData(), srcCs->getAlpha(srcIt.rawData()), 1); + } + else { + dstCs->setAlpha(dstIt.rawData(), OPACITY_OPAQUE, 1); + } + } + else { + + // To grayscale + + // Decide wether we need downscaling + if (channelSize == 1 && destSize == 1) { + + // Both 8-bit channels + dstIt.rawData()[0] = srcIt.rawData()[channelPos]; + + if (alphaOps == COPY_ALPHA_TO_SEPARATIONS) { + dstCs->setAlpha(dstIt.rawData(), srcCs->getAlpha(srcIt.rawData()), 1); + } + else { + dstCs->setAlpha(dstIt.rawData(), OPACITY_OPAQUE, 1); + } + } + else if (channelSize == 2 && destSize == 2) { + + // Both 16-bit + dstIt.rawData()[0] = srcIt.rawData()[channelPos]; + dstIt.rawData()[1] = srcIt.rawData()[channelPos + 1]; + + if (alphaOps == COPY_ALPHA_TO_SEPARATIONS) { + dstCs->setAlpha(dstIt.rawData(), srcCs->getAlpha(srcIt.rawData()), 1); + } + else { + dstCs->setAlpha(dstIt.rawData(), OPACITY_OPAQUE, 1); + } + } + else if (channelSize != 1 && destSize == 1) { + // Downscale + memset(dstIt.rawData(), srcCs->scaleToU8(srcIt.rawData(), channelPos), 1); + + // XXX: Do alpha + dstCs->setAlpha(dstIt.rawData(), OPACITY_OPAQUE, 1); + } + else if (channelSize != 2 && destSize == 2) { + // Upscale + dstIt.rawData()[0] = srcCs->scaleToU8(srcIt.rawData(), channelPos); + + // XXX: Do alpha + dstCs->setAlpha(dstIt.rawData(), OPACITY_OPAQUE, 1); + + } + } + } + ++dstIt; + ++srcIt; + } + } + ++i; + + emit notifyProgress((i * 100) / numberOfChannels); + if (m_cancelRequested) { + break; + } + } + + vKisPaintDeviceSP_it deviceIt = layers.begin(); + + emit notifyProgressDone(); + + if (!m_cancelRequested) { + + KisUndoAdapter * undo = 0; + if ((undo = image->undoAdapter()) && undo->undo()) { + undo->beginMacro(i18n("Separate Image")); + } + + // Flatten the image if required + switch(sourceOps) { + case(ALL_LAYERS): + image->flatten(); + break; + default: + break; + } + + for (TQValueVector<KisChannelInfo *>::const_iterator it = begin; it != end; ++it) + { + + KisChannelInfo * ch = (*it); + + if (ch->channelType() == KisChannelInfo::ALPHA && alphaOps != CREATE_ALPHA_SEPARATION) { + // Don't make an separate separation of the alpha channel if the user didn't ask for it. + continue; + } + + if (outputOps == TO_LAYERS) { + KisPaintLayerSP l = new KisPaintLayer( image, ch->name(), OPACITY_OPAQUE, *deviceIt); + image->addLayer( dynamic_cast<KisLayer*>(l.data()), image->rootLayer(), 0); + } + else { + TQStringList listMimeFilter = KoFilterManager::mimeFilter("application/x-chalk", KoFilterManager::Export); + TQString mimelist = listMimeFilter.join(" "); + + KFileDialog fd (TQString(), mimelist, m_view, "Export Layer", true); + fd.setCaption(i18n("Export Layer") + "(" + ch->name() + ")"); + fd.setMimeFilter(listMimeFilter); + fd.setOperationMode(KFileDialog::Saving); + fd.setURL(KURL(ch->name())); + if (!fd.exec()) return; + + KURL url = fd.selectedURL(); + TQString mimefilter = fd.currentMimeFilter(); + + if (url.isEmpty()) + return; + + KisPaintLayerSP l = new KisPaintLayer( image, ch->name(), OPACITY_OPAQUE, *deviceIt); + TQRect r = l->exactBounds(); + + KisDoc d; + d.prepareForImport(); + + KisImageSP dst = new KisImage(d.undoAdapter(), r.width(), r.height(), (*deviceIt)->colorSpace(), l->name()); + d.setCurrentImage( dst ); + dst->addLayer(l->clone(), dst->rootLayer(), 0); + + d.setOutputMimeType(mimefilter.latin1()); + d.exp0rt(url); + + } + + ++deviceIt; + } + + if (undo && undo->undo()) { + undo->endMacro(); + } + + m_view->canvasSubject()->document()->setModified(true); + } +} + + + + +#include "kis_channel_separator.moc" diff --git a/chalk/plugins/viewplugins/separate_channels/kis_channel_separator.h b/chalk/plugins/viewplugins/separate_channels/kis_channel_separator.h new file mode 100644 index 00000000..d8bf777e --- /dev/null +++ b/chalk/plugins/viewplugins/separate_channels/kis_channel_separator.h @@ -0,0 +1,70 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_CHANNEL_SEPARATOR_H_ +#define _KIS_CHANNEL_SEPARATOR_H_ + +#include <kis_progress_subject.h> + +class KisView; +class KisProgressDisplayInterface; + + +enum enumSepAlphaOptions { + COPY_ALPHA_TO_SEPARATIONS = 0, + DISCARD_ALPHA = 1, + CREATE_ALPHA_SEPARATION = 2 +}; + + +enum enumSepSource { + CURRENT_LAYER = 0, + ALL_LAYERS = 1, + VISIBLE_LAYERS = 2 +}; + +enum enumSepOutput { + TO_LAYERS = 0, + TO_IMAGES = 1 +}; + +class KisChannelSeparator : public KisProgressSubject { + + Q_OBJECT + TQ_OBJECT + +public: + + KisChannelSeparator(KisView * view); + virtual ~KisChannelSeparator() {}; + + void separate(KisProgressDisplayInterface * progress, enumSepAlphaOptions alphaOps, enumSepSource sourceOps, enumSepOutput outputOps, bool downscale, bool toColor); + +public: // Implement KisProgressSubject + virtual void cancel() { m_cancelRequested = true; } + + +private: + KisView * m_view; + bool m_cancelRequested; + +}; + +#endif diff --git a/chalk/plugins/viewplugins/separate_channels/kis_separate_channels_plugin.cc b/chalk/plugins/viewplugins/separate_channels/kis_separate_channels_plugin.cc new file mode 100644 index 00000000..64a83db5 --- /dev/null +++ b/chalk/plugins/viewplugins/separate_channels/kis_separate_channels_plugin.cc @@ -0,0 +1,96 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> + +#include <kis_view.h> +#include <kis_types.h> +#include <kis_image.h> +#include <kis_paint_device.h> +#include <kis_layer.h> + +#include "kis_separate_channels_plugin.h" +#include "kis_channel_separator.h" +#include "dlg_separate.h" + +K_EXPORT_COMPONENT_FACTORY( chalkseparatechannels, KGenericFactory<KisSeparateChannelsPlugin>( "chalk" ) ) + +KisSeparateChannelsPlugin::KisSeparateChannelsPlugin(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + + if ( tqparent->inherits("KisView") ) { + setInstance(KGenericFactory<KisSeparateChannelsPlugin>::instance()); + setXMLFile(locate("data","chalkplugins/imageseparate.rc"), true); + m_view = (KisView*) tqparent; + (void) new KAction(i18n("Separate Image..."), 0, 0, this, TQT_SLOT(slotSeparate()), actionCollection(), "separate"); + } +} + +KisSeparateChannelsPlugin::~KisSeparateChannelsPlugin() +{ +} + +void KisSeparateChannelsPlugin::slotSeparate() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + if (!image) return; + + KisLayerSP l = image->activeLayer(); + if (!l) return; + + KisPaintDeviceSP dev = image->activeDevice(); + if (!dev) return; + + DlgSeparate * dlgSeparate = new DlgSeparate(dev->colorSpace()->id().name(), + image->colorSpace()->id().name(), m_view, "Separate"); + Q_CHECK_PTR(dlgSeparate); + + dlgSeparate->setCaption(i18n("Separate Image")); + + // If we're 8-bits, disable the downscale option + if (dev->pixelSize() == dev->nChannels()) { + dlgSeparate->enableDownscale(false); + } + + if (dlgSeparate->exec() == TQDialog::Accepted) { + + KisChannelSeparator separator(m_view); + separator.separate(m_view->canvasSubject()->progressDisplay(), + dlgSeparate->getAlphaOptions(), + dlgSeparate->getSource(), + dlgSeparate->getOutput(), + dlgSeparate->getDownscale(), + dlgSeparate->getToColor()); + + } + + delete dlgSeparate; + +} + +#include "kis_separate_channels_plugin.moc" diff --git a/chalk/plugins/viewplugins/separate_channels/kis_separate_channels_plugin.h b/chalk/plugins/viewplugins/separate_channels/kis_separate_channels_plugin.h new file mode 100644 index 00000000..ce3aa731 --- /dev/null +++ b/chalk/plugins/viewplugins/separate_channels/kis_separate_channels_plugin.h @@ -0,0 +1,46 @@ +/* + * This file is part of Chalk + * + * Copyright (c) Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _KIS_SEPARATE_CHANNELS_PLUGIN_H_ +#define _KIS_SEPARATE_CHANNELS_PLUGIN_H_ + +#include <kparts/plugin.h> + +class KisView; + + + +class KisSeparateChannelsPlugin : public KParts::Plugin +{ + Q_OBJECT + TQ_OBJECT +public: + KisSeparateChannelsPlugin(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~KisSeparateChannelsPlugin(); + +private slots: + + void slotSeparate(); + +private: + + KisView * m_view; +}; + +#endif diff --git a/chalk/plugins/viewplugins/separate_channels/wdg_separations.ui b/chalk/plugins/viewplugins/separate_channels/wdg_separations.ui new file mode 100644 index 00000000..0593258b --- /dev/null +++ b/chalk/plugins/viewplugins/separate_channels/wdg_separations.ui @@ -0,0 +1,182 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgSeparations</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgSeparations</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>570</width> + <height>350</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQCheckBox" row="4" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>chkColors</cstring> + </property> + <property name="text"> + <string>Output to color, not grayscale</string> + </property> + </widget> + <widget class="TQCheckBox" row="3" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>chkDownscale</cstring> + </property> + <property name="text"> + <string>Downscale to 8-bit before separating</string> + </property> + </widget> + <widget class="TQButtonGroup" row="2" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>grpAlpha</cstring> + </property> + <property name="title"> + <string>Alpha Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radioCopyAlpha</cstring> + </property> + <property name="text"> + <string>Copy alpha channel to each separated channel as an alpha channel</string> + </property> + </widget> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radioDiscardAlpha</cstring> + </property> + <property name="text"> + <string>Discard alpha channel</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radioSeparateAlpha</cstring> + </property> + <property name="text"> + <string>Create separate separation from alpha channel</string> + </property> + </widget> + </vbox> + </widget> + <spacer row="5" column="1"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="TQButtonGroup" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>grpSource</cstring> + </property> + <property name="title"> + <string>Source</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQRadioButton" row="0" column="0"> + <property name="name"> + <cstring>radioCurrentLayer</cstring> + </property> + <property name="text"> + <string>Current layer</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQRadioButton" row="1" column="0"> + <property name="name"> + <cstring>radioAllLayers</cstring> + </property> + <property name="text"> + <string>Flatten all layers before separation</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQButtonGroup" row="1" column="2"> + <property name="name"> + <cstring>grpOutput</cstring> + </property> + <property name="title"> + <string>Output</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radioLayers</cstring> + </property> + <property name="text"> + <string>To layers</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radioImages</cstring> + </property> + <property name="text"> + <string>To images</string> + </property> + </widget> + </vbox> + </widget> + <widget class="TQLabel" row="0" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>lblColormodel</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Current color model:</string> + </property> + </widget> + </grid> +</widget> +<tabstops> + <tabstop>radioCurrentLayer</tabstop> + <tabstop>radioLayers</tabstop> + <tabstop>radioDiscardAlpha</tabstop> + <tabstop>chkDownscale</tabstop> + <tabstop>chkColors</tabstop> +</tabstops> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/plugins/viewplugins/shearimage/Makefile.am b/chalk/plugins/viewplugins/shearimage/Makefile.am new file mode 100644 index 00000000..5f8efe55 --- /dev/null +++ b/chalk/plugins/viewplugins/shearimage/Makefile.am @@ -0,0 +1,25 @@ +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = shearimage.rc + +EXTRA_DIST = $(chalkrc_DATA) + + +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +kde_module_LTLIBRARIES = chalkshearimage.la + +kde_services_DATA = chalkshearimage.desktop + +chalkshearimage_la_SOURCES = wdg_shearimage.ui shearimage.cc dlg_shearimage.cc +noinst_HEADERS = wdg_shearimage.h dlg_shearimage.h shearimage.h + +chalkshearimage_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) chalkblurfilter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui +chalkshearimage_la_LIBADD = ../../../libchalkcommon.la + +chalkshearimage_la_METASOURCES = AUTO diff --git a/chalk/plugins/viewplugins/shearimage/chalkshearimage.desktop b/chalk/plugins/viewplugins/shearimage/chalkshearimage.desktop new file mode 100644 index 00000000..6f3ac5ae --- /dev/null +++ b/chalk/plugins/viewplugins/shearimage/chalkshearimage.desktop @@ -0,0 +1,37 @@ +[Desktop Entry] +Name=Shear Image Plugin +Name[bg]=Приставка за отрязване на изображение +Name[ca]=Connector de tall d'imatge +Name[da]=Plugin for skævvrid billede +Name[de]="Bild scheren"-Modul +Name[el]=Πρόσθετο στρέβλωσης εικόνας +Name[es]=Complemento para cortar la imagen +Name[et]=Pildinihke plugin +Name[fa]=اشتراک وصلۀ تصویر +Name[fr]=Module de rognage d'images +Name[fy]=Ofbylding skeanlûke plugin +Name[gl]=Plugin de Inclinación da Imaxe +Name[hu]=Képnyíró modul +Name[is]=Klippa mynd íforrit +Name[it]=Plugin di distorsione delle immagini +Name[ja]=画像剪断変形プラグイン +Name[km]=កម្មវិធីជំនួយដើម្បីកាត់រូបភាព +Name[nb]=Programtillegg for bildeskjæring +Name[nds]=Bildscheer-Moduul +Name[ne]=छवि प्लगइन अपूर्ण गर्नुहोस् +Name[nl]=Afbeelding schuintrekken +Name[pl]=Wtyczka obcinania obrazków +Name[pt]='Plugin' de Inclinação da Imagem +Name[pt_BR]=Plugin de Inclinação da Imagem +Name[ru]=Сдвиг +Name[sk]=Modul roztrhnutie obrázku +Name[sl]=Vstavek Ostriži sliko +Name[sr]=Прикључак за смицање слике +Name[sr@Latn]=Priključak za smicanje slike +Name[sv]=Insticksprogram för skjuva bild +Name[uk]=Втулок перекошення зображення +Name[zh_TW]=修剪圖片外掛程式 +ServiceTypes=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkshearimage +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/shearimage/dlg_shearimage.cc b/chalk/plugins/viewplugins/shearimage/dlg_shearimage.cc new file mode 100644 index 00000000..ff6dadde --- /dev/null +++ b/chalk/plugins/viewplugins/shearimage/dlg_shearimage.cc @@ -0,0 +1,96 @@ +/* + * dlg_shearimage.cc - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <config.h> + +#include <math.h> + +#include <iostream> + +using namespace std; + +#include <tqradiobutton.h> +#include <tqcheckbox.h> +#include <tqlabel.h> +#include <tqlayout.h> + +#include <klocale.h> +#include <knuminput.h> +#include <kdebug.h> + +#include "dlg_shearimage.h" +#include "wdg_shearimage.h" + + +DlgShearImage::DlgShearImage( TQWidget * tqparent, + const char * name) + : super (tqparent, name, true, i18n("Shear Image"), Ok | Cancel, Ok) +{ + m_lock = false; + + m_page = new WdgShearImage(this, "shear_image"); + m_page->tqlayout()->setMargin(0); + Q_CHECK_PTR(m_page); + + setMainWidget(m_page); + resize(m_page->tqsizeHint()); + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); + +} + +DlgShearImage::~DlgShearImage() +{ + delete m_page; +} + +void DlgShearImage::setAngleX(TQ_UINT32 angle) +{ + m_page->shearAngleX->setValue(angle); + m_oldAngle = angle; + +} + +void DlgShearImage::setAngleY(TQ_UINT32 angle) +{ + m_page->shearAngleY->setValue(angle); + m_oldAngle = angle; + +} + +TQ_INT32 DlgShearImage::angleX() +{ + return (TQ_INT32)tqRound(m_page->shearAngleX->value()); +} + +TQ_INT32 DlgShearImage::angleY() +{ + return (TQ_INT32)tqRound(m_page->shearAngleY->value()); +} + +// SLOTS + +void DlgShearImage::okClicked() +{ + accept(); +} + +#include "dlg_shearimage.moc" diff --git a/chalk/plugins/viewplugins/shearimage/dlg_shearimage.h b/chalk/plugins/viewplugins/shearimage/dlg_shearimage.h new file mode 100644 index 00000000..5c82abc7 --- /dev/null +++ b/chalk/plugins/viewplugins/shearimage/dlg_shearimage.h @@ -0,0 +1,55 @@ +/* + * dlg_shearimage.h -- part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef DLG_SHEARIMAGE +#define DLG_SHEARIMAGE + +#include <kdialogbase.h> + +class WdgShearImage; + +class DlgShearImage: public KDialogBase { + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + + DlgShearImage(TQWidget * tqparent = 0, + const char* name = 0); + ~DlgShearImage(); + + void setAngleX(TQ_UINT32 w); + void setAngleY(TQ_UINT32 w); + TQ_INT32 angleX(); + TQ_INT32 angleY(); + +private slots: + + void okClicked(); + +private: + + WdgShearImage * m_page; + double m_oldAngle; + bool m_lock; + +}; + +#endif // DLG_SHEARIMAGE diff --git a/chalk/plugins/viewplugins/shearimage/shearimage.cc b/chalk/plugins/viewplugins/shearimage/shearimage.cc new file mode 100644 index 00000000..4e7e61d6 --- /dev/null +++ b/chalk/plugins/viewplugins/shearimage/shearimage.cc @@ -0,0 +1,113 @@ +/* + * shearimage.cc -- Part of Chalk + * + * Copyright (c) 2004 Michael Thaler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include <math.h> + +#include <stdlib.h> + +#include <tqslider.h> +#include <tqpoint.h> + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> + +#include <kis_doc.h> +#include <kis_config.h> +#include <kis_image.h> +#include <kis_layer.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_view.h> +#include <kis_selection.h> + +#include "shearimage.h" +#include "dlg_shearimage.h" + +typedef KGenericFactory<ShearImage> ShearImageFactory; +K_EXPORT_COMPONENT_FACTORY( chalkshearimage, ShearImageFactory( "chalk" ) ) + +// XXX: this plugin could also provide layer scaling/resizing +ShearImage::ShearImage(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + if ( tqparent->inherits("KisView") ) + { + setInstance(ShearImageFactory::instance()); + setXMLFile(locate("data","chalkplugins/shearimage.rc"), true); + + (void) new KAction(i18n("&Shear Image..."), 0, 0, this, TQT_SLOT(slotShearImage()), actionCollection(), "shearimage"); + (void) new KAction(i18n("&Shear Layer..."), 0, 0, this, TQT_SLOT(slotShearLayer()), actionCollection(), "shearlayer"); + + m_view = (KisView*) tqparent; + } +} + +ShearImage::~ShearImage() +{ + m_view = 0; +} + +void ShearImage::slotShearImage() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgShearImage * dlgShearImage = new DlgShearImage(m_view, "ShearImage"); + Q_CHECK_PTR(dlgShearImage); + + dlgShearImage->setCaption(i18n("Shear Image")); + + if (dlgShearImage->exec() == TQDialog::Accepted) { + TQ_INT32 angleX = dlgShearImage->angleX(); + TQ_INT32 angleY = dlgShearImage->angleY(); + m_view->shearCurrentImage(angleX, angleY); + } + delete dlgShearImage; +} + +void ShearImage::slotShearLayer() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (!image) return; + + DlgShearImage * dlgShearImage = new DlgShearImage(m_view, "ShearLayer"); + Q_CHECK_PTR(dlgShearImage); + + dlgShearImage->setCaption(i18n("Shear Layer")); + + if (dlgShearImage->exec() == TQDialog::Accepted) { + TQ_INT32 angleX = dlgShearImage->angleX(); + TQ_INT32 angleY = dlgShearImage->angleY(); + m_view->shearLayer(angleX, angleY); + + } + delete dlgShearImage; +} + +#include "shearimage.moc" diff --git a/chalk/plugins/viewplugins/shearimage/shearimage.h b/chalk/plugins/viewplugins/shearimage/shearimage.h new file mode 100644 index 00000000..c824fb51 --- /dev/null +++ b/chalk/plugins/viewplugins/shearimage/shearimage.h @@ -0,0 +1,47 @@ +/* + * shearimage.h -- Part of Chalk + * + * Copyright (c) 2004 Michael Thaler (michael.thaler@physik.tu-muenchen.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef SHEARIMAGE_H +#define SHEARIMAGE_H + +#include <kparts/plugin.h> + +class KisView; + +class ShearImage : public KParts::Plugin +{ + Q_OBJECT + TQ_OBJECT +public: + ShearImage(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~ShearImage(); + +private slots: + + void slotShearImage(); + void slotShearLayer(); + +private: + + KisView * m_view; + KisPainter * m_painter; + +}; + +#endif // SHEARIMAGE_H diff --git a/chalk/plugins/viewplugins/shearimage/shearimage.rc b/chalk/plugins/viewplugins/shearimage/shearimage.rc new file mode 100644 index 00000000..8b6cbf1a --- /dev/null +++ b/chalk/plugins/viewplugins/shearimage/shearimage.rc @@ -0,0 +1,13 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkshearimage" version="6"> +<MenuBar> + <Menu name="Image"><text>&Image</text> + <Separator/> + <Action name="shearimage"/> + </Menu> + <Menu name="Layer"><text>La&yer</text> + <Separator/> + <Action name="shearlayer"/> + </Menu> +</MenuBar> +</kpartgui> diff --git a/chalk/plugins/viewplugins/shearimage/wdg_shearimage.ui b/chalk/plugins/viewplugins/shearimage/wdg_shearimage.ui new file mode 100644 index 00000000..d63b58f5 --- /dev/null +++ b/chalk/plugins/viewplugins/shearimage/wdg_shearimage.ui @@ -0,0 +1,102 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgShearImage</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgShearImage</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>323</width> + <height>114</height> + </rect> + </property> + <property name="caption"> + <string>Shear Image</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQButtonGroup" row="0" column="0"> + <property name="name"> + <cstring>grpPixelDimensions</cstring> + </property> + <property name="title"> + <string>&Shear Image</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KIntNumInput" row="0" column="1"> + <property name="name"> + <cstring>shearAngleX</cstring> + </property> + <property name="minValue"> + <number>-45</number> + </property> + <property name="maxValue"> + <number>45</number> + </property> + <property name="suffix"> + <string>°</string> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>lblShearAngelY</cstring> + </property> + <property name="text"> + <string>Shear angle Y:</string> + </property> + </widget> + <widget class="KIntNumInput" row="1" column="1"> + <property name="name"> + <cstring>shearAngleY</cstring> + </property> + <property name="tqmaximumSize"> + <size> + <width>32767</width> + <height>100</height> + </size> + </property> + <property name="minValue"> + <number>-45</number> + </property> + <property name="maxValue"> + <number>45</number> + </property> + <property name="suffix"> + <string>°</string> + </property> + </widget> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>lblShearAngleX</cstring> + </property> + <property name="text"> + <string>Shear angle X:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>intWidth</cstring> + </property> + </widget> + </grid> + </widget> + </grid> +</widget> +<customwidgets> +</customwidgets> +<tabstops> + <tabstop>shearAngleX</tabstop> +</tabstops> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> +</includehints> +</UI> diff --git a/chalk/plugins/viewplugins/substrate/Makefile.am b/chalk/plugins/viewplugins/substrate/Makefile.am new file mode 100644 index 00000000..5331a04e --- /dev/null +++ b/chalk/plugins/viewplugins/substrate/Makefile.am @@ -0,0 +1,26 @@ +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = substrate.rc + +EXTRA_DIST = $(chalkrc_DATA) + + +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../ui \ + -I$/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +kde_module_LTLIBRARIES = chalksubstrate.la + +chalksubstrate_la_SOURCES = substrate.cc dlg_substrate.cc wdgsubstrate.ui kis_repeating_substrate.cc +noinst_HEADERS = wdgsubstrate.h dlg_substrate.h kis_repeating_substrate.h substrate.h + +chalksubstrate_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) chalkblurfilter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui +chalksubstrate_la_LIBADD = ../../../libchalkcommon.la + +kde_services_DATA = chalksubstrate.desktop + +METASOURCES = AUTO diff --git a/chalk/plugins/viewplugins/substrate/chalksubstrate.desktop b/chalk/plugins/viewplugins/substrate/chalksubstrate.desktop new file mode 100644 index 00000000..8d8a7f7b --- /dev/null +++ b/chalk/plugins/viewplugins/substrate/chalksubstrate.desktop @@ -0,0 +1,35 @@ +[Desktop Entry] +Name=Substrate +Name[bg]=Основа +Name[ca]=Substrat +Name[da]=Substrat +Name[de]=Träger +Name[el]=Υπόστρωμα +Name[es]=Sustrato +Name[et]=Substraat +Name[fa]=زیربنا +Name[fy]=Substraat +Name[ga]=Foshraith +Name[gl]=Substrato +Name[hu]=Szubsztrát +Name[it]=Substrato +Name[ja]=下地 +Name[nb]=Substrat +Name[nds]=Wassboden +Name[ne]=जीवाधार +Name[nl]=Substraat +Name[pl]=Wycięcie +Name[pt]=Substrato +Name[pt_BR]=Substrato +Name[ru]=Подложка +Name[sk]=Substrát +Name[sl]=Substrat +Name[sr]=Супстрат +Name[sr@Latn]=Supstrat +Name[sv]=Substrat +Name[uk]=Підложка +Name[zh_TW]=基底 +ServiceTypes=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalksubstrate +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/substrate/dlg_substrate.cc b/chalk/plugins/viewplugins/substrate/dlg_substrate.cc new file mode 100644 index 00000000..dcecce48 --- /dev/null +++ b/chalk/plugins/viewplugins/substrate/dlg_substrate.cc @@ -0,0 +1,59 @@ +/* + * dlg_substrate.cc - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <klocale.h> + +#include "dlg_substrate.h" +#include "wdgsubstrate.h" + + +DlgSubstrate::DlgSubstrate( TQWidget * tqparent, + const char * name) + : super (tqparent, name, true, i18n("Color Range"), Ok | Cancel, Ok) +{ + m_previewPix = TQPixmap(); + m_page = new WdgSubstrate(this, "substrate"); + Q_CHECK_PTR(m_page); + setCaption(i18n("Substrate")); + setMainWidget(m_page); + resize(m_page -> size()); + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); +} + +DlgSubstrate::~DlgSubstrate() +{ + delete m_page; +} + +void DlgSubstrate::setPixmap(TQPixmap pix) +{ + m_previewPix = pix; + m_previewPix.detach(); +} + +void DlgSubstrate::okClicked() +{ + accept(); +} + +#include "dlg_substrate.moc" + diff --git a/chalk/plugins/viewplugins/substrate/dlg_substrate.h b/chalk/plugins/viewplugins/substrate/dlg_substrate.h new file mode 100644 index 00000000..82051ad3 --- /dev/null +++ b/chalk/plugins/viewplugins/substrate/dlg_substrate.h @@ -0,0 +1,62 @@ +/* + * dlg_substrate.h -- part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef DLG_SUBSTRATE +#define DLG_SUBSTRATE + +#include <tqpixmap.h> + +#include <kdialogbase.h> + +#include "wdgsubstrate.h" + + +/** + * This dialog allows the user to modify a layer or a selection + * by adding more colour in a particular channel or lighten or + * darken an image. + */ +class DlgSubstrate: public KDialogBase { + + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + + DlgSubstrate(TQWidget * tqparent = 0, + const char* name = 0); + ~DlgSubstrate(); + + /** + * Set the initial preview pixmap + */ + void setPixmap(TQPixmap pix); + +private slots: + + void okClicked(); + +private: + + WdgSubstrate * m_page; + TQPixmap m_previewPix; +}; + +#endif // DLG_SUBSTRATE diff --git a/chalk/plugins/viewplugins/substrate/kis_repeating_substrate.cc b/chalk/plugins/viewplugins/substrate/kis_repeating_substrate.cc new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/chalk/plugins/viewplugins/substrate/kis_repeating_substrate.cc diff --git a/chalk/plugins/viewplugins/substrate/kis_repeating_substrate.h b/chalk/plugins/viewplugins/substrate/kis_repeating_substrate.h new file mode 100644 index 00000000..1a229dc1 --- /dev/null +++ b/chalk/plugins/viewplugins/substrate/kis_repeating_substrate.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2006 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_SUBSTRATE_H +#define KIS_SUBSTRATE_H + +#include <tqrect.h> +#include <ksharedptr.h> + +class KisImage; + +/// All values are normalized to a range between 0 and 1. +/// XXX: Do we need more? +struct KisSubstratePixel { + float height; // absolute height of the current position + float smoothness; // determines how easily the painting tool "slips" over the surface + float absorbency; // determines how much wetness the substrate can absorb. XXX: How about speed of absorbing? + float r; //.Red component of reflectivity + float g; // Green component of reflectivity + float b; // Blue component of reflectivity + float transmittance; // Similar to alpha. XXX: Ask Leonardo about this. +}; + +/** + * This abstract class defines the properties of a substrate -- that is, the simulation + * of the paper or canvas for natural media. + * + * Subclass this interface to define a specific type of substrate: repeating, + * or full-size, with specific and cool ways of generating the surface, or + * maybe based on scans of real substrates. + */ +class KisSubstrate : public KShared { + +public: + + KisSubstrate(KisImage * /*img*/) : KShared() {}; + virtual ~KisSubstrate() {}; + + + /** + * Copy the pixel values in the specified rect into an array of Substrate. + * Make sure the array is big enough! + */ + virtual void getPixels(KisSubstratePixel * /*substrate*/, const TQRect & /*rc*/) = 0; + + /** + * Return a pointer to the substrate at the specified position. Note that + * you cannot do pointe arithmetic with this value: the position of the + * neighbouring pixels cannot be determined from this value + */ + virtual KisSubstratePixel * getPixel(uint x, uint y) = 0; + +}; + +#endif diff --git a/chalk/plugins/viewplugins/substrate/substrate.cc b/chalk/plugins/viewplugins/substrate/substrate.cc new file mode 100644 index 00000000..8aa4d32e --- /dev/null +++ b/chalk/plugins/viewplugins/substrate/substrate.cc @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2006 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <math.h> + +#include <stdlib.h> + +#include <tqslider.h> +#include <tqpoint.h> + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> + +#include <kis_doc.h> +#include <kis_image.h> +#include <kis_layer.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_view.h> + +#include "substrate.h" +#include "dlg_substrate.h" + +typedef KGenericFactory<SubstratePlugin> SubstrateFactory; +K_EXPORT_COMPONENT_FACTORY( chalksubstrate, SubstrateFactory( "chalk" ) ) + +SubstratePlugin::SubstratePlugin(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + + if ( tqparent->inherits("KisView") ) + { + setInstance(SubstrateFactory::instance()); + setXMLFile(locate("data","chalkplugins/substrate.rc"), true); + + (void) new KAction(i18n("&Substrate..."), 0, 0, this, TQT_SLOT(slotSubstrateActivated()), actionCollection(), "substrate"); + + m_view = (KisView*) tqparent; + } +} + +SubstratePlugin::~SubstratePlugin() +{ +} + +void SubstratePlugin::slotSubstrateActivated() +{ + DlgSubstrate * dlgSubstrate = new DlgSubstrate(m_view, "Substrate"); + Q_CHECK_PTR(dlgSubstrate); + if (dlgSubstrate -> exec() == TQDialog::Accepted) { + // Retrieve changes made by dialog + // Apply changes to layer (selection) + } + delete dlgSubstrate; +} + +#include "substrate.moc" + diff --git a/chalk/plugins/viewplugins/substrate/substrate.h b/chalk/plugins/viewplugins/substrate/substrate.h new file mode 100644 index 00000000..409a00f3 --- /dev/null +++ b/chalk/plugins/viewplugins/substrate/substrate.h @@ -0,0 +1,45 @@ +/* + * substrate.h -- Part of Chalk + * + * Copyright (c) 2006 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SUBSTATE_H +#define SUBSTATE_H + +#include <kparts/plugin.h> + +class KisView; + +class SubstratePlugin : public KParts::Plugin +{ + Q_OBJECT + TQ_OBJECT +public: + SubstratePlugin(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~SubstratePlugin(); + +private slots: + void slotSubstrateActivated(); + +private: + KisView * m_view; + KisPainter * m_painter; + +}; + +#endif // SUBSTATE_H diff --git a/chalk/plugins/viewplugins/substrate/substrate.rc b/chalk/plugins/viewplugins/substrate/substrate.rc new file mode 100644 index 00000000..cf8b8537 --- /dev/null +++ b/chalk/plugins/viewplugins/substrate/substrate.rc @@ -0,0 +1,8 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalksubstrate" version="1"> +<MenuBar> + <Menu name="Image"><text>Image</text> + <Action name="substrate"/> + </Menu> +</MenuBar> +</kpartgui> diff --git a/chalk/plugins/viewplugins/substrate/wdgsubstrate.ui b/chalk/plugins/viewplugins/substrate/wdgsubstrate.ui new file mode 100644 index 00000000..be0713ed --- /dev/null +++ b/chalk/plugins/viewplugins/substrate/wdgsubstrate.ui @@ -0,0 +1,221 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgSubstrate</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>Form1</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>478</width> + <height>358</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQButtonGroup" row="0" column="0"> + <property name="name"> + <cstring>grpCustom</cstring> + </property> + <property name="title"> + <string>Custom Canvas Definition</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout3</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQComboBox" row="0" column="1" rowspan="1" colspan="2"> + <item> + <property name="text"> + <string>Custom</string> + </property> + </item> + <property name="name"> + <cstring>cmbPredefinedCanvases</cstring> + </property> + </widget> + <widget class="KColorButton" row="2" column="2"> + <property name="name"> + <cstring>bnBackground</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Save custom substrate as:</string> + </property> + </widget> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>lblPredefined</cstring> + </property> + <property name="text"> + <string>&Pre-defined canvas types:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cmbPredefinedCanvases</cstring> + </property> + </widget> + <widget class="TQLabel" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>lblColor</cstring> + </property> + <property name="text"> + <string>&Basic color:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>bnBackground</cstring> + </property> + </widget> + <widget class="TQLineEdit" row="1" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>lineEdit1</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout2</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQSlider" row="3" column="1"> + <property name="name"> + <cstring>slAbsorbency</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="TQSlider" row="2" column="1"> + <property name="name"> + <cstring>slFiber</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="TQLabel" row="1" column="2"> + <property name="name"> + <cstring>textLabel9</cstring> + </property> + <property name="text"> + <string>Grainy</string> + </property> + </widget> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>lblSmoothness</cstring> + </property> + <property name="text"> + <string>&Smooth:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>slSlippery</cstring> + </property> + </widget> + <widget class="TQLabel" row="3" column="0"> + <property name="name"> + <cstring>lblAbsorbency</cstring> + </property> + <property name="text"> + <string>&Water repellant:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>slAbsorbency</cstring> + </property> + </widget> + <widget class="TQSlider" row="0" column="1"> + <property name="name"> + <cstring>slSlippery</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>lblHeight</cstring> + </property> + <property name="text"> + <string>&Flat:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>slHeight</cstring> + </property> + </widget> + <widget class="TQLabel" row="2" column="0"> + <property name="name"> + <cstring>lblFiber</cstring> + </property> + <property name="text"> + <string>Fine &fiber:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>slFiber</cstring> + </property> + </widget> + <widget class="TQLabel" row="0" column="2"> + <property name="name"> + <cstring>lblRough</cstring> + </property> + <property name="text"> + <string>Rough</string> + </property> + </widget> + <widget class="TQSlider" row="1" column="1"> + <property name="name"> + <cstring>slHeight</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="TQLabel" row="3" column="2"> + <property name="name"> + <cstring>textLabel11</cstring> + </property> + <property name="text"> + <string>Absorbent</string> + </property> + </widget> + <widget class="TQLabel" row="2" column="2"> + <property name="name"> + <cstring>textLabel10</cstring> + </property> + <property name="text"> + <string>Coarse</string> + </property> + </widget> + </grid> + </widget> + </vbox> + </widget> + </grid> +</widget> +<customwidgets> +</customwidgets> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kcolorbutton.h</includehint> +</includehints> +</UI> diff --git a/chalk/plugins/viewplugins/variations/Makefile.am b/chalk/plugins/viewplugins/variations/Makefile.am new file mode 100644 index 00000000..5a3fafc9 --- /dev/null +++ b/chalk/plugins/viewplugins/variations/Makefile.am @@ -0,0 +1,26 @@ +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = variations.rc + +EXTRA_DIST = $(chalkrc_DATA) + + +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../ui \ + -I$/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +kde_module_LTLIBRARIES = chalkvariations.la + +chalkvariations_la_SOURCES = variations.cc dlg_variations.cc wdg_variations.ui +noinst_HEADERS = wdg_variations.h + +chalkvariations_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) chalkblurfilter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui +chalkvariations_la_LIBADD = ../../../libchalkcommon.la + +kde_services_DATA = chalkvariations.desktop + +chalkvariations_la_METASOURCES = AUTO diff --git a/chalk/plugins/viewplugins/variations/chalkvariations.desktop b/chalk/plugins/viewplugins/variations/chalkvariations.desktop new file mode 100644 index 00000000..32b873d1 --- /dev/null +++ b/chalk/plugins/viewplugins/variations/chalkvariations.desktop @@ -0,0 +1,40 @@ +[Desktop Entry] +Name=Variations Plugin +Name[bg]=Приставка за вариации +Name[ca]=Connector de variacions +Name[da]=Plugin med variationer +Name[de]=Variationen-Modul +Name[el]=Πρόσθετο παραλλαγών +Name[eo]=Variaĵ-kromprogramo +Name[es]=Complemento para variaciones +Name[et]=Variatsioonide plugin +Name[fa]=وصلۀ تغییرات +Name[fr]=Module de variations +Name[fy]=Fariaasjeplugin +Name[gl]=Extensión de Variacións +Name[hu]=Variációk modul +Name[is]=Breytileika íforrit +Name[it]=Plugin delle variazioni +Name[ja]=バリエーションプラグイン +Name[km]=កម្មវិធីជំនួយភាពប្រែប្រួល +Name[nb]=Programtillegg for variasjoner +Name[nds]=Varianten-Moduul +Name[ne]=भिन्नता प्लगइन +Name[nl]=Variatieplugin +Name[pl]=Wtyczka wariacji +Name[pt]='Plugin' de Variações +Name[pt_BR]=Plugin de Variações +Name[ru]=Вариации +Name[sk]=Modul variácie +Name[sl]=Vstavek Variacije +Name[sr]=Прикључак за варијације +Name[sr@Latn]=Priključak za varijacije +Name[sv]=Insticksprogram med variationer +Name[uk]=Варіації +Name[uz]=Variatsiya plagini +Name[uz@cyrillic]=Вариация плагини +Name[zh_TW]=變動外掛程式 +ServiceTypes=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkvariations +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/variations/dlg_variations.cc b/chalk/plugins/viewplugins/variations/dlg_variations.cc new file mode 100644 index 00000000..13324623 --- /dev/null +++ b/chalk/plugins/viewplugins/variations/dlg_variations.cc @@ -0,0 +1,58 @@ +/* + * dlg_variations.cc - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <klocale.h> + +#include "dlg_variations.h" +#include "wdg_variations.h" + + +DlgVariations::DlgVariations( TQWidget * tqparent, + const char * name) + : super (tqparent, name, true, i18n("Color Range"), Ok | Cancel, Ok) +{ + m_previewPix = TQPixmap(); + m_page = new WdgVariations(this, "variations"); + Q_CHECK_PTR(m_page); + setCaption(i18n("Variations")); + setMainWidget(m_page); + resize(m_page -> size()); + + connect(this, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); +} + +DlgVariations::~DlgVariations() +{ + delete m_page; +} + +void DlgVariations::setPixmap(TQPixmap pix) +{ + m_previewPix = pix; + m_previewPix.detach(); +} + +void DlgVariations::okClicked() +{ + accept(); +} + +#include "dlg_variations.moc" diff --git a/chalk/plugins/viewplugins/variations/dlg_variations.h b/chalk/plugins/viewplugins/variations/dlg_variations.h new file mode 100644 index 00000000..e160e6aa --- /dev/null +++ b/chalk/plugins/viewplugins/variations/dlg_variations.h @@ -0,0 +1,62 @@ +/* + * dlg_variations.h -- part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef DLG_VARIATIONS +#define DLG_VARIATIONS + +#include <tqpixmap.h> + +#include <kdialogbase.h> + +#include "wdg_variations.h" + + +/** + * This dialog allows the user to modify a layer or a selection + * by adding more colour in a particular channel or lighten or + * darken an image. + */ +class DlgVariations: public KDialogBase { + + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + + DlgVariations(TQWidget * tqparent = 0, + const char* name = 0); + ~DlgVariations(); + + /** + * Set the initial preview pixmap + */ + void setPixmap(TQPixmap pix); + +private slots: + + void okClicked(); + +private: + + WdgVariations * m_page; + TQPixmap m_previewPix; +}; + +#endif // DLG_VARIATIONS diff --git a/chalk/plugins/viewplugins/variations/variations.cc b/chalk/plugins/viewplugins/variations/variations.cc new file mode 100644 index 00000000..40e8fcf8 --- /dev/null +++ b/chalk/plugins/viewplugins/variations/variations.cc @@ -0,0 +1,88 @@ +/* + * variation.h -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include <math.h> + +#include <stdlib.h> + +#include <tqslider.h> +#include <tqpoint.h> + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> + +#include <kis_doc.h> +#include <kis_image.h> +#include <kis_layer.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_view.h> + +#include "variations.h" +#include "dlg_variations.h" + +typedef KGenericFactory<Variations> VariationsFactory; +K_EXPORT_COMPONENT_FACTORY( chalkvariations, VariationsFactory( "chalk" ) ) + +Variations::Variations(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + + if ( tqparent->inherits("KisView") ) + { + setInstance(VariationsFactory::instance()); + setXMLFile(locate("data","chalkplugins/variations.rc"), true); + + (void) new KAction(i18n("&Variations..."), 0, 0, this, TQT_SLOT(slotVariationsActivated()), actionCollection(), "variations"); + + m_view = (KisView*) tqparent; + } +} + +Variations::~Variations() +{ +} + +void Variations::slotVariationsActivated() +{ + DlgVariations * dlgVariations = new DlgVariations(m_view, "Variations"); + Q_CHECK_PTR(dlgVariations); + // Render layer to a TQIMage -- keep in mind possibility of selection + + // Scale TQImage + + // Set original TQImage in dialog + + if (dlgVariations -> exec() == TQDialog::Accepted) { + // Retrieve changes made by dialog + // Apply changes to layer (selection) + } + delete dlgVariations; +} + +#include "variations.moc" + diff --git a/chalk/plugins/viewplugins/variations/variations.h b/chalk/plugins/viewplugins/variations/variations.h new file mode 100644 index 00000000..d8680ba7 --- /dev/null +++ b/chalk/plugins/viewplugins/variations/variations.h @@ -0,0 +1,45 @@ +/* + * variation.h -- Part of Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef VARIATIONS_H +#define VARIATIONS_H + +#include <kparts/plugin.h> + +class KisView; + +class Variations : public KParts::Plugin +{ + Q_OBJECT + TQ_OBJECT +public: + Variations(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~Variations(); + +private slots: + void slotVariationsActivated(); + +private: + KisView * m_view; + KisPainter * m_painter; + +}; + +#endif // VARIATIONS_H diff --git a/chalk/plugins/viewplugins/variations/variations.rc b/chalk/plugins/viewplugins/variations/variations.rc new file mode 100644 index 00000000..d5db6590 --- /dev/null +++ b/chalk/plugins/viewplugins/variations/variations.rc @@ -0,0 +1,8 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkvariations" version="6"> +<MenuBar> + <Menu name="Image"><text>Image</text> + <Action name="variations"/> + </Menu> +</MenuBar> +</kpartgui> diff --git a/chalk/plugins/viewplugins/variations/wdg_variations.ui b/chalk/plugins/viewplugins/variations/wdg_variations.ui new file mode 100644 index 00000000..191b84bb --- /dev/null +++ b/chalk/plugins/viewplugins/variations/wdg_variations.ui @@ -0,0 +1,897 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>WdgVariations</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgVariations</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>763</width> + <height>852</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string>Variations</string> + </property> + <widget class="TQFrame"> + <property name="name"> + <cstring>framePreview</cstring> + </property> + <property name="geometry"> + <rect> + <x>11</x> + <y>11</y> + <width>328</width> + <height>255</height> + </rect> + </property> + <property name="paletteBackgroundColor"> + <color> + <red>166</red> + <green>188</green> + <blue>153</blue> + </color> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>lblOriginal</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLabel" row="0" column="1"> + <property name="name"> + <cstring>lblCurrentPick</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLabel" row="1" column="1"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="text"> + <string>Current Pick</string> + </property> + <property name="tqalignment"> + <set>AlignCenter</set> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>Original</string> + </property> + <property name="tqalignment"> + <set>AlignCenter</set> + </property> + </widget> + </grid> + </widget> + <widget class="TQGroupBox"> + <property name="name"> + <cstring>grpOptions</cstring> + </property> + <property name="geometry"> + <rect> + <x>345</x> + <y>11</y> + <width>210</width> + <height>250</height> + </rect> + </property> + <property name="title"> + <string>Options</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQRadioButton" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>radioShadows</cstring> + </property> + <property name="text"> + <string>&Shadows</string> + </property> + </widget> + <widget class="TQRadioButton" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>radioMidtones</cstring> + </property> + <property name="text"> + <string>&Midtones</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="TQRadioButton" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>radioHighlights</cstring> + </property> + <property name="text"> + <string>&Highlights</string> + </property> + </widget> + <widget class="TQRadioButton" row="3" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>radioSaturation</cstring> + </property> + <property name="text"> + <string>&Saturation</string> + </property> + </widget> + <widget class="TQCheckBox" row="6" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>chkClipping</cstring> + </property> + <property name="text"> + <string>Show &clipping</string> + </property> + </widget> + <widget class="TQSlider" row="5" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>slider1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="TQLabel" row="4" column="0"> + <property name="name"> + <cstring>lblFine</cstring> + </property> + <property name="text"> + <string>Fine</string> + </property> + </widget> + <widget class="TQLabel" row="4" column="1"> + <property name="name"> + <cstring>lblCoars</cstring> + </property> + <property name="text"> + <string>Coarse</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout5</cstring> + </property> + <property name="geometry"> + <rect> + <x>570</x> + <y>10</y> + <width>174</width> + <height>819</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQPushButton"> + <property name="name"> + <cstring>bnLoad</cstring> + </property> + <property name="text"> + <string>&Load...</string> + </property> + </widget> + <widget class="TQPushButton"> + <property name="name"> + <cstring>bnSave</cstring> + </property> + <property name="text"> + <string>&Save As...</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>187</height> + </size> + </property> + </spacer> + <widget class="TQFrame"> + <property name="name"> + <cstring>frameLight</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqmaximumSize"> + <size> + <width>32767</width> + <height>556</height> + </size> + </property> + <property name="paletteBackgroundColor"> + <color> + <red>166</red> + <green>188</green> + <blue>153</blue> + </color> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>lblLighter</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel12</cstring> + </property> + <property name="text"> + <string>Lighter</string> + </property> + <property name="tqalignment"> + <set>AlignCenter</set> + </property> + </widget> + <widget class="TQLabel" row="2" column="0"> + <property name="name"> + <cstring>lblCurrentPick3</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLabel" row="3" column="0"> + <property name="name"> + <cstring>textLabel13</cstring> + </property> + <property name="text"> + <string>Current Pick</string> + </property> + <property name="tqalignment"> + <set>AlignCenter</set> + </property> + </widget> + <widget class="TQLabel" row="4" column="0"> + <property name="name"> + <cstring>lblDarker</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLabel" row="5" column="0"> + <property name="name"> + <cstring>textLabel14</cstring> + </property> + <property name="text"> + <string>Darker</string> + </property> + <property name="tqalignment"> + <set>AlignCenter</set> + </property> + </widget> + </grid> + </widget> + </vbox> + </widget> + <widget class="TQFrame"> + <property name="name"> + <cstring>frameColor</cstring> + </property> + <property name="geometry"> + <rect> + <x>10</x> + <y>270</y> + <width>540</width> + <height>556</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>540</width> + <height>556</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>540</width> + <height>556</height> + </size> + </property> + <property name="paletteBackgroundColor"> + <color> + <red>166</red> + <green>188</green> + <blue>153</blue> + </color> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>lblMoreCyan</cstring> + </property> + <property name="geometry"> + <rect> + <x>30</x> + <y>190</y> + <width>150</width> + <height>150</height> + </rect> + </property> + <property name="tqminimumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel9</cstring> + </property> + <property name="geometry"> + <rect> + <x>390</x> + <y>350</y> + <width>110</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>More Red</string> + </property> + <property name="tqalignment"> + <set>AlignCenter</set> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel7</cstring> + </property> + <property name="geometry"> + <rect> + <x>50</x> + <y>350</y> + <width>120</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>More Cyan</string> + </property> + <property name="tqalignment"> + <set>AlignCenter</set> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>lblMoreBlue</cstring> + </property> + <property name="geometry"> + <rect> + <x>110</x> + <y>380</y> + <width>150</width> + <height>150</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel5</cstring> + </property> + <property name="geometry"> + <rect> + <x>140</x> + <y>170</y> + <width>91</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>More Green</string> + </property> + <property name="tqalignment"> + <set>AlignCenter</set> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>lblMoreRed</cstring> + </property> + <property name="geometry"> + <rect> + <x>370</x> + <y>190</y> + <width>150</width> + <height>150</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>lblMoreYellow</cstring> + </property> + <property name="geometry"> + <rect> + <x>280</x> + <y>10</y> + <width>150</width> + <height>150</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>lblMoreMagenta</cstring> + </property> + <property name="geometry"> + <rect> + <x>280</x> + <y>380</y> + <width>150</width> + <height>150</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel8</cstring> + </property> + <property name="geometry"> + <rect> + <x>210</x> + <y>350</y> + <width>128</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>Current Pick</string> + </property> + <property name="tqalignment"> + <set>AlignCenter</set> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel6</cstring> + </property> + <property name="geometry"> + <rect> + <x>310</x> + <y>170</y> + <width>93</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>More Yellow</string> + </property> + <property name="tqalignment"> + <set>AlignCenter</set> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>lblCurrentPick2</cstring> + </property> + <property name="geometry"> + <rect> + <x>200</x> + <y>190</y> + <width>150</width> + <height>150</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="frameShape"> + <enum>Box</enum> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>lblMoreGreen</cstring> + </property> + <property name="geometry"> + <rect> + <x>110</x> + <y>10</y> + <width>150</width> + <height>150</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>150</width> + <height>150</height> + </size> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel11</cstring> + </property> + <property name="geometry"> + <rect> + <x>290</x> + <y>540</y> + <width>128</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>More Magenta</string> + </property> + <property name="tqalignment"> + <set>AlignCenter</set> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel10</cstring> + </property> + <property name="geometry"> + <rect> + <x>140</x> + <y>540</y> + <width>77</width> + <height>20</height> + </rect> + </property> + <property name="text"> + <string>More Blue</string> + </property> + <property name="tqalignment"> + <set>AlignCenter</set> + </property> + </widget> + </widget> +</widget> +<images> + <image name="image0"> + <data format="XPM.GZ" length="55092">789cccbd47b7eb38b2ef397f9fa2d6e5ecae5e7cf266d0035266cb6da7ed77af1ed07b2f1aa9bf7c83883f704c56d5cd7c75bb5f95d6c9ca5f8a22114044202200f0fccffffcdbe7d3fddffef37ffe8fea625c02eb6f966f947ffb4fbb4e92ebfff57fff9fffcffff88fe160f0b7fecf68389bfe6df41fffc7fff80febf96fd6df9401ff5fcff64232ffde36244f7a762ac953fefd56f29cf35cf2a267f3072ff9f733c906e7836493f35eb2c59fd74ab6797b1f243bfcfb46b2cb7fef0a1e72799c5af2907f7f94cce5732cc963fefd483297cf3a8387d43f992999ffde0c25f3dfb79a64de5f662099dfcfe924cf386f24f3fe4a44ff0fd17e5b327f9e772799dfcfb8078fa87d662499cbebbb9249de6fc9bcbd9d2f99dab795ccc7b31a48e6e3b71a4ae6e315ed25f3f1b04f82a93f0dc1636a9ff32999daf32599f757a54ae6fde17e48e6fae23892b97e78a2bd63ea1f438cef849e97e892f9f7652b99b76f3d91cce53763f0947e6f08fd9c1137b664de5e43c83fc7f53bf0022cf475499c8be719c4f113d824de5cc01671fd0eb6895dbaff50d8ab174ae6f2ad3ac9a47f63c924df4832d73f732a99f777f324998fb73993ccfb5f7f96ccc7df3a49e6e3514592b9bd3aa664ae1fd6bd646eaf9a2b98f4ddf52573fdb58e60d89f6d49e6df9b13c97c3c1d45326fbf634826ffb2934cfee40086fdf88164de7ff65232d9eb9b646e1fa607867e9bbe641a8f816092cf14f2423f4d070c7d8b9f25f3e7bbaf60e89fb791ccfb3b15df43ffe22f30f42f13f240ffea1b18fab716bf877ee967b043dc92bf1f0ea16fdd9af3a8f740bc3dbe64f2f70bc9bcbfcd2fc9bcbfbd4432f90b4730f5cff55e3297bfc9c0187f732899f4772099c6e35b321f7f6b0fc6f8daa6649aff7692f9f3724d32d7f7cb4932ef6ffb4e32e9b302c6f86723c9dcdefc50326f9ff32e99f7975382a10fd75c32d7e795906742fdd3bd49e6df67a2bdd09ff20886beb89164fefcd54932ef9ffa2c98fca72bda0b7d6a9f25f3feb0c4f842bf9a07b0d02fd13fd0afe2090cffd6c660e85b24ae87be05a40f63e1df8277c9bc7debab643e5e575732efef6e2799cb1bfcf89ecbdbed2573fd5cfd781e1fcf952d98fa3b91cf277f74cd24f3fe0f3ec08807ba8d64ae9fc54232e98f27993faff9f13df787ae680ff4d57995cce57103c95c7fac3bc97c7c7c5f308d67b8028bf9f72299cbd3dc49e6f2981f92797fd69664de5f7e2499dbb33b92ccdb6f2dc1d067772099fca72e99b7ff6a49a6f946f437f4b9bd48267934b0d0ef77c9bc7dad68df9cee9fee25f3fe69447fcc31df88f1843eaf6e92f9f3da89649a0fee25f3f1cb85be41ff0331bed07f5f8ca7f0a7d43f13a1df9d2a99f777f32899dfffea80111faeae92b93cee41f090f7effa0c463ce77f48a6f9ee51321fafeb4930f547bb01433fecb164fe7cff5b321f2f2f92ccfb3f93d793bd745b30f421ae2593bfd94be6fd1b2692b93cde4e32b79fda164ced8ddec1d017e74332f9dbb564de5e772899e299140c7dcaa692b93db8df92797fe61d18fe3117e303fd59b792e979b164de3f8918ff05f5cf46f40ff4c715e301fdb9bd80e13f57f792797fad4a30fce906bf17f3f51ae331c4fc19a13d43f89780e693a9f0a7ed028cebfd4e321fafe6198c7cc00b2473f9bc77c95cdf4a4ff0908fc75a5c8f78bfb52553fcf02999ebbfdf08a6f10e5ec1c2bfdc49a6f97c2b99e6ff27c9642f3fbee7fab416f2407fc299643efe912f99ec692099cbd3b492b9bc9ab8ff94c63711fd0bfdb2a792c93e2ac9140f689229df5125f3feed5660e85ffd2a99fce34432efdfee00867e5e14c9941f8ec0d0bfcc904cf9572a99b7a76e25f3fe73c760a1afaa646ebf99e85fe86f2ec61bfaea0b79e11f0ba12f2eda8bfb4b7d267b98897c64dd81a1cfeb503297afbd934cf1d45e30fc93f81ef363b896ccefbf3a4a26793dc1149fae7d30f247ff2a99ea1d3fbee7fed68b05a31eb1924cf9c2083ca5f6076bc9542fd948e6fa900e2473fdbbbc09463d630246be1a6692f9f84481643edef95532b73f5df01cfd7993ccdb7be92453beb5924cf3c14432efbf5cfc7e01fffa2999e6bfb1646e5f9b022ce2cba364de3e37114cfec132c0d047f74d32f9e37b30f26b2f05431f5763c9bc7f42c1d04797e6cf99d0c71be41fc21fa52a18fe24207d9f0bfd5a1d04d3f8570fe009d573dca3642e7fbb054f697ca237c1246f3a944cf53a5b32c5a72f60f81bd796ccaf4f2bc994af2d2593be6f2453bea682e7345eed4e32d5ff14c9bcbf2f57c95cff7dd15ef8a35097ccdb93cd25537e2bfa6b3124fffd055ec2bfcc24537c548045fe518331decda7647ebd2eda6ba37fc478c01f6d44ffb8d43e1ded17e3af3960cc97f5022cf481e257a6dd149fd96bf08cc6ffe64aa6f92604c35eec4032b7efab2799e2375b30e94b2aae5f50ff58aa642e6fe148a67ce1065e927fb80d2553bd2494cc9fdf3e49a6fc45c863c07e1dc97cfcd3a3606a5f7d05633e887682497faf4bb08df8e2030cfb2bc9de17a2ff4bf49f886762f4cf10f666bd80618f3e8dff92f5177f5e914be6ed2f36e005c91b5f24533cf22598ecafeec04be467ae64f28757b041bfaf5f040f29fe68c0268d9726da63917e14a2bdd0c7f424998f5f44fdb314fd91bf83a18f8105467fdc4660e86783e789fee94a30e215e3118c78a3a0f9dc60fd45fa34072f491fc329d8a0f685a964aae7dfc0265d5f2f05537f568f60d86bb091ccfbe36248e6fad988dfbba85f8e24533e48f66f88fe892b30fa67634ba6f97508467f6d1cb0a827435ed11f35fa6388f9c9a7f8c814f157fd065e92fe5f6e6083e42f5cb0897ac417d8227dca3fc036f55fb305431fba77c1747f3b02bba4df3ad9ab29e42f669229df46fb647fe460d8d3aa0243fecd2758d4bbefc0a21eb403a33f2a8a772c263f6fff35055ba827d1f85aa2bf2f1a58f4f70a8cfb252a18febdf1c0f02701f58f2dda7f5d48a6fe9b8071fff21d2cfc83603caf51c1b87fb106433f4b1a1f87fd17eebf1b17ec903efbd43e46b0f71a0c79cb2d58c4e72d18cf2f1bb078be0dc6f3339abf5cd11f8906c6f5de1a8cf846e3f6c1cbe724df068cf6548964ae3f1b130c7f9096608c7f7603a3bde90e8ce7bb2f60b4d77e00c39f075c9f98f639e47fa34832d7e7f84c2c9eb7ba80216ffb08c6f3cc042cd64f1a30e42f9760d88fe382d19e1ced19c11e42aebf0cf17cd306435ecb04a33d610e16f20b16f1470a16ed3981457cf9443c82bdae2660e19f79bc341c8be7d70e18cfd71ec022df8ac178feaa05e379d72bf108e3df70ff369cc8fe1d8345bc9c81d1fe60452cfaeb7a03c3be74ba7e2adbd382f1fbcb3b18e3910dc1689f4df24e657fd4603cafb2c168bffb0cc6f32b1ebf0c67e2fe01e9d34cdcef1283e12faa6f30ee67f860e1ffe660a1efdc7f0ee7e2fed58c58b6e70cc6ef8d002cd6173db0a83f2dc0d0b78edbf77021e5bd078bf6aec1f87d41fabd14f2155bb0f8fd108cdfeb2330da93de83f1fc8ac6d310f2ac1a309ed772ff3734c5fdb48d64ee0fb72e58d4e75ec0f87d7202a33f0d713df4a5237bb7e4782a60b11ee681d15eed112cee1782a1cf158f4f86b6b8bf6581c5fa2af5a733823f762d30eed7d2efdd11f2efcd1d18d76bdc5e468311f2a3c007e379f5082cea75f760e8fbfa8d782cf49dfba3d150fcbebc030b7bdc83a17f099faf472371ffe64c2ceed73460e883cefb6b3416f7ab4fc463e10f2c30e46b8927e279b94b2cee6f6cc1d087ec092cec4930c6f342f24f85fc46442caef75660e8cf85fb93d18cfd9ec783f1162ceaa37cfe19cdc5fd3ceabfb990d79d80d13eeb152cd64fe9fa85f8de7c05a33df9188cf66cbec0d0c7f50d0c7df3b8ff1f2d85bcce002ce227078ceb1d0f2cfca54e3c41fb6f74bd21ef5780f17c5d058bf53beeaf46e618ebd77a2299c77f5bba9f25c6b7f4c1c2bfbd80d19eeb07f104fda1933cb678de2603e37eba01c6ef6f57b0a8ff71ff3d72c6a8b7e8d47faee88fb507c6effd188cdf3bdc1ec67d38c739e2e3c5a63393e21723269e60fde4f22c99d677b93e307577285eb7b8fd8f27ecfe9cf50e0c7d8a79ff8ca7ec7bfefb6b412cc627db81c57e823730ead9eb1158d43fb8bce399b8fe7a0716eb5d7330c663c3fb733c67eda1fa484d2cc6c39a83a11fed193ca57a651282b13e16f3f96ebc9860bdc8d880c5fe810c2cf21bae8fe3e544d4cb23c93c5ed30a30ea071b170cff92d0f81813d443d71730eaed9a07c6f53eb7b7b1c9bee7fa117c49a6f5024b30c5b3760cb6b19ec9e3adb13331e8face93ccfbaf3883f13c23013ba8a72e05d3fd0d1b8c7c734df23b53d8df86facf9da03e7e1b80f1fc82f7e76430813e6d63e229fa3be5e333194e4cd40b52b04ded31b8fe4e4653110ff2fa0a73a736f28d9a788afd67fa180cfd6a1db0588fe3fe7f32610accfb77c3f59721f2c77c493cc5fe0aaf00e37eb731788afa4e059ed1f8361f60d48f6dde1f93d914ebc7460a46bd2fe4fd37994fc7940f6cbec1e89f98cf5f93a578def5013c433d86da6f4c51bf09b9bd4dcce982f2b39cebcbc49a22fff6b83e4dec29ea15d95932adb704c433acffebf43c776ad1fd039d7886f5d315bf3f5356f09acf77d3d1d4a5fa65734f3cc3fe035d134cf7372c30ec355b824dc413dc3fb0e9906574dcdf79c4e2f74501c6fa5b74104cdfb73c3e9d4ea6d6887f7fdb10b3e791bef1f9940ddf1ceb078fe005f5b7c5e7e3e96c86f58f8d0246fd3a76c1f311f9b377b043e31bf07c693a9fa1de19df816dec07f804bb584fa3fe5accc47a86069e517b82002cd6f775b043f39bc6e3dde9923d8eeb7332035bd47f3705ec60ff824d3cc7fecf84ebefd498c19e2faf609bfa2be6f9f0d49c2d51cff5c016e5fb2b176c8f78fb8b15d8a5fa99c9e7d7a93543fdab1b831dfafde6287844f5d10e8cf1af49bfac39c63bff024f499e98ee6fb3fb937f7d023bd4fed407bb435aafb124d37e2d5d30b53f03cf87d43eeb0d8cf5dd7803c67cb7e1f63d75587f707df1e9fece7c30a2fd5d7b30f6b3469f9269fdc792cce5594dc1587fba52ffb84c1edebecd5e326f7f41faebceb19f2cda8271bfa6133ca2e727e0118d4fb2164cfa9c2892f978af4c30eca1f1c19321d7bf2bff7e3660e34ff5e53bb043cfaf5dc174bf6c0076a97fdb929805acfcfb6d0446bdbee4ed9f0d857eddd660f89b6e2298da5f05c4ac3f687e6bc0c311ad87e07a263f9f0fda77f094da537f8067245fc5f569369a1963d29f2b31eb5fdabfe20ba6e7a777e0d188ff3eb9815906c29fa78227d04f053ca3f6b65c3f6663260fd553a93d2cfca4fec91bc95cfeea041e517f5fb8fece2662fcdd023c86ff33c1d31167cd06cf21cf5c308d679d8017d41f0df72fb3e9cc1ef3ebab14ec8c69bfc05432ed47d38885fe5d4cc9b4fe37028fc8fecb37c9649f25784cf6ebbf82e7f47dbc042fe87e05f5cf4ce8936b82e7f4fb36113ca6f17a002fe8f986b8de80fe8bef4dd28fc292cce52fa68269fc4d1effb0db2f49decd0c0c7fdc92fe2ce6131a3f6d2d98fcb7bf02cf49bf370330d68fea5a30fdde38831dfabea3fe59b2fea178b0009bd41e4f03db23aeff37713decb5f00593fc2df5a7c1ee47eb6f2330eadd17156c8ea87ff7609bfc45590b267f78d5c02e714bfa6ab2f1207ff80136c87ef22918f34dfe06c67cd186c48b018dafcee3cd99c5ee47faa48217647f99609bf4c7a0f1b2160392afa3f6da6cfc68bcd69279ff949f6093daef4ec1f067f5817831a4e76de8f70ebb9ece177c806d6abfb3235ec0dfba2bc9b4df9bc6d7ed1376ae5f5c3fe703263f6f4f520a1e53fc99102f66d4be8cf7cf7cc8e4e3d7673e784c7cdd82a7d4de5a03c3fe751e9f3265c2fca09be009d94fc2e397394b87c99f186bf08cfa4fe3fd3b9fb0e7717dacc792e97c0b8f5f58f8bb20d6793d613e5f2cc7b49fc5005bd49e35b56fb1c4fcecf1fe9e2fd9f7743dfdde582ca83f8267b049ed59f3f9686eb2eb69fd782699d62fa83de67244f67de1fa3eb79643b237ef2698f4ab9e8347d4feb0008fc99e1c6a8fbd70d05f4762261e6f9f46e3e730a6f3160618fdbbe6f9c6dc5d0ea8bd0df5bf6b88f89aebdfa25f00a5f8ff4e32edd749c0636aff66019ee17939780e7de2f92a73f643e8bb031e537b7c133c237bf5dec073ba7f44f71f1a225ea3e78f447f79dfe011ddcfe3f22dc68c29feff06e379ba0e9ed2ef0b1effb1747d44f3b1fd0d5ed2f78d0236c65cdf367c7e5fb0009858bf07cfd15f7bf082f4a3492473f96f19d8257b6df8f82e66cb05f55fbe223630ff6f797cbc98b3f67079527afe82319d17e1f6b7581a03fafdc693ccc7d7a0fb194b97da7bbb111b63f2af1bae9f0bd31810eb7cbd61612d1dd2bf94da671943c8cfe7af856d8c69be6e0563be594f2573fdd7b8bd2c1c763ded0f53c01392c7bb4ae6fdd3717d5db8c684fa4bbb134cdfa767f094e28180fba3e5c080fff15fc0b309f5ef9764d24ff13dfc43cae7a3e5d0807d6cf8782d47acbdfcfeed0b783ea1fad50ebca0ef6f3ed82079a32f30f2c5644f6c627f5acce7df655fd0e1e3930460a662dc3f1cc14beaaf40133ca178a8069bf47cdf90ccc74ff3c10e8de78dfa676c8afd09b564daff5982b1ff36a6f64c58ffd2fed40b7836a1fac504bc9c50fd6101c6fc97abc426e2b3700fc67911f3018cf33ac99d643e1edd198cf3176e07463da4fa0063bf8826be47bd53e7fe773965e345fded806db217eb1d8c78f29612b3f6923ea9603cbffb0663bf4949d7b38083c663b3022f68fceb7bb043f6118682a9ff8c02ec92bfcbe9fe7dba49f5c30d18fb636c9e2f2ce7ecf7144f2a6097e4bbe5c4ecf7140fcdc0b0b734018bfde03a784af3c53504cfb15f47dc0ffb0bbb8160ecbffc002fa95e58edc1d8bf1a4dc1163d2f36c1a8575495609c5f1a4aa6f3a134febd83e2ed2f376093faafa3e72fcc01f1f50b3c217ddd5660ac37ad63f00cfe5407cf69beef5230ea35c6026c60bfe55532e55b39d8a4eb6f73b0d8df20ee6f637fe04a32cdff03b043fd757b904cf9d9168c7ae7ed2299ce7b3692697fc898d8c2f99ddb128cf3b317f49f85fa6348f75f1a06d9afb604c37ff817b04dfa1c0ec10ee9bb4ef22ecd015d7fdd8047345eb5079e907e598e60d2d7b40363ffe3762598e2d5750e16e703d692297ffc128cf35768af897afb36108cfaee5c32d56b0f9269fe2e24f3f61731d880ff5125d37ed80558ac974c25d37ec09d64de7fe64132f73fea27d8a2f15732c9b4bea008a6f655a23fb1dfb28c24d3fe470d8c7ae1ed5132e95b2099cf8fa6e82fd4e3c32fc9b4bee3125b38ef7723ff641816d99b7d03dbe48fc22bd8a1f9f95a825d9adf4af28706eb1ede5eaf060fe97aaf133ca1fc5605237e6d8ee009e5bbd5198cf58b4efc1efb6fb71730f67bae66e025c5df8a09c6fecae020998fafd248a6f3ba909fd93b6f4f71025bb0af52329ddf9849e6cf533fc036e993924ba6f96726993f2fcec00ef57ff12e99e2c34a32ed7f0cc1f017d5bb649aef7cc9bc3f22f13c97fa4fc3f859388f5a6d25f3f69443c1d86f3b06e37c4be54ae6edd354c9bc7dd791643aefdc4aa67acf2b18e7f134f13dced325a4ef26d3379affc95f9826e2cb952a99c6f7153ca57835fd0463ff691108267fb579028b78c2001b34dee14532bf7f62814df88b4832d52f2ab085f59d0118eba3752899ecff2699eae307c9b43fb405431f9454329d2fbb97ccdb938cc02ee95b2adaebd2f8b590dfc279e448974ce3f12998e67b4d30ce074713c934ff403e0be72d2dba9fc5e607defeca014fc85f5413f094e2313b954cfea0114cfe467901233fd41792a99e6a49a6f527c198afd71bc9549fb9822dea8fba944cf9502799dad782b17e6d7592c9be6782495fea42321fdff8c7f77cbcb477b043fa1deb9229ff4904e37cc697641a7f0decd27828aa647abfc45032ade7b982495f13b25fcbc2fb0c944032d9cb93606abf5949a6f314cf60bc4fc00a24f3f6b79960d29f5a914cf11dfa53d87bf82999d6df303e16ceb755a4cf369b3fc8ff7660ec3f57de04933ff0f760ac5f665bc114df2b67c1a44f57156c507f5f1cc9b49ff3198cfdc69bab60aac7ac4f601be7fd22c1781fc95132ddaf95ccdbabd492b93e794f60e883229e87fd9ef959326fbf3a964cf9e00318fe5d9d4be6fda192fed916ce83a92f92a93dbe64ca8fd11f229e4c6f92f9f3938164ca1f4f82b1fe994ae6df871f60acf79a6bc9bc7f62f49785f3b1b75230d95775914cf30bfacfc279b22df90f47c413a621995f9f7be011f99b6d2b98e2136d021e4f683d63059e4cb83e7ae2fa19dd4f3b83e734df943118f581f22099cba33c8397549f592dc026d69b8f9279fb6f9f60e453d6156c537f5a63c9644f8160aa47695330fc8dee0aa6e7c5b964f28791648a6fe692297e580aa6fa6628da8bf8c3bc974cf9642118fa38954cf58f89649acf1692e93c27e9936361ffbdd149e6df2b9e609c1f7d96ccf549ad24d37974e887d0676721998f8fba924cf1fa9364b247713df687754f92e9fc672399ea45a23d581f35af92f9f7b9f81eef13885ac1181f4b32d5dfa10f16f6a3044bc974dee9158cfd3f892399fcbb2d993fff26fa6786fd3ba23f711ef146d7bbcc7e283f7b944ce7995ec0639aafab25784af671db0a9e52feb200cfc9fe320f2cec650f5e52beae7d49a6f319e2fe4bd457766083f453bf80b11fa878154cf6b2adc1585f37c4fde0af235530f251717fc45b9e90d7c17ca848a67add5530ad1f74a160aa8f76e279c8e7c34630f97f3b174cf2379a645abf247fe35a781f90ff2818f3c1443297571d49a67cfd4930cd87da1b58e8ff5630ece74b32cd1fa564aaef7982697dc87900633f73694ae6faa0be4aa6fd789a648aa724637fd25a32ed3f79924ceb3d3330f6f325ad64de1fd98364927f2598facbd42553fd3594ccafcf311e16cecbdf22c95c5e652a99de7f267e8ff3c9e1bb641a6f4732bf3efb008bfd812f92297eb32473794b31bec87fa30a2ccea3ee0493ff30f79269bfe23718f53e6b2099ea0377609c7f34be2453fc7b914cf91c1f2f63c0e6478a0fb6e019d58be207c1538aff8fe039e503712b99e6eb5c3297a750c04b1afff22618fb1922c1347fc73bc9b47f4630f2f9eda360b2efab2e98fcd1ea158cfd83452598f47f6b48e6cf8feec1a8b7a40bc1f05f3bc9bcffb61918f596f85d32d5e3447fbaa48ff94030f6ffdc24737bf267c416f6a7ac3f2453fe580bc67e99122cceeb9c24533d6b2299f4ad108cfce30773fd500cc9341f7792a9fe6b0ba6f5da6b2399ce372ec1d85f1d9d25f3efd59b60f89f3bc9bc3fd4a364f22f6f60ec97543792797fa8a960d8c74d32f9932918f61ed49269ff832d99e44d24f3f61a23c1d43f96fc1ef1fe1c8cf763448e645a3f16cfc3fe3d632899e2955832cdafd01f0be7d5ad4a32ad9f3792b9fcc64030ced3d792b93e9723c9b41feb02c6fe67732b99f68b7c4aa6faa3180f9c17f6499ffa032dc46bf098ec5d8f24d3fe08133ca1f530ed049e527eb7f50593ffb83c48a6fd570a7846f7d36b30e6fff25b32d5ab73c1145f28ef82299ed1e660d473b64f92a9def92698fcdd5a3cdf46fd24914cfbcd74c9b43e21e445fda611f7437cb1fe124cf65edcc02edd3f7225d3fb001e05d3fc5ebd108b7879bb93ccfbc72f05937e66a9605abf538e92493f56e021d99f6249a6fa5b2b98fc9f72914cedc3785a789f52f12698e42943c964ef17c9e40fe792697e1849e6f2648e60ac470660bc9f243b4aa6fd3fa1647ebda20826f9d24c32ef0ff55e32d5d7447f60fe2f9f25933f5a4aa6f8e62c18f9502299f40ffa61e1fd4b4a2899f6279492495ed19e29e297028cf795048d64dedef05530e29137c9e47fe4efb19f740cc6fed152134ced0f55c9fcfb488c17dedf74b9934cf64dfa3c326754ffab0cc1643f510ac67a78ba04633e77466083ecb309c026cdffa921998f476582b19fa7ba0aa6f93e5e0ba6fca6188051bf4b447bb1bf4aff00237ff60f92e9fd41f792e9bc7d2599e6f717c1d8cf247e8f7a5d160ba6fecf23c1b4bf21a0f86264e13c72f82499f2fd57c1f06727c954bfcec098df755b30d9ef7a2e98ecdf78974cf54cb447d47b3d5330e2cb0fc9b4df47dc0ffbd12ea9647a9fec1e2cde07f92e99f60b1c05239e3e4ba6f9df974cf9d74932ed9ffff17b2e5f70014f90ef288261df8664b25f5332bd6f0ae36be1fc4ef92499f22d4b3297ff593c0fefb7525dc9e4df3c30de5fa53a9229feb12553bc2ec66f46f2565f92c97f37609ca7b4df25d37e825a32adff89fba39eaafb92293fea24f3ebb7627cb13ebbfd944cfbadbf2453fe37154cf287a664d257d15e715e80fa6fcce673f2af117846f94076075e503d2188c1d88f9a9b82c91f2457c954cf38832df2279ba9647adfe70a8cfaecf62098e2ef6e2699ce27ed04533cb2d5c0d8efaa3c09a6fa46f12199ec5d3c0feba51dcd9f63517f5dbd0886bd3f4be6d76f7f30d59b62c164afde5432d5271f2453bdf0118c7abd77124ced4f1ac914afae2553bd5edc0ff3b9f32498ec6d1308a6f66c55c9341fdd83313f9ba23da8ef46a564dabf664aa6fd21f27b8a37e291643abfe249a6f9ce174cfb13a2028cf78b25b9647a1fd4a364f20fdf92c97f0c25d37a512599d607a03f22bf375ac994ffa49229ff78944cf94a2618fe48fe1ef59e4632bd3f270163becf2ac994bf8beb71fe4b0d2453bd27964cf552d13fa807da2f9269ff612499e627d13ed40f424330b55f13d763bfc6ed4332c50f37c1f0f78a64daff3d964cfb43c578637daf7a138cfd39429f719e6745fa30314df21f590ec6fedd32134cfbb10c5d30f98bcb8b64da2f3c01dbd87fbc174cf5c92001e37c4d25eee760fff1b7605a0fc8b792e9fc81b8bf43f149740263ff68fe2a989eb722fb9c8878201849a6f75f9e25d3f37cc974fee15532bdaf752898ecdd0904d37a475080512faf7e30e9432e18e7f56e82914f5482c91e0bf13ce4ff7e2698c627fb924cebcfe2f7d8ff1b3e80719eaa934cfaee3992491e717ff80f6f2699f22ff13dcecfa753c9e4bf0e92293f394aa6fd139660b2cfc8904cf9df4230e68b4a32add78bf1c0feda740ec6fbebcab3648a8f2792c95fd492299e1848a67ccd164cf25b2d58f887ab64f2379d64de3fea4132bd6f4efc7e8e7827944cfb7f1e2553bd4f134cfa6c799269ffb6781eea8df14432b57f2718ebe591645a2f8b05231f15bfc77e0f652699e229f13cbc7faa9a4ba6f361427fb03f5013fa8cf5e2c495ccbfd73dc924af180fec0fd33e24737922f17c9c6f6cc91ea626f69b5e13f082fccfe64d32d547bfc0385f565ec0886fba1cecd07a663394ccfb237b05633d627b144cf6779949a6f75fd682c93f06349f4dc5fa433d154cfaace982697d721b4aa6f3c11918f585742299fce5bd64aa67958229be5ac560ac27ac12c178bfd79b64da0ff1e37b7adf95fc3dcef70592a95ebb174cfe3a10cf47fda01c08c67e1b5f32bdcfb0134cfde12a92493ed17f585fc81f25d378dc49a6f8e253308d57249e3f417c7a904cfbcd7e30c5d382b11e982592797f24df82b1de954ba67aa6907f4af69baec138af6c8d24533d692f99ea733bc1e4ff3c0b2cde37be944cfe712499f2b1b964b2675732c52bd0670bfb45d54832e58fba64da0fb301e3fd8d4a2499d67f857ee0fc72f82d99be5f81713e3e194aa6fd49e27e588fb89ec1884fae13c9d4ffa27fb0bff0229e67537fae481f66e612fb2d776083ec3debc026eaa53618f18a3b0323fe580f04d3f5c98b64da7f63825df217852e99ce77907c33113f6c4dc134df6f1f24d37c9982b17ee04f05537b9a77c9148f88dfa3deb07a92ccfb7f73168cf365778229be48bf25537d19f28bf501e55e309d4fc94f92c97fcec158cf2b12c1e41fbb4fc9b43e3d104cf3f7f6158cf87ebb170cffe448267942c1e47fba05187f1f455049a6f5614330f4ff0d8cf3b88ab83fde3770d94ba6fafc12bca0f6a557c1c80f6dc9644fb964aa7f1492a99eb1934cf3f718bc44fd632199f2ab67c914bfd782518f16e389f78346a23dd8bfa58c25d379ba4030c95b5f2453fc5c824deacfec2299f6eb6c25d37ae74630e2b94632ad170bf9b13fb87b964cf514713df61bd4aa643a9f0f7bb31cecbf10fa28f6e3f89269bd83e2adb9399f52bd33032fa6fcfef9086cd07e8d95f81eeb1b97a964b2bf0dd8a2f958ff02dbb41fbbbb825d9a3f2eb5608a3fe28560caafb6141fcd45fdb11a83b11e180f05d37e5c5f114cfe669d8051ef6f3dc1a40fab108cf3d9e55a30ce3b1a60d4d78bab649a5fe5f7645f978364dededbb360f247452899ea616730d6e7d6779269fdfb4330f9bbd4148cf8e7058cf5b8e44932bdffe25e30f6835c24d3f9d1b964b27f713decdd16ed9b937fd2f792a99ed2082679a247b0380f33964cf3ab18af05c52f57d1df381f5baf2453bcff0046fcacfe60daaf6a4aa6f9ed4b30ce7fce25d3fedd1918f65f8af1c37e6d4f954cf9cf5a32c927fa17fbede254326faf22aec77c1bd582a9fd971d58ecef3524d3fe5ea1bfd84f97d1f82ec47a83be124cf5c8ca07dba4efbab8de9df2dffba44f0b51afeb5cc1747d32154cf61eecc043ccf74f9269ffd3098cf7495c1e25d3f9c14a30ad9f281f92693de2001ee3bcf34430e94f71114cfe259883f17ef6b52599de2f36144cfaa23c4aa6fafd188cfa79d60a267de832c1345f1786649a3f7e30cd97a2bdc86ff55232c54fb9648a6fc4f367e44fbaa1649a5f669269ffb7f87e4ef6915f2453beaf4ba6f9443c1feb655a2c99e47b944cfb532493ff6bef25d3f86ec1e2bc532318ef1712fa82f3cdc55e32b5ff1b0c7b5acd25d3df9fa04ba67ac25e32bd0f44b4cfc0f95ad13f787f759c08c6fb8f34c9141f6e2453fee80b46fe22fac7c2fbafef24933f17fa8efdf9590dc6fb8d4a8a079626ceb3d513b04bfa5a527cb664f645eb65067848f359fd8369bfec063cc27ae45532d5e31f25f3f15c3d83315f5d12c9544f740553fe1e6592a93f3dc158bfb88127145ffb9560b2873a96cce5d75f25537ce90ba6fa62f283a95e2ae49bd2f82b0f82c93ef385645a6f17ed453d39984aa6fac04c32fdfd5607c1a42ff14a30cdb7b74232e5a76f60e483fe5132cdafb960c4fb5f60c4aba52218ebaf7b30d69fb6e27b9c1f0ceec1d82f962b92c95f1d24537da7148cf93d05239f534f92e9bc8bb81fcefb1547c9544fabc1383fe68af1c67e92f807d3fe43213ff6af7662fcb19fdaa37cc410f5ebfc5e30cd1f6b07ecd2f85a347e06332faa8f1cc0d0efdb17784cf6e91a82499ff44ff004eb318f92693fdebd649adf5f05937efa67c1347fe91618e7bb6e7782112faa60ac8736a1601a8fac00a31ee98c05e37d155bc1347ff8aa647a1fc009bca0f1f21682c99f9ae2fe0b6acf360763fd62bb168cfcb0148cf7790879f1be9ad4954cf53cd17fd8bfe49f24533db1164cfdbd7d07e33cd346fc1efb17b789643a4f300423bf303760bcdfec42f669b27885ee47f38169e1bc977e124cf18d3706e3fd11fa163c22fdda9482a7b43e7805c3ff058660ba9f2b9e87f364d14632d5fb4792e9ef37fe02e33cd926028bf364efe039c9b712f747fdd9ad24d3f58231fee58b601affdb9b648a6f7230dedfe12d25d3fa760a467d3817f218145fd99f9269bda1924cefdf93df23fe7e009b349f98623c2c1a5ffb2298ee97d8609c3f32e6609c3f8b2cc9646f0bc914cf3f4aa6786607c6fe958ee20f8bcdafb43f81e20b165e93fe5c3e25d37e30f13dea3ddd093cc27ede2d18f5983804e3fd1d9a25989ed7168269ff61fa089e223f9e8167d47f862699d6f39e25d3fe68152ce2b70318e7c9ec67c9f4fe12138cf70f252918f1932b9e67507caf08f9f1be9938069b648fc15e308dbf32108cf7df88e7637f627c150cff7a0163ff42f000c6f99c88ec9b4d37a867d1fc62b3f1a3fd3c743f5b8c5ff102463cb2da82117fb4df9269bde12498ec510f25d3fef01c8cfcb8b425d37eaa5232bd5f2506235ed85a9269bda4154ce31d89f6cef17ea8037841f76b447b17d84fb6012fa9fd6b211fea49978b608a4f0c156c423f3bc9b49f3602c31e6f7bc1d0bf4a32c50fe44f6c1bfb3be22918e7e93a6287d907adb70ec063eacfd51b784afdb3d1c0c85f8a5232cd97afe0398ddf652d99fcf75130e5879d09c67c961482c97eae7bb049f74b3ac9349e86649a4f2692b93cb978be8df749b88229be509660eca7f39f24d3f922713dd6afaedf8269bcd690c7c6f9d755001e52bc5b533ceb5a63d29fab2199ce63edc1139a9f82083c25f9f5068cf745dd2cf082c6238d25d3fb1d378229bf503ec178dfce6a0946fce9bd0aa6fe5ccf04e37d0af27aca77ac1bd8a2e747df9229fe2dc136f98ffc4530e9f34a934cf9f10fa6e78be739387f48fde9daa8f7273c3e310716f67b260f9269ffde1318efefb91e24537dcd06e3fd79f6156ca0deb1904cf6a080d1fe6a2199e67b5f303d4fbb801dd8fb0a8cf8f9a611db78ff5dac8211df745f60d413133e7e2c389be17ccc183c27ff97459279ffac4b30de27947e0826f94c4532bd7f5d032fa9fd6d2a784af58e21d8a0f9e1aa48a6f53f5b30d58ffd6730de5f94ad89ed01d9ef86eb2b0b2eb0feac6fc04b92af7525d3fbcd8f6093fccde64532d9cb4d30c57fe1128cfd33eb77c1a41feb028cf7355a1f82e9f9ee1cec62ffea9b60f227892918e785f0bd8dfdafe9b3601a4f270463fda81980f17ea59adbbf3966fd41ef472dc14bf2075b1b6c60fdec4132d50f0bc9944f1cc126c693dad7bf5e9ff2075c6f63bd6b45fd33b1e6549fb8adc0580fdc7682c97fdd5ab035a5f74309c67961e50bec523c1de2f736eaf7f11c3ca4feaba8bfa6d664467fffdc080c7f53b492a97e6f08a6f686776013fab4964cf69982717ed224ff30b5b15fe81608c6fbd3ce60c48b2d8dd78cdd8ff2eb5430c5839b5730f2dff60086be74a4af33d6ff148fdd8391ff6a74bf390b30693de808b6917f64c436ce8fdf1230f6bfb7345e0b6b3a27fbe9c0f319bdaf8bfcc782a5f7e43f0f60cc4705f99f256b3fedf71c826d92ef3625b627349f68dcdf9b2c9f9b927f237d3458ffd1fc5b8327f007241f530f1aaf6b00467cad51ffb2f8674efd41fed5b6711ed0e4fac192cf39b57733022fe97ecf977feda32abf7d8c9f3e26ffa7827fa74fcf0afb9da5daaac3fe58ff6a0be8f3df21cb2f72b9ecf3bb5c0afe9b90afff77f7df5116d62247f5d81ffad87ddba87590cbfd87bfb3f1f9779605f20899fa6be8cfffb79fff167b71e9f393743ffadc1663f4e33aa96fbdedf8eccf3f18b9ffff65e16dfbc90e6009240d1fa9bf2b3bc9439ee0df4d1661eb3f64f9313a3f24f3e4e717cbfa7791e5379fecfefa91d758f05a8e94457a8a7f2b590235542335561335553335570b364ea55aa917b5669f86e951ab76ec7365b2de544dd5d99f15ff9dc67eb1fe379365a3aed827652391a85bf6b963d2ecd43dfbec982c07464726dd91fdfb4e3da9f74cce7bf5817d0c76e53ff4daff5b6479e43dfdc446e699fddb597d515fb94ebda9efea87faa906ec9a9449f8c524f85607ea501da96375a24ed5993a67d2fc1bc9c25a7a5637ec9f91ba607f02d8fd92c9f2cafe6929aafaa4284cc7be15431d2ba662b18fad380af31a8aa7f8ff3d92fcf7cc954aa0844aa4c44aa2a44aa6e44ccf5ca63d2dfbf4b6622a059b45064aa954ca45a9954669954eb92a3745537465a5acffe8b5ff37cab251b6ca9db253cf8aa2ec95036bf1513929f7ca83f2a83c29cfca5979515e9537e55df9503e952ff6dfbf9581325446ca589928d37f23596c65a6cc9505d3b393b26413cd83f261288661b044c0b00dc7700dcff08dc0088dc8888dc4488dccc88dc2288dcab8a87746fddf23c99f9345b58ca6ff23a390df6677a3353ae36adc0ccdd08d95b13636c6d6b83376c69efd391847e364dcb3cf897d8e8c1fd8e7d178329e8db3f162bc1a6fc6bbf1c1b4b0cf02685e757f9b797f9aadfe999ff8af6561527c1a5feccfb7313086c6c818315fd4186363624c8d194b9916c6b2370ad3304dd3326de3683aa68b8fc73ebe19b04f684666c465eaa53a9a31936a6726666a66666e16666956e6c5accdc66ccdcebc9a375333757365aecdcd2f33b1f2eb1cfcd764311a736bde3169becd9db9e7b21ccc8379344fe6bdf9603e9a4fe6b379365fcc57f3cd7c373fcc4ff38b7dbecd8139c467648ed967c23e63736aceccb9b960992a3334e3de322cd3b22cdb722cd7f22cdf0aacd08aacd84aacd4caacdc2aac12b9dc2f91c5ffaa2c56655dac4b3f2e566d0cad5a3d5b8dd55a9d75b56e9666e9d6ca5a5b1bd6d3f7ccd96ead3bd6522689b5b3f61677bfd6019f2393666a9dac7beb817d1ead27ebd93ab351da592fd6abf566bd5b1fd6274b98bf5884b0601e3d61b3e9c0faeea3cf1fd1d1bfa2634cb31a8bfe82f001fff74a89aca135b2c6d6c49a5a336b6e2d7acdb196cc74fa4a9ed18f85b5b34d48f2439643bf4c614e6ddb766cd77ab03ddbb7033bb42326cfc178b4633bb1533bb37336abda766197ea935dd997de92fecce74fc932307756cdc6646055aa67d77663b776675fed9badd9ba71303fec95bdb6376c249ef9676fed9924625414662bcc5e602bf766681bf6d6beb377f6de3eb0cfde3eda27fb9e8debde7eb01fed27fbd93eb319d7b35fec57656fbfb1d1b07efffcafc9f27cb16a66274cb78cc6f8b4df992c1ff6a7fd657fdb037bc8faf3c47a7864bbe6dc1edb137b6a2db924bb7e64fab161ff9cb1f6ce85fd9b91bdb0972c485698ddcc1dc3311d662c8eed384cd2bde33a9ee33b8113b218f5dd89545df17fcdecfe155954d7183ab113333bb1edda499cd4c9ec2f27778a5e0ea7640ff0ed3d6b55653d3b17361acf4cc706cc6216dc6ed8ff3b356b6be3b44ca6b9d3998173756e8e66f7938feeac9cb5b3b1b7ecf78eb365d21c8d9d73e7ec9cbd73708ecec9b9771e7ec9107ecb7a7eb6a03f234b2f09f3c683fe7ecea3f3e43c3b67e7c58cadb33db1ced6b33d6656cc3ece2b6b5dc5dab5c0a7f765ec63cfe9e374f8bc39efbd24f6d20e9d0f66fd47e7d3f9ea7fe954ce379366dffff5f6cec8e9ff5acca933b3eb9fe4f8576599ab9db3b05f9c25fba1e21a6ce2b08c23f34accd3bab6ebb8aebd702a73e17ab66b1f5d9ff9a8931b981fccdacfaca5f76ec86c2ae673e6d18ddcd84d98bde0e3746e6a7acc73b02b594fbcd93336be67377373b7704bb7722f6e6d176e63356e6b358ae67656f3afe8987a70afaaeddeecd6d55cdd5db96b3626cfeec6dd9a43f7ceddb97b3622dbde86dd837bb4576e6031ed331df7e4debb0feea3fbe43e1b817b765fdc472195fbeabeb9efec5707f7c3f9703fdd2ff7db1db84377c474f1c0fe7dec4edca93b73e7eec25daabd2f6091b8a7aa81f70fbdda9f91c533d8f46d79b6e778ae937b9e71b2179eef055ec8e4601fdbf0222ff612e6030eb6d1eb8c977a99977b85577a9577f16aaff15aaff3aedecdd33cdd5b796b36e7c7c6c9db785befce7a70471ebb0b1b5d9dfd3ff36fde8e59cec1db7b07efe89dbc7bb5f01e58467af31ebcc71f5af5bb1ff853b23c79cfded97bf15ebd37a730637362dbde3bd32f2e099368cbe6f229b39ae7de76bd0fefd3fbf2bebd8137f446ded89b78536fe6cdbd85b76441d7a3aff8866ffa966ffb8e71f45ddfb31e7c9ff9e8ad6df8811ff663e547ee8069e4831ffb899ffa198bd6be51bffd523c9189fe75599e2f7eee177ee957fec5af0d6603e6d46f7a49fc967d3aff6acead27ffd6cf77bee6ebfeca5ffb1b7febdff93b7fef1ffca37f62f966a2bef8f78aea3ff88ffe93ffec9ffd17ffd57ff3df8da3bdf03ffc4fff8bf9f485bd30c74ee57ffb037fe88f8cbd3ff627fed49ff9737fa1382c27fd6679f70f597ea97dfc99d8d25f066aa004060b112da65f6aff97c0f7fae5b7811d38fe3570cd0fe31478811f04411844411c24411a64411e14411954c14509839a7d1afb3d68838ee59af3e06a3f07b7400bf460c5fc48ef0d9560ddeb99ad30d906f6c27a0e36ecaedbe02ed8057ba50e0e4a191c8353708f0af54f35ab3f2d8b1d3c048fc153f01c9ccdd829ad73f012bcf6da15bc05ef81137c049fccf38c83afe03b1804c360148c8309fb330d66c19c49b47016c1325443253442d3188416fbc39c71e8865ee88741188651c86cc73a8709f3cb4698f29881c50f61d6fbfc300f8bb00cabf012d661e32fd421d3b41fb2387f94e5e77af6cf63d25f1db661175ec39b19875aa8b3bbafac636f27e13a5c33795e8c7b2f0d37e136bc0b77e13e3c84c7f014de870fe163f8143e8767f52d7c095fc337ab08dfc38ff033fc62d2982c22f6d97ff90e07e1301c8563e3184ed82cb40dd6e1943d63e6ee99fd7c9b53f6dfe7e1225c466aa428456444e68fcacdaf5a46b288ff862c28f1d4c8525fd5d7c88e1c7f19b9e673e41987c8376751c02375a61351c8e2f7cf88e524511c25511a65c62dca8347ab65f369cafe3c4645f01895aa1255d125aaa3266a5910d345d7e8166966678ccc75d4467ab48ad6d126da4677c629da452c82f0039ef778d68ecdb40bf6bc7d74888ed129ba77d2e8217aecefcdabed866af4d1eeaff6f2932c068fb043b77516ca2e7a8a9ea373f4629ea357f6a437e6750d16a79ca37773c2e6e8aad7eae823fa8cbea2ef68a0ce153f1a2aea8f2a2c7f9e1b8da27134096d2b8ca6d1cc8aa379b48896b11a2b56111b319bac629b85166eccbc3d9f73962c7f93b29843e33ef6e3200ea3fb388ae3f081f554cadbcafc5a1f25fe2c0b7ff68f7131d4f8f9e22cd4f73889d3388bf3b888cbb86277bcb0f87111d7d6dedd5b4f7c2639b959dcc46ddcc557ff515dfdb4f662cb3bbaca5875e25bacc5ba3f8b57f13adec4dbf82edec57ba5890fea323ec6a7f83e7e881fe327e3143fb3d866c9bc7380b86e689de373fc120ce2d76011bfc5effd88736b3055a38fdeff992c0ad34726cb6b9cb8adba8a3f4c23fe649db7641ec6b09ee3da665ed3fc0c33f6dcaff83b1ec4c378a456eaca7e51ee94713c862c3c1eecff9dfdb7493c55f57816cfe345bc4c54e3c17e4894c448ccc44aecc449dcc44bfc24484263efde9b3e8bd8d887e7a42c3b65f3d6d17c4da2244e92244db2a84872b1baf07765b1c886f8155b36bbb2fe65914fa2b8499194e69b71f26fd69e8dc9d9b998dff6c13ad953e39054c925a99326d6d5f7beea9db4ccca52f40d55c1d97d95bb385332bb4abae49adc12cd38252ceb4956c93ad924dbe42eba26bb641f1c9243724cd82c657a8ec272014364d94c9b4b2f4dee9387e4d158264f09b34ab146d2e722ff4c96e499f5e198e50e2bf6efe7e4257935dfad3e3f3f276f56ff8afa7df26ece8dfb709c7c249fc957f29d0c143d192a8b64c4abe3bdc7b4fbac8dc9c264b2df93713231de9269324be6c63159d8c76469c6a99a2aa9919aa995daa9e3dfa76eeaa5bef1603a2cbfe1b2f45910cb54b769601cd3308dd2384dd294cbc2d76dfa7cc4180aaff6932c96b0fe3453466e6b97cc8e9d344f8bb4343fd22a4c98f75a5afdfe8687f4621becee75daa46ddaa5d7d451f4a04b6fa996ea91c9fd3f978549c3644957e93adda4dbf42eddb15fedd3837d4c8fe9c9d8a7f7e943fa18fae953642b7a344c9fd373fa92bed2c8902c2ca7db4681719fbea5efe947fa997ef5feb197a56f7f9f5bfd2acb8f91e17a78607dbb5412ff2139a7dfce9069eb673ae86da5f7c54ee5fa696f8f553a4ac7e9249da6b3a4b50b65c3f42c5177fe23ef31361a7d0edad724d379ba4897999a29c63163f971b4efb3e3ccecb3e2649559999d39ea57ea0475e6665ee66781e9fa81a3a06ab0eb675096e1c5599845599c25ce23b3172e8b6af5b9d52fb2889a9add3f99d14efd4a064ccf952c553eb2cc74cc2fe61b077dcecbf477613d982316e37efaeb2ccf8aaccc2a61e7e45b98b34db24b56678d5dc763f53b6bb32ebb662c62f343d6df6ff6c2fd66de9c652c99661ce3a74ccf56d93adb306bd3b36d76e74efa5999c53363a603cf76bfcd8445369691edb23d93e5901db313d31d85db7491ddff268bf28b2ca67a973d3032b24743c99eb82ccc37f67d642ebcc4661146f69c9db397ec357bcbde852c1855577d4bdaec23fb8c9e93419a655fd97736c8d8e866a36cec8eb24936355da7cc66d9bcf7ebacbf17d93257734509552b377233b7723b77d8377d3d6dc29edad74398b7cedddccbfdec900779a828ff4496be024a7dabf8bd36f63edacc23c330ee982cbd97efed70c024619219f7799c27fe364ff32c3c30597eac4172bf95e779919779a556f925aff3266f8d63dee5d75eb7dc613f1ef9cdfdeeb3e25cb316f153aee7ab7cad9eed32dfe4dbfcced67396c1b09879c8729a4bafd9feb7719f29f93e3fe4c73cc88e4c9b1392c52afe812cbd0f559209d332db2ed5263f1926f32baed05ca6678eed5877ecbfbce6f7fe5dfe104cf347a3fd690d92d97afe943f671725cecff94bfe9abfe5ef7dd4937ff49909af719cddaf6cca73628dcd8871fe997fe5dff9404d9cc833f3613ecac7f1579ff1997dbc4c51b4cfee30c9a7f92cc9988e1d59a699f47e377c0bdffe200bb75792259fab7b854d65ea77be302c63cfd2fb1dd5bc481673943bf9b2500b8545f5b3e8814547b6dcabc0575793b1fa919f0ba33059b7d9ac557d2cbfe8f312ebaeb7e4c2e96b1785cb62ad53e1157e111461112923d52ee22229d22233f67d5ec365611ac6aecdd98cb92f8aa22caa3c2459faf6b398f5f597f9e5375958c6b34f6fcc62be8b0b7be4ce74a97227646177ae8ba6688b2e288a6b714bf25f7684303d53fc645268855eac8ab5710835e7b597a5d8b06cabaf6a7ef4d5be60cd243916dbe2aed815fbe2a0d8c5317b284ec57df1503c16cc3efa1a279764614e0b268f7128cec54bf15abcfd248b1aaa7f57164fcab22bde59fe742a3ed894b5efa33c5420875c9645f1597c15dfc5a01806398ba2c90bffd8555114a3625c4c8a692f4931ebd72c989ea8c5bc8f467b5b6677e03163b12cd5ecbb544287c540d7d250c2d22cadd22e9dd2354ebc22c2ae36c7f6a1f498cdc6a55f06e1ae64290dd731f7efc822d654c40cf3adb665c472b053191b2ecbef852cfb5e16f3cb3a9749999659996749745f163f564a7824669465599597b22e9b5e92b2cd34661b565f3b6371dc985bb4e10ffaaca7ecca6b79b3be4acd0a4a9d8d67c4a45995eb72536e992cbabdeda326368e5bebbecf64cabb7257ee7b591425cd7a6d28b552fb45961fd13ef773ea8dcd103b75c56439183e1bebc81c5b7d3d2cb0674e63cfcb63792aefcb87f2b17c6271ce86e527a398c594ca9d5d97cfe5b97c295fcbb7f29d79d12eef32adafee9bb3bebec13f337b5f7eb079bc2c3fcbaff2bb1c985d392c47e5b89c94d3c42d67e5bc5c944be3c45c7d156a7c4c0f665f1939564a655466d06746a7e0d4ef2ab2aadf62fedefb3059d8b7663f36c8d834bbaa2c26cbbd19b2deec97483a264b6b06c6a1b22bc79bc5e3a00996e5c4dc562e538ba86236cfa29545e5574115329fca66bb3ea736471513d73a313946fd9a4515dbdb2aa9d22aabf2aaa84a2bacaaea52d55553b5556745c1b1ba062b362e5ba7a355b57ebda3aff254b74aabf42467b21c83a36ad9f51f641151a5cf6571d488e9e246bd315559556b264bc4662c268b193269f64c96a37bf65a6fae2e2387e9eb5bb5a9b6d55db5abf6cab53a54c7ea54f575e17be6c717d681c5d5233e26a3fe2ebd3d570f4c96c7eaa97af646d5b97ab1aaead5dc556fd57bf5517d565ff128afabef5e966ac07ac2e5f5cf678bddb11a56a36a9ce4ce23c6c5339adf627e4bca6270efba60d1ee539ac5a36a524db98e912c51af654c965335f33a8f656bca3c34ccae9a87af9eaac6ac3f17d5f2a26637f7f5a25cb81fb615f38349d17f26b406c3ee7570377d7e75312fd6c5be38e1cbc5bd78179f8d897f092e6134b8449798c9d2b91fccbadefb159cde673059946a7449823e47f6d9c7fea32ca859283c96225912f549bdbfa4ec9e593fc6fdfa9c6df523d4af3d18a774e75d2fb9925e8ad0c8eefbbcfd525eaacbe5525f9a4b6b9c2edde56a6fcdd1e5165f98bd93244764f10773e445d68e5da55df4cbeab2b6c2cbe6b2bddc5d7655a7b697fde57039ba2fbd2c173633b1d8cde27fd5d684fde2fef27079e4b2a0adfd5add3f95256071f24d29c2faf27479eeb585d61bfb95a07ecd81e9d8a377f35545b3df7975c88ca6feec72bebc5c5ecdc4383afae58daf136d8235f75dbd7e8db92c7c3d96f5f196c5dd5333bebc5f3e2e9f97afcb777cbcf06a13d388e16578195dc66c869ddb6c66cd466c967db5ee7adbbf4c2ed3cb8ccba2f0bcc2fe5d16392f4096545373b5cdcf97f9657159f6eb90bdcdb2d8b85fd50accc08d8c83a7298f8a1fb4c620fca8d55a49b6b5519bc98ac9f9565bb56def1cc38bfaf99ecd8d336ef74cc7b8341e9b3146e6dcdef82cdeac9ddaadbddaaf83484b46e9ad0eeba88eeb84e5ca9fcce3796c6e9db008f4c9dd32590e755a67756e325990875bfd0aeaeff9cbcfb2287eaa2b6e5dd4a5f25557c68149c0bc0fb3dfa8978569716cc69eee2b6aa9cc422bfc8caa9a4590ec7f0d6b5beb7eb84347cdaf2c63af9cd73063f67faa22f6ebdeaff7d27875c746f9cbfc626d5cd6d7fa566bb55eafea35d36ca77c8af27a536fcdd8b9b23cdceb6318d6239bdec2eabb7a57efcb3d932515759e3fe695d8112074cc55efd44370523ae5b13e184cb3597e7f6fdbbc12cfda581f599b4ff57dfde0b6a1556d13b77eac9fea67e3549feb17a65b8bfab59f159cd728b02d1691ceeb37bfb1b7fe376fd994b220ca89acbdfb5abfd71ff56738a8bfeaef7a500fcba01e992ed3c27db17077aec3f29881cb324b63578feb493de5b2507ef20f7264f6a797a59ffb13f6ff0d9bfda7f5ac9ed70b9657b2fc8bc52e5b7b592f9d779bcdc98dda288de13f5a35f3ca1f8dd958c64363db47f6d9374e3f438693be6ed3fbb2c665ff34a2d0def09a9af1cb1ae0d074eb5be3357e1334a1f3d4444ddc244dcafae291e54977eeaec9ac2dfb158b429bbc299ab2a9b8bdd09ca8f42b763fcb42732397c5e4b364aa8cd2cc99c77a7369eaa6316377c3eefb7039352d0b8359d6e186c6aee99a6b738badd0b48a466b74fbc18c9b557aecc7c57c6fd64cdfc76c2c3efa5cbdd9345bebdcdcb9dbbe8283d53fac9c9b5ebfb3a4d935fbe6604d9a63736aee9b0726c363f3d43c3799bbeb6be64c2fe3e6dcbc34afcd9b948559c51f65a1d95ecaa2f1959bb5faa138cd7bf3c1a22ac7ff609e89d973bfa6686f9b4fe3e0dbcd57f31dbae167ad3483669828d60b7bde283359ae356bc66c961b46611f41369366dacc9ab971b296eeb6e1e3815566167d9b9ed3354b63efad5bb5555aa3355bcbe8ebd581396efb15c45d9f2b87ba71689dd66dbdd6ef63181e7719aadfaf09ff365752a5cfa4bdc2fdfa937a8bc76de03dc65d1b1afd4afdb658703fbbed6dba8d8c531bb7499b865ef5de666d9e9fdaa22ddbcad8370fed85595585fce4beaddba66ddbaebd5e5876dfded8bcf3ddd70ee4eabfefed5aaddf1de36baddeaeda755bb35f6dda6df0dede056f5ec89eb7734a63d7eedb437b6c4f52163f38fd41161bd97abff39945bc2c951e313ddbe5b9a2b7f7ed43fbc8b4f7686ffa9d05b5d53ef55adf326fdf9edb97f6d518861f4e5c44ed5bb269df59ccb3cf3b7bc9645ef5f949fbd17eb65fed773b6887eda865b3068b697aed123b19f67e906bf6b69db0acf8d44edb593b6751cb397875ed76d12e3bb59fdbeace38754a67746667c571922779af472c8e39fe4116e75759d84c99a94967770e93e6dab99d67192cd770d89cb063be56ef7c7b5b9f7d3753baa00bbba8da767197746997b1b0b8e8ca7e6dc8db75157bfea5abbbc6df756dd775d7eed6699ddeadfaac8e723b5ec95b326b687b8fe2fb4e65dce75db7ee36eeaedb76776c02d875fbe6397aef0eddb13b75f7dd43f7f8ab2cbfc563b40fdae2fbb87b59fabdb76ef7d43de7cfddb97be95e6bc738b9ae7de8ff1a4166c38eb3eddeba77964f9cba8feeb3fbeabe9d85fad80dba6137eac6d19d195b0b33f6b56ed24dbb5937ef16ddf2aa5e95ab71358d9dfbca7763f9bd1ce6d00ffa99fd6ad97bc7bada4cbe73b7bb322bb18ee1cadd5d5deffdea3109dfaffe35b886d7280fa302b66ffe1d1d13eb0b72bf196a7fdcef5de36b52b2d65d53ebe19ab119ef6c9dddcf7eb5f79ab3ff5a5ccb6bc5e29897ebe55a5bfeb5b9b6d7ee7acd27d7db55bb321d5533b30bdf8da69c5c57d7f57573dde6937efe655aa8f4750ce623a2be06c6f7638dd87c74ecfd38d515ade7de5aaa8171bcde5d77d7bdda3847b5edab2c5993353c07367f9c07f8afd7f89ca7ebe17a8cd953afa7eb3d3dddbf998b6641d1eef5e1fa787dba3e5fcfd797eb6bad3069deaeefd78febe7f5ebfa5d75d74139bc0eafa3eb987d26d7e975769d7b6bd60b8bcccccceb92dba2f5f327f2dd7d73c7fc1c27ebcc52c3a79b7263f955348c4c36f3b9aa6dbf33591cbebef31764b99937eb66df1cd6379ecb66877edf8bad140b2fb9b139d0b8f7b51b0b346f8152ddc25b748bd5db2db9a5b7ec96df8a68d025e15755df4a7377ab6e97f0e3c626c65b5bac6e9db1ef772df0fd16d6af1f5eafb0d86cc4246aee7236b3dcaeb7db4d4bc6d133cb2d44fefb87ddf3ffb52ce6e34dbfad6eeb86c5860d1b0d663515f3f8ecff6d8fc5eecc9fe593dbe6b6bdddd5a5fa62d7cae2b65386b7fdeda0d4ea58dd869f55773bde4eb7fbcbddede1f6787bba3ddfce51623f180fb71733643e7af24759983454afa4fbbfdede54f7f67efb48068a226ac97f7d7d3f2a6e9fb7afdbf76dc02b565f2cb35c58776c86d89a73162f6d6e43e3741bddc6b7c96d9abab759eadce6f1241ef77bf56f8bc80a5fa2eab6d4d4a8d394a85202f5ac199aa9599aadb1b16e5acdedade4e78fbbef3396c82759cc58f3345f0bb4508bf242d1d20ce3f287d3597fc25e1eb5584bb454cbfad981dd7b617e7a119385f624cdedad96f733a75668a5566917ad564325615ed0b65fe289b25322add15aadd3aedacdf84c1dd573979aa6e9da4a5b6b1b7ba16da99af0ebc8b03f2a8bb1ad7667dada9db653bba0b9bddbef2c7f37642dcfa1f8f22fc8926a7beda01db59376af3db008efce9cfa1f2c3bda71eb6451633568f92e43ed517bd29eb5b3f6a2bd46b935d2de8c85f61e4fb40f36269f2c216e94246ccb2767e999da97f6ad0d3436a6edeeefd98bf5dcee2c35f2b59136d6260a8bd955d72eed525db37111f562ef2fcbf2a84db59936d716da52578d7da8318f79673d9993b86e6fecb363518056b6bac26c79a71bbad92a9dab5bc64db77527327457c97596ee844e7fe622ce597e32d4033dd4233dd6133dedc7e0d74f98f5b2447e2f95bbd7333dcfebb2d20bf6fbfe0c84266b797c86ff2b3a16157aa957fa45aff5466ff5aedf11c3f2de39af8f322fa45ffb798faffbfaa6ebbe66817ed3355dd757fa5adfe85bfdcef850bff59dbe77c6d5413fe847fda4dfeb0ffaa3fe14bd07aece722db28dde4ef86e0bf3e78fe9e8e764adbfe8af4aa36ead86cdca34abf4f6eff075c43fbd8724c9f537fdbdb8ea1ffaa7fea57febcc07588affed6ed3ca56a3f7beea637afd3a561f4733895c33d687fa888dd0589fe8537da6cff585be5ca92b6565accc95e5eddd3c7ded778d38d5ca5e39b6e1eec90f0b0ff68b2cae7170dc95bbf2567e3c535f56415f310a4e2cdeea57df6a5a7bfb73b2048fab701505b355bc4a56e92a5be5ed78555807166b6efa5ccb3afe248bc9b28265dee5ceed8565b4b755b9aa5697555dcd568d3e5ab5b1c7f7c23129dcddaaeb76abab395e752c5bbbe3f66e626ef955166f7533e3b261f9d270a5b1f178e335567efeafaf2afd9571311f57fa6ab55a6bb362b8daacb6abbbcbc76ad75767d2a05f79b0b67d0ecf64796372ec983c0adfc570cff7819ef85efea3d8cf6bdcbbdf76e87ff8cd6abf3aac8ead1d7cb84edffa7e9e679aa6b63b6627bfcae2af4eab7b9643ad570fcdfbea919fce727f3a052c4f69fca971795a3dafceab176db67ad5ebd5dbea7df5b1fa8cbff26ef595f615a31fbbddf98749f7c177bc0f9d57f6795b7daf06d17e35147b2cfbbdbccd9339ee7739b58bd5a8d72e173b9358e3acdf65b1ceab717d67ec5693d574355bcd51c3b7708ec1fdf3314c92af16abe55a5d2b6b439badcdb5b5b6d7ceda5d7bc69e45cffb1f7bdefb489eaffb32097a7b62b3105fc7e3fba9f9beea7e36627e6318266b7f1dacc3c0091cbecb91452c6431bd17f85d967e7473dbd8d7efeb681dab77e20c2d9745f9b16be9cff8b1f03198af933c5d5bc1789daeb375be2ed6e5ba5a5fd6b5b5b437741601fbf7fbd5b30fbe57a25f6bb15a16fc34ceba757416dfb3e83e9ce9d77ecd807df6ebceefd6cc62bc50c8d2eeb411f366bfd90bd7d26374b7beadb53573e4b2fee5fed5793f628aba5eaf37ebedfa6ebd5befd787f5717d5adfaf1fd68feba790c5fdd69eef5ac1b8b04fbf9ef76a7e704b3e584bbedb9f5950bffba8f7e2eb7e97fcb1df83b63eaf5f02d736cc28effa73246c8e1feb193f73d2e7373edfafe4b23c69bb7e5dbf35cafa7dfdc1e617c8f2f7f78ffdf38ff3283f69566595d196e7f5e7fa6bfdbd1eac87eb11d335bea38c568b980e4db0afbf8fa6c6acc7cffc04c6b2dfadd7cbe90f7a7bea77569a43967505d5e0a69a713e6171d79d36d1f3f5b8f776eb49bfa3b61f93cb389f38de7aba9eade7eabdd8d32b674be7afc8f2d3d9621ecf798f6a11dcaf179774bdcc5f36ea46d9181bb37faead164ebf368979c230a77db5439cb4602336661ab91436d3dc39174ba1fd0a2caa7f6511e4ae0f0b36569fdfacc6cce59f8ce3c6c9271b77e36dfc4d607da94f56f35b9bfed2b8fc7eb6381a2a9ee2da55972acd26dc449b78936cd24db6c9f9aa0bcb6eac27ffdbf68bbc782effdf76ae6549552488eee733a6f615fdba7dbb6356a899203e5a6db51f3b4444f0c14b1489987f9faa8202a4bd37b457331113b9d010943a661645669d93b6d9e37b5a6207f5ce54d90a7b630ee6244ed8f3c2d4532060d9afca32ad349d280e4d481246103617866ae8b10a11c3b2b36c86248e1fe983506f36cb7bd7f59cde1344592e9dd23decc91c0e90c0115250a0014d680104cf80a691efb672cf7c667bc1191af13a6a6c8d2ed758790ea8a041fba8a546ca6681e23a2c67047dffd9b4a1130fb9e20cbad0833e2ce34747a706bc2c0e85fef98baee722bfd4f4404187dc51957668dcd0c2d0b660004318c12b8c61025378f3347fb13bb0acbe5df0f8ab3a31cdd0e01d3ee0136ee036e9c2ddb1ed7437f7e95459c13d7169c0bcfd003fe0117eb2bb700a4ff08c94def1b9eef5e9337dca1557dfc052a8ea8aefae6ed98c216b9d45ef4ffa485524aebeeaa181333471eeaa5edbb7f71bff47100423b4421517519a70a1686ff7106f632dbe471b97ebe0a027b3a4874ec8a276354cdffc603e255ca59dee228325a4b8c2354b719e8d29bbca113774bcb961e319c8f15c1f6327bd3884873ca043ee1bdcda7dce35430f7d0c30740718e10e636fed2f7ddd7f0cc2861b3aa1161991827b3cecfa8d66ec6112bce2115354f693204dfadb96d559cd6ccab25f967cd21655d61b3627a2d61336b0892d72a03dc20e53978ef868d8fa229f5faee75a7fe935c07eb745b764495b08ec7d0311d5f514356ca3bffd70224ff774bfb3f1822818bb5ad8461d3bd8c5de6e837df6fe0507fb088787258ef015c7d68bd0fa1a7cc79ef3f0a8623d21573237714a0f6bb636061dba66de58d0211dac1b76bfe293ef6039b59ad281736c393795d713791dceebf80ee712f96e3009ddd07544a5d179e13613e6e4967d435ca3ec245389a0cad56bfd58aad7bf7aee9fc122ff178e852391e3f3ba9c7d9399eff23a234758aeb7d96b869def6fe7fb0f468e60216ac18678a2378b9890bd31a42ee18c42f1d27b720dcf09969c1fb0909d7904e76ec356026184f0baafc89d66956e3da5fecbf6f6f369d67545d6b5c5d924df135a7ec542cb5e26e49a7cbfc201afa191da8093df3604f79408ae9ab0ad576031ca9ca3caca1635c83935653d22cfb448ce3bcf6adc752c32e62a9eb9443352aa19aaaae7e288acea1ab4729f2cb50e052bf5d4871cf952b02732ae47d9db635ea9689b453c57bc2062244752ad5f5e84c592fcc3e1ee4c949995795bc152fdbea830d827ffc84c20e9088f91d2fb395e4b665b520152c3422492ebf27dce3a1163b10a2cc60916c11710bad85b6ed69a7320cdc09db863ceee0a1533e20c1ccef6c814cd995eb334f9fc9ecf4b7ebda988b5c23b67b1108e04dff03d63da7fc32f8b9a5f4caeec2fc7c9c7e6f5bc5e154b795ce2e596e3679fca7dd222b624e3bc58134fe3a1e0bbcd199677fcb81c4b3d6a7ea7d6aeb0fb7e71ceb9a3f5738b7cbeda2ba7de3ba79caf57e52fff15fb1fcbbfd3fefcfbaf3ffe0193cc32fd</data> + </image> +</images> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> |