diff options
Diffstat (limited to 'src/imageplugins/inserttext')
-rw-r--r-- | src/imageplugins/inserttext/Makefile.am | 34 | ||||
-rw-r--r-- | src/imageplugins/inserttext/digikamimageplugin_inserttext.desktop | 50 | ||||
-rw-r--r-- | src/imageplugins/inserttext/digikamimageplugin_inserttext_ui.rc | 20 | ||||
-rw-r--r-- | src/imageplugins/inserttext/fontchooserwidget.cpp | 738 | ||||
-rw-r--r-- | src/imageplugins/inserttext/fontchooserwidget.h | 172 | ||||
-rw-r--r-- | src/imageplugins/inserttext/imageeffect_inserttext.cpp | 348 | ||||
-rw-r--r-- | src/imageplugins/inserttext/imageeffect_inserttext.h | 103 | ||||
-rw-r--r-- | src/imageplugins/inserttext/imageplugin_inserttext.cpp | 70 | ||||
-rw-r--r-- | src/imageplugins/inserttext/imageplugin_inserttext.h | 56 | ||||
-rw-r--r-- | src/imageplugins/inserttext/inserttexttool.cpp | 336 | ||||
-rw-r--r-- | src/imageplugins/inserttext/inserttexttool.h | 111 | ||||
-rw-r--r-- | src/imageplugins/inserttext/inserttextwidget.cpp | 622 | ||||
-rw-r--r-- | src/imageplugins/inserttext/inserttextwidget.h | 156 |
13 files changed, 2816 insertions, 0 deletions
diff --git a/src/imageplugins/inserttext/Makefile.am b/src/imageplugins/inserttext/Makefile.am new file mode 100644 index 00000000..2753def7 --- /dev/null +++ b/src/imageplugins/inserttext/Makefile.am @@ -0,0 +1,34 @@ +METASOURCES = AUTO + +INCLUDES = -I$(top_srcdir)/src/utilities/imageeditor/editor \ + -I$(top_srcdir)/src/utilities/imageeditor/canvas \ + -I$(top_srcdir)/src/libs/histogram \ + -I$(top_srcdir)/src/libs/levels \ + -I$(top_srcdir)/src/libs/curves \ + -I$(top_srcdir)/src/libs/whitebalance \ + -I$(top_srcdir)/src/libs/widgets/common \ + -I$(top_srcdir)/src/libs/widgets/iccprofiles \ + -I$(top_srcdir)/src/libs/widgets/imageplugins \ + -I$(top_srcdir)/src/libs/dialogs \ + -I$(top_srcdir)/src/libs/dimg \ + -I$(top_srcdir)/src/libs/dmetadata \ + -I$(top_srcdir)/src/libs/dimg/filters \ + -I$(top_srcdir)/src/digikam \ + $(LIBKDCRAW_CFLAGS) \ + $(all_includes) + +digikamimageplugin_inserttext_la_SOURCES = imageplugin_inserttext.cpp inserttextwidget.cpp \ + inserttexttool.cpp fontchooserwidget.cpp + +digikamimageplugin_inserttext_la_LIBADD = $(LIB_TDEPARTS) \ + $(top_builddir)/src/digikam/libdigikam.la + +digikamimageplugin_inserttext_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) -ltdecore -ltdeui $(LIB_TQT) -ltdefx -lkdcraw -ltdeio + +kde_services_DATA = digikamimageplugin_inserttext.desktop + +kde_module_LTLIBRARIES = digikamimageplugin_inserttext.la + +rcdir = $(kde_datadir)/digikam +rc_DATA = digikamimageplugin_inserttext_ui.rc + diff --git a/src/imageplugins/inserttext/digikamimageplugin_inserttext.desktop b/src/imageplugins/inserttext/digikamimageplugin_inserttext.desktop new file mode 100644 index 00000000..e9ca6cfd --- /dev/null +++ b/src/imageplugins/inserttext/digikamimageplugin_inserttext.desktop @@ -0,0 +1,50 @@ +[Desktop Entry] +Name=ImagePlugin_InsertText +Name[bg]=Приставка за снимки - Добавяне на текст +Name[da]=Plugin til at indsætte tekst +Name[el]=ΠρόσθετοΕικόνας_ΕισαγωγήΚειμένου +Name[fi]=Tekstinlisäys +Name[hr]=Tekst +Name[it]=PluginImmagini_InserisciTesto +Name[nl]=Afbeeldingsplugin_TekstInvoegen +Name[sr]=Убаци текст +Name[sr@Latn]=Ubaci tekst +Name[sv]=Insticksprogram för infoga text +Name[tr]=ResimEklentisi_MetinEkle +Name[xx]=xxImagePlugin_InsertTextxx +Type=Service +X-TDE-ServiceTypes=Digikam/ImagePlugin +Encoding=UTF-8 +Comment=Insert text to image plugin for digiKam +Comment[bg]=Приставка на digiKam за добавяне на текст към снимки +Comment[ca]=Connector pel digiKam per inserir text en una imatge +Comment[da]=Digikam plugin til at indsætte tekst i billeder +Comment[de]=digiKam-Modul zum Einfügen von Text in ein Bild +Comment[el]=Πρόσθετο εισαγωγής κειμένου σε εικόνα για το digiKam +Comment[es]=Plugin de digiKampara insertar texto a una imagen +Comment[et]=DigiKami pildile teksti lisamise plugin +Comment[fa]=درج متن در وصلۀ تصویر برای digiKam +Comment[fi]=Lisää tekstiä kuvaan +Comment[gl]=Un plugin de digiKam para inserir texto na imaxe +Comment[hr]=digiKam dodatak za umetanje teksta +Comment[is]=Íforrit fyrir digiKam sem setur texta inn á mynd +Comment[it]=Plugin per l'aggiunta di testo nell'immagire per digiKam +Comment[ja]=digiKam テキスト挿入プラグイン +Comment[nds]=digiKam-Moduul för't Infögen vun Text in en Bild +Comment[nl]=Digikam-plugin voor het invoegen van tekst +Comment[pa]=ਡਿਜ਼ੀਕੈਮ ਲਈ ਚਿੱਤਰ ਉੱਤੇ ਪਾਠ ਲਿਖਣ ਲਈ ਪਲੱਗਇਨ +Comment[pl]=Wtyczka do programu digiKam dodająca tekst do zdjęcia +Comment[pt]=Um 'plugin' do digiKam para inserir texto na imagem +Comment[pt_BR]=Plugin de inserção de texto na imagem +Comment[ru]=Модуль digiKam наложения текста на изображения +Comment[sk]=digiKam plugin pre vkladanie textu do obrázku +Comment[sr]=digiKam-ов прикључак за убацивање текста у слику +Comment[sr@Latn]=digiKam-ov priključak za ubacivanje teksta u sliku +Comment[sv]=Digikam insticksprogram för att infoga text i bilder +Comment[tr]=digiKam için resme metin ekleme eklentisi +Comment[uk]=Втулок для вставляння тексту в зображення для digiKam +Comment[vi]=Phần bổ sung chèn chữ vào ảnh cho digiKam +Comment[xx]=xxInsert text to image plugin for digiKamxx + +X-TDE-Library=digikamimageplugin_inserttext +author=Gilles Caulier, caulier dot gilles at gmail dot com diff --git a/src/imageplugins/inserttext/digikamimageplugin_inserttext_ui.rc b/src/imageplugins/inserttext/digikamimageplugin_inserttext_ui.rc new file mode 100644 index 00000000..4fa71fcc --- /dev/null +++ b/src/imageplugins/inserttext/digikamimageplugin_inserttext_ui.rc @@ -0,0 +1,20 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui version="5" name="digikamimageplugin_inserttext" > + + <MenuBar> + + <Menu name="Decorate" ><text>&Decorate</text> + <Action name="imageplugin_inserttext" /> + </Menu> + + </MenuBar> + + <ToolBar name="ToolBar" > + <text>Main Toolbar</text> + </ToolBar> + + <ActionProperties> + <Action name="imageplugin_inserttext" /> + </ActionProperties> + +</kpartgui> diff --git a/src/imageplugins/inserttext/fontchooserwidget.cpp b/src/imageplugins/inserttext/fontchooserwidget.cpp new file mode 100644 index 00000000..aa76ea8e --- /dev/null +++ b/src/imageplugins/inserttext/fontchooserwidget.cpp @@ -0,0 +1,738 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-02-14 + * Description : a simple widget to choose a font based on + * KDE FontChooserWidget implementation. + * + * Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com> + * Copyright (C) 1999 by Preston Brown <[email protected]> + * Copyright (C) 1997 by Bernd Johannes Wuebben <[email protected]> + * + * 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, 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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqcheckbox.h> +#include <tqcombobox.h> +#include <tqfile.h> +#include <tqfont.h> +#include <tqfontdatabase.h> +#include <tqgroupbox.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqscrollbar.h> +#include <tqspinbox.h> +#include <tqstringlist.h> +#include <tqtooltip.h> +#include <tqwhatsthis.h> + +// KDE includes. + +#include <tdeapplication.h> +#include <kcharsets.h> +#include <tdeconfig.h> +#include <kdialog.h> +#include <tdeglobal.h> +#include <tdeglobalsettings.h> +#include <tdelistbox.h> +#include <tdelocale.h> +#include <knuminput.h> +#include <kstandarddirs.h> +#include <tqlineedit.h> + +// Local includes. + +#include "fontchooserwidget.h" +#include "fontchooserwidget.moc" + +namespace DigikamInsertTextImagesPlugin +{ + +class FontChooserWidget::FontChooserWidgetPrivate +{ +public: + + FontChooserWidgetPrivate() + { + m_palette.setColor(TQPalette::Active, TQColorGroup::Text, TQt::black); + m_palette.setColor(TQPalette::Active, TQColorGroup::Base, TQt::white); + } + + TQPalette m_palette; +}; + +FontChooserWidget::FontChooserWidget(TQWidget *parent, const char *name, + bool onlyFixed, const TQStringList &fontList, + int visibleListSize, bool diff, + TQButton::ToggleState *sizeIsRelativeState ) + : TQWidget(parent, name), usingFixed(onlyFixed) +{ + charsetsCombo = 0; + + TQString mainWhatsThisText = i18n( "Here you can choose the font to be used." ); + TQWhatsThis::add( this, mainWhatsThisText ); + + d = new FontChooserWidgetPrivate; + TQVBoxLayout *topLayout = new TQVBoxLayout( this, 0, KDialog::spacingHint() ); + int checkBoxGap = KDialog::spacingHint() / 2; + + int row = 0; + TQWidget *page = new TQWidget( this ); + topLayout->addWidget(page); + TQGridLayout *gridLayout = new TQGridLayout( page, 4, 3, 0, KDialog::spacingHint() ); + + // First, create the labels across the top + + TQHBoxLayout *familyLayout = new TQHBoxLayout(); + familyLayout->addSpacing( checkBoxGap ); + + if (diff) + { + familyCheckbox = new TQCheckBox(i18n("Font"), page); + + connect(familyCheckbox, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(toggled_checkbox())); + + familyLayout->addWidget(familyCheckbox, 0, TQt::AlignLeft); + TQString familyCBToolTipText = + i18n("Change font family?"); + TQString familyCBWhatsThisText = + i18n("Enable this checkbox to change the font family settings."); + TQWhatsThis::add( familyCheckbox, familyCBWhatsThisText ); + TQToolTip::add( familyCheckbox, familyCBToolTipText ); + familyLabel = 0; + } + else + { + familyCheckbox = 0; + familyLabel = new TQLabel( i18n("Font:"), page, "familyLabel" ); + familyLayout->addWidget(familyLabel, 1, TQt::AlignLeft); + } + + gridLayout->addLayout(familyLayout, row, 0 ); + + TQHBoxLayout *styleLayout = new TQHBoxLayout(); + + if (diff) + { + styleCheckbox = new TQCheckBox(i18n("Style:"), page); + + connect(styleCheckbox, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(toggled_checkbox())); + + styleLayout->addWidget(styleCheckbox, 0, TQt::AlignLeft); + TQString styleCBToolTipText = + i18n("Change font style?"); + TQString styleCBWhatsThisText = + i18n("Enable this checkbox to change the font style settings."); + TQWhatsThis::add( styleCheckbox, styleCBWhatsThisText ); + TQToolTip::add( styleCheckbox, styleCBToolTipText ); + styleLabel = 0; + } + else + { + styleCheckbox = 0; + styleLabel = new TQLabel( i18n("Style:"), page, "styleLabel"); + styleLayout->addWidget(styleLabel, 1, TQt::AlignLeft); + } + + styleLayout->addSpacing( checkBoxGap ); + gridLayout->addLayout(styleLayout, row, 1 ); + + TQHBoxLayout *sizeLayout = new TQHBoxLayout(); + + if (diff) + { + sizeCheckbox = new TQCheckBox(i18n("Size"),page); + + connect(sizeCheckbox, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(toggled_checkbox())); + + sizeLayout->addWidget(sizeCheckbox, 0, TQt::AlignLeft); + TQString sizeCBToolTipText = + i18n("Change font size?"); + TQString sizeCBWhatsThisText = + i18n("Enable this checkbox to change the font size settings."); + TQWhatsThis::add( sizeCheckbox, sizeCBWhatsThisText ); + TQToolTip::add( sizeCheckbox, sizeCBToolTipText ); + sizeLabel = 0; + } + else + { + sizeCheckbox = 0; + sizeLabel = new TQLabel( i18n("Size:"), page, "sizeLabel"); + sizeLayout->addWidget(sizeLabel, 1, TQt::AlignLeft); + } + + sizeLayout->addSpacing( checkBoxGap ); + sizeLayout->addSpacing( checkBoxGap ); // prevent label from eating border + gridLayout->addLayout(sizeLayout, row, 2 ); + + row ++; + + // Now create the actual boxes that hold the info + + familyListBox = new TDEListBox( page, "familyListBox"); + familyListBox->setEnabled( !diff ); + gridLayout->addWidget( familyListBox, row, 0 ); + TQString fontFamilyWhatsThisText = i18n("Here you can choose the font family to be used." ); + TQWhatsThis::add( familyListBox, fontFamilyWhatsThisText ); + TQWhatsThis::add(diff?(TQWidget *) familyCheckbox:(TQWidget *) familyLabel, fontFamilyWhatsThisText ); + + connect(familyListBox, TQ_SIGNAL(highlighted(const TQString &)), + this, TQ_SLOT(family_chosen_slot(const TQString &))); + + if(!fontList.isEmpty()) + { + familyListBox->insertStringList(fontList); + } + else + { + fillFamilyListBox(onlyFixed); + } + + familyListBox->setMinimumHeight( minimumListHeight( familyListBox, visibleListSize ) ); + + styleListBox = new TDEListBox( page, "styleListBox"); + styleListBox->setEnabled( !diff ); + gridLayout->addWidget(styleListBox, row, 1); + TQString fontStyleWhatsThisText = i18n("Here you can choose the font style to be used." ); + TQWhatsThis::add( styleListBox, fontStyleWhatsThisText ); + TQWhatsThis::add(diff?(TQWidget *)styleCheckbox:(TQWidget *)styleLabel, fontFamilyWhatsThisText ); + styleListBox->insertItem(i18n("Regular")); + styleListBox->insertItem(i18n("Italic")); + styleListBox->insertItem(i18n("Bold")); + styleListBox->insertItem(i18n("Bold Italic")); + styleListBox->setMinimumWidth( minimumListWidth( styleListBox ) ); + styleListBox->setMinimumHeight( minimumListHeight( styleListBox, visibleListSize ) ); + + connect(styleListBox, TQ_SIGNAL(highlighted(const TQString &)), + this, TQ_SLOT(style_chosen_slot(const TQString &))); + + sizeListBox = new TDEListBox( page, "sizeListBox"); + sizeOfFont = new KIntNumInput( page, "sizeOfFont"); + sizeOfFont->setMinValue(4); + + sizeListBox->setEnabled( !diff ); + sizeOfFont->setEnabled( !diff ); + + if( sizeIsRelativeState ) + { + TQString sizeIsRelativeCBText = + i18n("Relative"); + TQString sizeIsRelativeCBToolTipText = + i18n("Font size<br><i>fixed</i> or <i>relative</i><br>to environment"); + TQString sizeIsRelativeCBWhatsThisText = + i18n("Here you can switch between a fixed font size and a font size " + "to be calculated dynamically and adjusted to any changing " + "environment (e.g. widget dimensions, paper size)." ); + sizeIsRelativeCheckBox = new TQCheckBox( sizeIsRelativeCBText, + page, + "sizeIsRelativeCheckBox" ); + sizeIsRelativeCheckBox->setTristate( diff ); + TQGridLayout *sizeLayout2 = new TQGridLayout( 3,2, KDialog::spacingHint()/2, "sizeLayout2" ); + gridLayout->addLayout(sizeLayout2, row, 2); + sizeLayout2->setColStretch( 1, 1 ); // to prevent text from eating the right border + sizeLayout2->addMultiCellWidget( sizeOfFont, 0, 0, 0, 1); + sizeLayout2->addMultiCellWidget(sizeListBox, 1,1, 0,1); + sizeLayout2->addWidget(sizeIsRelativeCheckBox, 2, 0, TQt::AlignLeft); + TQWhatsThis::add( sizeIsRelativeCheckBox, sizeIsRelativeCBWhatsThisText ); + TQToolTip::add( sizeIsRelativeCheckBox, sizeIsRelativeCBToolTipText ); + } + else + { + sizeIsRelativeCheckBox = 0L; + TQGridLayout *sizeLayout2 = new TQGridLayout( 2,1, KDialog::spacingHint()/2, "sizeLayout2" ); + gridLayout->addLayout(sizeLayout2, row, 2); + sizeLayout2->addWidget( sizeOfFont, 0, 0); + sizeLayout2->addMultiCellWidget(sizeListBox, 1,1, 0,0); + } + + TQString fontSizeWhatsThisText = i18n("Here you can choose the font size to be used." ); + TQWhatsThis::add( sizeListBox, fontSizeWhatsThisText ); + TQWhatsThis::add( diff?(TQWidget *)sizeCheckbox:(TQWidget *)sizeLabel, fontSizeWhatsThisText ); + + fillSizeList(); + sizeListBox->setMinimumWidth( minimumListWidth(sizeListBox) + + sizeListBox->fontMetrics().maxWidth() ); + sizeListBox->setMinimumHeight( minimumListHeight( sizeListBox, visibleListSize ) ); + + connect( sizeOfFont, TQ_SIGNAL( valueChanged(int) ), + this, TQ_SLOT(size_value_slot(int))); + + connect( sizeListBox, TQ_SIGNAL(highlighted(const TQString&)), + this, TQ_SLOT(size_chosen_slot(const TQString&)) ); + + sizeListBox->setSelected(sizeListBox->findItem(TQString::number(10)), true); // default to 10pt. + + row ++; + + row ++; + + TQVBoxLayout *vbox; + page = new TQWidget( this ); + topLayout->addWidget(page); + vbox = new TQVBoxLayout( page, 0, KDialog::spacingHint() ); + TQLabel *label = new TQLabel( i18n("Actual Font"), page ); + vbox->addWidget( label ); + + xlfdEdit = new TQLineEdit( page, "xlfdEdit" ); + vbox->addWidget( xlfdEdit ); + + // lets initialize the display if possible + setFont( TDEGlobalSettings::generalFont(), usingFixed ); + + // check or uncheck or gray out the "relative" checkbox + if( sizeIsRelativeState && sizeIsRelativeCheckBox ) + setSizeIsRelative( *sizeIsRelativeState ); + + TDEConfig *config = TDEGlobal::config(); + TDEConfigGroupSaver saver(config, TQString::fromLatin1("General")); + showXLFDArea(config->readBoolEntry(TQString::fromLatin1("fontSelectorShowXLFD"), false)); +} + +FontChooserWidget::~FontChooserWidget() +{ + delete d; +} + +int FontChooserWidget::minimumListWidth( const TQListBox *list ) +{ + int w=0; + + for( uint i=0; i<list->count(); i++ ) + { + int itemWidth = list->item(i)->width(list); + w = TQMAX(w,itemWidth); + } + + if( w == 0 ) + { + w = 40; + } + + w += list->frameWidth() * 2; + w += list->verticalScrollBar()->sizeHint().width(); + return w; +} + +int FontChooserWidget::minimumListHeight( const TQListBox *list, int numVisibleEntry ) +{ + int w = list->count() > 0 ? list->item(0)->height(list) : + list->fontMetrics().lineSpacing(); + + if( w < 0 ) { w = 10; } + if( numVisibleEntry <= 0 ) { numVisibleEntry = 4; } + return ( w * numVisibleEntry + 2 * list->frameWidth() ); +} + +void FontChooserWidget::fillSizeList() +{ + if(! sizeListBox) return; //assertion. + + static const int c[] = + { + 4, 5, 6, 7, + 8, 9, 10, 11, + 12, 13, 14, 15, + 16, 17, 18, 19, + 20, 22, 24, 26, + 28, 32, 48, 64, + 72, 80, 94, 102, + 116, 128, 132, 148, + 156, 164, 172, 188, + 192, 202, 212, 224, + 232, 240, 248, 256, + 0 + }; + + for(int i = 0; c[i]; ++i) + { + sizeListBox->insertItem(TQString::number(c[i])); + } +} + +void FontChooserWidget::setColor( const TQColor & col ) +{ + d->m_palette.setColor( TQPalette::Active, TQColorGroup::Text, col ); +} + +TQColor FontChooserWidget::color() const +{ + return d->m_palette.color( TQPalette::Active, TQColorGroup::Text ); +} + +void FontChooserWidget::setBackgroundColor( const TQColor & col ) +{ + d->m_palette.setColor( TQPalette::Active, TQColorGroup::Base, col ); +} + +TQColor FontChooserWidget::backgroundColor() const +{ + return d->m_palette.color( TQPalette::Active, TQColorGroup::Base ); +} + +void FontChooserWidget::setSizeIsRelative( TQButton::ToggleState relative ) +{ + // check or uncheck or gray out the "relative" checkbox + if( sizeIsRelativeCheckBox ) + { + if( TQButton::NoChange == relative ) + sizeIsRelativeCheckBox->setNoChange(); + else + sizeIsRelativeCheckBox->setChecked( TQButton::On == relative ); + } +} + +TQButton::ToggleState FontChooserWidget::sizeIsRelative() const +{ + return sizeIsRelativeCheckBox + ? sizeIsRelativeCheckBox->state() + : TQButton::NoChange; +} + +TQSize FontChooserWidget::sizeHint( void ) const +{ + return minimumSizeHint(); +} + +void FontChooserWidget::enableColumn( int column, bool state ) +{ + if( column & FamilyList ) + { + familyListBox->setEnabled(state); + } + if( column & StyleList ) + { + styleListBox->setEnabled(state); + } + if( column & SizeList ) + { + sizeListBox->setEnabled(state); + } +} + +void FontChooserWidget::setFont( const TQFont& aFont, bool onlyFixed ) +{ + selFont = aFont; + selectedSize=aFont.pointSize(); + if (selectedSize == -1) + selectedSize = TQFontInfo(aFont).pointSize(); + + if( onlyFixed != usingFixed) + { + usingFixed = onlyFixed; + fillFamilyListBox(usingFixed); + } + setupDisplay(); + displaySample(selFont); +} + +int FontChooserWidget::fontDiffFlags() { + int diffFlags = 0; + if (familyCheckbox && styleCheckbox && sizeCheckbox) + { + diffFlags = (int)(familyCheckbox->isChecked() ? FontDiffFamily : 0) + | (int)( styleCheckbox->isChecked() ? FontDiffStyle : 0) + | (int)( sizeCheckbox->isChecked() ? FontDiffSize : 0); + } + return diffFlags; +} + +void FontChooserWidget::toggled_checkbox() +{ + familyListBox->setEnabled( familyCheckbox->isChecked() ); + styleListBox->setEnabled( styleCheckbox->isChecked() ); + sizeListBox->setEnabled( sizeCheckbox->isChecked() ); + sizeOfFont->setEnabled( sizeCheckbox->isChecked() ); +} + +void FontChooserWidget::family_chosen_slot(const TQString& family) +{ + TQFontDatabase dbase; + TQStringList styles = TQStringList(dbase.styles(family)); + styleListBox->clear(); + currentStyles.clear(); + TQStringList::Iterator end(styles.end()); + for ( TQStringList::Iterator it = styles.begin(); it != end; ++it ) + { + TQString style = *it; + int pos = style.find("Plain"); + if(pos >=0) style = style.replace(pos,5,i18n("Regular")); + pos = style.find("Normal"); + if(pos >=0) style = style.replace(pos,6,i18n("Regular")); + pos = style.find("Oblique"); + if(pos >=0) style = style.replace(pos,7,i18n("Italic")); + if(!styleListBox->findItem(style)) + { + styleListBox->insertItem(i18n(style.utf8())); + currentStyles.insert(i18n(style.utf8()), *it); + } + } + if(styleListBox->count()==0) + { + styleListBox->insertItem(i18n("Regular")); + currentStyles.insert(i18n("Regular"), "Normal"); + } + + styleListBox->blockSignals(true); + TQListBoxItem *item = styleListBox->findItem(selectedStyle); + if (item) + styleListBox->setSelected(styleListBox->findItem(selectedStyle), true); + else + styleListBox->setSelected(0, true); + styleListBox->blockSignals(false); + + style_chosen_slot(TQString()); +} + +void FontChooserWidget::size_chosen_slot(const TQString& size) +{ + selectedSize=size.toInt(); + sizeOfFont->setValue(selectedSize); + selFont.setPointSize(selectedSize); + emit fontSelected(selFont); +} + +void FontChooserWidget::size_value_slot(int val) +{ + selFont.setPointSize(val); + emit fontSelected(selFont); +} + +void FontChooserWidget::style_chosen_slot(const TQString& style) +{ + TQString currentStyle; + if (style.isEmpty()) + currentStyle = styleListBox->currentText(); + else + currentStyle = style; + + int diff=0; // the difference between the font size requested and what we can show. + + sizeListBox->clear(); + TQFontDatabase dbase; + if(dbase.isSmoothlyScalable(familyListBox->currentText(), currentStyles[currentStyle])) + { // is vector font + //sampleEdit->setPaletteBackgroundPixmap( VectorPixmap ); // TODO + fillSizeList(); + } + else + { // is bitmap font. + //sampleEdit->setPaletteBackgroundPixmap( BitmapPixmap ); // TODO + TQValueList<int> sizes = dbase.smoothSizes(familyListBox->currentText(), currentStyles[currentStyle]); + if(sizes.count() > 0) + { + TQValueList<int>::iterator it; + diff=1000; + TQValueList<int>::iterator end(sizes.end()); + for ( it = sizes.begin(); it != end; ++it ) + { + if(*it <= selectedSize || diff > *it - selectedSize) diff = selectedSize - *it; + sizeListBox->insertItem(TQString::number(*it)); + } + } + else // there are times TQT does not provide the list.. + fillSizeList(); + } + sizeListBox->blockSignals(true); + sizeListBox->setSelected(sizeListBox->findItem(TQString::number(selectedSize)), true); + sizeListBox->blockSignals(false); + sizeListBox->ensureCurrentVisible(); + + selFont = dbase.font(familyListBox->currentText(), currentStyles[currentStyle], selectedSize-diff); + emit fontSelected(selFont); + if (!style.isEmpty()) + selectedStyle = style; +} + +void FontChooserWidget::displaySample(const TQFont& font) +{ + xlfdEdit->setText(font.rawName()); + xlfdEdit->setCursorPosition(0); +} + +void FontChooserWidget::setupDisplay() +{ + // Calling familyListBox->setCurrentItem() causes the value of selFont + // to change, so we save the family, style and size beforehand. + TQString family = selFont.family().lower(); + int style = (selFont.bold() ? 2 : 0) + (selFont.italic() ? 1 : 0); + int size = selFont.pointSize(); + if (size == -1) + size = TQFontInfo(selFont).pointSize(); + TQString sizeStr = TQString::number(size); + + int numEntries, i; + + numEntries = familyListBox->count(); + for (i = 0; i < numEntries; i++) + { + if (family == familyListBox->text(i).lower()) + { + familyListBox->setCurrentItem(i); + break; + } + } + + // 1st Fallback + if ( (i == numEntries) ) + { + if (family.contains('[')) + { + family = family.left(family.find('[')).stripWhiteSpace(); + for (i = 0; i < numEntries; i++) + { + if (family == familyListBox->text(i).lower()) + { + familyListBox->setCurrentItem(i); + break; + } + } + } + } + + // 2nd Fallback + if ( (i == numEntries) ) + { + TQString fallback = family+" ["; + for (i = 0; i < numEntries; i++) + { + if (familyListBox->text(i).lower().startsWith(fallback)) + { + familyListBox->setCurrentItem(i); + break; + } + } + } + + // 3rd Fallback + if ( (i == numEntries) ) + { + for (i = 0; i < numEntries; i++) + { + if (familyListBox->text(i).lower().startsWith(family)) + { + familyListBox->setCurrentItem(i); + break; + } + } + } + + // Fall back in case nothing matched. Otherwise, diff doesn't work + if ( i == numEntries ) + familyListBox->setCurrentItem( 0 ); + + styleListBox->setCurrentItem(style); + + numEntries = sizeListBox->count(); + for (i = 0; i < numEntries; i++) + { + if (sizeStr == sizeListBox->text(i)) + { + sizeListBox->setCurrentItem(i); + break; + } + } + + sizeOfFont->setValue(size); +} + +void FontChooserWidget::getFontList( TQStringList &list, uint fontListCriteria) +{ + TQFontDatabase dbase; + TQStringList lstSys(dbase.families()); + + // if we have criteria; then check fonts before adding + if (fontListCriteria) + { + TQStringList lstFonts; + TQStringList::Iterator end(lstSys.end()); + for (TQStringList::Iterator it = lstSys.begin(); it != end; ++it) + { + if ((fontListCriteria & FixedWidthFonts) > 0 && !dbase.isFixedPitch(*it)) continue; + if (((fontListCriteria & (SmoothScalableFonts | ScalableFonts)) == ScalableFonts) && + !dbase.isBitmapScalable(*it)) continue; + if ((fontListCriteria & SmoothScalableFonts) > 0 && !dbase.isSmoothlyScalable(*it)) continue; + lstFonts.append(*it); + } + + if((fontListCriteria & FixedWidthFonts) > 0) { + // Fallback.. if there are no fixed fonts found, it is probably a + // bug in the font server or TQt. In this case, just use 'fixed' + if (lstFonts.count() == 0) + lstFonts.append("fixed"); + } + + lstSys = lstFonts; + } + + lstSys.sort(); + + list = lstSys; +} + +void FontChooserWidget::addFont( TQStringList &list, const char *xfont ) +{ + const char *ptr = strchr( xfont, '-' ); + if ( !ptr ) + return; + + ptr = strchr( ptr + 1, '-' ); + if ( !ptr ) + return; + + TQString font = TQString::fromLatin1(ptr + 1); + + int pos; + if ( ( pos = font.find( '-' ) ) > 0 ) { + font.truncate( pos ); + + if ( font.find( TQString::fromLatin1("open look"), 0, false ) >= 0 ) + return; + + TQStringList::Iterator it = list.begin(); + TQStringList::Iterator end(list.end()); + for ( ; it != end; ++it ) + if ( *it == font ) + return; + list.append( font ); + } +} + +void FontChooserWidget::fillFamilyListBox(bool onlyFixedFonts) +{ + TQStringList fontList; + getFontList(fontList, onlyFixedFonts?FixedWidthFonts:0); + familyListBox->clear(); + familyListBox->insertStringList(fontList); +} + +void FontChooserWidget::showXLFDArea(bool show) +{ + if( show ) + { + xlfdEdit->parentWidget()->show(); + } + else + { + xlfdEdit->parentWidget()->hide(); + } +} + +} // NameSpace DigikamInsertTextImagesPlugin + diff --git a/src/imageplugins/inserttext/fontchooserwidget.h b/src/imageplugins/inserttext/fontchooserwidget.h new file mode 100644 index 00000000..4585c231 --- /dev/null +++ b/src/imageplugins/inserttext/fontchooserwidget.h @@ -0,0 +1,172 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-02-14 + * Description : a simple widget to choose a font based on + * KDE FontChooserWidget implementation. + * + * Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com> + * Copyright (C) 1999 by Preston Brown <[email protected]> + * Copyright (C) 1997 by Bernd Johannes Wuebben <[email protected]> + * + * 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, 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. + * + * ============================================================ */ + +#ifndef FONT_CHOOSER_WIDGET_H +#define FONT_CHOOSER_WIDGET_H + +#include <tqlineedit.h> +#include <tqbutton.h> + +class TQComboBox; +class TQCheckBox; +class TQFont; +class TQGroupBox; +class TQLabel; +class TQStringList; + +class TDEListBox; +class KIntNumInput; + +namespace DigikamInsertTextImagesPlugin +{ + +class FontChooserWidget : public TQWidget +{ + TQ_OBJECT + + TQ_PROPERTY( TQFont font READ font WRITE setFont ) + +public: + + enum FontColumn + { + FamilyList=0x01, + StyleList=0x02, + SizeList=0x04 + }; + + enum FontDiff + { + FontDiffFamily=0x01, + FontDiffStyle=0x02, + FontDiffSize=0x04 + }; + + enum FontListCriteria + { + FixedWidthFonts=0x01, + ScalableFonts=0x02, + SmoothScalableFonts=0x04 + }; + +public: + + FontChooserWidget(TQWidget *parent = 0L, const char *name = 0L, + bool onlyFixed = false, + const TQStringList &fontList = TQStringList(), + int visibleListSize=8, + bool diff = false, + TQButton::ToggleState *sizeIsRelativeState = 0L ); + + ~FontChooserWidget(); + + void setFont( const TQFont &font, bool onlyFixed = false ); + void setColor( const TQColor & col ); + void setBackgroundColor( const TQColor & col ); + void setSizeIsRelative( TQButton::ToggleState relative ); + + TQFont font() const { return selFont; }; + TQColor color() const; + TQColor backgroundColor() const; + static void getFontList( TQStringList &list, uint fontListCriteria); + TQButton::ToggleState sizeIsRelative() const; + static TQString getXLFD( const TQFont &theFont ) { return theFont.rawName(); }; + + int fontDiffFlags(); + void enableColumn( int column, bool state ); + virtual TQSize sizeHint( void ) const; + +signals: + + void fontSelected( const TQFont &font ); + +private slots: + + void toggled_checkbox(); + void family_chosen_slot(const TQString&); + void size_chosen_slot(const TQString&); + void style_chosen_slot(const TQString&); + void displaySample(const TQFont &font); + void showXLFDArea(bool); + void size_value_slot(int); + +private: + + void fillFamilyListBox(bool onlyFixedFonts = false); + void fillSizeList(); + + void addFont( TQStringList &list, const char *xfont ); + + void setupDisplay(); + + int minimumListWidth( const TQListBox *list ); + int minimumListHeight( const TQListBox *list, int numVisibleEntry ); + +private: + + bool usingFixed; + int selectedSize; + + TQMap<TQString, TQString> currentStyles; + + // pointer to an optinally supplied list of fonts to + // inserted into the fontdialog font-family combo-box + TQStringList fontList; + + TQLineEdit *xlfdEdit; + + TQLabel *familyLabel; + TQLabel *styleLabel; + + TQCheckBox *familyCheckbox; + TQCheckBox *styleCheckbox; + TQCheckBox *sizeCheckbox; + TQCheckBox *sizeIsRelativeCheckBox; + + TQComboBox *charsetsCombo; + + TQFont selFont; + + TQString selectedStyle; + + TQLabel *sizeLabel; + + KIntNumInput *sizeOfFont; + + TDEListBox *familyListBox; + TDEListBox *styleListBox; + TDEListBox *sizeListBox; + +private: + + class FontChooserWidgetPrivate; + FontChooserWidgetPrivate *d; + +}; + +} // NameSpace DigikamInsertTextImagesPlugin + +#endif // FONT_CHOOSER_WIDGET_H diff --git a/src/imageplugins/inserttext/imageeffect_inserttext.cpp b/src/imageplugins/inserttext/imageeffect_inserttext.cpp new file mode 100644 index 00000000..3f88644b --- /dev/null +++ b/src/imageplugins/inserttext/imageeffect_inserttext.cpp @@ -0,0 +1,348 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-02-14 + * Description : a plugin to insert a text over an image. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * Copyright (C) 2006-2008 by Marcel Wiesweg <marcel dot wiesweg at gmx dot 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, 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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqvgroupbox.h> +#include <tqlabel.h> +#include <tqpushbutton.h> +#include <tqwhatsthis.h> +#include <tqlayout.h> +#include <tqframe.h> +#include <tqcombobox.h> +#include <tqcheckbox.h> +#include <tqpixmap.h> +#include <tqpainter.h> +#include <tqbrush.h> +#include <tqpen.h> +#include <tqfont.h> +#include <tqtimer.h> +#include <tqhbuttongroup.h> +#include <tqtooltip.h> + +// KDE includes. + +#include <tdelocale.h> +#include <kcursor.h> +#include <tdeaboutdata.h> +#include <khelpmenu.h> +#include <kiconloader.h> +#include <tdeapplication.h> +#include <tdepopupmenu.h> +#include <kstandarddirs.h> +#include <tdeconfig.h> +#include <kcolorbutton.h> +#include <ktextedit.h> + +// Local includes. + +#include "version.h" +#include "ddebug.h" +#include "dimg.h" +#include "imageiface.h" +#include "inserttextwidget.h" +#include "fontchooserwidget.h" +#include "imageeffect_inserttext.h" +#include "imageeffect_inserttext.moc" + +namespace DigikamInsertTextImagesPlugin +{ + +ImageEffect_InsertText::ImageEffect_InsertText(TQWidget* parent) + : Digikam::ImageDlgBase(parent, i18n("Insert Text on Photograph"), + "inserttext", false, false) +{ + TQString whatsThis; + + // About data and help button. + + TDEAboutData* about = new TDEAboutData("digikam", + I18N_NOOP("Insert Text"), + digikam_version, + I18N_NOOP("A digiKam image plugin for inserting text on a photograph."), + TDEAboutData::License_GPL, + "(c) 2005-2006, Gilles Caulier\n" + "(c) 2006-2007, Gilles Caulier and Marcel Wiesweg", + 0, + "http://www.digikam.org"); + + about->addAuthor("Gilles Caulier", I18N_NOOP("Author and maintainer"), + "caulier dot gilles at gmail dot com"); + + about->addAuthor("Marcel Wiesweg", I18N_NOOP("Developer"), + "marcel dot wiesweg at gmx dot de"); + + setAboutData(about); + + // ------------------------------------------------------------- + + TQFrame *frame = new TQFrame(plainPage()); + frame->setFrameStyle(TQFrame::Panel|TQFrame::Sunken); + TQVBoxLayout* l = new TQVBoxLayout(frame, 5, 0); + m_previewWidget = new InsertTextWidget(480, 320, frame); + l->addWidget(m_previewWidget); + TQWhatsThis::add( m_previewWidget, i18n("<p>This previews the text inserted in the image. " + "You can use the mouse to move the text to the right location.")); + setPreviewAreaWidget(frame); + + // ------------------------------------------------------------- + + TQWidget *gbox2 = new TQWidget(plainPage()); + TQGridLayout *gridBox2 = new TQGridLayout( gbox2, 9, 1, spacingHint()); + + m_textEdit = new KTextEdit(gbox2); + m_textEdit->setCheckSpellingEnabled(true); + m_textEdit->setWordWrap(TQTextEdit::NoWrap); + TQWhatsThis::add( m_textEdit, i18n("<p>Here, enter the text you want to insert in your image.")); + gridBox2->addMultiCellWidget(m_textEdit, 0, 2, 0, 1); + + // ------------------------------------------------------------- + + m_fontChooserWidget = new FontChooserWidget(gbox2); + TQWhatsThis::add( m_textEdit, i18n("<p>Here you can choose the font to be used.")); + gridBox2->addMultiCellWidget(m_fontChooserWidget, 3, 3, 0, 1); + + // ------------------------------------------------------------- + + TDEIconLoader icon; + m_alignButtonGroup = new TQHButtonGroup(gbox2); + + TQPushButton *alignLeft = new TQPushButton( m_alignButtonGroup ); + m_alignButtonGroup->insert(alignLeft, ALIGN_LEFT); + alignLeft->setPixmap( icon.loadIcon( "format-text-direction-ltr", (TDEIcon::Group)TDEIcon::Small ) ); + alignLeft->setToggleButton(true); + TQToolTip::add( alignLeft, i18n( "Align text to the left" ) ); + + TQPushButton *alignRight = new TQPushButton( m_alignButtonGroup ); + m_alignButtonGroup->insert(alignRight, ALIGN_RIGHT); + alignRight->setPixmap( icon.loadIcon( "format-text-direction-rtl", (TDEIcon::Group)TDEIcon::Small ) ); + alignRight->setToggleButton(true); + TQToolTip::add( alignRight, i18n( "Align text to the right" ) ); + + TQPushButton *alignCenter = new TQPushButton( m_alignButtonGroup ); + m_alignButtonGroup->insert(alignCenter, ALIGN_CENTER); + alignCenter->setPixmap( icon.loadIcon( "text_center", (TDEIcon::Group)TDEIcon::Small ) ); + alignCenter->setToggleButton(true); + TQToolTip::add( alignCenter, i18n( "Align text to center" ) ); + + TQPushButton *alignBlock = new TQPushButton( m_alignButtonGroup ); + m_alignButtonGroup->insert(alignBlock, ALIGN_BLOCK); + alignBlock->setPixmap( icon.loadIcon( "text_block", (TDEIcon::Group)TDEIcon::Small ) ); + alignBlock->setToggleButton(true); + TQToolTip::add( alignBlock, i18n( "Align text to a block" ) ); + + m_alignButtonGroup->setExclusive(true); + m_alignButtonGroup->setFrameShape(TQFrame::NoFrame); + gridBox2->addMultiCellWidget(m_alignButtonGroup, 4, 4, 0, 1); + + // ------------------------------------------------------------- + + TQLabel *label1 = new TQLabel(i18n("Rotation:"), gbox2); + m_textRotation = new TQComboBox( false, gbox2 ); + m_textRotation->insertItem( i18n("None") ); + m_textRotation->insertItem( i18n("90 Degrees") ); + m_textRotation->insertItem( i18n("180 Degrees") ); + m_textRotation->insertItem( i18n("270 Degrees") ); + TQWhatsThis::add( m_textRotation, i18n("<p>Select the text rotation to use.")); + gridBox2->addMultiCellWidget(label1, 5, 5, 0, 0); + gridBox2->addMultiCellWidget(m_textRotation, 5, 5, 1, 1); + + // ------------------------------------------------------------- + + TQLabel *label2 = new TQLabel(i18n("Color:"), gbox2); + m_fontColorButton = new KColorButton( TQt::black, gbox2 ); + TQWhatsThis::add( m_fontColorButton, i18n("<p>Select the font color to use.")); + gridBox2->addMultiCellWidget(label2, 6, 6, 0, 0); + gridBox2->addMultiCellWidget(m_fontColorButton, 6, 6, 1, 1); + + // ------------------------------------------------------------- + + m_borderText = new TQCheckBox( i18n( "Add border"), gbox2 ); + TQToolTip::add( m_borderText, i18n( "Add a solid border around text using current text color" ) ); + + m_transparentText = new TQCheckBox( i18n( "Semi-transparent"), gbox2 ); + TQToolTip::add( m_transparentText, i18n( "Use semi-transparent text background under image" ) ); + + gridBox2->addMultiCellWidget(m_borderText, 7, 7, 0, 1); + gridBox2->addMultiCellWidget(m_transparentText, 8, 8, 0, 1); + gridBox2->setRowStretch(9, 10); + + setUserAreaWidget(gbox2); + + // ------------------------------------------------------------- + + connect(m_fontChooserWidget, TQ_SIGNAL(fontSelected (const TQFont &)), + this, TQ_SLOT(slotFontPropertiesChanged(const TQFont &))); + + connect(m_fontColorButton, TQ_SIGNAL(changed(const TQColor &)), + this, TQ_SLOT(slotUpdatePreview())); + + connect(m_textEdit, TQ_SIGNAL(textChanged()), + this, TQ_SLOT(slotUpdatePreview())); + + connect(m_alignButtonGroup, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotAlignModeChanged(int))); + + connect(m_borderText, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotUpdatePreview())); + + connect(m_transparentText, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotUpdatePreview())); + + connect(m_textRotation, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotUpdatePreview())); + + connect(this, TQ_SIGNAL(signalUpdatePreview()), TQ_SLOT(slotUpdatePreview())); + // ------------------------------------------------------------- + + slotUpdatePreview(); +} + +ImageEffect_InsertText::~ImageEffect_InsertText() +{ +} + +void ImageEffect_InsertText::readUserSettings() +{ + TDEConfig *config = kapp->config(); + config->setGroup("inserttext Tool Dialog"); + TQColor black(0, 0, 0); + TQFont defaultFont; + + int orgW = m_previewWidget->imageIface()->originalWidth(); + int orgH = m_previewWidget->imageIface()->originalHeight(); + + if ( orgW > orgH ) m_defaultSizeFont = (int)(orgH / 8.0); + else m_defaultSizeFont = (int)(orgW / 8.0); + + defaultFont.setPointSize(m_defaultSizeFont); + m_textRotation->setCurrentItem( config->readNumEntry("Text Rotation", 0) ); + m_fontColorButton->setColor(config->readColorEntry("Font Color", &black)); + m_textEdit->setText(config->readEntry("Text String", i18n("Enter your text here!"))); + m_textFont = config->readFontEntry("Font Properties", &defaultFont); + m_fontChooserWidget->setFont(m_textFont); + m_alignTextMode = config->readNumEntry("Text Alignment", ALIGN_LEFT); + m_borderText->setChecked( config->readBoolEntry("Border Text", false) ); + m_transparentText->setChecked( config->readBoolEntry("Transparent Text", false) ); + m_previewWidget->setPositionHint( config->readRectEntry("Position Hint") ); + + static_cast<TQPushButton*>(m_alignButtonGroup->find(m_alignTextMode))->setOn(true); + slotAlignModeChanged(m_alignTextMode); +} + +void ImageEffect_InsertText::writeUserSettings() +{ + TDEConfig *config = kapp->config(); + config->setGroup("inserttext Tool Dialog"); + + config->writeEntry( "Text Rotation", m_textRotation->currentItem() ); + config->writeEntry( "Font Color", m_fontColorButton->color() ); + config->writeEntry( "Text String", m_textEdit->text() ); + config->writeEntry( "Font Properties", m_textFont ); + config->writeEntry( "Text Alignment", m_alignTextMode ); + config->writeEntry( "Border Text", m_borderText->isChecked() ); + config->writeEntry( "Transparent Text", m_transparentText->isChecked() ); + config->writeEntry( "Position Hint", m_previewWidget->getPositionHint() ); + + config->sync(); +} + +void ImageEffect_InsertText::resetValues() +{ + m_fontColorButton->blockSignals(true); + m_alignButtonGroup->blockSignals(true); + m_fontChooserWidget->blockSignals(true); + + m_textRotation->setCurrentItem(0); // No rotation. + m_fontColorButton->setColor(TQt::black); + TQFont defaultFont; + m_textFont = defaultFont; // Reset to default TDE font. + m_textFont.setPointSize( m_defaultSizeFont ); + m_fontChooserWidget->setFont(m_textFont); + m_borderText->setChecked( false ); + m_transparentText->setChecked( false ); + m_previewWidget->resetEdit(); + static_cast<TQPushButton*>(m_alignButtonGroup->find(ALIGN_LEFT))->setOn(true); + + m_fontChooserWidget->blockSignals(false); + m_fontColorButton->blockSignals(false); + m_alignButtonGroup->blockSignals(false); + slotAlignModeChanged(ALIGN_LEFT); +} + +void ImageEffect_InsertText::slotAlignModeChanged(int mode) +{ + m_alignTextMode = mode; + m_textEdit->selectAll(true); + + switch (m_alignTextMode) + { + case ALIGN_LEFT: + m_textEdit->setAlignment( TQt::AlignLeft ); + break; + + case ALIGN_RIGHT: + m_textEdit->setAlignment( TQt::AlignRight ); + break; + + case ALIGN_CENTER: + m_textEdit->setAlignment( TQt::AlignHCenter ); + break; + + case ALIGN_BLOCK: + m_textEdit->setAlignment( TQt::AlignJustify ); + break; + } + + m_textEdit->selectAll(false); + emit signalUpdatePreview(); +} + +void ImageEffect_InsertText::slotFontPropertiesChanged(const TQFont &font) +{ + m_textFont = font; + emit signalUpdatePreview(); +} + +void ImageEffect_InsertText::slotUpdatePreview() +{ + m_previewWidget->setText(m_textEdit->text(), m_textFont, m_fontColorButton->color(), m_alignTextMode, + m_borderText->isChecked(), m_transparentText->isChecked(), + m_textRotation->currentItem()); +} + +void ImageEffect_InsertText::finalRendering() +{ + accept(); + kapp->setOverrideCursor( KCursor::waitCursor() ); + + Digikam::ImageIface iface(0, 0); + Digikam::DImg dest = m_previewWidget->makeInsertText(); + iface.putOriginalImage(i18n("Insert Text"), dest.bits(), dest.width(), dest.height()); + + kapp->restoreOverrideCursor(); +} + +} // NameSpace DigikamInsertTextImagesPlugin + diff --git a/src/imageplugins/inserttext/imageeffect_inserttext.h b/src/imageplugins/inserttext/imageeffect_inserttext.h new file mode 100644 index 00000000..2b7c204c --- /dev/null +++ b/src/imageplugins/inserttext/imageeffect_inserttext.h @@ -0,0 +1,103 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-02-14 + * Description : a plugin to insert a text over an image. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot 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, 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. + * + * ============================================================ */ + +#ifndef IMAGEEFFECT_INSERTEXT_H +#define IMAGEEFFECT_INSERTEXT_H + +// TQt includes. + +#include <tqcolor.h> +#include <tqimage.h> + +// Digikam includes. + +#include "imagedlgbase.h" + +class TQLabel; +class TQFont; +class TQHButtonGroup; +class TQComboBox; +class TQCheckBox; + +class KTextEdit; +class KColorButton; + +namespace DigikamInsertTextImagesPlugin +{ + +class InsertTextWidget; +class FontChooserWidget; + +class ImageEffect_InsertText : public Digikam::ImageDlgBase +{ + TQ_OBJECT + + +public: + + ImageEffect_InsertText(TQWidget *parent); + ~ImageEffect_InsertText(); + +signals: + + void signalUpdatePreview(); + +private slots: + + void slotFontPropertiesChanged(const TQFont &font); + void slotUpdatePreview(); + void slotAlignModeChanged(int mode); + +private: + + void readUserSettings(); + void writeUserSettings(); + void resetValues(); + void finalRendering(); + +private: + + int m_alignTextMode; + int m_defaultSizeFont; + + TQComboBox *m_textRotation; + + TQCheckBox *m_borderText; + TQCheckBox *m_transparentText; + + TQHButtonGroup *m_alignButtonGroup; + + TQFont m_textFont; + + KColorButton *m_fontColorButton; + + FontChooserWidget *m_fontChooserWidget; + + KTextEdit *m_textEdit; + + InsertTextWidget *m_previewWidget; +}; + +} // NameSpace DigikamInsertTextImagesPlugin + +#endif /* IMAGEEFFECT_INSERTEXT_H */ diff --git a/src/imageplugins/inserttext/imageplugin_inserttext.cpp b/src/imageplugins/inserttext/imageplugin_inserttext.cpp new file mode 100644 index 00000000..a7a5ab6b --- /dev/null +++ b/src/imageplugins/inserttext/imageplugin_inserttext.cpp @@ -0,0 +1,70 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-02-14 + * Description : a plugin to insert a text over an image. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot 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, 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. + * + * ============================================================ */ + +// KDE includes. + +#include <tdelocale.h> +#include <kgenericfactory.h> +#include <klibloader.h> +#include <tdeaction.h> +#include <kcursor.h> + +// Local includes. + +#include "ddebug.h" +#include "inserttexttool.h" +#include "imageplugin_inserttext.h" +#include "imageplugin_inserttext.moc" + +using namespace DigikamInsertTextImagesPlugin; + +K_EXPORT_COMPONENT_FACTORY(digikamimageplugin_inserttext, + KGenericFactory<ImagePlugin_InsertText>("digikamimageplugin_inserttext")); + +ImagePlugin_InsertText::ImagePlugin_InsertText(TQObject *parent, const char*, const TQStringList &) + : Digikam::ImagePlugin(parent, "ImagePlugin_InsertText") +{ + m_insertTextAction = new TDEAction(i18n("Insert Text..."), "inserttext", + SHIFT+CTRL+Key_T, + this, TQ_SLOT(slotInsertText()), + actionCollection(), "imageplugin_inserttext"); + + setXMLFile("digikamimageplugin_inserttext_ui.rc"); + + DDebug() << "ImagePlugin_InsertText plugin loaded" << endl; +} + +ImagePlugin_InsertText::~ImagePlugin_InsertText() +{ +} + +void ImagePlugin_InsertText::setEnabledActions(bool enable) +{ + m_insertTextAction->setEnabled(enable); +} + +void ImagePlugin_InsertText::slotInsertText() +{ + InsertTextTool *tool = new InsertTextTool(this); + loadTool(tool); +} diff --git a/src/imageplugins/inserttext/imageplugin_inserttext.h b/src/imageplugins/inserttext/imageplugin_inserttext.h new file mode 100644 index 00000000..427b47c6 --- /dev/null +++ b/src/imageplugins/inserttext/imageplugin_inserttext.h @@ -0,0 +1,56 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-02-14 + * Description : a plugin to insert a text over an image. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot 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, 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. + * + * ============================================================ */ + +#ifndef IMAGEPLUGIN_INSERTTEXT_H +#define IMAGEPLUGIN_INSERTTEXT_H + +// Digikam includes. + +#include "imageplugin.h" +#include "digikam_export.h" + +class TDEAction; + +class DIGIKAMIMAGEPLUGINS_EXPORT ImagePlugin_InsertText : public Digikam::ImagePlugin +{ + TQ_OBJECT + + +public: + + ImagePlugin_InsertText(TQObject *parent, const char* name, + const TQStringList &args); + ~ImagePlugin_InsertText(); + + void setEnabledActions(bool enable); + +private slots: + + void slotInsertText(); + +private: + + TDEAction *m_insertTextAction; +}; + +#endif /* IMAGEPLUGIN_INSERTTEXT_H */ diff --git a/src/imageplugins/inserttext/inserttexttool.cpp b/src/imageplugins/inserttext/inserttexttool.cpp new file mode 100644 index 00000000..3c854896 --- /dev/null +++ b/src/imageplugins/inserttext/inserttexttool.cpp @@ -0,0 +1,336 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-02-14 + * Description : a plugin to insert a text over an image. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * Copyright (C) 2006-2008 by Marcel Wiesweg <marcel dot wiesweg at gmx dot 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, 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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqbrush.h> +#include <tqcheckbox.h> +#include <tqcombobox.h> +#include <tqframe.h> +#include <tqhbuttongroup.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqpainter.h> +#include <tqpen.h> +#include <tqpixmap.h> +#include <tqpushbutton.h> +#include <tqtimer.h> +#include <tqtooltip.h> +#include <tqvgroupbox.h> +#include <tqwhatsthis.h> + +// KDE includes. + +#include <tdeaboutdata.h> +#include <tdeapplication.h> +#include <kcolorbutton.h> +#include <tdeconfig.h> +#include <kcursor.h> +#include <khelpmenu.h> +#include <kiconloader.h> +#include <tdelocale.h> +#include <tdepopupmenu.h> +#include <kstandarddirs.h> +#include <ktextedit.h> + +// Local includes. + +#include "daboutdata.h" +#include "ddebug.h" +#include "dimg.h" +#include "editortoolsettings.h" +#include "fontchooserwidget.h" +#include "imageiface.h" +#include "inserttextwidget.h" +#include "inserttexttool.h" +#include "inserttexttool.moc" + +using namespace Digikam; + +namespace DigikamInsertTextImagesPlugin +{ + +InsertTextTool::InsertTextTool(TQObject* parent) + : EditorTool(parent) +{ + setName("inserttext"); + setToolName(i18n("Insert Text")); + setToolIcon(SmallIcon("inserttext")); + + // ------------------------------------------------------------- + + TQFrame *frame = new TQFrame(0); + frame->setFrameStyle(TQFrame::Panel|TQFrame::Sunken); + TQVBoxLayout* l = new TQVBoxLayout(frame, 5, 0); + m_previewWidget = new InsertTextWidget(480, 320, frame); + l->addWidget(m_previewWidget); + TQWhatsThis::add(m_previewWidget, i18n("<p>This previews the text inserted in the image. " + "You can use the mouse to move the text to the right location.")); + setToolView(frame); + + // ------------------------------------------------------------- + + m_gboxSettings = new EditorToolSettings(EditorToolSettings::Default| + EditorToolSettings::Ok| + EditorToolSettings::Cancel); + TQGridLayout *grid = new TQGridLayout(m_gboxSettings->plainPage(), 9, 1); + + m_textEdit = new KTextEdit(m_gboxSettings->plainPage()); + m_textEdit->setCheckSpellingEnabled(true); + m_textEdit->setWordWrap(TQTextEdit::NoWrap); + TQWhatsThis::add(m_textEdit, i18n("<p>Here, enter the text you want to insert in your image.")); + + // ------------------------------------------------------------- + + m_fontChooserWidget = new FontChooserWidget(m_gboxSettings->plainPage()); + TQWhatsThis::add( m_textEdit, i18n("<p>Here you can choose the font to be used.")); + + // ------------------------------------------------------------- + + TDEIconLoader icon; + m_alignButtonGroup = new TQHButtonGroup(m_gboxSettings->plainPage()); + + TQPushButton *alignLeft = new TQPushButton(m_alignButtonGroup); + m_alignButtonGroup->insert(alignLeft, ALIGN_LEFT); + alignLeft->setPixmap(icon.loadIcon("format-text-direction-ltr", (TDEIcon::Group) TDEIcon::Small)); + alignLeft->setToggleButton(true); + TQToolTip::add(alignLeft, i18n("Align text to the left")); + + TQPushButton *alignRight = new TQPushButton(m_alignButtonGroup); + m_alignButtonGroup->insert(alignRight, ALIGN_RIGHT); + alignRight->setPixmap(icon.loadIcon("format-text-direction-rtl", (TDEIcon::Group) TDEIcon::Small)); + alignRight->setToggleButton(true); + TQToolTip::add(alignRight, i18n("Align text to the right")); + + TQPushButton *alignCenter = new TQPushButton(m_alignButtonGroup); + m_alignButtonGroup->insert(alignCenter, ALIGN_CENTER); + alignCenter->setPixmap(icon.loadIcon("text_center", (TDEIcon::Group) TDEIcon::Small)); + alignCenter->setToggleButton(true); + TQToolTip::add(alignCenter, i18n("Align text to center")); + + TQPushButton *alignBlock = new TQPushButton(m_alignButtonGroup); + m_alignButtonGroup->insert(alignBlock, ALIGN_BLOCK); + alignBlock->setPixmap(icon.loadIcon("text_block", (TDEIcon::Group) TDEIcon::Small)); + alignBlock->setToggleButton(true); + TQToolTip::add(alignBlock, i18n("Align text to a block")); + + m_alignButtonGroup->setExclusive(true); + m_alignButtonGroup->setFrameShape(TQFrame::NoFrame); + + // ------------------------------------------------------------- + + TQLabel *label1 = new TQLabel(i18n("Rotation:"), m_gboxSettings->plainPage()); + m_textRotation = new TQComboBox(false, m_gboxSettings->plainPage()); + m_textRotation->insertItem(i18n("None")); + m_textRotation->insertItem(i18n("90 Degrees")); + m_textRotation->insertItem(i18n("180 Degrees")); + m_textRotation->insertItem(i18n("270 Degrees")); + TQWhatsThis::add( m_textRotation, i18n("<p>Select the text rotation to use.")); + + // ------------------------------------------------------------- + + TQLabel *label2 = new TQLabel(i18n("Color:"), m_gboxSettings->plainPage()); + m_fontColorButton = new KColorButton( TQt::black, m_gboxSettings->plainPage() ); + TQWhatsThis::add( m_fontColorButton, i18n("<p>Select the font color to use.")); + + // ------------------------------------------------------------- + + m_borderText = new TQCheckBox(i18n("Add border"), m_gboxSettings->plainPage()); + TQToolTip::add(m_borderText, i18n("Add a solid border around text using current text color")); + + m_transparentText = new TQCheckBox(i18n("Semi-transparent"), m_gboxSettings->plainPage()); + TQToolTip::add(m_transparentText, i18n("Use semi-transparent text background under image")); + + grid->addMultiCellWidget(m_textEdit, 0, 2, 0, 1); + grid->addMultiCellWidget(m_fontChooserWidget, 3, 3, 0, 1); + grid->addMultiCellWidget(m_alignButtonGroup, 4, 4, 0, 1); + grid->addMultiCellWidget(label1, 5, 5, 0, 0); + grid->addMultiCellWidget(m_textRotation, 5, 5, 1, 1); + grid->addMultiCellWidget(label2, 6, 6, 0, 0); + grid->addMultiCellWidget(m_fontColorButton, 6, 6, 1, 1); + grid->addMultiCellWidget(m_borderText, 7, 7, 0, 1); + grid->addMultiCellWidget(m_transparentText, 8, 8, 0, 1); + grid->setMargin(0); + grid->setSpacing(m_gboxSettings->spacingHint()); + grid->setRowStretch(9, 10); + + setToolSettings(m_gboxSettings); + init(); + + // ------------------------------------------------------------- + + connect(m_fontChooserWidget, TQ_SIGNAL(fontSelected (const TQFont&)), + this, TQ_SLOT(slotFontPropertiesChanged(const TQFont&))); + + connect(m_fontColorButton, TQ_SIGNAL(changed(const TQColor&)), + this, TQ_SLOT(slotUpdatePreview())); + + connect(m_textEdit, TQ_SIGNAL(textChanged()), + this, TQ_SLOT(slotUpdatePreview())); + + connect(m_alignButtonGroup, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotAlignModeChanged(int))); + + connect(m_borderText, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotUpdatePreview())); + + connect(m_transparentText, TQ_SIGNAL(toggled(bool)), + this, TQ_SLOT(slotUpdatePreview())); + + connect(m_textRotation, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotUpdatePreview())); + + connect(this, TQ_SIGNAL(signalUpdatePreview()), + this, TQ_SLOT(slotUpdatePreview())); + + // ------------------------------------------------------------- + + slotUpdatePreview(); +} + +InsertTextTool::~InsertTextTool() +{ +} + +void InsertTextTool::readSettings() +{ + TDEConfig *config = kapp->config(); + config->setGroup("inserttext Tool"); + TQColor black(0, 0, 0); + TQFont defaultFont; + + int orgW = m_previewWidget->imageIface()->originalWidth(); + int orgH = m_previewWidget->imageIface()->originalHeight(); + + if (orgW > orgH) m_defaultSizeFont = (int)(orgH / 8.0); + else m_defaultSizeFont = (int)(orgW / 8.0); + + defaultFont.setPointSize(m_defaultSizeFont); + m_textRotation->setCurrentItem(config->readNumEntry("Text Rotation", 0)); + m_fontColorButton->setColor(config->readColorEntry("Font Color", &black)); + m_textEdit->setText(config->readEntry("Text String", i18n("Enter your text here!"))); + m_textFont = config->readFontEntry("Font Properties", &defaultFont); + m_fontChooserWidget->setFont(m_textFont); + m_alignTextMode = config->readNumEntry("Text Alignment", ALIGN_LEFT); + m_borderText->setChecked(config->readBoolEntry("Border Text", false)); + m_transparentText->setChecked(config->readBoolEntry("Transparent Text", false)); + m_previewWidget->setPositionHint(config->readRectEntry("Position Hint")); + + static_cast<TQPushButton*>(m_alignButtonGroup->find(m_alignTextMode))->setOn(true); + slotAlignModeChanged(m_alignTextMode); +} + +void InsertTextTool::writeSettings() +{ + TDEConfig *config = kapp->config(); + config->setGroup("inserttext Tool"); + + config->writeEntry("Text Rotation", m_textRotation->currentItem()); + config->writeEntry("Font Color", m_fontColorButton->color()); + config->writeEntry("Text String", m_textEdit->text()); + config->writeEntry("Font Properties", m_textFont); + config->writeEntry("Text Alignment", m_alignTextMode); + config->writeEntry("Border Text", m_borderText->isChecked()); + config->writeEntry("Transparent Text", m_transparentText->isChecked()); + config->writeEntry("Position Hint", m_previewWidget->getPositionHint()); + + config->sync(); +} + +void InsertTextTool::slotResetSettings() +{ + m_fontColorButton->blockSignals(true); + m_alignButtonGroup->blockSignals(true); + m_fontChooserWidget->blockSignals(true); + + m_textRotation->setCurrentItem(0); // No rotation. + m_fontColorButton->setColor(TQt::black); + TQFont defaultFont; + m_textFont = defaultFont; // Reset to default TDE font. + m_textFont.setPointSize(m_defaultSizeFont); + m_fontChooserWidget->setFont(m_textFont); + m_borderText->setChecked(false); + m_transparentText->setChecked(false); + m_previewWidget->resetEdit(); + static_cast<TQPushButton*> (m_alignButtonGroup->find(ALIGN_LEFT))->setOn(true); + + m_fontChooserWidget->blockSignals(false); + m_fontColorButton->blockSignals(false); + m_alignButtonGroup->blockSignals(false); + slotAlignModeChanged(ALIGN_LEFT); +} + +void InsertTextTool::slotAlignModeChanged(int mode) +{ + m_alignTextMode = mode; + m_textEdit->selectAll(true); + + switch (m_alignTextMode) + { + case ALIGN_LEFT: + m_textEdit->setAlignment( TQt::AlignLeft ); + break; + + case ALIGN_RIGHT: + m_textEdit->setAlignment( TQt::AlignRight ); + break; + + case ALIGN_CENTER: + m_textEdit->setAlignment( TQt::AlignHCenter ); + break; + + case ALIGN_BLOCK: + m_textEdit->setAlignment( TQt::AlignJustify ); + break; + } + + m_textEdit->selectAll(false); + emit signalUpdatePreview(); +} + +void InsertTextTool::slotFontPropertiesChanged(const TQFont& font) +{ + m_textFont = font; + emit signalUpdatePreview(); +} + +void InsertTextTool::slotUpdatePreview() +{ + m_previewWidget->setText(m_textEdit->text(), m_textFont, m_fontColorButton->color(), m_alignTextMode, + m_borderText->isChecked(), m_transparentText->isChecked(), + m_textRotation->currentItem()); +} + +void InsertTextTool::finalRendering() +{ + kapp->setOverrideCursor(KCursor::waitCursor()); + + ImageIface iface(0, 0); + DImg dest = m_previewWidget->makeInsertText(); + iface.putOriginalImage(i18n("Insert Text"), dest.bits(), dest.width(), dest.height()); + + kapp->restoreOverrideCursor(); +} + +} // NameSpace DigikamInsertTextImagesPlugin diff --git a/src/imageplugins/inserttext/inserttexttool.h b/src/imageplugins/inserttext/inserttexttool.h new file mode 100644 index 00000000..c148aa60 --- /dev/null +++ b/src/imageplugins/inserttext/inserttexttool.h @@ -0,0 +1,111 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-02-14 + * Description : a plugin to insert a text over an image. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot 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, 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. + * + * ============================================================ */ + +#ifndef INSERTEXTTOOL_H +#define INSERTEXTTOOL_H + +// TQt includes. + +#include <tqfont.h> +#include <tqcolor.h> +#include <tqimage.h> + +// Digikam includes. + +#include "editortool.h" + +class TQLabel; +class TQFont; +class TQHButtonGroup; +class TQComboBox; +class TQCheckBox; + +class KTextEdit; +class KColorButton; + +namespace Digikam +{ +class EditorToolSettings; +} + +namespace DigikamInsertTextImagesPlugin +{ + +class InsertTextWidget; +class FontChooserWidget; + +class InsertTextTool : public Digikam::EditorTool +{ + TQ_OBJECT + + +public: + + InsertTextTool(TQObject *parent); + ~InsertTextTool(); + +signals: + + void signalUpdatePreview(); + +private slots: + + void slotFontPropertiesChanged(const TQFont& font); + void slotUpdatePreview(); + void slotAlignModeChanged(int mode); + void slotResetSettings(); + +private: + + void readSettings(); + void writeSettings(); + void finalRendering(); + +private: + + int m_alignTextMode; + int m_defaultSizeFont; + + TQComboBox *m_textRotation; + + TQCheckBox *m_borderText; + TQCheckBox *m_transparentText; + + TQHButtonGroup *m_alignButtonGroup; + + TQFont m_textFont; + + KColorButton *m_fontColorButton; + + KTextEdit *m_textEdit; + + Digikam::EditorToolSettings *m_gboxSettings; + + FontChooserWidget *m_fontChooserWidget; + + InsertTextWidget *m_previewWidget; +}; + +} // NameSpace DigikamInsertTextImagesPlugin + +#endif /* INSERTEXTTOOL_H */ diff --git a/src/imageplugins/inserttext/inserttextwidget.cpp b/src/imageplugins/inserttext/inserttextwidget.cpp new file mode 100644 index 00000000..dc5b65f4 --- /dev/null +++ b/src/imageplugins/inserttext/inserttextwidget.cpp @@ -0,0 +1,622 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-02-14 + * Description : a widget to insert a text over an image. + * + * Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com> + * Copyright (C) 2006-2007 by Marcel Wiesweg <marcel dot wiesweg at gmx dot 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, 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. + * + * ============================================================ */ + +// C++ includes. + +#include <cstdio> +#include <cmath> + +// TQt includes. + +#include <tqpainter.h> +#include <tqfont.h> +#include <tqfontmetrics.h> + +// KDE includes. + +#include <kstandarddirs.h> +#include <kcursor.h> +#include <tdeglobal.h> + +// Digikam includes. + +#include "imageiface.h" + +// Local includes. + +#include "inserttextwidget.h" +#include "inserttextwidget.moc" + +namespace DigikamInsertTextImagesPlugin +{ + +InsertTextWidget::InsertTextWidget(int w, int h, TQWidget *parent) + : TQWidget(parent, 0, TQt::WDestructiveClose) +{ + m_currentMoving = false; + + m_iface = new Digikam::ImageIface(w, h); + m_data = m_iface->getPreviewImage(); + m_w = m_iface->previewWidth(); + m_h = m_iface->previewHeight(); + m_pixmap = new TQPixmap(w, h); + m_pixmap->fill(colorGroup().background()); + + setBackgroundMode(TQt::NoBackground); + setMinimumSize(w, h); + setMouseTracking(true); + + m_rect = TQRect(width()/2-m_w/2, height()/2-m_h/2, m_w, m_h); + m_textRect = TQRect(); + + m_backgroundColor = TQColor(0xCC, 0xCC, 0xCC); + m_transparency = 210; +} + +InsertTextWidget::~InsertTextWidget() +{ + delete [] m_data; + delete m_iface; + delete m_pixmap; +} + +Digikam::ImageIface* InsertTextWidget::imageIface() +{ + return m_iface; +} + +void InsertTextWidget::resetEdit() +{ + // signal this needs to be filled by makePixmap + m_textRect = TQRect(); + makePixmap(); + repaint(false); +} + +void InsertTextWidget::setText(TQString text, TQFont font, TQColor color, int alignMode, + bool border, bool transparent, int rotation) +{ + m_textString = text; + m_textColor = color; + m_textBorder = border; + m_textTransparent = transparent; + m_textRotation = rotation; + + switch (alignMode) + { + case ALIGN_LEFT: + m_alignMode = TQt::AlignLeft; + break; + + case ALIGN_RIGHT: + m_alignMode = TQt::AlignRight; + break; + + case ALIGN_CENTER: + m_alignMode = TQt::AlignHCenter; + break; + + case ALIGN_BLOCK: + m_alignMode = TQt::AlignJustify; + break; + } + + // Center text if top left corner text area is not visible. + + /* + if ( m_textFont.pointSize() != font.pointSize() && + !rect().contains( m_textRect.x(), m_textRect.y() ) ) + { + m_textFont = font; + resetEdit(); + return; + } + */ + + m_textFont = font; + + makePixmap(); + repaint(false); +} + +void InsertTextWidget::setPositionHint(TQRect hint) +{ + // interpreted by composeImage + m_positionHint = hint; + if (m_textRect.isValid()) + { + // invalidate current position so that hint is certainly interpreted + m_textRect = TQRect(); + makePixmap(); + repaint(); + } +} + +TQRect InsertTextWidget::getPositionHint() +{ + TQRect hint; + if (m_textRect.isValid()) + { + // We normalize on the size of the image, but we store as int. Precision loss is no problem. + hint.setX( (int) ((float)(m_textRect.x() - m_rect.x()) / (float)m_rect.width() * 10000.0) ); + hint.setY( (int) ((float)(m_textRect.y() - m_rect.y()) / (float)m_rect.height() * 10000.0) ); + hint.setWidth( (int) ((float)m_textRect.width() / (float)m_rect.width() * 10000.0) ); + hint.setHeight( (int) ((float)m_textRect.height() / (float)m_rect.height() * 10000.0) ); + } + return hint; +} + +Digikam::DImg InsertTextWidget::makeInsertText(void) +{ + int orgW = m_iface->originalWidth(); + int orgH = m_iface->originalHeight(); + float ratioW = (float)orgW/(float)m_w; + float ratioH = (float)orgH/(float)m_h; + + int x, y; + if (m_textRect.isValid()) + { + // convert from widget to image coordinates, then to original size + x = lroundf( (m_textRect.x() - m_rect.x()) * ratioW); + y = lroundf( (m_textRect.y() - m_rect.y()) * ratioH); + } + else + { + x = -1; + y = -1; + } + + // Get original image + Digikam::DImg image = m_iface->getOriginalImg()->copy(); + + int borderWidth = TQMAX(1, lroundf(ratioW)); + // compose and draw result on image + composeImage(&image, 0, x, y, + m_textFont, m_textFont.pointSizeFloat(), + m_textRotation, m_textColor, m_alignMode, m_textString, + m_textTransparent, m_backgroundColor, + m_textBorder ? BORDER_NORMAL : BORDER_NONE, borderWidth, borderWidth); + + return image; +} + +void InsertTextWidget::makePixmap(void) +{ + int orgW = m_iface->originalWidth(); + int orgH = m_iface->originalHeight(); + float ratioW = (float)m_w / (float)orgW; + float ratioH = (float)m_h / (float)orgH; + + int x, y; + if (m_textRect.isValid()) + { + // convert from widget to image coordinates + x = m_textRect.x() - m_rect.x(); + y = m_textRect.y() - m_rect.y(); + } + else + { + x = -1; + y = -1; + } + + // get preview image data + uchar *data = m_iface->getPreviewImage(); + Digikam::DImg image(m_iface->previewWidth(), m_iface->previewHeight(), m_iface->previewSixteenBit(), + m_iface->previewHasAlpha(), data); + delete [] data; + + // paint pixmap for drawing this widget + // First, fill with background color + m_pixmap->fill(colorGroup().background()); + TQPainter p(m_pixmap); + // Convert image to pixmap and draw it + TQPixmap imagePixmap = image.convertToPixmap(); + p.drawPixmap(m_rect.x(), m_rect.y(), + imagePixmap, 0, 0, imagePixmap.width(), imagePixmap.height()); + + // prepare painter for use by compose image + p.setClipRect(m_rect); + p.translate(m_rect.x(), m_rect.y()); + + // compose image and draw result directly on pixmap, with correct offset + TQRect textRect = composeImage(&image, &p, x, y, + m_textFont, m_textFont.pointSizeFloat() * ((ratioW > ratioH) ? ratioW : ratioH), + m_textRotation, m_textColor, m_alignMode, m_textString, + m_textTransparent, m_backgroundColor, + m_textBorder ? BORDER_NORMAL : BORDER_SUPPORT, 1, 1); + + p.end(); + + // store new text rectangle + // convert from image to widget coordinates + m_textRect.setX(textRect.x() + m_rect.x()); + m_textRect.setY(textRect.y() + m_rect.y()); + m_textRect.setSize(textRect.size()); +} + +/* + Take data from image, draw text at x|y with specified parameters. + If destPainter is null, draw to image, + if destPainter is not null, draw directly using the painter. + Returns modified area of image. +*/ +TQRect InsertTextWidget::composeImage(Digikam::DImg *image, TQPainter *destPainter, + int x, int y, + TQFont font, float pointSize, int textRotation, TQColor textColor, + int alignMode, const TQString &textString, + bool transparentBackground, TQColor backgroundColor, + BorderMode borderMode, int borderWidth, int spacing) +{ + /* + The problem we have to solve is that we have no pixel access to font rendering, + we have to let TQt do the drawing. On the other hand we need to support 16 bit, which + cannot be done with TQPixmap. + The current solution cuts out the text area, lets TQt do its drawing, converts back and blits to original. + */ + Digikam::DColorComposer *composer = Digikam::DColorComposer::getComposer(Digikam::DColorComposer::PorterDuffNone); + + int maxWidth, maxHeight; + if (x == -1 && y == -1) + { + maxWidth = image->width(); + maxHeight = image->height(); + } + else + { + maxWidth = image->width() - x; + maxHeight = image->height() - y; + } + + // find out size of the area that we are drawing to + font.setPointSizeFloat(pointSize); + TQFontMetrics fontMt( font ); + TQRect fontRect = fontMt.boundingRect(0, 0, maxWidth, maxHeight, 0, textString); + + int fontWidth, fontHeight; + + switch(textRotation) + { + case ROTATION_NONE: + case ROTATION_180: + default: + fontWidth = fontRect.width(); + fontHeight = fontRect.height(); + break; + + case ROTATION_90: + case ROTATION_270: + fontWidth = fontRect.height(); + fontHeight = fontRect.width(); + break; + } + + // x, y == -1 means that we have to find a good initial position for the text here + if (x == -1 && y == -1) + { + // was a valid position hint stored from last use? + if (m_positionHint.isValid()) + { + // We assume that people tend to orient text along the edges, + // so we do some guessing so that positions such as "in the lower right corner" + // will be remembered across different image sizes. + + // get relative positions + float fromTop = (float)m_positionHint.top() / 10000.0; + float fromBottom = 1.0 - (float)m_positionHint.bottom() / 10000.0; + float fromLeft = (float)m_positionHint.left() / 10000.0; + float fromRight = 1.0 - (float)m_positionHint.right() / 10000.0; + + // calculate horizontal position + if (fromLeft < fromRight) + { + x = (int)(fromLeft * maxWidth); + + // we are placing from the smaller distance, + // so if now the larger distance is actually too small, + // fall back to standard placement, nothing to lose. + if (x + fontWidth > maxWidth) + x = TQMAX( (maxWidth - fontWidth) / 2, 0); + } + else + { + x = maxWidth - (int)(fromRight * maxWidth) - fontWidth; + if ( x < 0 ) + x = TQMAX( (maxWidth - fontWidth) / 2, 0); + } + + // calculate vertical position + if (fromTop < fromBottom) + { + y = (int)(fromTop * maxHeight); + if (y + fontHeight > maxHeight) + y = TQMAX( (maxHeight - fontHeight) / 2, 0); + } + else + { + y = maxHeight - (int)(fromBottom * maxHeight) - fontHeight; + if ( y < 0 ) + y = TQMAX( (maxHeight - fontHeight) / 2, 0); + } + + if (! TQRect(x, y, fontWidth, fontHeight). + intersects(TQRect(0, 0, maxWidth, maxHeight)) ) + { + // emergency fallback - nothing is visible + x = TQMAX( (maxWidth - fontWidth) / 2, 0); + y = TQMAX( (maxHeight - fontHeight) / 2, 0); + } + + // invalidate position hint, use only once + m_positionHint = TQRect(); + } + else + { + // use standard position + x = TQMAX( (maxWidth - fontWidth) / 2, 0); + y = TQMAX( (maxHeight - fontHeight) / 2, 0); + } + } + + // create a rectangle relative to image + TQRect drawRect( x, y, fontWidth + 2 * borderWidth + 2 * spacing, fontHeight + 2 * borderWidth + 2 * spacing); + + // create a rectangle relative to textArea, excluding the border + TQRect textAreaBackgroundRect( borderWidth, borderWidth, fontWidth + 2 * spacing, fontHeight + 2 * spacing); + + // create a rectangle relative to textArea, excluding the border and spacing + TQRect textAreaTextRect( borderWidth + spacing, borderWidth + spacing, fontWidth, fontHeight ); + + // create a rectangle relative to textArea, including the border, + // for drawing the rectangle, taking into account that the width of the TQPen goes in and out in equal parts + TQRect textAreaDrawRect( borderWidth / 2, borderWidth / 2, fontWidth + borderWidth + 2 * spacing, + fontHeight + borderWidth + 2 * spacing ); + + // cut out the text area + Digikam::DImg textArea = image->copy(drawRect); + + if (textArea.isNull()) + return TQRect(); + + // compose semi-transparent background over textArea + if (transparentBackground) + { + Digikam::DImg transparentLayer(textAreaBackgroundRect.width(), textAreaBackgroundRect.height(), textArea.sixteenBit(), true); + Digikam::DColor transparent(backgroundColor); + transparent.setAlpha(m_transparency); + if (image->sixteenBit()) + transparent.convertToSixteenBit(); + transparentLayer.fill(transparent); + textArea.bitBlendImage(composer, &transparentLayer, 0, 0, transparentLayer.width(), transparentLayer.height(), + textAreaBackgroundRect.x(), textAreaBackgroundRect.y()); + } + + Digikam::DImg textNotDrawn; + if (textArea.sixteenBit()) + { + textNotDrawn = textArea.copy(); + textNotDrawn.convertToEightBit(); + } + else + textNotDrawn = textArea; + + // We have no direct pixel access to font rendering, so now we need to use TQt/X11 for the drawing + + // convert text area to pixmap + TQPixmap pixmap = textNotDrawn.convertToPixmap(); + // paint on pixmap + TQPainter p(&pixmap); + p.setPen( TQPen(textColor, 1) ) ; + p.setFont( font ); + p.save(); + + // translate to origin of text, leaving space for the border + p.translate(textAreaTextRect.x(), textAreaTextRect.y()); + + switch(textRotation) + { + case ROTATION_NONE: + p.drawText( 0, 0, textAreaTextRect.width(), + textAreaTextRect.height(), alignMode, textString ); + break; + case ROTATION_90: + p.translate(textAreaTextRect.width(), 0); + p.rotate(90.0); + p.drawText( 0, 0, textAreaTextRect.height(), textAreaTextRect.width(), + alignMode, textString ); + break; + case ROTATION_180: + p.translate(textAreaTextRect.width(), textAreaTextRect.height()); + p.rotate(180.0); + p.drawText( 0, 0, textAreaTextRect.width(), textAreaTextRect.height(), + alignMode, textString ); + break; + case ROTATION_270: + p.translate(0, textAreaTextRect.height()); + p.rotate(270.0); + p.drawText( 0, 0, textAreaTextRect.height(), textAreaTextRect.width(), + alignMode, textString ); + break; + } + + p.restore(); + + // Drawing rectangle around text. + + if (borderMode == BORDER_NORMAL) // Decorative border using text color. + { + p.setPen( TQPen(textColor, borderWidth, TQt::SolidLine, + TQt::SquareCap, TQt::RoundJoin) ) ; + p.drawRect(textAreaDrawRect); + } + else if (borderMode == BORDER_SUPPORT) // Make simple dot line border to help user. + { + p.setPen(TQPen(TQt::white, 1, TQt::SolidLine)); + p.drawRect(textAreaDrawRect); + p.setPen(TQPen(TQt::red, 1, TQt::DotLine)); + p.drawRect(textAreaDrawRect); + } + p.end(); + + if (!destPainter) + { + // convert to TQImage, then to DImg + TQImage pixmapImage = pixmap.convertToImage(); + Digikam::DImg textDrawn(pixmapImage.width(), pixmapImage.height(), false, true, pixmapImage.bits()); + + // This does not work: during the conversion, colors are altered significantly (diffs of 1 to 10 in each component), + // so we cannot find out which pixels have actually been touched. + /* + // Compare the result of drawing with the previous version. + // Set all unchanged pixels to transparent + Digikam::DColor color, ncolor; + uchar *ptr, *nptr; + ptr = textDrawn.bits(); + nptr = textNotDrawn.bits(); + int bytesDepth = textDrawn.bytesDepth(); + int numPixels = textDrawn.width() * textDrawn.height(); + for (int i = 0; i < numPixels; i++, ptr+= bytesDepth, nptr += bytesDepth) + { + color.setColor(ptr, false); + ncolor.setColor(nptr, false); + if ( color.red() == ncolor.red() && + color.green() == ncolor.green() && + color.blue() == ncolor.blue()) + { + color.setAlpha(0); + color.setPixel(ptr); + } + } + // convert to 16 bit if needed + */ + textDrawn.convertToDepthOfImage(&textArea); + + // now compose to original: only pixels affected by drawing text and border are changed, not whole area + textArea.bitBlendImage(composer, &textDrawn, 0, 0, textDrawn.width(), textDrawn.height(), 0, 0); + + // copy result to original image + image->bitBltImage(&textArea, drawRect.x(), drawRect.y()); + } + else + { + destPainter->drawPixmap(drawRect.x(), drawRect.y(), pixmap, 0, 0, pixmap.width(), pixmap.height()); + } + + delete composer; + + return drawRect; +} + +void InsertTextWidget::paintEvent( TQPaintEvent * ) +{ + bitBlt(this, 0, 0, m_pixmap); +} + +void InsertTextWidget::resizeEvent(TQResizeEvent * e) +{ + blockSignals(true); + delete m_pixmap; + + int w = e->size().width(); + int h = e->size().height(); + + int textX = m_textRect.x() - m_rect.x(); + int textY = m_textRect.y() - m_rect.y(); + int old_w = m_w; + int old_h = m_h; + m_data = m_iface->setPreviewImageSize(w, h); + m_w = m_iface->previewWidth(); + m_h = m_iface->previewHeight(); + + m_pixmap = new TQPixmap(w, h); + m_rect = TQRect(w/2-m_w/2, h/2-m_h/2, m_w, m_h); + + if (m_textRect.isValid()) + { + int textWidth = m_textRect.width(); + int textHeight = m_textRect.height(); + + textX = lroundf( textX * (float)m_w / (float)old_w ); + textY = lroundf( textY * (float)m_h / (float)old_h ); + textWidth = lroundf(textWidth * (float)m_w / (float)old_w ); + textHeight = lroundf(textHeight * (float)m_h / (float)old_h ); + + m_textRect.setX(textX + m_rect.x()); + m_textRect.setY(textY + m_rect.y()); + m_textRect.setWidth(textWidth); + m_textRect.setHeight(textHeight); + makePixmap(); + } + + blockSignals(false); +} + +void InsertTextWidget::mousePressEvent ( TQMouseEvent * e ) +{ + if ( e->button() == TQt::LeftButton && + m_textRect.contains( e->x(), e->y() ) ) + { + m_xpos = e->x(); + m_ypos = e->y(); + setCursor ( KCursor::sizeAllCursor() ); + m_currentMoving = true; + } +} + +void InsertTextWidget::mouseReleaseEvent ( TQMouseEvent * ) +{ + setCursor ( KCursor::arrowCursor() ); + m_currentMoving = false; +} + +void InsertTextWidget::mouseMoveEvent ( TQMouseEvent * e ) +{ + if ( rect().contains( e->x(), e->y() ) ) + { + if ( e->state() == TQt::LeftButton && m_currentMoving ) + { + uint newxpos = e->x(); + uint newypos = e->y(); + + m_textRect.moveBy(newxpos - m_xpos, newypos - m_ypos); + + makePixmap(); + repaint(false); + + m_xpos = newxpos; + m_ypos = newypos; + setCursor( KCursor::handCursor() ); + } + else if ( m_textRect.contains( e->x(), e->y() ) ) + { + setCursor ( KCursor::sizeAllCursor() ); + } + else + { + setCursor ( KCursor::arrowCursor() ); + } + } +} + +} // NameSpace DigikamInsertTextImagesPlugin diff --git a/src/imageplugins/inserttext/inserttextwidget.h b/src/imageplugins/inserttext/inserttextwidget.h new file mode 100644 index 00000000..bbce9189 --- /dev/null +++ b/src/imageplugins/inserttext/inserttextwidget.h @@ -0,0 +1,156 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-02-14 + * Description : a widget to insert a text over an image. + * + * Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com> + * Copyright (C) 2006-2007 by Marcel Wiesweg <marcel dot wiesweg at gmx dot 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, 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. + * + * ============================================================ */ + +#ifndef INSERTTEXTWIDGET_H +#define INSERTTEXTWIDGET_H + +// TQt includes. + +#include <tqwidget.h> +#include <tqimage.h> +#include <tqrect.h> +#include <tqsize.h> +#include <tqpixmap.h> +#include <tqstring.h> +#include <tqfont.h> +#include <tqcolor.h> + +// KDE includes. + +#include <kurl.h> + +// Digikam includes. + +#include "dimg.h" + +class TQPixmap; + +namespace Digikam +{ +class ImageIface; +} + +namespace DigikamInsertTextImagesPlugin +{ + +enum Action +{ + ALIGN_LEFT=0, + ALIGN_RIGHT, + ALIGN_CENTER, + ALIGN_BLOCK, + BORDER_TEXT, + TRANSPARENT_TEXT +}; + +enum TextRotation +{ + ROTATION_NONE=0, + ROTATION_90, + ROTATION_180, + ROTATION_270 +}; + +enum BorderMode +{ + BORDER_NONE, + BORDER_SUPPORT, + BORDER_NORMAL +}; + +class InsertTextWidget : public TQWidget +{ +TQ_OBJECT + + +public: + + InsertTextWidget(int w, int h, TQWidget *parent=0); + ~InsertTextWidget(); + + Digikam::ImageIface* imageIface(); + Digikam::DImg makeInsertText(void); + + void setText(TQString text, TQFont font, TQColor color, int alignMode, + bool border, bool transparent, int rotation); + void resetEdit(void); + + void setPositionHint(TQRect hint); + TQRect getPositionHint(); + +protected: + + void paintEvent(TQPaintEvent *e); + void resizeEvent(TQResizeEvent * e); + void mousePressEvent(TQMouseEvent * e); + void mouseReleaseEvent(TQMouseEvent * e); + void mouseMoveEvent(TQMouseEvent * e); + + void makePixmap(void); + TQRect composeImage(Digikam::DImg *image, TQPainter *destPainter, + int x, int y, + TQFont font, float pointSize, int textRotation, TQColor textColor, + int alignMode, const TQString &textString, + bool transparentBackground, TQColor backgroundColor, + BorderMode borderMode, int borderWidth, int spacing); + +private: + + bool m_currentMoving; + bool m_textBorder; + bool m_textTransparent; + + int m_alignMode; + int m_textRotation; + + uchar *m_data; + int m_w; + int m_h; + + int m_xpos; + int m_ypos; + + int m_transparency; + + TQPixmap *m_pixmap; + + TQRect m_rect; + TQRect m_textRect; + + TQString m_textString; + + TQFont m_textFont; + + TQColor m_textColor; + + TQColor m_backgroundColor; + + TQRect m_positionHint; + + Digikam::ImageIface *m_iface; +}; + +} // NameSpace DigikamInsertTextImagesPlugin + +#endif /* INSERTTEXTWIDGET_H */ |