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