00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "qsignalmapper.h"
00020 #include <qlayout.h>
00021 #include <qframe.h>
00022 #include <qcursor.h>
00023 #include <qapplication.h>
00024 #include <kmessagebox.h>
00025 #include <kguiitem.h>
00026
00027 #include "kaction.h"
00028
00029 #include "kis_part_layer.h"
00030 #include "kis_id.h"
00031 #include "kis_view.h"
00032 #include "kis_doc.h"
00033 #include "kis_filter.h"
00034 #include "kis_layer.h"
00035 #include "kis_paint_device.h"
00036 #include "kis_paint_layer.h"
00037 #include "kis_filter_manager.h"
00038 #include "kis_filter_config_widget.h"
00039 #include "kis_previewwidget.h"
00040 #include "kis_previewdialog.h"
00041 #include "kis_filter_registry.h"
00042 #include "kis_transaction.h"
00043 #include "kis_undo_adapter.h"
00044 #include "kis_previewdialog.h"
00045 #include "kis_previewwidget.h"
00046 #include "kis_painter.h"
00047 #include "kis_selection.h"
00048 #include "kis_id.h"
00049 #include "kis_canvas_subject.h"
00050 #include "kis_doc.h"
00051 #include "kis_transaction.h"
00052 #include <kis_progress_display_interface.h>
00053
00054 KisFilterManager::KisFilterManager(KisView * view, KisDoc * doc)
00055 : m_view(view),
00056 m_doc(doc)
00057 {
00058
00059 m_reapplyAction = 0;
00060 m_lastFilterConfig = 0;
00061 m_lastDialog = 0;
00062 m_lastFilter = 0;
00063 m_lastWidget = 0;
00064
00065 m_filterMapper = new QSignalMapper(this);
00066
00067 connect(m_filterMapper, SIGNAL(mapped(int)), this, SLOT(slotApplyFilter(int)));
00068
00069 }
00070
00071 KisFilterManager::~KisFilterManager()
00072 {
00073
00074
00075
00076 }
00077
00078 void KisFilterManager::setup(KActionCollection * ac)
00079 {
00080 KisFilter * f = 0;
00081 int i = 0;
00082
00083
00084
00085
00086 KActionMenu * other = 0;
00087 KActionMenu * am = 0;
00088
00089 m_filterList = KisFilterRegistry::instance()->listKeys();
00090
00091 for ( KisIDList::Iterator it = m_filterList.begin(); it != m_filterList.end(); ++it ) {
00092 f = KisFilterRegistry::instance()->get(*it);
00093 if (!f) break;
00094
00095 QString s = f->menuCategory();
00096 if (s == "adjust" && !m_filterActionMenus.find("adjust")) {
00097 am = new KActionMenu(i18n("Adjust"), ac, "adjust_filters");
00098 m_filterActionMenus.insert("adjust", am);
00099 }
00100
00101 else if (s == "artistic" && !m_filterActionMenus.find("artistic")) {
00102 am = new KActionMenu(i18n("Artistic"), ac, "artistic_filters");
00103 m_filterActionMenus.insert("artistic", am);
00104 }
00105
00106 else if (s == "blur" && !m_filterActionMenus.find("blur")) {
00107 am = new KActionMenu(i18n("Blur"), ac, "blur_filters");
00108 m_filterActionMenus.insert("blur", am);
00109 }
00110
00111 else if (s == "colors" && !m_filterActionMenus.find("colors")) {
00112 am = new KActionMenu(i18n("Colors"), ac, "color_filters");
00113 m_filterActionMenus.insert("colors", am);
00114 }
00115
00116 else if (s == "decor" && !m_filterActionMenus.find("decor")) {
00117 am = new KActionMenu(i18n("Decor"), ac, "decor_filters");
00118 m_filterActionMenus.insert("decor", am);
00119 }
00120
00121 else if (s == "edge" && !m_filterActionMenus.find("edge")) {
00122 am = new KActionMenu(i18n("Edge Detection"), ac, "edge_filters");
00123 m_filterActionMenus.insert("edge", am);
00124 }
00125
00126 else if (s == "emboss" && !m_filterActionMenus.find("emboss")) {
00127 am = new KActionMenu(i18n("Emboss"), ac, "emboss_filters");
00128 m_filterActionMenus.insert("emboss", am);
00129 }
00130
00131 else if (s == "enhance" && !m_filterActionMenus.find("enhance")) {
00132 am = new KActionMenu(i18n("Enhance"), ac, "enhance_filters");
00133 m_filterActionMenus.insert("enhance", am);
00134 }
00135
00136 else if (s == "map" && !m_filterActionMenus.find("map")) {
00137 am = new KActionMenu(i18n("Map"), ac, "map_filters");
00138 m_filterActionMenus.insert("map", am);
00139 }
00140
00141 else if (s == "nonphotorealistic" && !m_filterActionMenus.find("nonphotorealistic")) {
00142 am = new KActionMenu(i18n("Non-photorealistic"), ac, "nonphotorealistic_filters");
00143 m_filterActionMenus.insert("nonphotorealistic", am);
00144 }
00145
00146 else if (s == "other" && !m_filterActionMenus.find("other")) {
00147 other = new KActionMenu(i18n("Other"), ac, "misc_filters");
00148 m_filterActionMenus.insert("other", am);
00149 }
00150
00151 }
00152
00153 m_reapplyAction = new KAction(i18n("Apply Filter Again"),
00154 "Ctrl+Shift+F",
00155 this, SLOT(slotApply()),
00156 ac, "filter_apply_again");
00157
00158 m_reapplyAction->setEnabled(false);
00159
00160 f = 0;
00161 i = 0;
00162 for ( KisIDList::Iterator it = m_filterList.begin(); it != m_filterList.end(); ++it ) {
00163 f = KisFilterRegistry::instance()->get(*it);
00164
00165 if (!f) break;
00166
00167
00168 KAction * a = new KAction(f->menuEntry(), 0, m_filterMapper, SLOT(map()), ac,
00169 QString("krita_filter_%1").arg((*it) . id()).ascii());
00170
00171
00172 KActionMenu * m = m_filterActionMenus.find( f->menuCategory() );
00173 if (m) {
00174 m->insert(a);
00175 }
00176 else {
00177 if (!other) {
00178 other = new KActionMenu(i18n("Other"), ac, "misc_filters");
00179 m_filterActionMenus.insert("other", am);
00180 }
00181 other->insert(a);
00182 }
00183
00184
00185 m_filterMapper->setMapping( a, i );
00186
00187 m_filterActions.append( a );
00188 ++i;
00189 }
00190 }
00191
00192 void KisFilterManager::updateGUI()
00193 {
00194 KisImageSP img = m_view->currentImg();
00195 if (!img) return;
00196
00197 KisLayerSP layer = img->activeLayer();
00198 if (!layer) return;
00199
00200 KisPartLayer * partLayer = dynamic_cast<KisPartLayer*>(layer.data());
00201
00202 bool enable = !(layer->locked() || !layer->visible() || partLayer);
00203 KisPaintLayerSP player = dynamic_cast<KisPaintLayer*>( layer.data());
00204 if(!player)
00205 {
00206 enable = false;
00207 }
00208 m_reapplyAction->setEnabled(m_lastFilterConfig);
00209 if (m_lastFilterConfig)
00210 m_reapplyAction->setText(i18n("Apply Filter Again") + ": "
00211 + KisFilterRegistry::instance()->get(m_lastFilterConfig->name())->id().name());
00212 else
00213 m_reapplyAction->setText(i18n("Apply Filter Again"));
00214
00215 KAction * a;
00216 int i = 0;
00217 for (a = m_filterActions.first(); a; a = m_filterActions.next() , i++) {
00218 KisFilter* filter = KisFilterRegistry::instance()->get(m_filterList[i]);
00219 if(player && filter->workWith( player->paintDevice()->colorSpace()))
00220 {
00221 a->setEnabled(enable);
00222 } else {
00223 a->setEnabled(false);
00224 }
00225 }
00226
00227 }
00228
00229 void KisFilterManager::slotApply()
00230 {
00231 apply();
00232 }
00233
00234 bool KisFilterManager::apply()
00235 {
00236 if (!m_lastFilter) return false;
00237
00238 KisImageSP img = m_view->currentImg();
00239 if (!img) return false;
00240
00241 KisPaintDeviceSP dev = img->activeDevice();
00242 if (!dev) return false;
00243
00244 QApplication::setOverrideCursor( Qt::waitCursor );
00245
00246
00247 m_lastFilterConfig = m_lastFilter->configuration(m_lastWidget);
00248
00249 QRect r1 = dev->extent();
00250 QRect r2 = img->bounds();
00251
00252
00253 QRect rect = r1.intersect(r2);
00254
00255 if (dev->hasSelection()) {
00256 QRect r3 = dev->selection()->selectedExactRect();
00257 rect = rect.intersect(r3);
00258 }
00259
00260 m_lastFilter->enableProgress();
00261
00262 m_view->progressDisplay()->setSubject(m_lastFilter, true, true);
00263 m_lastFilter->setProgressDisplay( m_view->progressDisplay());
00264
00265 KisTransaction * cmd = 0;
00266 if (img->undo()) cmd = new KisTransaction(m_lastFilter->id().name(), dev);
00267
00268 m_lastFilter->process(dev, dev, m_lastFilterConfig, rect);
00269 m_reapplyAction->setEnabled(m_lastFilterConfig);
00270 if (m_lastFilterConfig)
00271 m_reapplyAction->setText(i18n("Apply Filter Again") + ": "
00272 + KisFilterRegistry::instance()->get(m_lastFilterConfig->name())->id().name());
00273
00274 else
00275 m_reapplyAction->setText(i18n("Apply Filter Again"));
00276
00277 if (m_lastFilter->cancelRequested()) {
00278 delete m_lastFilterConfig;
00279 if (cmd) {
00280 cmd->unexecute();
00281 delete cmd;
00282 }
00283 m_lastFilter->disableProgress();
00284 QApplication::restoreOverrideCursor();
00285 return false;
00286
00287 } else {
00288 if (dev->parentLayer()) dev->parentLayer()->setDirty(rect);
00289 m_doc->setModified(true);
00290 if (img->undo() && cmd) img->undoAdapter()->addCommand(cmd);
00291 m_lastFilter->disableProgress();
00292 QApplication::restoreOverrideCursor();
00293 return true;
00294 }
00295 }
00296
00297 void KisFilterManager::slotApplyFilter(int i)
00298 {
00299 KisPreviewDialog * oldDialog = m_lastDialog;
00300 KisFilterConfiguration * oldConfig = m_lastFilterConfig;
00301 KisFilter * oldFilter = m_lastFilter;
00302
00303 m_lastFilter = KisFilterRegistry::instance()->get(m_filterList[i]);
00304
00305 if (!m_lastFilter) {
00306 m_lastFilter = oldFilter;
00307 return;
00308 }
00309
00310 KisImageSP img = m_view->currentImg();
00311 if (!img) return;
00312
00313 KisPaintDeviceSP dev = img->activeDevice();
00314 if (!dev) return;
00315
00316 if (dev->colorSpace()->willDegrade(m_lastFilter->colorSpaceIndependence())) {
00317
00318 if (m_lastFilter->colorSpaceIndependence() == TO_LAB16) {
00319 if (KMessageBox::warningContinueCancel(m_view,
00320 i18n("The %1 filter will convert your %2 data to 16-bit L*a*b* and vice versa. ")
00321 .arg(m_lastFilter->id().name())
00322 .arg(dev->colorSpace()->id().name()),
00323 i18n("Filter Will Convert Your Layer Data"),
00324 KGuiItem(i18n("Continue")),
00325 "lab16degradation") != KMessageBox::Continue) return;
00326
00327 }
00328 else if (m_lastFilter->colorSpaceIndependence() == TO_RGBA8) {
00329 if (KMessageBox::warningContinueCancel(m_view,
00330 i18n("The %1 filter will convert your %2 data to 8-bit RGBA and vice versa. ")
00331 .arg(m_lastFilter->id().name())
00332 .arg(dev->colorSpace()->id().name()),
00333 i18n("Filter Will Convert Your Layer Data"),
00334 KGuiItem(i18n("Continue")),
00335 "rgba8degradation") != KMessageBox::Continue) return;
00336 }
00337 }
00338
00339 m_lastFilter->disableProgress();
00340
00341
00342 m_lastDialog = new KisPreviewDialog(m_view, m_lastFilter->id().name().ascii(), true, m_lastFilter->id().name());
00343 Q_CHECK_PTR(m_lastDialog);
00344 m_lastWidget = m_lastFilter->createConfigurationWidget( (QWidget*)m_lastDialog->container(), dev );
00345
00346
00347 if( m_lastWidget != 0)
00348 {
00349 connect(m_lastWidget, SIGNAL(sigPleaseUpdatePreview()), this, SLOT(slotConfigChanged()));
00350
00351 m_lastDialog->previewWidget()->slotSetDevice( dev );
00352
00353 connect(m_lastDialog->previewWidget(), SIGNAL(updated()), this, SLOT(refreshPreview()));
00354
00355 QGridLayout *widgetLayout = new QGridLayout((QWidget *)m_lastDialog->container(), 1, 1);
00356
00357 widgetLayout->addWidget(m_lastWidget, 0 , 0);
00358
00359 m_lastDialog->container()->setMinimumSize(m_lastWidget->minimumSize());
00360
00361 refreshPreview();
00362
00363 if(m_lastDialog->exec() == QDialog::Rejected )
00364 {
00365 delete m_lastDialog;
00366 m_lastDialog = oldDialog;
00367 m_lastFilter = oldFilter;
00368 return;
00369 }
00370 }
00371
00372 if (!apply()) {
00373 m_lastFilterConfig = oldConfig;
00374 m_lastDialog = oldDialog;
00375 m_lastFilter = oldFilter;
00376 }
00377
00378 }
00379
00380 void KisFilterManager::slotConfigChanged()
00381 {
00382 if( m_lastDialog == 0 )
00383 return;
00384 if(m_lastDialog->previewWidget()->getAutoUpdate())
00385 {
00386 refreshPreview();
00387 } else {
00388 m_lastDialog->previewWidget()->needUpdate();
00389 }
00390 }
00391
00392
00393 void KisFilterManager::refreshPreview( )
00394 {
00395 if( m_lastDialog == 0 )
00396 return;
00397
00398 KisPaintDeviceSP dev = m_lastDialog->previewWidget()->getDevice();
00399 if (!dev) return;
00400
00401 KisFilterConfiguration* config = m_lastFilter->configuration(m_lastWidget);
00402
00403 QRect rect = dev->extent();
00404 KisTransaction cmd("Temporary transaction", dev);
00405 m_lastFilter->process(dev, dev, config, rect);
00406 m_lastDialog->previewWidget()->slotUpdate();
00407 cmd.unexecute();
00408 }
00409
00410
00411 #include "kis_filter_manager.moc"