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