krita

kis_view.cc

00001 /* This file is part of KimageShop^WKrayon^WKrita
00002  *
00003  *  Copyright (c) 1999 Matthias Elter  <me@kde.org>
00004  *                1999 Michael Koch    <koch@kde.org>
00005  *                1999 Carsten Pfeiffer <pfeiffer@kde.org>
00006  *                2002 Patrick Julien <freak@codepimps.org>
00007  *                2003-2005 Boudewijn Rempt <boud@valdyas.org>
00008  *                2004 Clarence Dang <dang@kde.org>
00009  *
00010  *  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU General Public License for more details.
00019  *
00020  *  You should have received a copy of the GNU General Public License
00021  *  along with this program; if not, write to the Free Software
00022  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00023  */
00024 
00025 #include <algorithm>
00026 #include <cmath>
00027 
00028 // Qt
00029 #include <qapplication.h>
00030 #include <qbutton.h>
00031 #include <qcursor.h>
00032 #include <qevent.h>
00033 #include <qpainter.h>
00034 #include <qscrollbar.h>
00035 #include <qspinbox.h>
00036 #include <qdockarea.h>
00037 #include <qstringlist.h>
00038 #include <qstyle.h>
00039 #include <qpopupmenu.h>
00040 #include <qvaluelist.h>
00041 #include <qstringlist.h>
00042 #include <qobjectlist.h>
00043 
00044 // KDE
00045 #include <kis_meta_registry.h>
00046 #include <kglobalsettings.h>
00047 #include <dcopobject.h>
00048 #include <kaction.h>
00049 #include <kcolordialog.h>
00050 #include <kiconloader.h>
00051 #include <kfiledialog.h>
00052 #include <klocale.h>
00053 #include <kmessagebox.h>
00054 #include <knotifyclient.h>
00055 #include <kprinter.h>
00056 #include <kpushbutton.h>
00057 #include <kstatusbar.h>
00058 #include <kstdaction.h>
00059 #include <kinputdialog.h>
00060 #include <kurldrag.h>
00061 #include <kpopupmenu.h>
00062 #include <kdebug.h>
00063 #include <ksharedptr.h>
00064 #include <ktoolbar.h>
00065 #include <kparts/plugin.h>
00066 #include <kservice.h>
00067 #include <ktrader.h>
00068 #include <kparts/componentfactory.h>
00069 #include <kparts/event.h>
00070 
00071 // KOffice
00072 #include <KoPartSelectAction.h>
00073 #include <KoFilterManager.h>
00074 #include <KoMainWindow.h>
00075 #include <KoView.h>
00076 #include <KoTabBar.h>
00077 #include <ko_gray_widget.h>
00078 #include <ko_hsv_widget.h>
00079 #include <ko_rgb_widget.h>
00080 #include <kopalettemanager.h>
00081 #include <kopalette.h>
00082 
00083 // Local
00084 #include "kis_brush.h"
00085 #include "kis_button_press_event.h"
00086 #include "kis_button_release_event.h"
00087 #include "kis_canvas.h"
00088 #include "kis_canvas_painter.h"
00089 #include "kis_color.h"
00090 #include "kis_colorspace_factory_registry.h"
00091 #include "kis_config.h"
00092 #include "kis_controlframe.h"
00093 #include "kis_cursor.h"
00094 #include "kis_doc.h"
00095 #include "kis_double_click_event.h"
00096 #include "kis_factory.h"
00097 #include "kis_filter_strategy.h"
00098 #include "kis_gradient.h"
00099 #include "kis_group_layer.h"
00100 #include "kis_adjustment_layer.h"
00101 #include "kis_paint_device.h"
00102 #include "kis_tool_freehand.h"
00103 //#include "kis_guide.h"
00104 #include "kis_scale_visitor.h"
00105 #include "kis_layerbox.h"
00106 #include "kis_import_catcher.h"
00107 #include "kis_layer.h"
00108 #include "kis_paint_layer.h"
00109 #include "kis_move_event.h"
00110 #include "kis_paint_device.h"
00111 #include "kis_painter.h"
00112 #include "kis_paintop_registry.h"
00113 #include "kis_part_layer.h"
00114 #include "kis_part_layer_handler.h"
00115 #include "kis_pattern.h"
00116 #include "kis_profile.h"
00117 #include "kis_rect.h"
00118 #include "kis_resource.h"
00119 #include "kis_palette.h"
00120 #include "kis_ruler.h"
00121 #include "kis_selection.h"
00122 #include "KoToolBox.h"
00123 #include "kis_tool.h"
00124 #include "kis_tool_manager.h"
00125 #include "kis_transaction.h"
00126 #include "kis_types.h"
00127 #include "kis_undo_adapter.h"
00128 #include "kis_view.h"
00129 #include "kis_view_iface.h"
00130 #include "kis_label_progress.h"
00131 #include "kis_opengl_image_context.h"
00132 #include "kis_background.h"
00133 #include "kis_paint_device_action.h"
00134 #include "kis_filter_configuration.h"
00135 #include "kis_transform_worker.h"
00136 #include "kis_shear_visitor.h"
00137 
00138 #include <kis_resourceserver.h>
00139 #include <kis_resource_mediator.h>
00140 
00141 #include "kis_icon_item.h"
00142 #include "kis_palette_widget.h"
00143 #include "kis_birdeye_box.h"
00144 #include "kis_color.h"
00145 #include "kis_factory.h"
00146 
00147 // Dialog boxes
00148 #include "kis_dlg_new_layer.h"
00149 #include "kis_dlg_layer_properties.h"
00150 #include "kis_dlg_preferences.h"
00151 #include "kis_dlg_image_properties.h"
00152 #include "kis_dlg_adjustment_layer.h"
00153 #include "kis_dlg_adj_layer_props.h"
00154 
00155 // Action managers
00156 #include "kis_selection_manager.h"
00157 #include "kis_filter_manager.h"
00158 #include "kis_grid_manager.h"
00159 #include "kis_perspective_grid_manager.h"
00160 
00161 #include "kis_custom_palette.h"
00162 #include "wdgpalettechooser.h"
00163 
00164 #include <fixx11h.h>
00165 
00166 // Time in ms that must pass after a tablet event before a mouse event is allowed to
00167 // change the input device to the mouse. This is needed because mouse events are always
00168 // sent to a receiver if it does not accept the tablet event.
00169 #define MOUSE_CHANGE_EVENT_DELAY 100
00170 
00171 KisView::KisView(KisDoc *doc, KisUndoAdapter *adapter, QWidget *parent, const char *name)
00172     : super(doc, parent, name)
00173     , KXMLGUIBuilder( shell() )
00174     , m_panning( false )
00175     , m_oldTool( 0 )
00176     , m_doc( doc )
00177     , m_canvas( 0 )
00178     , m_popup( 0 )
00179     , m_partHandler( 0 )
00180     , m_gridManager( 0 )
00181     , m_perspectiveGridManager( 0 )
00182     , m_selectionManager( 0 )
00183     , m_filterManager( 0 )
00184     , m_paletteManager( 0 )
00185     , m_toolManager( 0 )
00186     , m_actLayerVis( false )
00187     , m_hRuler( 0 )
00188     , m_vRuler( 0 )
00189     , m_imgFlatten( 0 )
00190     , m_imgMergeLayer( 0 )
00191     , m_imgRename( 0 )
00192     , m_imgResizeToLayer( 0 )
00193     , m_imgScan( 0 )
00194     , m_actionPartLayer( 0 )
00195     , m_layerAdd( 0 )
00196     , m_layerBottom( 0 )
00197     , m_layerDup( 0 )
00198     , m_layerHide( 0 )
00199     , m_layerLower( 0 )
00200     , m_layerProperties( 0 )
00201     , m_layerRaise( 0 )
00202     , m_layerRm( 0 )
00203     , m_layerSaveAs( 0 )
00204     , m_layerTop( 0 )
00205     , m_zoomIn( 0 )
00206     , m_zoomOut( 0 )
00207     , m_actualPixels( 0 )
00208     , m_actualSize( 0 )
00209     , m_fitToCanvas( 0 )
00210     , m_fullScreen( 0 )
00211     , m_imgProperties( 0 )
00212     , m_RulerAction( 0 )
00213     , m_guideAction( 0 )
00214     , m_dcop( 0 )
00215     , m_hScroll( 0 )
00216     , m_vScroll( 0 )
00217     , m_scrollX( 0 )
00218     , m_scrollY( 0 )
00219     , m_canvasXOffset( 0)
00220     , m_canvasYOffset( 0)
00221     , m_paintViewEnabled( false )
00222     , m_guiActivateEventReceived( false )
00223     , m_showEventReceived( false )
00224     , m_imageLoaded( false )
00225 //    , m_currentGuide( 0 )
00226     , m_adapter( adapter )
00227     , m_statusBarZoomLabel( 0 )
00228     , m_statusBarSelectionLabel( 0 )
00229     , m_statusBarProfileLabel( 0 )
00230     , m_progress( 0 )
00231     , m_layerBox( 0 )
00232     , m_toolBox( 0 )
00233     , m_brush( 0 )
00234     , m_pattern( 0 )
00235     , m_gradient( 0 )
00236     , m_toolIsPainting( false )
00237     , m_monitorProfile( 0 )
00238     , m_HDRExposure( 0 )
00239 {
00240 
00241     Q_ASSERT(doc);
00242     Q_ASSERT(adapter);
00243     Q_ASSERT(parent);
00244 
00245     KisConfig cfg;
00246 
00247     m_currentColorChooserDisplay = KisID("BLA");
00248     setFocusPolicy( QWidget::StrongFocus );
00249 
00250     // Must come before input devices are referenced as this detects them.
00251 #ifdef Q_WS_X11
00252     KisCanvasWidget::initX11Support();
00253 #endif
00254     // Install event filter before we create any child widgets so they can see
00255     // the tablet events.
00256     qApp->installEventFilter(this);
00257 
00258     m_tabletEventTimer.start();
00259     m_inputDevice = KisInputDevice::mouse();
00260 
00261     connect(&m_initialZoomTimer, SIGNAL(timeout()), SLOT(slotInitialZoomTimeout()));
00262 
00263     m_paletteManager = new KoPaletteManager(this, actionCollection(), "Krita palette manager");
00264     if (cfg.fixDockerWidth()) m_paletteManager->setFixedWidth( 360 );
00265 
00266     m_paletteManager->createPalette( krita::CONTROL_PALETTE, i18n("Control box"));
00267     m_paletteManager->createPalette( krita::COLORBOX, i18n("Colors"));
00268     m_paletteManager->createPalette( krita::LAYERBOX, i18n("Layers"));
00269 
00270     m_selectionManager = new KisSelectionManager(this, doc);
00271     m_filterManager = new KisFilterManager(this, doc);
00272     m_toolManager = new KisToolManager(canvasSubject(), getCanvasController());
00273     m_gridManager = new KisGridManager(this);
00274     m_perspectiveGridManager = new KisPerspectiveGridManager(this);
00275 
00276     // This needs to be set before the dockers are created.
00277     m_image = m_doc->currentImage();
00278     KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getRGB8();
00279     m_fg = KisColor(Qt::black, cs);
00280     m_bg = KisColor(Qt::white, cs);
00281 
00282     createDockers();
00283 
00284     setInstance(KisFactory::instance(), false);
00285     setClientBuilder( this );
00286 
00287     if (!doc->isReadWrite())
00288         setXMLFile("krita_readonly.rc");
00289     else
00290         setXMLFile("krita.rc");
00291 
00292     KStdAction::keyBindings( mainWindow()->guiFactory(), SLOT( configureShortcuts() ), actionCollection() );
00293 
00294     createLayerBox();
00295 
00296     setupCanvas();
00297     m_canvas->hide();
00298     setupRulers();
00299     setupScrollBars();
00300     setupStatusBar();
00301 
00302     setupActions();
00303     dcopObject();
00304 
00305 
00306     connect(this, SIGNAL(autoScroll(const QPoint &)), SLOT(slotAutoScroll(const QPoint &)));
00307 
00308     setMouseTracking(true);
00309 
00310     resetMonitorProfile();
00311 
00312     layersUpdated();
00313 
00314     m_brushesAndStuffToolBar = new KisControlFrame(mainWindow(), this);
00315 
00316     // Load all plugins
00317     KTrader::OfferList offers = KTrader::self()->query(QString::fromLatin1("Krita/ViewPlugin"),
00318                                                          QString::fromLatin1("(Type == 'Service') and "
00319                                                                              "([X-Krita-Version] == 2)"));
00320     KTrader::OfferList::ConstIterator iter;
00321     for(iter = offers.begin(); iter != offers.end(); ++iter)
00322     {
00323         KService::Ptr service = *iter;
00324         int errCode = 0;
00325         KParts::Plugin* plugin =
00326              KParts::ComponentFactory::createInstanceFromService<KParts::Plugin> ( service, this, 0, QStringList(), &errCode);
00327         if ( plugin ) {
00328             kdDebug(41006) << "found plugin " << service->property("Name").toString() << "\n";
00329             insertChildClient(plugin);
00330         }
00331         else {
00332             kdDebug(41006) << "found plugin " << service->property("Name").toString() << ", " << errCode << "\n";
00333         if( errCode == KParts::ComponentFactory::ErrNoLibrary)
00334         {
00335         kdWarning(41006) << " Error loading plugin was : ErrNoLibrary " << KLibLoader::self()->lastErrorMessage() << endl;
00336         }
00337         }
00338     }
00339 
00340     if(!doc->isLoading())
00341     {
00342         slotLoadingFinished();
00343     } else {
00344         connect(doc, SIGNAL(loadingFinished()), this, SLOT(slotLoadingFinished()));
00345     }
00346 
00347     setFocus();
00348 }
00349 
00350 KisView::~KisView()
00351 {
00352     KisConfig cfg;
00353     cfg.setShowRulers( m_RulerAction->isChecked() );
00354 
00355     delete m_dcop;
00356     delete m_paletteManager;
00357     delete m_selectionManager;
00358     delete m_filterManager;
00359     delete m_toolManager;
00360 
00361 }
00362 
00363 
00364 static Qt::Dock stringToDock( const QString& attrPosition )
00365 {
00366     KToolBar::Dock dock = KToolBar::DockTop;
00367     if ( !attrPosition.isEmpty() ) {
00368         if ( attrPosition == "top" )
00369             dock = Qt::DockTop;
00370         else if ( attrPosition == "left" )
00371             dock = Qt::DockLeft;
00372         else if ( attrPosition == "right" )
00373             dock = Qt::DockRight;
00374         else if ( attrPosition == "bottom" )
00375             dock = Qt::DockBottom;
00376         else if ( attrPosition == "floating" )
00377             dock = Qt::DockTornOff;
00378         else if ( attrPosition == "flat" )
00379             dock = Qt::DockMinimized;
00380     }
00381     return dock;
00382 }
00383 
00384 QWidget * KisView::createContainer( QWidget *parent, int index, const QDomElement &element, int &id )
00385 {
00386     if( element.attribute( "name" ) == "ToolBox" )
00387     {
00388         m_toolBox = new KoToolBox(mainWindow(), "ToolBox", KisFactory::instance(), NUMBER_OF_TOOLTYPES);
00389         m_toolBox->setLabel(i18n("Krita"));
00390         m_toolManager->setUp(m_toolBox, m_paletteManager, actionCollection());
00391 
00392         Dock dock = stringToDock( element.attribute( "position" ).lower() );
00393 
00394         mainWindow()->addDockWindow( m_toolBox, dock, false);
00395         mainWindow()->moveDockWindow( m_toolBox, dock, false, 0, 0 );
00396     }
00397 
00398     return KXMLGUIBuilder::createContainer( parent, index, element, id );
00399 
00400 }
00401 
00402 void KisView::removeContainer( QWidget *container, QWidget *parent, QDomElement &element, int id )
00403 {
00404     Q_ASSERT(container);
00405 
00406     if( shell() && container == m_toolBox )
00407     {
00408         delete m_toolBox;
00409         m_toolManager->youAintGotNoToolBox();
00410     }
00411     else {
00412         KXMLGUIBuilder::removeContainer( container, parent, element, id );
00413     }
00414 }
00415 
00416 KoPaletteManager * KisView::paletteManager()
00417 {
00418     if (!m_paletteManager) {
00419         m_paletteManager = new KoPaletteManager(this, actionCollection(), "Krita palette manager");
00420         Q_CHECK_PTR(m_paletteManager);
00421     }
00422     return m_paletteManager;
00423 }
00424 
00425 void KisView::createLayerBox()
00426 {
00427     m_layerBox = new KisLayerBox(this);
00428     m_layerBox->setCaption(i18n("Layers"));
00429 
00430     connect(m_layerBox, SIGNAL(sigRequestLayer(KisGroupLayerSP, KisLayerSP)),
00431             this, SLOT(addLayer(KisGroupLayerSP, KisLayerSP)));
00432     connect(m_layerBox, SIGNAL(sigRequestGroupLayer(KisGroupLayerSP, KisLayerSP)),
00433             this, SLOT(addGroupLayer(KisGroupLayerSP, KisLayerSP)));
00434     connect(m_layerBox, SIGNAL(sigRequestAdjustmentLayer(KisGroupLayerSP, KisLayerSP)),
00435             this, SLOT(addAdjustmentLayer(KisGroupLayerSP, KisLayerSP)));
00436     connect(m_layerBox, SIGNAL(sigRequestPartLayer(KisGroupLayerSP, KisLayerSP, const KoDocumentEntry&)),
00437             this, SLOT(addPartLayer(KisGroupLayerSP, KisLayerSP, const KoDocumentEntry&)));
00438     connect(m_layerBox, SIGNAL(sigRequestLayerProperties(KisLayerSP)),
00439             this, SLOT(showLayerProperties(KisLayerSP)));
00440     connect(m_layerBox, SIGNAL(sigOpacityChanged(int, bool)), this, SLOT(layerOpacity(int, bool)));
00441     connect(m_layerBox, SIGNAL(sigOpacityFinishedChanging(int, int)),
00442             this, SLOT(layerOpacityFinishedChanging(int, int)));
00443     connect(m_layerBox, SIGNAL(sigItemComposite(const KisCompositeOp&)), this, SLOT(layerCompositeOp(const KisCompositeOp&)));
00444 
00445     paletteManager()->addWidget(m_layerBox, "layerbox", krita::LAYERBOX, 0);
00446 
00447 }
00448 
00449 DCOPObject* KisView::dcopObject()
00450 {
00451     if (!m_dcop) {
00452         m_dcop = new KisViewIface(this);
00453         Q_CHECK_PTR(m_dcop);
00454     }
00455     return m_dcop;
00456 }
00457 
00458 void KisView::setupScrollBars()
00459 {
00460     m_scrollX = 0;
00461     m_scrollY = 0;
00462     m_vScroll = new QScrollBar(QScrollBar::Vertical, this);
00463     Q_CHECK_PTR(m_vScroll);
00464 
00465     m_hScroll = new QScrollBar(QScrollBar::Horizontal, this);
00466     Q_CHECK_PTR(m_hScroll);
00467 
00468     m_vScroll->setGeometry(width() - 16, 20, 16, height() - 36);
00469     m_hScroll->setGeometry(20, height() - 16, width() - 36, 16);
00470     m_hScroll->setValue(0);
00471     m_vScroll->setValue(0);
00472     QObject::connect(m_vScroll, SIGNAL(valueChanged(int)), this, SLOT(scrollV(int)));
00473     QObject::connect(m_hScroll, SIGNAL(valueChanged(int)), this, SLOT(scrollH(int)));
00474 }
00475 
00476 void KisView::setupRulers()
00477 {
00478     m_hRuler = new KisRuler(Qt::Horizontal, this);
00479     Q_CHECK_PTR(m_hRuler);
00480 
00481     m_vRuler = new KisRuler(Qt::Vertical, this);
00482     Q_CHECK_PTR(m_vRuler);
00483 
00484     m_hRuler->setGeometry(20, 0, width() - 20, 20);
00485     m_vRuler->setGeometry(0, 20, 20, height() - 20);
00486 
00487     if (statusBar()) {
00488         m_hRuler->installEventFilter(this);
00489         m_vRuler->installEventFilter(this);
00490     }
00491 }
00492 
00493 #define EPSILON 1e-6
00494 
00495 void KisView::updateStatusBarZoomLabel ()
00496 {
00497     if (zoom() < 1 - EPSILON) {
00498         m_statusBarZoomLabel->setText(i18n("Zoom %1%").arg(zoom() * 100, 0, 'g', 4));
00499     } else {
00500         m_statusBarZoomLabel->setText(i18n("Zoom %1%").arg(zoom() * 100, 0, 'f', 0));
00501     }
00502     m_statusBarZoomLabel->setMaximumWidth(m_statusBarZoomLabel->fontMetrics().width(i18n("Zoom %1%").arg("0.8888  ")));
00503 }
00504 
00505 void KisView::updateStatusBarSelectionLabel()
00506 {
00507     if (m_statusBarSelectionLabel == 0) {
00508         return;
00509     }
00510 
00511     KisImageSP img = currentImg();
00512     if (img) {
00513         KisPaintDeviceSP dev = img->activeDevice();
00514         if (dev) {
00515             if (dev->hasSelection()) {
00516                 QRect r = dev->selection()->selectedExactRect();
00517                 m_statusBarSelectionLabel->setText( i18n("Selection Active: x = %1 y = %2 width = %3 height = %4").arg(r.x()).arg(r.y()).arg( r.width()).arg( r.height()));
00518                 return;
00519             }
00520         }
00521     }
00522 
00523     m_statusBarSelectionLabel->setText(i18n("No Selection"));
00524 }
00525 
00526 void KisView::updateStatusBarProfileLabel()
00527 {
00528     if (m_statusBarProfileLabel == 0) {
00529         return;
00530     }
00531 
00532     KisImageSP img = currentImg();
00533     if (!img) return;
00534 
00535     if (img->getProfile() == 0) {
00536         m_statusBarProfileLabel->setText(i18n("No profile"));
00537     }
00538     else {
00539         m_statusBarProfileLabel->setText(img->colorSpace()->id().name() + "  " + img->getProfile()->productName());
00540     }
00541 }
00542 
00543 
00544 KisProfile *  KisView::monitorProfile()
00545 {
00546     if (m_monitorProfile == 0) {
00547         resetMonitorProfile();
00548     }
00549     return m_monitorProfile;
00550 }
00551 
00552 
00553 void KisView::resetMonitorProfile()
00554 {
00555     m_monitorProfile = KisProfile::getScreenProfile();
00556 
00557     if (m_monitorProfile == 0) {
00558         KisConfig cfg;
00559         QString monitorProfileName = cfg.monitorProfile();
00560         m_monitorProfile = KisMetaRegistry::instance()->csRegistry()->getProfileByName(monitorProfileName);
00561     }
00562 
00563 }
00564 
00565 void KisView::setupStatusBar()
00566 {
00567     KStatusBar *sb = statusBar();
00568 
00569     if (sb) {
00570         m_statusBarZoomLabel = new QLabel(sb);
00571         addStatusBarItem(m_statusBarZoomLabel,1);
00572         updateStatusBarZoomLabel();
00573 
00574         m_statusBarSelectionLabel = new KSqueezedTextLabel(sb);
00575         addStatusBarItem(m_statusBarSelectionLabel,2);
00576         updateStatusBarSelectionLabel();
00577 
00578         m_statusBarProfileLabel = new KSqueezedTextLabel(sb);
00579         addStatusBarItem(m_statusBarProfileLabel,3);
00580         updateStatusBarProfileLabel();
00581 
00582         //int height = m_statusBarProfileLabel->height();
00583 
00584         m_progress = new KisLabelProgress(this);
00585         m_progress->setMaximumWidth(225);
00586         m_progress->setMinimumWidth(225);
00587         m_progress->setMaximumHeight(fontMetrics().height() );
00588         addStatusBarItem(m_progress, 2, true);
00589 
00590         m_progress->hide();
00591     }
00592 }
00593 
00594 void KisView::setupActions()
00595 {
00596     KisConfig cfg;
00597 
00598     m_selectionManager->setup(actionCollection());
00599     m_filterManager->setup(actionCollection());
00600     m_gridManager->setup(actionCollection());
00601     m_perspectiveGridManager->setup(actionCollection());
00602 
00603 
00604     m_fullScreen = KStdAction::fullScreen( NULL, NULL, actionCollection(), this );
00605     connect( m_fullScreen, SIGNAL( toggled( bool )), this, SLOT( slotUpdateFullScreen( bool )));
00606 
00607     m_imgProperties = new KAction(i18n("Image Properties"), 0, this, SLOT(slotImageProperties()), actionCollection(), "img_properties");
00608     m_imgScan = 0; // How the hell do I get a KAction to the scan plug-in?!?
00609     m_imgResizeToLayer = new KAction(i18n("Resize Image to Size of Current Layer"), 0, this, SLOT(imgResizeToActiveLayer()), actionCollection(), "resizeimgtolayer");
00610 
00611     // view actions
00612     m_zoomIn = KStdAction::zoomIn(this, SLOT(slotZoomIn()), actionCollection(), "zoom_in");
00613     m_zoomOut = KStdAction::zoomOut(this, SLOT(slotZoomOut()), actionCollection(), "zoom_out");
00614     m_actualPixels = new KAction(i18n("Actual Pixels"), "Ctrl+0", this, SLOT(slotActualPixels()), actionCollection(), "actual_pixels");
00615     m_actualSize = KStdAction::actualSize(this, SLOT(slotActualSize()), actionCollection(), "actual_size");
00616     m_actualSize->setEnabled(false);
00617     m_fitToCanvas = KStdAction::fitToPage(this, SLOT(slotFitToCanvas()), actionCollection(), "fit_to_canvas");
00618 
00619     // layer actions
00620     m_layerAdd = new KAction(i18n("&Add..."), "Ctrl+Shift+N", this, SLOT(layerAdd()), actionCollection(), "insert_layer");
00621 
00622     m_actionPartLayer = new KoPartSelectAction( i18n( "&Object Layer" ), "frame_query",
00623                                                     this, SLOT( addPartLayer() ),
00624                                                     actionCollection(), "insert_part_layer" );
00625 
00626 
00627     m_actionAdjustmentLayer = new KAction( i18n( "&Adjustment Layer" ), 0,
00628             this, SLOT( addAdjustmentLayer() ),
00629             actionCollection(), "insert_adjustment_layer" );
00630 
00631 
00632     m_layerRm = new KAction(i18n("&Remove"), 0, this, SLOT(layerRemove()), actionCollection(), "remove_layer");
00633     m_layerDup = new KAction(i18n("Duplicate"), 0, this, SLOT(layerDuplicate()), actionCollection(), "duplicate_layer");
00634     m_layerHide = new KAction(i18n("&Hide/Show"), 0, this, SLOT(layerToggleVisible()), actionCollection(), "hide_layer");
00635     m_layerRaise = new KAction(i18n("Raise"), "raise", "Ctrl+]", this, SLOT(layerRaise()), actionCollection(), "raiselayer");
00636     m_layerLower = new KAction(i18n("Lower"), "lower", "Ctrl+[", this, SLOT(layerLower()), actionCollection(), "lowerlayer");
00637     m_layerTop = new KAction(i18n("To Top"), "bring_forward", "Ctrl+Shift+]", this, SLOT(layerFront()), actionCollection(), "toplayer");
00638     m_layerBottom = new KAction(i18n("To Bottom"), "send_backward", "Ctrl+Shift+[", this, SLOT(layerBack()), actionCollection(), "bottomlayer");
00639     m_layerProperties = new KAction(i18n("Properties"), 0, this, SLOT(layerProperties()), actionCollection(), "layer_properties");
00640     (void)new KAction(i18n("I&nsert Image as Layer..."), 0, this, SLOT(slotInsertImageAsLayer()), actionCollection(), "insert_image_as_layer");
00641     m_layerSaveAs = new KAction(i18n("Save Layer as Image..."), "filesave", this, SLOT(saveLayerAsImage()), actionCollection(), "save_layer_as_image");
00642     (void)new KAction(i18n("Flip on &X Axis"), "view_left_right", 0, this, SLOT(mirrorLayerX()), actionCollection(), "mirrorLayerX");
00643     (void)new KAction(i18n("Flip on &Y Axis"), "view_top_bottom", 0, this, SLOT(mirrorLayerY()), actionCollection(), "mirrorLayerY");
00644 
00645     m_createMask = new KAction(i18n("Create Mask"), 0, this,
00646                                SLOT(slotCreateMask()), actionCollection(), "create_mask");
00647     m_maskFromSelection = new KAction(i18n("Mask From Selection"), 0, this,
00648                                       SLOT(slotMaskFromSelection()), actionCollection(),
00649                                       "mask_fromsel");
00650     m_maskToSelection = new KAction(i18n("Mask to Selection"), 0, this,
00651                                SLOT(slotMaskToSelection()), actionCollection(), "mask_tosel");
00652     m_applyMask = new KAction(i18n("Apply Mask"), 0, this, SLOT(slotApplyMask()),
00653                               actionCollection(), "apply_mask");
00654     m_removeMask = new KAction(i18n("Remove Mask"), 0, this,
00655                                SLOT(slotRemoveMask()), actionCollection(), "remove_mask");
00656     m_showMask = new KToggleAction(i18n( "Show Mask" ), 0, this,
00657                                    SLOT(slotShowMask()), actionCollection(), "show_mask");
00658     m_editMask = new KToggleAction(i18n( "Edit Mask" ), 0, this,
00659                                    SLOT(slotEditMask()), actionCollection(), "edit_mask");
00660 
00661     // image actions
00662     m_imgFlatten = new KAction(i18n("&Flatten Image"), "Ctrl+Shift+E", this, SLOT(flattenImage()), actionCollection(), "flatten_image");
00663     m_imgMergeLayer = new KAction(i18n("&Merge with Layer Below"), "Ctrl+E", this, SLOT(mergeLayer()), actionCollection(), "merge_layer");
00664 
00665     // setting actions
00666     KStdAction::preferences(this, SLOT(preferences()), actionCollection(), "preferences");
00667 
00668     m_RulerAction = new KToggleAction( i18n( "Show Rulers" ), "Ctrl+R", this, SLOT( showRuler() ), actionCollection(), "view_ruler" );
00669     m_RulerAction->setChecked(cfg.showRulers());
00670     m_RulerAction->setCheckedState(i18n("Hide Rulers"));
00671     m_RulerAction->setWhatsThis( i18n("The rulers show the horizontal and vertical positions of the mouse on the image "
00672                                       "and can be used to position your mouse at the right place on the canvas. <p>Uncheck this to disable "
00673                                       "the rulers from being displayed." ) );
00674 
00675     //m_guideAction = new KToggleAction( i18n( "Guide Lines" ), 0, this, SLOT( viewGuideLines() ), actionCollection(), "view_guidelines" );
00676 
00677     // Add new palette
00678     new KAction(i18n("Add New Palette..."), 0, this, SLOT(slotAddPalette()),
00679                 actionCollection(), "add_palette");
00680     new KAction(i18n("Edit Palette..."), 0, this, SLOT(slotEditPalette()),
00681                 actionCollection(), "edit_palette");
00682 
00683     // XXX: This triggers a repaint of the image, but way too early
00684     //showRuler();
00685 
00686 }
00687 
00688 void KisView::resizeEvent(QResizeEvent *)
00689 {
00690     if (!m_paintViewEnabled) {
00691         startInitialZoomTimerIfReady();
00692     }
00693 
00694     KisImageSP img = currentImg();
00695     Q_INT32 scrollBarExtent = style().pixelMetric(QStyle::PM_ScrollBarExtent);
00696     Q_INT32 drawH;
00697     Q_INT32 drawW;
00698     Q_INT32 docW;
00699     Q_INT32 docH;
00700 
00701 //    if (img) {
00702 //        KisGuideMgr *mgr = img->guides();
00703 //        mgr->resize(size());
00704 //    }
00705 
00706     docW = static_cast<Q_INT32>(ceil(docWidth() * zoom()));
00707     docH = static_cast<Q_INT32>(ceil(docHeight() * zoom()));
00708 
00709     m_rulerThickness = m_RulerAction->isChecked() ? RULER_THICKNESS : 0;
00710     drawH = height() - m_rulerThickness;
00711     drawW = width() - m_rulerThickness;
00712 
00713     if (drawH < docH) {
00714         // Will need vert scrollbar
00715         drawW -= scrollBarExtent;
00716         if (drawW < docW)
00717             // Will need horiz scrollbar
00718             drawH -= scrollBarExtent;
00719     } else if (drawW < docW) {
00720         // Will need horiz scrollbar
00721         drawH -= scrollBarExtent;
00722         if (drawH < docH)
00723             // Will need vert scrollbar
00724             drawW -= scrollBarExtent;
00725     }
00726 
00727     m_vScroll->setEnabled(docH > drawH);
00728     m_hScroll->setEnabled(docW > drawW);
00729 
00730     if (docH <= drawH && docW <= drawW) {
00731         // we need no scrollbars
00732         m_vScroll->hide();
00733         m_hScroll->hide();
00734         m_vScroll->setValue(0);
00735         m_hScroll->setValue(0);
00736         m_vScrollBarExtent = 0;
00737         m_hScrollBarExtent = 0;
00738     } else if (docH <= drawH) {
00739         // we need a horizontal scrollbar only
00740         m_vScroll->hide();
00741         m_vScroll->setValue(0);
00742         m_hScroll->setRange(0, docW - drawW);
00743         m_hScroll->setGeometry(m_rulerThickness,
00744                      height() - scrollBarExtent,
00745                      width() - m_rulerThickness,
00746                      scrollBarExtent);
00747         m_hScroll->show();
00748         m_hScrollBarExtent = scrollBarExtent;
00749         m_hScrollBarExtent = scrollBarExtent;
00750     } else if(docW <= drawW) {
00751         // we need a vertical scrollbar only
00752         m_hScroll->hide();
00753         m_hScroll->setValue(0);
00754         m_vScroll->setRange(0, docH - drawH);
00755         m_vScroll->setGeometry(width() - scrollBarExtent, m_rulerThickness, scrollBarExtent, height()  - m_rulerThickness);
00756         m_vScroll->show();
00757         m_vScrollBarExtent = scrollBarExtent;
00758     } else {
00759         // we need both scrollbars
00760         m_vScroll->setRange(0, docH - drawH);
00761         m_vScroll->setGeometry(width() - scrollBarExtent,
00762                     m_rulerThickness,
00763                     scrollBarExtent,
00764                     height() -2* m_rulerThickness);
00765         m_hScroll->setRange(0, docW - drawW);
00766         m_hScroll->setGeometry(m_rulerThickness,
00767                      height() - scrollBarExtent,
00768                      width() - 2*m_rulerThickness,
00769                      scrollBarExtent);
00770         m_vScroll->show();
00771         m_hScroll->show();
00772         m_vScrollBarExtent = scrollBarExtent;
00773         m_hScrollBarExtent = scrollBarExtent;
00774     }
00775 
00776     Q_INT32 oldCanvasXOffset = m_canvasXOffset;
00777     Q_INT32 oldCanvasYOffset = m_canvasYOffset;
00778 
00779     if (docW < drawW) {
00780         m_canvasXOffset = (drawW - docW) / 2;
00781     } else {
00782         m_canvasXOffset = 0;
00783     }
00784 
00785     if (docH < drawH) {
00786         m_canvasYOffset = (drawH - docH) / 2;
00787     } else {
00788         m_canvasYOffset = 0;
00789     }
00790 
00791     //Check if rulers are visible
00792     if( m_RulerAction->isChecked() )
00793         m_canvas->setGeometry(m_rulerThickness, m_rulerThickness, drawW, drawH);
00794     else
00795         m_canvas->setGeometry(0, 0, drawW, drawH);
00796     m_canvas->show();
00797 
00798     if (!m_canvas->isOpenGLCanvas()) {
00799 
00800         if (m_canvasPixmap.size() != QSize(drawW, drawH)) {
00801 
00802             Q_INT32 oldCanvasWidth = m_canvasPixmap.width();
00803             Q_INT32 oldCanvasHeight = m_canvasPixmap.height();
00804 
00805             Q_INT32 newCanvasWidth = drawW;
00806             Q_INT32 newCanvasHeight = drawH;
00807 
00808             QRegion exposedRegion = QRect(0, 0, newCanvasWidth, newCanvasHeight);
00809 
00810             // Increase size first so that we can copy the old image area to the new one.
00811             m_canvasPixmap.resize(QMAX(oldCanvasWidth, newCanvasWidth), QMAX(oldCanvasHeight, newCanvasHeight));
00812 
00813             if (!m_canvasPixmap.isNull()) {
00814 
00815                 if (oldCanvasXOffset != m_canvasXOffset || oldCanvasYOffset != m_canvasYOffset) {
00816 
00817                     Q_INT32 srcX;
00818                     Q_INT32 srcY;
00819                     Q_INT32 srcWidth;
00820                     Q_INT32 srcHeight;
00821                     Q_INT32 dstX;
00822                     Q_INT32 dstY;
00823 
00824                     if (oldCanvasXOffset <= m_canvasXOffset) {
00825                         // Move to the right
00826                         srcX = 0;
00827                         dstX = m_canvasXOffset - oldCanvasXOffset;
00828                         srcWidth = oldCanvasWidth;
00829                     } else {
00830                         // Move to the left
00831                         srcX = oldCanvasXOffset - m_canvasXOffset;
00832                         dstX = 0;
00833                         srcWidth = newCanvasWidth;
00834                     }
00835 
00836                     if (oldCanvasYOffset <= m_canvasYOffset) {
00837                         // Move down
00838                         srcY = 0;
00839                         dstY = m_canvasYOffset - oldCanvasYOffset;
00840                         srcHeight = oldCanvasHeight;
00841                     } else {
00842                         // Move up
00843                         srcY = oldCanvasYOffset - m_canvasYOffset;
00844                         dstY = 0;
00845                         srcHeight = newCanvasHeight;
00846                     }
00847 
00848                     bitBlt(&m_canvasPixmap, dstX, dstY, &m_canvasPixmap, srcX, srcY, srcWidth, srcHeight);
00849                     exposedRegion -= QRegion(QRect(dstX, dstY, srcWidth, srcHeight));
00850                 } else {
00851                     exposedRegion -= QRegion(QRect(0, 0, oldCanvasWidth, oldCanvasHeight));
00852                 }
00853             }
00854 
00855             m_canvasPixmap.resize(newCanvasWidth, newCanvasHeight);
00856 
00857             if (!m_canvasPixmap.isNull() && !exposedRegion.isEmpty()) {
00858 
00859                 QMemArray<QRect> rects = exposedRegion.rects();
00860 
00861                 for (unsigned int i = 0; i < rects.count(); i++) {
00862                     QRect r = rects[i];
00863                     updateQPaintDeviceCanvas(viewToWindow(r));
00864                 }
00865             }
00866         }
00867     }
00868 
00869     int fontheight = QFontMetrics(KGlobalSettings::generalFont()).height() * 3;
00870     m_vScroll->setPageStep(drawH);
00871     m_vScroll->setLineStep(fontheight);
00872     m_hScroll->setPageStep(drawW);
00873     m_hScroll->setLineStep(fontheight);
00874 
00875     m_hRuler->setGeometry(m_rulerThickness + m_canvasXOffset, 0, QMIN(docW, drawW), m_rulerThickness);
00876     m_vRuler->setGeometry(0, m_rulerThickness + m_canvasYOffset, m_rulerThickness, QMIN(docH, drawH));
00877 
00878     if (m_vScroll->isVisible())
00879         m_vRuler->updateVisibleArea(0, m_vScroll->value());
00880     else
00881         m_vRuler->updateVisibleArea(0, 0);
00882 
00883     if (m_hScroll->isVisible())
00884         m_hRuler->updateVisibleArea(m_hScroll->value(), 0);
00885     else
00886         m_hRuler->updateVisibleArea(0, 0);
00887 
00888     if( m_RulerAction->isChecked() )
00889     {
00890         m_hRuler->show();
00891         m_vRuler->show();
00892     }
00893     else {
00894         m_hRuler->hide();
00895         m_vRuler->hide();
00896     }
00897 
00898     emit viewTransformationsChanged();
00899 }
00900 
00901 void KisView::styleChange(QStyle& oldStyle)
00902 {
00903     Q_UNUSED(oldStyle);
00904     m_canvas->updateGeometry();
00905     refreshKisCanvas();
00906 }
00907 
00908 void KisView::paletteChange(const QPalette& oldPalette)
00909 {
00910     Q_UNUSED(oldPalette);
00911     refreshKisCanvas();
00912 }
00913 
00914 void KisView::showEvent(QShowEvent *)
00915 {
00916     if (!m_showEventReceived) {
00917         m_showEventReceived = true;
00918         startInitialZoomTimerIfReady();
00919     }
00920 }
00921 
00922 void KisView::updateReadWrite(bool readwrite)
00923 {
00924     layerUpdateGUI(readwrite);
00925 }
00926 
00927 Q_INT32 KisView::horzValue() const
00928 {
00929     return m_hScroll->value() - m_canvasXOffset;
00930 }
00931 
00932 Q_INT32 KisView::vertValue() const
00933 {
00934     return m_vScroll->value() - m_canvasYOffset;
00935 }
00936 
00937 void KisView::updateQPaintDeviceCanvas(const QRect& imageRect)
00938 {
00939     QRect vr = windowToView(imageRect);
00940     vr &= QRect(0, 0, m_canvas->width(), m_canvas->height());
00941 
00942     if (!vr.isEmpty()) {
00943 
00944         QPainter gc;
00945 
00946         if (gc.begin(&m_canvasPixmap)) {
00947 
00948             KisImageSP img = currentImg();
00949 
00950             if (img && m_paintViewEnabled) {
00951 
00952                 QRect wr = viewToWindow(vr);
00953 
00954                 if (wr.left() < 0 || wr.right() >= img->width() || wr.top() < 0 || wr.bottom() >= img->height()) {
00955                     // Erase areas outside document
00956                     QRegion rg(vr);
00957                     rg -= QRegion(windowToView(QRect(0, 0, img->width(), img->height())));
00958 
00959                     QMemArray<QRect> rects = rg.rects();
00960 
00961                     for (unsigned int i = 0; i < rects.count(); i++) {
00962                         QRect er = rects[i];
00963                         gc.fillRect(er, colorGroup().mid());
00964                     }
00965                     wr &= QRect(0, 0, img->width(), img->height());
00966                 }
00967 
00968                 if (!wr.isEmpty()) {
00969 
00970                     KisImage::PaintFlags paintFlags = (KisImage::PaintFlags)KisImage::PAINT_BACKGROUND;
00971 
00972                     if (m_actLayerVis) {
00973                         paintFlags = (KisImage::PaintFlags)(paintFlags|KisImage::PAINT_MASKINACTIVELAYERS);
00974                     }
00975 
00976                     if (m_selectionManager->displaySelection())
00977                     {
00978                         paintFlags = (KisImage::PaintFlags)(paintFlags|KisImage::PAINT_SELECTION);
00979                     }
00980 
00981                     if (zoom() > 1.0 - EPSILON) {
00982 
00983                         gc.setWorldXForm(true);
00984                         gc.translate(-horzValue(), -vertValue());
00985                         gc.scale(zoomFactor(), zoomFactor());
00986 
00987                         m_image->renderToPainter(wr.left(), wr.top(),
00988                             wr.right(), wr.bottom(), gc, monitorProfile(),
00989                             paintFlags, HDRExposure());
00990                     } else {
00991 
00992                         QRect canvasRect = windowToView(wr);
00993                         QRect scaledImageRect = canvasRect;
00994                         scaledImageRect.moveBy(horzValue(), vertValue());
00995 
00996                         QSize scaledImageSize(static_cast<Q_INT32>(ceil(docWidth() * zoom())),
00997                                             static_cast<Q_INT32>(ceil(docHeight() * zoom())));
00998 
00999                         QImage image = m_image->convertToQImage(scaledImageRect, scaledImageSize,
01000                                                                 monitorProfile(), paintFlags, HDRExposure());
01001 
01002                         gc.drawImage(canvasRect.topLeft(), image, image.rect());
01003 
01004                         // Set up for the grid drawer.
01005                         gc.setWorldXForm(true);
01006                         gc.translate(-horzValue(), -vertValue());
01007                         gc.scale(zoomFactor(), zoomFactor());
01008                     }
01009 
01010                     m_gridManager->drawGrid( wr, &gc );
01011                     m_perspectiveGridManager->drawGrid( wr, &gc );
01012                 }
01013 //                    paintGuides();
01014             } else {
01015                 gc.fillRect(vr, colorGroup().mid());
01016             }
01017         }
01018     }
01019 }
01020 
01021 void KisView::paintQPaintDeviceView(const QRegion& canvasRegion)
01022 {
01023     Q_ASSERT(m_canvas->QPaintDeviceWidget() != 0);
01024 
01025     if (m_canvas->QPaintDeviceWidget() != 0 && !m_canvasPixmap.isNull()) {
01026         QMemArray<QRect> rects = canvasRegion.rects();
01027 
01028         for (unsigned int i = 0; i < rects.count(); i++) {
01029             QRect r = rects[i];
01030 
01031             bitBlt(m_canvas->QPaintDeviceWidget(), r.x(), r.y(), &m_canvasPixmap,
01032                    r.x(), r.y(), r.width(), r.height());
01033         }
01034 
01035         paintToolOverlay(canvasRegion);
01036     }
01037 }
01038 
01039 void KisView::updateOpenGLCanvas(const QRect& imageRect)
01040 {
01041 #ifdef HAVE_GL
01042     KisImageSP img = currentImg();
01043 
01044     if (img && m_paintViewEnabled) {
01045         Q_ASSERT(m_OpenGLImageContext != 0);
01046 
01047         if (m_OpenGLImageContext != 0) {
01048             m_OpenGLImageContext->update(imageRect);
01049         }
01050     }
01051 #else
01052     Q_UNUSED(imageRect);
01053 #endif
01054 }
01055 
01056 void KisView::paintOpenGLView(const QRect& canvasRect)
01057 {
01058 #ifdef HAVE_GL
01059     if (!m_canvas->isUpdatesEnabled()) {
01060         return;
01061     }
01062 
01063     m_canvas->OpenGLWidget()->makeCurrent();
01064 
01065     glDrawBuffer(GL_BACK);
01066 
01067     QColor widgetBackgroundColor = colorGroup().mid();
01068 
01069     glClearColor(widgetBackgroundColor.red() / 255.0, widgetBackgroundColor.green() / 255.0, widgetBackgroundColor.blue() / 255.0, 1.0);
01070     glClear(GL_COLOR_BUFFER_BIT);
01071 
01072     KisImageSP img = currentImg();
01073 
01074     if (img && m_paintViewEnabled) {
01075 
01076         QRect vr = canvasRect;
01077         vr &= QRect(0, 0, m_canvas->width(), m_canvas->height());
01078 
01079         if (!vr.isNull()) {
01080 
01081             glMatrixMode(GL_PROJECTION);
01082             glLoadIdentity();
01083             glViewport(0, 0, m_canvas->width(), m_canvas->height());
01084             glOrtho(0, m_canvas->width(), m_canvas->height(), 0, -1, 1);
01085 
01086             glMatrixMode(GL_MODELVIEW);
01087             glLoadIdentity();
01088 
01089             glBindTexture(GL_TEXTURE_2D, m_OpenGLImageContext->backgroundTexture());
01090 
01091             glTranslatef(m_canvasXOffset, m_canvasYOffset, 0.0);
01092 
01093             glEnable(GL_TEXTURE_2D);
01094             glBegin(GL_QUADS);
01095 
01096             glTexCoord2f(0.0, 0.0);
01097             glVertex2f(0.0, 0.0);
01098 
01099             glTexCoord2f((img->width() * zoom()) / KisOpenGLImageContext::BACKGROUND_TEXTURE_WIDTH, 0.0);
01100             glVertex2f(img->width() * zoom(), 0.0);
01101 
01102             glTexCoord2f((img->width() * zoom()) / KisOpenGLImageContext::BACKGROUND_TEXTURE_WIDTH,
01103                          (img->height() * zoom()) / KisOpenGLImageContext::BACKGROUND_TEXTURE_HEIGHT);
01104             glVertex2f(img->width() * zoom(), img->height() * zoom());
01105 
01106             glTexCoord2f(0.0, (img->height() * zoom()) / KisOpenGLImageContext::BACKGROUND_TEXTURE_HEIGHT);
01107             glVertex2f(0.0, img->height() * zoom());
01108 
01109             glEnd();
01110 
01111             glTranslatef(-m_canvasXOffset, -m_canvasYOffset, 0.0);
01112 
01113             glTranslatef(-horzValue(), -vertValue(), 0.0);
01114             glScalef(zoomFactor(), zoomFactor(), 1.0);
01115 
01116             glEnable(GL_BLEND);
01117             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01118 
01119             QRect wr = viewToWindow(QRect(0, 0, m_canvas->width(), m_canvas->height()));
01120             wr &= QRect(0, 0, img->width(), img->height());
01121 
01122             m_OpenGLImageContext->setHDRExposure(HDRExposure());
01123 
01124             m_canvas->OpenGLWidget()->makeCurrent();
01125 
01126             for (int x = (wr.left() / m_OpenGLImageContext->imageTextureTileWidth()) * m_OpenGLImageContext->imageTextureTileWidth();
01127                   x <= wr.right();
01128                   x += m_OpenGLImageContext->imageTextureTileWidth()) {
01129                 for (int y = (wr.top() / m_OpenGLImageContext->imageTextureTileHeight()) * m_OpenGLImageContext->imageTextureTileHeight();
01130                       y <= wr.bottom();
01131                       y += m_OpenGLImageContext->imageTextureTileHeight()) {
01132 
01133                     glBindTexture(GL_TEXTURE_2D, m_OpenGLImageContext->imageTextureTile(x, y));
01134 
01135                     glBegin(GL_QUADS);
01136 
01137                     glTexCoord2f(0.0, 0.0);
01138                     glVertex2f(x, y);
01139 
01140                     glTexCoord2f(1.0, 0.0);
01141                     glVertex2f(x + m_OpenGLImageContext->imageTextureTileWidth(), y);
01142 
01143                     glTexCoord2f(1.0, 1.0);
01144                     glVertex2f(x + m_OpenGLImageContext->imageTextureTileWidth(), y + m_OpenGLImageContext->imageTextureTileHeight());
01145 
01146                     glTexCoord2f(0.0, 1.0);
01147                     glVertex2f(x, y + m_OpenGLImageContext->imageTextureTileHeight());
01148 
01149                     glEnd();
01150                 }
01151             }
01152 
01153             glDisable(GL_TEXTURE_2D);
01154             glDisable(GL_BLEND);
01155 
01156             m_gridManager->drawGrid(wr, 0, true);
01157             m_perspectiveGridManager->drawGrid( wr, 0, true );
01158 
01159             // Unbind the texture otherwise the ATI driver crashes when the canvas context is
01160             // made current after the textures are deleted following an image resize.
01161             glBindTexture(GL_TEXTURE_2D, 0);
01162 
01163             //paintGuides();
01164         }
01165     }
01166 
01167     m_canvas->OpenGLWidget()->swapBuffers();
01168 
01169     paintToolOverlay(QRegion(canvasRect));
01170 
01171 #else
01172     Q_UNUSED(canvasRect);
01173 #endif
01174 }
01175 
01176 void KisView::setInputDevice(KisInputDevice inputDevice)
01177 {
01178     if (inputDevice != m_inputDevice) {
01179         m_inputDevice = inputDevice;
01180 
01181         m_toolManager->setToolForInputDevice(m_inputDevice, inputDevice);
01182 
01183         if (m_toolManager->currentTool() == 0) {
01184             m_toolManager->setCurrentTool(m_toolManager->findTool("tool_brush", m_inputDevice));
01185         }
01186         else {
01187             m_toolManager->setCurrentTool(m_toolManager->currentTool());
01188         }
01189         m_toolManager->activateCurrentTool();
01190 
01191         emit sigInputDeviceChanged(inputDevice);
01192     }
01193 
01194 }
01195 
01196 KisInputDevice KisView::currentInputDevice() const
01197 {
01198     return m_inputDevice;
01199 }
01200 
01201 
01202 KisCanvas *KisView::kiscanvas() const
01203 {
01204     return m_canvas;
01205 }
01206 
01207 void KisView::updateCanvas()
01208 {
01209     if (m_image) {
01210         updateCanvas(m_image->bounds());
01211     }
01212 }
01213 
01214 void KisView::updateCanvas(Q_INT32 x, Q_INT32 y, Q_INT32 w, Q_INT32 h)
01215 {
01216     updateCanvas(QRect(x, y, w, h));
01217 }
01218 
01219 void KisView::updateCanvas(const QRect& imageRect)
01220 {
01221     if (m_canvas->isOpenGLCanvas()) {
01222         updateOpenGLCanvas(imageRect);
01223         paintOpenGLView(windowToView(imageRect));
01224     } else {
01225         updateQPaintDeviceCanvas(imageRect);
01226         //m_canvas->update(windowToView(imageRect));
01227         m_canvas->repaint(windowToView(imageRect));
01228     }
01229 }
01230 
01231 void KisView::refreshKisCanvas()
01232 {
01233     QRect imageRect = viewToWindow(QRect(0, 0, m_canvas->width(), m_canvas->height()));
01234 
01235     if (m_image) {
01236         imageRect |= m_image->bounds();
01237     }
01238 
01239     updateCanvas(imageRect);
01240 
01241     // Enable this if updateCanvas does an m_canvas->update()
01242     //m_canvas->repaint();
01243 }
01244 
01245 void KisView::selectionDisplayToggled(bool displaySelection)
01246 {
01247 #ifdef HAVE_GL
01248     if (m_canvas->isOpenGLCanvas()) {
01249         if (m_OpenGLImageContext) {
01250             m_OpenGLImageContext->setSelectionDisplayEnabled(displaySelection);
01251         }
01252     }
01253 #else
01254     Q_UNUSED(displaySelection);
01255 #endif
01256     updateCanvas();
01257 }
01258 
01259 void KisView::layerUpdateGUI(bool enable)
01260 {
01261     KisImageSP img = currentImg();
01262 
01263     KisLayerSP layer;
01264     Q_INT32 nlayers = 0;
01265     Q_INT32 nvisible = 0;
01266 
01267 
01268 
01269     if (img) {
01270         layer = img->activeLayer();
01271         nlayers = img->nlayers();
01272         nvisible = nlayers - img->nHiddenLayers();
01273     }
01274 
01275     KisPaintLayer * pl = dynamic_cast<KisPaintLayer*>(layer.data());
01276 
01277     if (pl && ( m_currentColorChooserDisplay != KisID("BLA") ||
01278                 pl->paintDevice()->colorSpace()->id() != m_currentColorChooserDisplay)) {
01279         if (pl->paintDevice()->colorSpace()->id() == KisID("WET")) {
01280             m_paletteManager->hideWidget( "hsvwidget" );
01281             m_paletteManager->hideWidget( "rgbwidget" );
01282             m_paletteManager->hideWidget( "graywidget" );
01283             m_paletteManager->hideWidget( "palettewidget" );
01284             m_paletteManager->showWidget( "watercolor docker" );
01285         }
01286         else {
01287             m_paletteManager->hideWidget( "watercolor docker" );
01288             m_paletteManager->showWidget( "palettewidget" );
01289             m_paletteManager->showWidget( "graywidget" );
01290             m_paletteManager->showWidget( "rgbwidget" );
01291             m_paletteManager->showWidget( "hsvwidget" );
01292         }
01293         m_currentColorChooserDisplay = pl->paintDevice()->colorSpace()->id();
01294     }
01295 
01296     enable = enable && img && layer && layer->visible() && !layer->locked();
01297     m_layerDup->setEnabled(enable);
01298     m_layerRm->setEnabled(enable);
01299     m_layerHide->setEnabled(img && layer);
01300     m_layerProperties->setEnabled(enable);
01301     m_layerSaveAs->setEnabled(enable);
01302     m_layerRaise->setEnabled(enable && layer->prevSibling());
01303     m_layerLower->setEnabled(enable && layer->nextSibling());
01304     m_layerTop->setEnabled(enable && nlayers > 1 && layer != img->rootLayer()->firstChild());
01305     m_layerBottom->setEnabled(enable && nlayers > 1 && layer != img->rootLayer()->lastChild());
01306 
01307     // XXX these should be named layer instead of img
01308     m_imgFlatten->setEnabled(nlayers > 1);
01309     m_imgMergeLayer->setEnabled(nlayers > 1 && layer && layer->nextSibling());
01310 
01311 
01312     m_selectionManager->updateGUI();
01313     m_filterManager->updateGUI();
01314     m_toolManager->updateGUI();
01315     m_gridManager->updateGUI();
01316     m_perspectiveGridManager->updateGUI();
01317 
01318 
01319     KisPartLayer * partLayer = dynamic_cast<KisPartLayer*>(layer.data());
01320     if (partLayer) {
01321         setCanvasCursor( KisCursor::arrowCursor() );
01322     }
01323 
01324     if (img && img->activeDevice())
01325         emit currentColorSpaceChanged(img->activeDevice()->colorSpace());
01326 
01327     imgUpdateGUI();
01328 }
01329 
01330 
01331 void KisView::imgUpdateGUI()
01332 {
01333     KisImageSP img = currentImg();
01334 
01335     m_imgResizeToLayer->setEnabled(img && img->activeLayer());
01336 
01337     updateStatusBarProfileLabel();
01338 }
01339 
01340 static const double zoomLevels[] = {
01341     1.0 / 500,
01342     1.0 / 333.333333,
01343     1.0 / 250,
01344     1.0 / 200,
01345     1.0 / 150,
01346     1.0 / 100,
01347     1.0 / 66.666667,
01348     1.0 / 50,
01349     1.0 / 33.333333,
01350     1.0 / 25,
01351     1.0 / 20,
01352     1.0 / 16,
01353     1.0 / 12,
01354     1.0 / 8,
01355     1.0 / 6,
01356     1.0 / 4,
01357     1.0 / 3,
01358     1.0 / 2,
01359     1.0 / 1.5,
01360     1,
01361     2,
01362     3,
01363     4,
01364     5,
01365     6,
01366     7,
01367     8,
01368     12,
01369     16
01370 };
01371 
01372 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
01373 #define NUM_ZOOM_LEVELS ARRAY_SIZE(zoomLevels)
01374 
01375 #define FIRST_ZOOM_LEVEL_INDEX 0
01376 #define LAST_ZOOM_LEVEL_INDEX (NUM_ZOOM_LEVELS - 1)
01377 
01378 #define KISVIEW_MIN_ZOOM (zoomLevels[FIRST_ZOOM_LEVEL_INDEX])
01379 #define KISVIEW_MAX_ZOOM (zoomLevels[LAST_ZOOM_LEVEL_INDEX])
01380 
01381 double KisView::nextZoomInLevel() const
01382 {
01383     uint zoomLevelIndex = FIRST_ZOOM_LEVEL_INDEX;
01384 
01385     while (zoom() >= zoomLevels[zoomLevelIndex] && zoomLevelIndex < LAST_ZOOM_LEVEL_INDEX) {
01386         zoomLevelIndex++;
01387     }
01388 
01389     return zoomLevels[zoomLevelIndex];
01390 }
01391 
01392 double KisView::nextZoomOutLevel(double zoomLevel) const
01393 {
01394     int zoomLevelIndex = LAST_ZOOM_LEVEL_INDEX;
01395 
01396     while (zoomLevel <= zoomLevels[zoomLevelIndex] && zoomLevelIndex > FIRST_ZOOM_LEVEL_INDEX) {
01397         zoomLevelIndex--;
01398     }
01399 
01400     return zoomLevels[zoomLevelIndex];
01401 }
01402 
01403 double KisView::nextZoomOutLevel() const
01404 {
01405     return nextZoomOutLevel(zoom());
01406 }
01407 
01408 void KisView::zoomAroundPoint(double x, double y, double zf)
01409 {
01410     // Disable updates while we change the scrollbar settings.
01411     m_canvas->setUpdatesEnabled(false);
01412     m_hScroll->setUpdatesEnabled(false);
01413     m_vScroll->setUpdatesEnabled(false);
01414 
01415     if (x < 0 || y < 0) {
01416         // Zoom about the centre of the current display
01417         KisImageSP img = currentImg();
01418 
01419         if (img) {
01420             if (m_hScroll->isVisible()) {
01421                 KisPoint c = viewToWindow(KisPoint(m_canvas->width() / 2.0, m_canvas->height() / 2.0));
01422                 x = c.x();
01423             }
01424             else {
01425                 x = img->width() / 2.0;
01426             }
01427 
01428             if (m_vScroll->isVisible()) {
01429                 KisPoint c = viewToWindow(KisPoint(m_canvas->width() / 2.0, m_canvas->height() / 2.0));
01430                 y = c.y();
01431             }
01432             else {
01433                 y = img->height() / 2.0;
01434             }
01435         }
01436         else {
01437             x = 0;
01438             y = 0;
01439         }
01440     }
01441 
01442     setZoom(zf);
01443 
01444     Q_ASSERT(m_zoomIn);
01445     Q_ASSERT(m_zoomOut);
01446 
01447     updateStatusBarZoomLabel ();
01448 
01449     m_zoomIn->setEnabled(zf < KISVIEW_MAX_ZOOM);
01450     m_zoomOut->setEnabled(zf > KISVIEW_MIN_ZOOM);
01451     resizeEvent(0);
01452 
01453     m_hRuler->setZoom(zf);
01454     m_vRuler->setZoom(zf);
01455 
01456     if (m_hScroll->isVisible()) {
01457         double vcx = m_canvas->width() / 2.0;
01458         Q_INT32 scrollX = qRound(x * zoom() - vcx);
01459         m_hScroll->setValue(scrollX);
01460     }
01461 
01462     if (m_vScroll->isVisible()) {
01463         double vcy = m_canvas->height() / 2.0;
01464         Q_INT32 scrollY = qRound(y * zoom() - vcy);
01465         m_vScroll->setValue(scrollY);
01466     }
01467 
01468     // Now update everything.
01469     m_canvas->setUpdatesEnabled(true);
01470     m_hScroll->setUpdatesEnabled(true);
01471     m_vScroll->setUpdatesEnabled(true);
01472     m_hScroll->update();
01473     m_vScroll->update();
01474 
01475     if (m_canvas->isOpenGLCanvas()) {
01476         paintOpenGLView(QRect(0, 0, m_canvas->width(), m_canvas->height()));
01477     } else {
01478         refreshKisCanvas();
01479     }
01480 
01481     emit viewTransformationsChanged();
01482 }
01483 
01484 void KisView::zoomTo(const KisRect& r)
01485 {
01486     if (!r.isNull()) {
01487 
01488         double wZoom = fabs(m_canvas->width() / r.width());
01489         double hZoom = fabs(m_canvas->height() / r.height());
01490 
01491         double zf = kMin(wZoom, hZoom);
01492 
01493         if (zf < KISVIEW_MIN_ZOOM) {
01494             zf = KISVIEW_MIN_ZOOM;
01495         }
01496         else
01497             if (zf > KISVIEW_MAX_ZOOM) {
01498                 zf = KISVIEW_MAX_ZOOM;
01499             }
01500 
01501         zoomAroundPoint(r.center().x(), r.center().y(), zf);
01502     }
01503 }
01504 
01505 void KisView::zoomTo(const QRect& r)
01506 {
01507     zoomTo(KisRect(r));
01508 }
01509 
01510 void KisView::zoomTo(Q_INT32 x, Q_INT32 y, Q_INT32 w, Q_INT32 h)
01511 {
01512     zoomTo(KisRect(x, y, w, h));
01513 }
01514 
01515 void KisView::zoomIn(Q_INT32 x, Q_INT32 y)
01516 {
01517     zoomAroundPoint(x, y, nextZoomInLevel());
01518 }
01519 
01520 void KisView::zoomOut(Q_INT32 x, Q_INT32 y)
01521 {
01522     zoomAroundPoint(x, y, nextZoomOutLevel());
01523 }
01524 
01525 void KisView::zoomIn()
01526 {
01527     slotZoomIn();
01528 }
01529 
01530 void KisView::zoomOut()
01531 {
01532     slotZoomOut();
01533 }
01534 
01535 void KisView::slotZoomIn()
01536 {
01537     zoomIn(-1, -1);
01538 }
01539 
01540 void KisView::slotZoomOut()
01541 {
01542     zoomOut(-1, -1);
01543 }
01544 
01545 void KisView::slotActualPixels()
01546 {
01547     zoomAroundPoint(-1, -1, 1.0);
01548 }
01549 
01550 void KisView::slotActualSize()
01551 {
01552     //XXX later this should be update to take screen res and image res into consideration
01553     zoomAroundPoint(-1, -1, 1.0);
01554 }
01555 
01556 double KisView::fitToCanvasZoomLevel() const
01557 {
01558     int fullCanvasWidth = width();
01559 
01560     if (m_vRuler->isVisible()) {
01561         fullCanvasWidth -= m_vRuler->width();
01562     }
01563 
01564     int fullCanvasHeight = height();
01565 
01566     if (m_hRuler->isVisible()) {
01567         fullCanvasHeight -= m_hRuler->height();
01568     }
01569 
01570     KisImageSP img = currentImg();
01571     if (img) {
01572         double xZoomLevel = static_cast<double>(fullCanvasWidth) / img->width();
01573         double yZoomLevel = static_cast<double>(fullCanvasHeight) / img->height();
01574 
01575         return QMIN(xZoomLevel, yZoomLevel);
01576     }
01577     else {
01578         return 1;
01579     }
01580 }
01581 
01582 void KisView::slotFitToCanvas()
01583 {
01584     zoomAroundPoint(-1, -1, fitToCanvasZoomLevel());
01585 }
01586 
01587 void KisView::setInitialZoomLevel()
01588 {
01589     double zoomLevel = fitToCanvasZoomLevel();
01590 
01591     if (zoomLevel > 1) {
01592         zoomLevel = 1;
01593     } else {
01594         zoomLevel = nextZoomOutLevel(zoomLevel);
01595     }
01596 
01597     zoomAroundPoint(-1, -1, zoomLevel);
01598 }
01599 
01600 void KisView::imgResizeToActiveLayer()
01601 {
01602     KisImageSP img = currentImg();
01603     KisLayerSP layer;
01604 
01605     if (img && (layer = img->activeLayer())) {
01606 
01607         if (m_adapter && m_adapter->undo()) {
01608             m_adapter->beginMacro(i18n("Resize Image to Size of Current Layer"));
01609         }
01610 
01611         img->lock();
01612 
01613         QRect r = layer->exactBounds();
01614         img->resize(r.width(), r.height(), r.x(), r.y(), true);
01615 
01616         img->unlock();
01617 
01618         if (m_adapter && m_adapter->undo()) {
01619             m_adapter->endMacro();
01620         }
01621     }
01622 }
01623 
01624 void KisView::slotImageProperties()
01625 {
01626     KisImageSP img = currentImg();
01627 
01628     if (!img) return;
01629 
01630     KisDlgImageProperties dlg(img, this);
01631 
01632     if (dlg.exec() == QDialog::Accepted) {
01633         if (dlg.imageWidth() != img->width() ||
01634             dlg.imageHeight() != img->height()) {
01635 
01636             resizeCurrentImage(dlg.imageWidth(),
01637                                dlg.imageHeight());
01638         }
01639         Q_INT32 opacity = dlg.opacity();
01640         opacity = opacity * 255 / 100;
01641         img->setName(dlg.imageName());
01642         img->setColorSpace(dlg.colorSpace());
01643         img->setResolution(dlg.resolution(), dlg.resolution());
01644         img->setDescription(dlg.description());
01645         img->setProfile(dlg.profile());
01646     }
01647 }
01648 
01649 void KisView::slotInsertImageAsLayer()
01650 {
01651     if (importImage() > 0)
01652         m_doc->setModified(true);
01653 }
01654 
01655 void KisView::slotAddPalette()
01656 {
01657     KDialogBase* base = new KDialogBase(this, 0, true, i18n("Add Palette"), KDialogBase::Ok | KDialogBase::Cancel);
01658     KisCustomPalette* p = new KisCustomPalette(base, "add palette", i18n("Add Palette"), this);
01659     base->setMainWidget(p);
01660     base->show();
01661 }
01662 
01663 void KisView::slotEditPalette()
01664 {
01665     KisPaletteChooser chooser(this);
01666     KisResourceServerBase* srv = KisResourceServerRegistry::instance()->get("PaletteServer");
01667     if (!srv) {
01668         return;
01669     }
01670     QValueList<KisResource*> resources = srv->resources();
01671     QValueList<KisPalette*> palettes;
01672 
01673     for(uint i = 0; i < resources.count(); i++) {
01674         KisPalette* palette = dynamic_cast<KisPalette*>(*resources.at(i));
01675 
01676         chooser.paletteList->insertItem(palette->name());
01677         palettes.append(palette);
01678     }
01679 
01680     if (chooser.exec() != QDialog::Accepted ) {
01681         return;
01682     }
01683 
01684     int index = chooser.paletteList->currentItem();
01685     if (index < 0) {
01686         KMessageBox::error(this, i18n("No palette selected."), i18n("Palette"));
01687         return;
01688     }
01689 
01690     KDialogBase* base = new KDialogBase(this, 0, true, i18n("Edit Palette") , KDialogBase::Ok);
01691     KisCustomPalette* cp = new KisCustomPalette(base, "edit palette",
01692             i18n("Edit Palette"), this);
01693     cp->setEditMode(true);
01694     cp->setPalette(*palettes.at(index));
01695     base->setMainWidget(cp);
01696     base->show();
01697 }
01698 
01699 void KisView::saveLayerAsImage()
01700 {
01701     QStringList listMimeFilter = KoFilterManager::mimeFilter("application/x-krita", KoFilterManager::Export);
01702     QString mimelist = listMimeFilter.join(" ");
01703 
01704     KFileDialog fd (QString::null, mimelist, this, "Export Layer", true);
01705     fd.setCaption(i18n("Export Layer"));
01706     fd.setMimeFilter(listMimeFilter);
01707     fd.setOperationMode(KFileDialog::Saving);
01708 
01709     if (!fd.exec()) return;
01710 
01711     KURL url = fd.selectedURL();
01712     QString mimefilter = fd.currentMimeFilter();
01713 
01714     if (url.isEmpty())
01715         return;
01716 
01717 
01718     KisImageSP img = currentImg();
01719     if (!img) return;
01720 
01721     KisLayerSP l = img->activeLayer();
01722     if (!l) return;
01723 
01724     QRect r = l->exactBounds();
01725 
01726     KisDoc d;
01727     d.prepareForImport();
01728 
01729     KisImageSP dst = new KisImage(d.undoAdapter(), r.width(), r.height(), img->colorSpace(), l->name());
01730     d.setCurrentImage( dst );
01731     dst->addLayer(l->clone(),dst->rootLayer(),0);
01732 
01733     d.setOutputMimeType(mimefilter.latin1());
01734     d.exp0rt(url);
01735 }
01736 
01737 
01738 
01739 Q_INT32 KisView::importImage(const KURL& urlArg)
01740 {
01741     KisImageSP currentImage = currentImg();
01742 
01743     if (!currentImage) {
01744         return 0;
01745     }
01746 
01747     KURL::List urls;
01748     Q_INT32 rc = 0;
01749 
01750     if (urlArg.isEmpty()) {
01751         QString mimelist = KoFilterManager::mimeFilter("application/x-krita", KoFilterManager::Import).join(" ");
01752         urls = KFileDialog::getOpenURLs(QString::null, mimelist, 0, i18n("Import Image"));
01753     } else {
01754         urls.push_back(urlArg);
01755     }
01756 
01757     if (urls.empty())
01758         return 0;
01759 
01760     for (KURL::List::iterator it = urls.begin(); it != urls.end(); ++it) {
01761         new KisImportCatcher( *it, currentImage );
01762     }
01763 
01764     updateCanvas();
01765 
01766     return rc;
01767 }
01768 
01769 void KisView::rotateLayer180()
01770 {
01771     rotateLayer( 180 );
01772 }
01773 
01774 void KisView::rotateLayerLeft90()
01775 {
01776     rotateLayer( 270 );
01777 }
01778 
01779 void KisView::rotateLayerRight90()
01780 {
01781     rotateLayer( 90 );
01782 }
01783 
01784 void KisView::mirrorLayerX()
01785 {
01786     if (!currentImg()) return;
01787     KisPaintDeviceSP dev = currentImg()->activeDevice();
01788     if (!dev) return;
01789 
01790     KisTransaction * t = 0;
01791     if (undoAdapter() && undoAdapter()->undo()) {
01792         t = new KisTransaction(i18n("Mirror Layer X"), dev);
01793         Q_CHECK_PTR(t);
01794     }
01795 
01796     dev->mirrorX();
01797 
01798     if (t) undoAdapter()->addCommand(t);
01799 
01800     m_doc->setModified(true);
01801     layersUpdated();
01802     updateCanvas();
01803 }
01804 
01805 void KisView::mirrorLayerY()
01806 {
01807     if (!currentImg()) return;
01808     KisPaintDeviceSP dev = currentImg()->activeDevice();
01809     if (!dev) return;
01810 
01811     KisTransaction * t = 0;
01812     if (undoAdapter() && undoAdapter()->undo()) {
01813         t = new KisTransaction(i18n("Mirror Layer Y"), dev);
01814         Q_CHECK_PTR(t);
01815     }
01816 
01817     dev->mirrorY();
01818 
01819     if (t) undoAdapter()->addCommand(t);
01820 
01821     m_doc->setModified(true);
01822     layersUpdated();
01823     updateCanvas();
01824 }
01825 
01826 void KisView::scaleLayer(double sx, double sy, KisFilterStrategy *filterStrategy)
01827 {
01828     if (!currentImg()) return;
01829 
01830     KisPaintDeviceSP dev = currentImg()->activeDevice();
01831     if (!dev) return;
01832 
01833     KisTransaction * t = 0;
01834     if (undoAdapter() && undoAdapter()->undo()) {
01835         t = new KisTransaction(i18n("Scale Layer"), dev);
01836         Q_CHECK_PTR(t);
01837     }
01838     if ( dev->colorSpace()->id() == KisID("RGBA") || dev->colorSpace()->id() == KisID("CMYK") || dev->colorSpace()->id() == KisID("GRAYA")) {
01839         KisScaleWorker w (dev, sx, sy, filterStrategy);
01840         w.run();
01841     }
01842     else {
01843 
01844         KisTransformWorker worker(dev, sx, sy, 0, 0, 0.0, 0, 0, m_progress, filterStrategy);
01845         worker.run();
01846     }
01847 
01848     if (t) undoAdapter()->addCommand(t);
01849 
01850     m_doc->setModified(true);
01851     layersUpdated();
01852     updateCanvas();
01853 }
01854 
01855 void KisView::rotateLayer(double angle)
01856 {
01857     if (!currentImg()) return;
01858 
01859     KisPaintDeviceSP dev = currentImg()->activeDevice();
01860     if (!dev) return;
01861 
01862     KisTransaction * t = 0;
01863     if (undoAdapter() && undoAdapter()->undo()) {
01864         t = new KisTransaction(i18n("Rotate Layer"), dev);
01865         Q_CHECK_PTR(t);
01866     }
01867 
01868     KisFilterStrategy *filter = KisFilterStrategyRegistry::instance()->get(KisID("Triangle"));
01869     angle *= M_PI/180;
01870     Q_INT32 w = currentImg()->width();
01871     Q_INT32 h = currentImg()->height();
01872     Q_INT32 tx = Q_INT32((w*cos(angle) - h*sin(angle) - w) / 2 + 0.5);
01873     Q_INT32 ty = Q_INT32((h*cos(angle) + w*sin(angle) - h) / 2 + 0.5);
01874 
01875     KisTransformWorker tw(dev, 1.0, 1.0, 0, 0, angle, -tx, -ty, m_progress, filter);
01876     tw.run();
01877 
01878     if (t) undoAdapter()->addCommand(t);
01879 
01880     m_doc->setModified(true);
01881     layersUpdated();
01882     updateCanvas();
01883 }
01884 
01885 void KisView::shearLayer(double angleX, double angleY)
01886 {
01887     if (!currentImg()) return;
01888 
01889     KisLayerSP layer = currentImg()->activeLayer();
01890     if (!layer) return;
01891 
01892     KisUndoAdapter * undo = 0;
01893     if ((undo = currentImg()->undoAdapter())) {
01894         undo->beginMacro(i18n("Shear layer"));
01895     }
01896 
01897     KisShearVisitor v(angleX, angleY, m_progress);
01898     v.setUndoAdapter(undo);
01899     layer->accept(v);
01900 
01901     if (undo) undo->endMacro();
01902 
01903     m_doc->setModified(true);
01904     layersUpdated();
01905     updateCanvas();
01906 }
01907 
01908 void KisView::flattenImage()
01909 {
01910     KisImageSP img = currentImg();
01911 
01912     if (img) {
01913         bool doIt = true;
01914 
01915         if (img->nHiddenLayers() > 0) {
01916             int answer = KMessageBox::warningYesNo(this,
01917                                    i18n("The image contains hidden layers that will be lost."),
01918                                    i18n("Flatten Image"),
01919                                    i18n("&Flatten Image"),
01920                                    KStdGuiItem::cancel());
01921 
01922             if (answer != KMessageBox::Yes) {
01923                 doIt = false;
01924             }
01925         }
01926 
01927         if (doIt) {
01928             img->flatten();
01929         }
01930     }
01931 }
01932 
01933 void KisView::mergeLayer()
01934 {
01935     KisImageSP img = currentImg();
01936     if (!img) return;
01937 
01938     KisLayerSP layer = img->activeLayer();
01939     if (!layer) return;
01940 
01941     img->mergeLayer(layer);
01942 }
01943 
01944 void KisView::preferences()
01945 {
01946 #ifdef HAVE_GL
01947     bool canvasWasOpenGL = m_canvas->isOpenGLCanvas();
01948 #endif
01949 
01950     if (PreferencesDialog::editPreferences())
01951     {
01952         KisConfig cfg;
01953         m_paletteManager->slotResetFont();
01954         resetMonitorProfile();
01955 
01956 #ifdef HAVE_GL
01957         if (cfg.useOpenGL() != canvasWasOpenGL) {
01958 
01959             disconnectCurrentImg();
01960 
01961             //XXX: Need to notify other views that this global setting has changed.
01962             if (cfg.useOpenGL()) {
01963                 m_OpenGLImageContext = KisOpenGLImageContext::getImageContext(m_image, monitorProfile());
01964                 m_canvas->createOpenGLCanvas(m_OpenGLImageContext->sharedContextWidget());
01965             } else
01966             {
01967                 m_OpenGLImageContext = 0;
01968                 m_canvas->createQPaintDeviceCanvas();
01969             }
01970 
01971             connectCurrentImg();
01972 
01973             resizeEvent(0);
01974         }
01975 
01976         if (cfg.useOpenGL()) {
01977             m_OpenGLImageContext->setMonitorProfile(monitorProfile());
01978         }
01979 #endif
01980 
01981         refreshKisCanvas();
01982 
01983         if (m_toolManager->currentTool()) {
01984             setCanvasCursor(m_toolManager->currentTool()->cursor());
01985         }
01986 
01987 #if defined(EXTENDED_X11_TABLET_SUPPORT)
01988         m_canvas->selectTabletDeviceEvents();
01989 #endif
01990 
01991     }
01992 }
01993 
01994 void KisView::layerCompositeOp(const KisCompositeOp& compositeOp)
01995 {
01996     KisImageSP img = currentImg();
01997     if (!img) return;
01998 
01999     KisLayerSP layer = img->activeLayer();
02000     if (!layer) return;
02001 
02002     if (img->undo()) {
02003         KNamedCommand *cmd = layer->setCompositeOpCommand(compositeOp);
02004         cmd->execute();
02005         undoAdapter()->addCommand(cmd);
02006     }
02007 }
02008 
02009 // range: 0 - 100
02010 void KisView::layerOpacity(int opacity, bool dontundo)
02011 {
02012     KisImageSP img = currentImg();
02013     if (!img) return;
02014 
02015     KisLayerSP layer = img->activeLayer();
02016     if (!layer) return;
02017 
02018     opacity = int(float(opacity * 255) / 100 + 0.5);
02019     if (opacity > 255)
02020         opacity = 255;
02021 
02022     if (opacity == layer->opacity()) return;
02023 
02024     if (dontundo)
02025         layer->setOpacity( opacity );
02026     else
02027     {
02028         if (img->undo()) {
02029             KNamedCommand *cmd = layer->setOpacityCommand(opacity);
02030             cmd->execute();
02031             undoAdapter()->addCommand(cmd);
02032         }
02033     }
02034 }
02035 
02036 void KisView::layerOpacityFinishedChanging( int previous, int opacity )
02037 {
02038     KisImageSP img = currentImg();
02039     if (!img) return;
02040 
02041     KisLayerSP layer = img->activeLayer();
02042     if (!layer) return;
02043 
02044     opacity = int(float(opacity * 255) / 100 + 0.5);
02045     if (opacity > 255)
02046         opacity = 255;
02047 
02048     previous = int(float(previous * 255) / 100 + 0.5);
02049     if (previous > 255)
02050         previous = 255;
02051 
02052     if (previous == opacity) return;
02053 
02054     if (img->undo()) {
02055         KNamedCommand *cmd = layer->setOpacityCommand(previous, opacity);
02056         m_adapter->addCommand(cmd);
02057     }
02058 }
02059 
02060 
02061 void KisView::showRuler()
02062 {
02063     if( m_RulerAction->isChecked() )
02064     {
02065         m_hRuler->show();
02066         m_vRuler->show();
02067     }
02068     else
02069     {
02070         m_hRuler->hide();
02071         m_vRuler->hide();
02072     }
02073 
02074     resizeEvent(0);
02075     refreshKisCanvas();
02076 }
02077 
02078 void KisView::slotUpdateFullScreen(bool toggle)
02079 {
02080     if (KoView::shell()) {
02081 
02082         uint newState = KoView::shell()->windowState();
02083 
02084         if (toggle) {
02085             newState |= Qt::WindowFullScreen;
02086         } else {
02087             newState &= ~Qt::WindowFullScreen;
02088         }
02089 
02090         KoView::shell()->setWindowState(newState);
02091     }
02092 }
02093 
02094 Q_INT32 KisView::docWidth() const
02095 {
02096     return currentImg() ? currentImg()->width() : 0;
02097 }
02098 
02099 Q_INT32 KisView::docHeight() const
02100 {
02101     return currentImg() ? currentImg()->height() : 0;
02102 }
02103 
02104 void KisView::scrollTo(Q_INT32 x, Q_INT32 y)
02105 {
02106     if (m_hScroll->isVisible()) {
02107         m_hScroll->setValue(x);
02108     }
02109     if (m_vScroll->isVisible()) {
02110         m_vScroll->setValue(y);
02111     }
02112 }
02113 
02114 void KisView::brushActivated(KisResource *brush)
02115 {
02116 
02117     m_brush = dynamic_cast<KisBrush*>(brush);
02118 
02119     if (m_brush )
02120     {
02121         emit brushChanged(m_brush);
02122         notifyObservers();
02123     }
02124 }
02125 
02126 void KisView::patternActivated(KisResource *pattern)
02127 {
02128     m_pattern = dynamic_cast<KisPattern*>(pattern);
02129 
02130     if (m_pattern) {
02131         emit patternChanged(m_pattern);
02132         notifyObservers();
02133     }
02134 }
02135 
02136 void KisView::gradientActivated(KisResource *gradient)
02137 {
02138 
02139     m_gradient = dynamic_cast<KisGradient*>(gradient);
02140 
02141     if (m_gradient) {
02142         emit gradientChanged(m_gradient);
02143         notifyObservers();
02144     }
02145 }
02146 
02147 void KisView::paintopActivated(const KisID & paintop, const KisPaintOpSettings *paintopSettings)
02148 {
02149     if (paintop.id().isNull() || paintop.id().isEmpty()) {
02150         return;
02151     }
02152 
02153     m_paintop = paintop;
02154     m_paintopSettings = paintopSettings;
02155     emit paintopChanged(m_paintop, paintopSettings);
02156     notifyObservers();
02157 }
02158 
02159 void KisView::setBGColor(const KisColor& c)
02160 {
02161     m_bg = c;
02162     notifyObservers();
02163     emit sigBGQColorChanged( c.toQColor() );
02164 }
02165 
02166 void KisView::setFGColor(const KisColor& c)
02167 {
02168     m_fg = c;
02169     notifyObservers();
02170     emit sigFGQColorChanged( c.toQColor() );
02171 }
02172 
02173 void KisView::slotSetFGColor(const KisColor& c)
02174 {
02175 
02176     m_fg = c;
02177     notifyObservers();
02178 }
02179 
02180 void KisView::slotSetBGColor(const KisColor& c)
02181 {
02182 
02183     m_bg = c;
02184     notifyObservers();
02185 }
02186 
02187 void KisView::slotSetFGQColor(const QColor& c)
02188 {
02189     KisColorSpace * monitorSpace = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA"), m_monitorProfile);
02190     setFGColor(KisColor(c, monitorSpace));
02191     emit sigFGQColorChanged(c);
02192 }
02193 
02194 void KisView::slotSetBGQColor(const QColor& c)
02195 {
02196     KisColorSpace * monitorSpace = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA"), m_monitorProfile);
02197     setBGColor(KisColor(c, monitorSpace));
02198     emit sigBGQColorChanged(c);
02199 }
02200 
02201 
02202 void KisView::setupPrinter(KPrinter& printer)
02203 {
02204     KisImageSP img = currentImg();
02205 
02206     if (img) {
02207         printer.setPageSelection(KPrinter::ApplicationSide);
02208         printer.setPageSize(KPrinter::A4);
02209         printer.setOrientation(KPrinter::Portrait);
02210     }
02211 }
02212 
02213 void KisView::print(KPrinter& printer)
02214 {
02215     QPainter gc(&printer);
02216 
02217     KisImageSP img = currentImg();
02218     if (!img) return;
02219 
02220     printer.setFullPage(true);
02221     gc.setClipping(false);
02222 
02223     KisConfig cfg;
02224     QString printerProfileName = cfg.printerProfile();
02225     KisProfile *  printerProfile = KisMetaRegistry::instance()->csRegistry() ->getProfileByName(printerProfileName);
02226 
02227     QRect r = img->bounds();
02228     img->renderToPainter(r.x(), r.y(), r.width(), r.height(), gc, printerProfile, KisImage::PAINT_IMAGE_ONLY, HDRExposure());
02229 }
02230 
02231 void KisView::paintToolOverlay(const QRegion& region)
02232 {
02233     if (!region.isEmpty() && m_toolManager->currentTool() && !m_toolIsPainting) {
02234         KisCanvasPainter gc(m_canvas);
02235 
02236         gc.setClipRegion(region);
02237         gc.setClipping(true);
02238 
02239         // Prevent endless loop if the tool needs to have the canvas repainted
02240         m_toolIsPainting = true;
02241         m_toolManager->currentTool()->paint(gc, region.boundingRect());
02242         m_toolIsPainting = false;
02243     }
02244 }
02245 
02246 void KisView::canvasGotPaintEvent(QPaintEvent *event)
02247 {
02248     if (m_canvas->isOpenGLCanvas()) {
02249         paintOpenGLView(event->rect());
02250     } else {
02251         paintQPaintDeviceView(event->region());
02252     }
02253 }
02254 
02255 void KisView::canvasGotButtonPressEvent(KisButtonPressEvent *e)
02256 {
02257 #if defined(EXTENDED_X11_TABLET_SUPPORT)
02258     // The event filter doesn't see tablet events going to the canvas.
02259     if (e->device() != KisInputDevice::mouse()) {
02260         m_tabletEventTimer.start();
02261     }
02262 #endif // EXTENDED_X11_TABLET_SUPPORT
02263 
02264     if (e->device() != currentInputDevice()) {
02265         if (e->device() == KisInputDevice::mouse()) {
02266             if (m_tabletEventTimer.elapsed() > MOUSE_CHANGE_EVENT_DELAY) {
02267                 setInputDevice(KisInputDevice::mouse());
02268             }
02269         } else {
02270             setInputDevice(e->device());
02271         }
02272     }
02273 
02274     KisImageSP img = currentImg();
02275 
02276 //    if (img) {
02277 //        QPoint pt = mapToScreen(e->pos().floorQPoint());
02278 //        KisGuideMgr *mgr = img->guides();
02279 //
02280 //        m_lastGuidePoint = mapToScreen(e->pos().floorQPoint());
02281 //        m_currentGuide = 0;
02282 //
02283 //        if ((e->state() & ~Qt::ShiftButton) == Qt::NoButton) {
02284 //            KisGuideSP gd = mgr->find(static_cast<Q_INT32>(pt.x() / zoom()), static_cast<Q_INT32>(pt.y() / zoom()), QMAX(2.0, 2.0 / zoom()));
02285 //
02286 //            if (gd) {
02287 //                m_currentGuide = gd;
02288 //
02289 //                if ((e->button() == Qt::RightButton) || ((e->button() & Qt::ShiftButton) == Qt::ShiftButton)) {
02290 //                    if (gd->isSelected())
02291 //                        mgr->unselect(gd);
02292 //                    else
02293 //                        mgr->select(gd);
02294 //              } else {
02295 //                    if (!gd->isSelected()) {
02296 //                        mgr->unselectAll();
02297 //                        mgr->select(gd);
02298 //                    }
02299 //                }
02300 //
02301 //                updateGuides();
02302 //                return;
02303 //            }
02304 //        }
02305 //    }
02306     if (e->button() == Qt::RightButton) {
02307 
02308         if (m_popup == 0 && factory()) {
02309             Q_ASSERT(factory());
02310             m_popup = (QPopupMenu *)factory()->container("image_popup", this);
02311         }
02312         if (m_popup) m_popup->popup(e->globalPos().roundQPoint());
02313     }
02314     else if (e->device() == currentInputDevice() && m_toolManager->currentTool()) {
02315         KisPoint p = viewToWindow(e->pos());
02316         // somewhat of a hack: we should actually test if we intersect with the scrollers,
02317         // but the globalPos seems to be off by a few pixels
02318         if (m_vScroll->draggingSlider() || m_hScroll->draggingSlider())
02319             return;
02320 
02321         if (m_toolManager->currentTool()->wantsAutoScroll()) {
02322             enableAutoScroll();
02323         }
02324 
02325         KisButtonPressEvent ev(e->device(), p, e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), e->button(), e->state());
02326         m_toolManager->currentTool()->buttonPress(&ev);
02327     }
02328 }
02329 
02330 void KisView::canvasGotMoveEvent(KisMoveEvent *e)
02331 {
02332 #if defined(EXTENDED_X11_TABLET_SUPPORT)
02333     // The event filter doesn't see tablet events going to the canvas.
02334     if (e->device() != KisInputDevice::mouse()) {
02335         m_tabletEventTimer.start();
02336     }
02337 #endif // EXTENDED_X11_TABLET_SUPPORT
02338 
02339     if (e->device() != currentInputDevice()) {
02340         if (e->device() == KisInputDevice::mouse()) {
02341             if (m_tabletEventTimer.elapsed() > MOUSE_CHANGE_EVENT_DELAY) {
02342                 setInputDevice(KisInputDevice::mouse());
02343             }
02344         } else {
02345             setInputDevice(e->device());
02346         }
02347     }
02348 
02349     KisImageSP img = currentImg();
02350 
02351     m_hRuler->updatePointer(e->pos().floorX() - m_canvasXOffset, e->pos().floorY() - m_canvasYOffset);
02352     m_vRuler->updatePointer(e->pos().floorX() - m_canvasXOffset, e->pos().floorY() - m_canvasYOffset);
02353 
02354     KisPoint wp = viewToWindow(e->pos());
02355 
02356 #if 0
02357     if (img && m_currentGuide) {
02358         QPoint p = mapToScreen(e->pos().floorQPoint());
02359         KisGuideMgr *mgr = img->guides();
02360 
02361         if (((e->state() & Qt::LeftButton) == Qt::LeftButton) && mgr->hasSelected()) {
02362             eraseGuides();
02363             p -= m_lastGuidePoint;
02364 
02365             if (p.x())
02366                 mgr->moveSelectedByX(p.x() / zoom());
02367 
02368             if (p.y())
02369                 mgr->moveSelectedByY(p.y() / zoom());
02370 
02371             m_doc->setModified(true);
02372             paintGuides();
02373         }
02374     } else
02375 #endif
02376     if (e->device() == currentInputDevice() && m_toolManager->currentTool()) {
02377         KisMoveEvent ev(e->device(), wp, e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), e->state());
02378 
02379         m_toolManager->currentTool()->move(&ev);
02380     }
02381 
02382 //    m_lastGuidePoint = mapToScreen(e->pos().floorQPoint());
02383     emit cursorPosition(wp.floorX(), wp.floorY());
02384 }
02385 
02386 int KisView::leftBorder() const
02387 {
02388   return m_rulerThickness;
02389 }
02390 
02391 int KisView::rightBorder() const
02392 {
02393   return m_hScrollBarExtent;
02394 }
02395 
02396 int KisView::topBorder() const
02397 {
02398   return m_rulerThickness;
02399 }
02400 
02401 int KisView::bottomBorder() const
02402 {
02403   return m_vScrollBarExtent;
02404 }
02405 
02406 void KisView::mouseMoveEvent(QMouseEvent *e)
02407 {
02408     KisMoveEvent ke(currentInputDevice(), e->pos(), e->globalPos(), PRESSURE_DEFAULT, 0, 0, e->state());
02409     canvasGotMoveEvent(&ke);
02410 }
02411 
02412 void KisView::slotAutoScroll(const QPoint &p)
02413 {
02414     scrollTo(horzValue()+p.x(), vertValue()+p.y());
02415 }
02416 
02417 void KisView::canvasGotButtonReleaseEvent(KisButtonReleaseEvent *e)
02418 {
02419 #if defined(EXTENDED_X11_TABLET_SUPPORT)
02420     // The event filter doesn't see tablet events going to the canvas.
02421     if (e->device() != KisInputDevice::mouse()) {
02422         m_tabletEventTimer.start();
02423     }
02424 #endif // EXTENDED_X11_TABLET_SUPPORT
02425 
02426     if (e->device() != currentInputDevice()) {
02427         if (e->device() == KisInputDevice::mouse()) {
02428             if (m_tabletEventTimer.elapsed() > MOUSE_CHANGE_EVENT_DELAY) {
02429                 setInputDevice(KisInputDevice::mouse());
02430             }
02431         } else {
02432             setInputDevice(e->device());
02433         }
02434     }
02435 
02436     KisImageSP img = currentImg();
02437 
02438 //    if (img && m_currentGuide) {
02439 //        m_currentGuide = 0;
02440 //    } else
02441     if (e->device() == currentInputDevice() && m_toolManager->currentTool()) {
02442         KisPoint p = viewToWindow(e->pos());
02443         KisButtonReleaseEvent ev(e->device(), p, e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), e->button(), e->state());
02444 
02445         disableAutoScroll();
02446         if (m_toolManager->currentTool()) {
02447             m_toolManager->currentTool()->buttonRelease(&ev);
02448         }
02449     }
02450 }
02451 
02452 void KisView::canvasGotDoubleClickEvent(KisDoubleClickEvent *e)
02453 {
02454 #if defined(EXTENDED_X11_TABLET_SUPPORT)
02455     // The event filter doesn't see tablet events going to the canvas.
02456     if (e->device() != KisInputDevice::mouse()) {
02457         m_tabletEventTimer.start();
02458     }
02459 #endif // EXTENDED_X11_TABLET_SUPPORT
02460 
02461     if (e->device() != currentInputDevice()) {
02462         if (e->device() == KisInputDevice::mouse()) {
02463             if (m_tabletEventTimer.elapsed() > MOUSE_CHANGE_EVENT_DELAY) {
02464                 setInputDevice(KisInputDevice::mouse());
02465             }
02466         } else {
02467             setInputDevice(e->device());
02468         }
02469     }
02470 
02471     if (e->device() == currentInputDevice() && m_toolManager->currentTool()) {
02472         KisPoint p = viewToWindow(e->pos());
02473         KisDoubleClickEvent ev(e->device(), p, e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), e->button(), e->state());
02474 
02475         if (m_toolManager->currentTool()) {
02476             m_toolManager->currentTool()->doubleClick(&ev);
02477         }
02478     }
02479 }
02480 
02481 void KisView::canvasGotEnterEvent(QEvent *e)
02482 {
02483     Q_UNUSED( e );
02484 }
02485 
02486 void KisView::canvasGotLeaveEvent (QEvent *e)
02487 {
02488     Q_UNUSED( e );
02489 }
02490 
02491 void KisView::canvasGotMouseWheelEvent(QWheelEvent *event)
02492 {
02493     //if(event->state() == ControlButton )
02494     //{
02495         if(event->delta() / 120 != 0)
02496         {
02497             if(event->delta() > 0)
02498             {
02499                 zoomIn();
02500             } else {
02501                 zoomOut();
02502             }
02503         if (m_oldTool) {
02504                 KisCanvasPainter gc(m_canvas);
02505                 m_oldTool->paint(gc);
02506             }
02507         }
02508     //} else {
02509     //    QApplication::sendEvent(m_vScroll, event);
02510     //}
02511 }
02512 
02513 void KisView::canvasGotKeyPressEvent(QKeyEvent *event)
02514 {
02515     if (!m_toolManager->currentTool()) {
02516         event->ignore();
02517         return;
02518     }
02519 
02520     if (event->key() == Qt::Key_Space) {
02521         if (!m_panning) {
02522             // Set tool temporarily to pan
02523             m_panning = true;
02524             m_oldTool = m_toolManager->currentTool();
02525             m_toolManager->setCurrentTool( "tool_pan" );
02526         }
02527         else {
02528             // Unset panning
02529             m_panning = false;
02530             m_toolManager->setCurrentTool( m_oldTool );
02531             m_oldTool = 0;
02532         }
02533     }
02534     if (m_toolManager->currentTool())
02535         m_toolManager->currentTool()->keyPress(event);
02536 }
02537 
02538 void KisView::canvasGotKeyReleaseEvent(QKeyEvent *event)
02539 {
02540     if (m_toolManager->currentTool())
02541         m_toolManager->currentTool()->keyRelease(event);
02542 }
02543 
02544 void KisView::canvasGotDragEnterEvent(QDragEnterEvent *event)
02545 {
02546     bool accept = false;
02547 
02548     // Only accept drag if we're not busy, particularly as we may
02549     // be showing a progress bar and calling qApp->processEvents().
02550     if (KURLDrag::canDecode(event) && QApplication::overrideCursor() == 0) {
02551         accept = true;
02552     }
02553 
02554     event->accept(accept);
02555 }
02556 
02557 void KisView::canvasGotDropEvent(QDropEvent *event)
02558 {
02559     KURL::List urls;
02560 
02561     if (KURLDrag::decode(event, urls))
02562     {
02563         if (urls.count() > 0) {
02564             enum enumActionId {
02565                 addLayerId = 1,
02566                 addDocumentId = 2,
02567                 cancelId
02568             };
02569 
02570             KPopupMenu popup(this, "drop_popup");
02571 
02572             if (urls.count() == 1) {
02573                 if (currentImg() != 0) {
02574                     popup.insertItem(i18n("Insert as New Layer"), addLayerId);
02575                 }
02576                 popup.insertItem(i18n("Open in New Document"), addDocumentId);
02577             }
02578             else {
02579                 if (currentImg() != 0) {
02580                     popup.insertItem(i18n("Insert as New Layers"), addLayerId);
02581                 }
02582                 popup.insertItem(i18n("Open in New Documents"), addDocumentId);
02583             }
02584 
02585             popup.insertSeparator();
02586             popup.insertItem(i18n("Cancel"), cancelId);
02587 
02588             int actionId = popup.exec(QCursor::pos());
02589 
02590             if (actionId >= 0 && actionId != cancelId) {
02591                 for (KURL::List::ConstIterator it = urls.begin (); it != urls.end (); ++it) {
02592                     KURL url = *it;
02593 
02594                     switch (actionId) {
02595                     case addLayerId:
02596                         importImage(url);
02597                         break;
02598                     case addDocumentId:
02599                         if (shell() != 0) {
02600                             shell()->openDocument(url);
02601                         }
02602                         break;
02603                     }
02604                 }
02605             }
02606         }
02607     }
02608 }
02609 
02610 void KisView::layerProperties()
02611 {
02612     if (currentImg() && currentImg()->activeLayer())
02613         showLayerProperties(currentImg()->activeLayer());
02614 }
02615 
02616 namespace {
02617     class KisChangeFilterCmd : public KNamedCommand {
02618         typedef KNamedCommand super;
02619 
02620         public:
02621             // The QStrings are the _serialized_ configs
02622             KisChangeFilterCmd(KisAdjustmentLayerSP layer,
02623                                KisFilterConfiguration* config,
02624                                const QString& before,
02625                                const QString& after) : super(i18n("Change Filter"))
02626             {
02627                 m_layer = layer;
02628                 m_config = config;
02629                 m_before = before;
02630                 m_after = after;
02631             }
02632         public:
02633             virtual void execute()
02634             {
02635                 QApplication::setOverrideCursor(KisCursor::waitCursor());
02636                 m_config->fromXML(m_after);
02637                 //Q_ASSERT(m_after == m_config->toString());
02638                 m_layer->setFilter(m_config);
02639                 m_layer->setDirty();
02640                 QApplication::restoreOverrideCursor();
02641             }
02642 
02643             virtual void unexecute()
02644             {
02645                 QApplication::setOverrideCursor(KisCursor::waitCursor());
02646                 m_config->fromXML(m_before);
02647                 //Q_ASSERT(m_before == m_config->toString());
02648                 m_layer->setFilter(m_config);
02649                 m_layer->setDirty();
02650                 QApplication::restoreOverrideCursor();
02651             }
02652         private:
02653             KisAdjustmentLayerSP m_layer;
02654             KisFilterConfiguration* m_config;
02655             QString m_before;
02656             QString m_after;
02657     };
02658 }
02659 
02660 void KisView::showLayerProperties(KisLayerSP layer)
02661 {
02662     Q_ASSERT( layer );
02663     if ( !layer ) return;
02664 
02665     KisColorSpace * cs = 0;
02666     KisPaintLayer * pl = dynamic_cast<KisPaintLayer*>( layer.data() );
02667     if ( pl ) {
02668         cs = pl->paintDevice()->colorSpace();
02669     }
02670     else {
02671         cs = layer->image()->colorSpace();
02672     }
02673 
02674 
02675     if (KisAdjustmentLayerSP alayer = dynamic_cast<KisAdjustmentLayer*>(layer.data()))
02676     {
02677         KisDlgAdjLayerProps dlg(alayer, alayer->name(), i18n("Adjustment Layer Properties"), this, "dlgadjlayerprops");
02678         QString before = dlg.filterConfiguration()->toString();
02679         if (dlg.exec() == QDialog::Accepted)
02680         {
02681             KisChangeFilterCmd * cmd = new KisChangeFilterCmd(alayer,
02682                     dlg.filterConfiguration(),
02683                     before,
02684                     dlg.filterConfiguration()->toString());
02685             cmd->execute();
02686             m_adapter->addCommand(cmd);
02687             m_doc->setModified( true );
02688         }
02689     }
02690     else
02691     {
02692         KisDlgLayerProperties dlg(layer->name(),
02693                                   layer->opacity(),
02694                                   layer->compositeOp(),
02695                                   cs);
02696         if (dlg.exec() == QDialog::Accepted)
02697         {
02698             if (layer->name() != dlg.getName() ||
02699                 layer->opacity() != dlg.getOpacity() ||
02700                 layer->compositeOp() != dlg.getCompositeOp())
02701             {
02702                 QApplication::setOverrideCursor(KisCursor::waitCursor());
02703                 m_adapter->beginMacro(i18n("Property Changes"));
02704                 layer->image()->setLayerProperties(layer, dlg.getOpacity(), dlg.getCompositeOp(), dlg.getName());
02705                 layer->setDirty();
02706                 m_adapter->endMacro();
02707                 QApplication::restoreOverrideCursor();
02708                 m_doc->setModified( true );
02709             }
02710         }
02711     }
02712 }
02713 
02714 void KisView::layerAdd()
02715 {
02716     KisImageSP img = currentImg();
02717     if (img && img->activeLayer()) {
02718         addLayer(img->activeLayer()->parent(), img->activeLayer());
02719     }
02720     else if (img)
02721         addLayer(static_cast<KisGroupLayer*>(img->rootLayer().data()), 0);
02722 }
02723 
02724 void KisView::addLayer(KisGroupLayerSP parent, KisLayerSP above)
02725 {
02726     KisImageSP img = currentImg();
02727     if (img) {
02728         KisConfig cfg;
02729         QString profilename;
02730         if(img->colorSpace()->getProfile())
02731             profilename = img->colorSpace()->getProfile()->productName();
02732         NewLayerDialog dlg(img->colorSpace()->id(), profilename, img->nextLayerName(), this);
02733 
02734         if (dlg.exec() == QDialog::Accepted) {
02735             KisColorSpace* cs = KisMetaRegistry::instance()-> csRegistry() ->
02736                     getColorSpace(dlg.colorSpaceID(),dlg.profileName());
02737             KisLayerSP layer = new KisPaintLayer(img, dlg.layerName(), dlg.opacity(), cs);
02738             if (layer) {
02739                 layer->setCompositeOp(dlg.compositeOp());
02740                 img->addLayer(layer, parent.data(), above);
02741                 updateCanvas();
02742             } else {
02743                 KMessageBox::error(this, i18n("Could not add layer to image."), i18n("Layer Error"));
02744             }
02745         }
02746         else {
02747             img->rollBackLayerName();
02748         }
02749     }
02750 }
02751 
02752 void KisView::addGroupLayer(KisGroupLayerSP parent, KisLayerSP above)
02753 {
02754     KisImageSP img = currentImg();
02755     if (img) {
02756         QString profilename;
02757         if(img->colorSpace()->getProfile())
02758             profilename = img->colorSpace()->getProfile()->productName();
02759         KisConfig cfg;
02760         NewLayerDialog dlg(img->colorSpace()->id(), profilename, img->nextLayerName(), this);
02761         dlg.setColorSpaceEnabled(false);
02762 
02763         if (dlg.exec() == QDialog::Accepted) {
02764             KisLayerSP layer = new KisGroupLayer(img, dlg.layerName(), dlg.opacity());
02765             if (layer) {
02766                 layer->setCompositeOp(dlg.compositeOp());
02767                 img->addLayer(layer, parent.data(), above);
02768                 updateCanvas();
02769             } else {
02770                 KMessageBox::error(this, i18n("Could not add layer to image."), i18n("Layer Error"));
02771             }
02772         }
02773     }
02774 }
02775 
02776 void KisView::addPartLayer()
02777 {
02778     KisImageSP img = currentImg();
02779     if (!img) return;
02780 
02781     addPartLayer(img->rootLayer(), img->rootLayer()->firstChild(), m_actionPartLayer->documentEntry());
02782 }
02783 
02784 void KisView::addPartLayer(KisGroupLayerSP parent, KisLayerSP above, const KoDocumentEntry& entry)
02785 {
02786     delete m_partHandler; // Only one at a time
02787     m_partHandler = new KisPartLayerHandler(this, entry, parent, above);
02788 
02789     disconnect(m_canvas, SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent*)), this, 0);
02790     disconnect(m_canvas, SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent*)), this, 0);
02791     disconnect(m_canvas, SIGNAL(sigGotMoveEvent(KisMoveEvent*)), this, 0);
02792     disconnect(m_canvas, SIGNAL(sigGotKeyPressEvent(QKeyEvent*)), this, 0);
02793 
02794     connect(m_canvas, SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent*)),
02795             m_partHandler, SLOT(gotButtonPressEvent(KisButtonPressEvent*)));
02796     connect(m_canvas, SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent*)),
02797             m_partHandler, SLOT(gotButtonReleaseEvent(KisButtonReleaseEvent*)));
02798     connect(m_canvas, SIGNAL(sigGotMoveEvent(KisMoveEvent*)),
02799             m_partHandler, SLOT(gotMoveEvent(KisMoveEvent*)));
02800     connect(m_canvas, SIGNAL(sigGotKeyPressEvent(QKeyEvent*)),
02801             m_partHandler, SLOT(gotKeyPressEvent(QKeyEvent*)));
02802 
02803     connect(m_partHandler, SIGNAL(sigGotMoveEvent(KisMoveEvent*)),
02804             this, SLOT(canvasGotMoveEvent(KisMoveEvent*)));
02805     connect(m_partHandler, SIGNAL(sigGotKeyPressEvent(QKeyEvent*)),
02806             this, SLOT(canvasGotKeyPressEvent(QKeyEvent*)));
02807     connect(m_partHandler, SIGNAL(handlerDone()),
02808             this, SLOT(reconnectAfterPartInsert()));
02809 }
02810 
02811 void KisView::insertPart(const QRect& viewRect, const KoDocumentEntry& entry,
02812                          KisGroupLayerSP parent, KisLayerSP above) {
02813     KisImageSP img = currentImg();
02814     if (!img) return;
02815 
02816     KoDocument* doc = entry.createDoc(m_doc);
02817     if ( !doc )
02818         return;
02819 
02820     if ( !doc->showEmbedInitDialog(this) )
02821         return;
02822 
02823     QRect rect = viewToWindow(viewRect);
02824 
02825     KisChildDoc * childDoc = m_doc->createChildDoc(rect, doc);
02826 
02827     KisPartLayerImpl* partLayer = new KisPartLayerImpl(img, childDoc);
02828     partLayer->setDocType(entry.service()->genericName());
02829     img->addLayer(partLayer, parent, above);
02830     m_doc->setModified(true);
02831 
02832     reconnectAfterPartInsert();
02833 }
02834 
02835 void KisView::reconnectAfterPartInsert() {
02836     connect(m_canvas, SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent*)),
02837             this, SLOT(canvasGotButtonPressEvent(KisButtonPressEvent*)));
02838     connect(m_canvas, SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent*)),
02839             this, SLOT(canvasGotButtonReleaseEvent(KisButtonReleaseEvent*)));
02840     connect(m_canvas, SIGNAL(sigGotMoveEvent(KisMoveEvent*)),
02841             this, SLOT(canvasGotMoveEvent(KisMoveEvent*)));
02842     connect(m_canvas, SIGNAL(sigGotKeyPressEvent(QKeyEvent*)),
02843             this, SLOT(canvasGotKeyPressEvent(QKeyEvent*)));
02844 
02845     delete m_partHandler;
02846     m_partHandler = 0;
02847 }
02848 
02849 void KisView::addAdjustmentLayer()
02850 {
02851     KisImageSP img = currentImg();
02852     if (!img) return;
02853 
02854     addAdjustmentLayer( img->activeLayer()->parent(), img->activeLayer() );
02855 }
02856 
02857 void KisView::addAdjustmentLayer(KisGroupLayerSP parent, KisLayerSP above)
02858 {
02859     Q_ASSERT(parent);
02860     Q_ASSERT(above);
02861 
02862     KisImageSP img = currentImg();
02863     if (!img) return;
02864 
02865     KisLayerSP l = img->activeLayer();
02866 
02867     KisPaintDeviceSP dev;
02868 
02869     //  Argh! I hate having to cast, cast and cast again to see what kind of a layer I've got!
02870     KisPaintLayer * pl = dynamic_cast<KisPaintLayer*>(l.data());
02871     if (pl) {
02872         dev = pl->paintDevice();
02873     }
02874     else {
02875         KisGroupLayer * gl = dynamic_cast<KisGroupLayer*>(l.data());
02876         if (gl) {
02877             dev = gl->projection(img->bounds());
02878         }
02879         else {
02880             KisAdjustmentLayer * al = dynamic_cast<KisAdjustmentLayer*>(l.data());
02881             if (al) {
02882                 dev = al->cachedPaintDevice();
02883             }
02884             else {
02885                 return;
02886             }
02887         }
02888     }
02889 
02890     KisDlgAdjustmentLayer dlg(img, img->nextLayerName(), i18n("New Adjustment Layer"), this, "dlgadjustmentlayer");
02891     if (dlg.exec() == QDialog::Accepted) {
02892         KisSelectionSP selection = 0;
02893         if (dev->hasSelection()) {
02894             selection = dev->selection();
02895         }
02896         KisFilterConfiguration * filter = dlg.filterConfiguration();
02897         QString name = dlg.layerName();
02898 
02899         addAdjustmentLayer( parent, above, name, filter, selection);
02900 
02901     }
02902 }
02903 
02904 void KisView::addAdjustmentLayer(KisGroupLayerSP parent, KisLayerSP above, const QString & name,
02905                                  KisFilterConfiguration * filter, KisSelectionSP selection)
02906 {
02907     Q_ASSERT(parent);
02908     Q_ASSERT(above);
02909     Q_ASSERT(filter);
02910 
02911     KisImageSP img = currentImg();
02912     if (!img) return;
02913 
02914     KisAdjustmentLayer * l = new KisAdjustmentLayer(img, name, filter, selection);
02915     img->addLayer(l, parent, above);
02916 }
02917 
02918 void KisView::slotChildActivated(bool a) {
02919     // It should be so that the only part (child) we can activate, is the current layer:
02920     if (currentImg() && currentImg()->activeLayer())
02921     {
02922         if (a) {
02923             currentImg()->activeLayer()->activate();
02924         } else {
02925             currentImg()->activeLayer()->deactivate();
02926         }
02927     }
02928 
02929     super::slotChildActivated(a);
02930 }
02931 
02932 void KisView::layerRemove()
02933 {
02934     KisImageSP img = currentImg();
02935 
02936     if (img) {
02937         KisLayerSP layer = img->activeLayer();
02938 
02939         if (layer) {
02940 
02941 
02942             img->removeLayer(layer);
02943 
02944             if (layer->parent())
02945                 layer->parent()->setDirty(layer->extent());
02946 
02947             updateCanvas();
02948             layerUpdateGUI(img->activeLayer() != 0);
02949         }
02950     }
02951 }
02952 
02953 void KisView::layerDuplicate()
02954 {
02955     KisImageSP img = currentImg();
02956 
02957     if (!img)
02958         return;
02959 
02960     KisLayerSP active = img->activeLayer();
02961 
02962     if (!active)
02963         return;
02964 
02965     KisLayerSP dup = active->clone();
02966     dup->setName(i18n("Duplicate of '%1'").arg(active->name()));
02967     img->addLayer(dup, active->parent().data(), active);
02968     if (dup) {
02969         img->activate( dup );
02970         updateCanvas();
02971     } else {
02972         KMessageBox::error(this, i18n("Could not add layer to image."), i18n("Layer Error"));
02973     }
02974 }
02975 
02976 void KisView::layerRaise()
02977 {
02978     KisImageSP img = currentImg();
02979     KisLayerSP layer;
02980 
02981     if (!img)
02982         return;
02983 
02984     layer = img->activeLayer();
02985 
02986     img->raiseLayer(layer);
02987 }
02988 
02989 void KisView::layerLower()
02990 {
02991     KisImageSP img = currentImg();
02992     KisLayerSP layer;
02993 
02994     if (!img)
02995         return;
02996 
02997     layer = img->activeLayer();
02998 
02999     img->lowerLayer(layer);
03000 }
03001 
03002 void KisView::layerFront()
03003 {
03004     KisImageSP img = currentImg();
03005     KisLayerSP layer;
03006 
03007     if (!img)
03008         return;
03009 
03010     layer = img->activeLayer();
03011     img->toTop(layer);
03012 }
03013 
03014 void KisView::layerBack()
03015 {
03016     KisImageSP img = currentImg();
03017     if (!img) return;
03018 
03019     KisLayerSP layer;
03020 
03021     layer = img->activeLayer();
03022     img->toBottom(layer);
03023 }
03024 
03025 void KisView::layersUpdated()
03026 {
03027     KisImageSP img = currentImg();
03028     if (!img) return;
03029 
03030     KisLayerSP layer = img->activeLayer();
03031 
03032     layerUpdateGUI(img && layer);
03033 
03034     notifyObservers();
03035 }
03036 
03037 void KisView::layerToggleVisible()
03038 {
03039     KisImageSP img = currentImg();
03040     if (!img) return;
03041 
03042     KisLayerSP layer = img->activeLayer();
03043     if (!layer) return;
03044 
03045     layer->setVisible(!layer->visible());
03046 }
03047 
03048 void KisView::layerToggleLocked()
03049 {
03050     KisImageSP img = currentImg();
03051     if (!img) return;
03052 
03053     KisLayerSP layer = img->activeLayer();
03054     if (!layer) return;
03055 
03056     layer->setLocked(!layer->locked());
03057 }
03058 
03059 void KisView::actLayerVisChanged(int show)
03060 {
03061     m_actLayerVis = (show != 0);
03062 }
03063 
03064 bool KisView::activeLayerHasSelection()
03065 {
03066     return m_image && m_image->activeDevice() && m_image->activeDevice()->hasSelection();
03067 }
03068 
03069 void KisView::scrollH(int value)
03070 {
03071     m_hRuler->updateVisibleArea(value, 0);
03072 
03073     int xShift = m_scrollX - value;
03074     m_scrollX = value;
03075 
03076     if (m_canvas->isUpdatesEnabled()) {
03077         if (xShift > 0) {
03078 
03079             if (m_canvas->isOpenGLCanvas()) {
03080                 paintOpenGLView(QRect(0, 0, m_canvas->width(), m_canvas->height()));
03081             } else {
03082                 QRect drawRect(0, 0, xShift, m_canvasPixmap.height());
03083 
03084                 bitBlt(&m_canvasPixmap, xShift, 0, &m_canvasPixmap, 0, 0, m_canvasPixmap.width() - xShift, m_canvasPixmap.height());
03085 
03086                 updateQPaintDeviceCanvas(viewToWindow(drawRect));
03087                 m_canvas->repaint();
03088             }
03089         } else if (xShift < 0) {
03090 
03091             QRect drawRect(m_canvasPixmap.width() + xShift, 0, -xShift, m_canvasPixmap.height());
03092 
03093             if (m_canvas->isOpenGLCanvas()) {
03094                 paintOpenGLView(QRect(0, 0, m_canvas->width(), m_canvas->height()));
03095             } else {
03096                 bitBlt(&m_canvasPixmap, 0, 0, &m_canvasPixmap, -xShift, 0, m_canvasPixmap.width() + xShift, m_canvasPixmap.height());
03097 
03098                 updateQPaintDeviceCanvas(viewToWindow(drawRect));
03099                 m_canvas->repaint();
03100             }
03101         }
03102     if (m_oldTool) {
03103             KisCanvasPainter gc(m_canvas);
03104             m_oldTool->paint(gc);
03105         }
03106     }
03107 
03108     if (xShift != 0) {
03109         // XXX do sth with the childframe or so
03110     }
03111     emit viewTransformationsChanged();
03112 }
03113 
03114 void KisView::scrollV(int value)
03115 {
03116     m_vRuler->updateVisibleArea(0, value);
03117 
03118     int yShift = m_scrollY - value;
03119     m_scrollY = value;
03120 
03121     if (m_canvas->isUpdatesEnabled()) {
03122         if (yShift > 0) {
03123 
03124             if (m_canvas->isOpenGLCanvas()) {
03125                 paintOpenGLView(QRect(0, 0, m_canvas->width(), m_canvas->height()));
03126             } else {
03127                 QRect drawRect(0, 0, m_canvasPixmap.width(), yShift);
03128 
03129                 bitBlt(&m_canvasPixmap, 0, yShift, &m_canvasPixmap, 0, 0, m_canvasPixmap.width(), m_canvasPixmap.height() - yShift);
03130 
03131                 updateQPaintDeviceCanvas(viewToWindow(drawRect));
03132                 m_canvas->repaint();
03133             }
03134         } else if (yShift < 0) {
03135 
03136             if (m_canvas->isOpenGLCanvas()) {
03137                 paintOpenGLView(QRect(0, 0, m_canvas->width(), m_canvas->height()));
03138             } else {
03139                 QRect drawRect(0, m_canvasPixmap.height() + yShift, m_canvasPixmap.width(), -yShift);
03140 
03141                 bitBlt(&m_canvasPixmap, 0, 0, &m_canvasPixmap, 0, -yShift, m_canvasPixmap.width(), m_canvasPixmap.height() + yShift);
03142 
03143                 updateQPaintDeviceCanvas(viewToWindow(drawRect));
03144                 m_canvas->repaint();
03145             }
03146         }
03147     if (m_oldTool) {
03148             KisCanvasPainter gc(m_canvas);
03149             m_oldTool->paint(gc);
03150         }
03151     }
03152 
03153     if (yShift != 0) {
03154         // XXX do sth with the childframe or so
03155     }
03156     emit viewTransformationsChanged();
03157 }
03158 
03159 void KisView::setupCanvas()
03160 {
03161     m_canvas = new KisCanvas(this, "kis_canvas");
03162     m_canvas->setFocusPolicy( QWidget::StrongFocus );
03163     QObject::connect(m_canvas, SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent*)), this, SLOT(canvasGotButtonPressEvent(KisButtonPressEvent*)));
03164     QObject::connect(m_canvas, SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent*)), this, SLOT(canvasGotButtonReleaseEvent(KisButtonReleaseEvent*)));
03165     QObject::connect(m_canvas, SIGNAL(sigGotDoubleClickEvent(KisDoubleClickEvent*)), this, SLOT(canvasGotDoubleClickEvent(KisDoubleClickEvent*)));
03166     QObject::connect(m_canvas, SIGNAL(sigGotMoveEvent(KisMoveEvent*)), this, SLOT(canvasGotMoveEvent(KisMoveEvent*)));
03167     QObject::connect(m_canvas, SIGNAL(sigGotPaintEvent(QPaintEvent*)), this, SLOT(canvasGotPaintEvent(QPaintEvent*)));
03168     QObject::connect(m_canvas, SIGNAL(sigGotEnterEvent(QEvent*)), this, SLOT(canvasGotEnterEvent(QEvent*)));
03169     QObject::connect(m_canvas, SIGNAL(sigGotLeaveEvent(QEvent*)), this, SLOT(canvasGotLeaveEvent(QEvent*)));
03170     QObject::connect(m_canvas, SIGNAL(sigGotMouseWheelEvent(QWheelEvent*)), this, SLOT(canvasGotMouseWheelEvent(QWheelEvent*)));
03171     QObject::connect(m_canvas, SIGNAL(sigGotKeyPressEvent(QKeyEvent*)), this, SLOT(canvasGotKeyPressEvent(QKeyEvent*)));
03172     QObject::connect(m_canvas, SIGNAL(sigGotKeyReleaseEvent(QKeyEvent*)), this, SLOT(canvasGotKeyReleaseEvent(QKeyEvent*)));
03173     QObject::connect(m_canvas, SIGNAL(sigGotDragEnterEvent(QDragEnterEvent*)), this, SLOT(canvasGotDragEnterEvent(QDragEnterEvent*)));
03174     QObject::connect(m_canvas, SIGNAL(sigGotDropEvent(QDropEvent*)), this, SLOT(canvasGotDropEvent(QDropEvent*)));
03175 }
03176 
03177 void KisView::connectCurrentImg()
03178 {
03179     if (m_image) {
03180         connect(m_image, SIGNAL(sigActiveSelectionChanged(KisImageSP)), m_selectionManager, SLOT(imgSelectionChanged(KisImageSP)));
03181         connect(m_image, SIGNAL(sigActiveSelectionChanged(KisImageSP)), this, SLOT(updateCanvas()));
03182         connect(m_image, SIGNAL(sigColorSpaceChanged(KisColorSpace *)), this, SLOT(updateStatusBarProfileLabel()));
03183         connect(m_image, SIGNAL(sigProfileChanged(KisProfile * )), SLOT(profileChanged(KisProfile * )));
03184 
03185         connect(m_image, SIGNAL(sigLayersChanged(KisGroupLayerSP)), SLOT(layersUpdated()));
03186         connect(m_image, SIGNAL(sigMaskInfoChanged()), SLOT(maskUpdated()));
03187         connect(m_image, SIGNAL(sigLayerAdded(KisLayerSP)), SLOT(layersUpdated()));
03188         connect(m_image, SIGNAL(sigLayerRemoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)), SLOT(layersUpdated()));
03189         connect(m_image, SIGNAL(sigLayerMoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)), SLOT(layersUpdated()));
03190         connect(m_image, SIGNAL(sigLayerActivated(KisLayerSP)), SLOT(layersUpdated()));
03191         connect(m_image, SIGNAL(sigLayerActivated(KisLayerSP)), SLOT(updateCanvas()));
03192         connect(m_image, SIGNAL(sigLayerPropertiesChanged(KisLayerSP)), SLOT(layersUpdated()));
03193 
03194         KisConnectPartLayerVisitor v(m_image, this, true);
03195         m_image->rootLayer()->accept(v);
03196         connect(m_image, SIGNAL(sigLayerAdded(KisLayerSP)),
03197                 SLOT(handlePartLayerAdded(KisLayerSP)));
03198 
03199         maskUpdated();
03200 #ifdef HAVE_GL
03201         if (m_OpenGLImageContext != 0) {
03202             connect(m_OpenGLImageContext, SIGNAL(sigImageUpdated(QRect)), SLOT(slotOpenGLImageUpdated(QRect)));
03203             connect(m_OpenGLImageContext, SIGNAL(sigSizeChanged(Q_INT32, Q_INT32)), SLOT(slotImageSizeChanged(Q_INT32, Q_INT32)));
03204         } else
03205 #endif
03206         {
03207             connect(m_image, SIGNAL(sigImageUpdated(QRect)), SLOT(imgUpdated(QRect)));
03208             connect(m_image, SIGNAL(sigSizeChanged(Q_INT32, Q_INT32)), SLOT(slotImageSizeChanged(Q_INT32, Q_INT32)));
03209         }
03210     }
03211 
03212     m_layerBox->setImage(m_image);
03213     m_birdEyeBox->setImage(m_image);
03214 }
03215 
03216 void KisView::disconnectCurrentImg()
03217 {
03218     if (m_image) {
03219         m_image->disconnect(this);
03220         m_layerBox->setImage(0);
03221         m_birdEyeBox->setImage(0);
03222 
03223         KisConnectPartLayerVisitor v(m_image, this, false);
03224         m_image->rootLayer()->accept(v);
03225     }
03226 
03227 #ifdef HAVE_GL
03228     if (m_OpenGLImageContext != 0) {
03229         m_OpenGLImageContext->disconnect(this);
03230     }
03231 #endif
03232 }
03233 
03234 void KisView::handlePartLayerAdded(KisLayerSP layer)
03235 {
03236     KisPartLayer* l = dynamic_cast<KisPartLayer*>(layer.data());
03237     if (!l)
03238         return;
03239 
03240     connect(this, SIGNAL(childActivated(KoDocumentChild*)),
03241             layer, SLOT(childActivated(KoDocumentChild*)));
03242 }
03243 
03244 void KisView::imgUpdated(QRect rc)
03245 {
03246     updateCanvas(rc);
03247 }
03248 
03249 void KisView::slotOpenGLImageUpdated(QRect rc)
03250 {
03251     paintOpenGLView(windowToView(rc));
03252 }
03253 
03254 void KisView::profileChanged(KisProfile *  /*profile*/)
03255 {
03256     updateStatusBarProfileLabel();
03257 }
03258 
03259 void KisView::slotImageSizeChanged(Q_INT32 /*w*/, Q_INT32 /*h*/)
03260 {
03261     resizeEvent(0);
03262     refreshKisCanvas();
03263 }
03264 
03265 void KisView::resizeCurrentImage(Q_INT32 w, Q_INT32 h, bool cropLayers)
03266 {
03267     if (!currentImg()) return;
03268 
03269     currentImg()->resize(w, h, cropLayers);
03270     m_doc->setModified(true);
03271     layersUpdated();
03272 }
03273 
03274 void KisView::scaleCurrentImage(double sx, double sy, KisFilterStrategy *filterStrategy)
03275 {
03276     if (!currentImg()) return;
03277     currentImg()->scale(sx, sy, m_progress, filterStrategy);
03278     m_doc->setModified(true);
03279     layersUpdated();
03280 }
03281 
03282 void KisView::rotateCurrentImage(double angle)
03283 {
03284     if (!currentImg()) return;
03285     currentImg()->rotate(angle, m_progress);
03286     m_doc->setModified(true);
03287     layersUpdated();
03288 }
03289 
03290 void KisView::shearCurrentImage(double angleX, double angleY)
03291 {
03292     if (!currentImg()) return;
03293     currentImg()->shear(angleX, angleY, m_progress);
03294     m_doc->setModified(true);
03295     layersUpdated();
03296 }
03297 
03298 
03299 QPoint KisView::viewToWindow(const QPoint& pt)
03300 {
03301     QPoint converted;
03302 
03303     converted.rx() = static_cast<int>((pt.x() + horzValue()) / zoom());
03304     converted.ry() = static_cast<int>((pt.y() + vertValue()) / zoom());
03305 
03306     return converted;
03307 }
03308 
03309 QPoint KisView::viewToWindow(const QPoint& pt) const
03310 {
03311     QPoint converted;
03312 
03313     converted.rx() = static_cast<int>((pt.x() + horzValue()) / zoom());
03314     converted.ry() = static_cast<int>((pt.y() + vertValue()) / zoom());
03315 
03316     return converted;
03317 }
03318 
03319 KisPoint KisView::viewToWindow(const KisPoint& pt)
03320 {
03321     KisPoint converted;
03322 
03323     converted.setX((pt.x() + horzValue()) / zoom());
03324     converted.setY((pt.y() + vertValue()) / zoom());
03325 
03326     return converted;
03327 }
03328 
03329 QRect KisView::viewToWindow(const QRect& rc)
03330 {
03331     QRect r;
03332 
03333     r.setTopLeft(viewToWindow(rc.topLeft()));
03334     r.setRight((int)(ceil((rc.right() + 1.0 + horzValue()) / zoom()) - 1));
03335     r.setBottom((int)(ceil((rc.bottom() + 1.0 + vertValue()) / zoom()) - 1));
03336 
03337     return r;
03338 }
03339 
03340 KisRect KisView::viewToWindow(const KisRect& rc)
03341 {
03342     KisRect r;
03343     KisPoint p = viewToWindow(KisPoint(rc.x(), rc.y()));
03344     r.setX(p.x());
03345     r.setY(p.y());
03346     r.setWidth(rc.width() / zoom());
03347     r.setHeight(rc.height() / zoom());
03348 
03349     return r;
03350 }
03351 
03352 void KisView::viewToWindow(Q_INT32 *x, Q_INT32 *y)
03353 {
03354     if (x && y) {
03355         QPoint p = viewToWindow(QPoint(*x, *y));
03356         *x = p.x();
03357         *y = p.y();
03358     }
03359 }
03360 
03361 QPoint KisView::windowToView(const QPoint& pt)
03362 {
03363     QPoint p;
03364     p.setX(static_cast<int>(pt.x() * zoom() - horzValue()));
03365     p.setY(static_cast<int>(pt.y() * zoom() - vertValue()));
03366 
03367     return p;
03368 }
03369 
03370 QPoint KisView::windowToView(const QPoint& pt) const
03371 {
03372     QPoint p;
03373     p.setX(static_cast<int>(pt.x() * zoom() - horzValue()));
03374     p.setY(static_cast<int>(pt.y() * zoom() - vertValue()));
03375 
03376     return p;
03377 }
03378 
03379 KisPoint KisView::windowToView(const KisPoint& pt)
03380 {
03381     KisPoint p;
03382     p.setX(pt.x() * zoom() - horzValue());
03383     p.setY(pt.y() * zoom() - vertValue());
03384 
03385     return p;
03386 }
03387 
03388 QRect KisView::windowToView(const QRect& rc)
03389 {
03390     QRect r;
03391 
03392     r.setTopLeft(windowToView(rc.topLeft()));
03393     r.setRight((int)(ceil((rc.right() + 1.0) * zoom()) - horzValue() - 1));
03394     r.setBottom((int)(ceil((rc.bottom() + 1.0) * zoom()) - vertValue() - 1));
03395 
03396     return r;
03397 }
03398 
03399 KisRect KisView::windowToView(const KisRect& rc)
03400 {
03401     KisRect r;
03402     KisPoint p = windowToView(KisPoint(rc.x(), rc.y()));
03403     r.setX(p.x());
03404     r.setY(p.y());
03405     r.setWidth(rc.width() * zoom());
03406     r.setHeight(rc.height() * zoom());
03407 
03408     return r;
03409 }
03410 
03411 void KisView::windowToView(Q_INT32 *x, Q_INT32 *y)
03412 {
03413     if (x && y) {
03414         QPoint p = windowToView(QPoint(*x, *y));
03415         *x = p.x();
03416         *y = p.y();
03417     }
03418 }
03419 
03420 void KisView::guiActivateEvent(KParts::GUIActivateEvent *event)
03421 {
03422     Q_ASSERT(event);
03423 
03424     if (event->activated()) {
03425 
03426         KStatusBar *sb = statusBar();
03427         if (sb) {
03428             sb->show();
03429         }
03430 
03431         if (!m_guiActivateEventReceived) {
03432             m_guiActivateEventReceived = true;
03433             startInitialZoomTimerIfReady();
03434         }
03435     }
03436 
03437     super::guiActivateEvent(event);
03438 }
03439 
03440 bool KisView::eventFilter(QObject *o, QEvent *e)
03441 {
03442     Q_ASSERT(o);
03443     Q_ASSERT(e);
03444 
03445     switch (e->type()) {
03446     case QEvent::TabletMove:
03447     case QEvent::TabletPress:
03448     case QEvent::TabletRelease:
03449     {
03450         QTabletEvent *te = static_cast<QTabletEvent *>(e);
03451         KisInputDevice device;
03452 
03453         switch (te->device()) {
03454         default:
03455         case QTabletEvent::Stylus:
03456         case QTabletEvent::NoDevice:
03457             device = KisInputDevice::stylus();
03458             break;
03459         case QTabletEvent::Puck:
03460             device = KisInputDevice::puck();
03461             break;
03462         case QTabletEvent::Eraser:
03463             device = KisInputDevice::eraser();
03464             break;
03465         }
03466 
03467         setInputDevice(device);
03468 
03469         // We ignore device change due to mouse events for a short duration
03470         // after a tablet event, since these are almost certainly mouse events
03471         // sent to receivers that don't accept the tablet event.
03472         m_tabletEventTimer.start();
03473         break;
03474     }
03475     case QEvent::MouseButtonPress:
03476     case QEvent::MouseMove:
03477     case QEvent::MouseButtonRelease:
03478     {
03479 #ifdef EXTENDED_X11_TABLET_SUPPORT
03480         KisInputDevice device = KisCanvasWidget::findActiveInputDevice();
03481 
03482         if (device != KisInputDevice::mouse()) {
03483             setInputDevice(device);
03484             m_tabletEventTimer.start();
03485         } else
03486 #endif
03487         {
03488             if (currentInputDevice() != KisInputDevice::mouse() && m_tabletEventTimer.elapsed() > MOUSE_CHANGE_EVENT_DELAY) {
03489                 setInputDevice(KisInputDevice::mouse());
03490             }
03491         }
03492         break;
03493     }
03494     case QEvent::KeyPress:
03495     case QEvent::KeyRelease:
03496     {
03497         if (m_canvas->cursorIsOverCanvas()) {
03498             m_canvas->handleKeyEvent(e);
03499             return true;
03500         }
03501         break;
03502     }
03503 #if 0
03504     // This code is unnecessary now that there's an application event filter
03505     // This eventFilter is called for all widgets already, no need to install event filters multiple times
03506     // Even worse: with multiple views, they would all install event filters on each other's widgets,
03507     // due to the qapp event filter triggering in all views!
03508     case QEvent::ChildInserted:
03509     {
03510         QChildEvent *childEvent = static_cast<QChildEvent *>(e);
03511         QObject *child = childEvent->child();
03512         if ( child->isWidgetType() ) {
03513 
03514             child->installEventFilter(this);
03515 
03516             QObjectList *objectList = child->queryList("QWidget");
03517             QObjectListIt it(*objectList);
03518             QObject *obj;
03519             while ((obj = it.current()) != 0) {
03520                 obj->installEventFilter(this);
03521                 ++it;
03522             }
03523             delete objectList;
03524         }
03525     }
03526 #endif
03527     default:
03528         // Ignore
03529         break;
03530     }
03531 
03532 #if 0
03533     if ((o == m_hRuler || o == m_vRuler) && (e->type() == QEvent::MouseMove || e->type() == QEvent::MouseButtonRelease)) {
03534         QMouseEvent *me = dynamic_cast<QMouseEvent*>(e);
03535         QPoint pt = mapFromGlobal(me->globalPos());
03536         KisImageSP img = currentImg();
03537         KisGuideMgr *mgr;
03538 
03539         if (!img)
03540             return super::eventFilter(o, e);
03541 
03542         mgr = img->guides();
03543 
03544         if (e->type() == QEvent::MouseMove && (me->state() & Qt::LeftButton)) {
03545             bool flag = geometry().contains(pt);
03546             KisGuideSP gd;
03547 
03548             if (m_currentGuide == 0 && flag) {
03549                 // No guide is being edited and moving mouse over the canvas.
03550                 // Create a new guide.
03551                 enterEvent(0);
03552                 eraseGuides();
03553                 mgr->unselectAll();
03554 
03555                 if (o == m_vRuler)
03556                     gd = mgr->add((pt.x() - m_vRuler->width() + horzValue()) / zoom(), Qt::Vertical);
03557                 else
03558                     gd = mgr->add((pt.y() - m_hRuler->height() + vertValue()) / zoom(), Qt::Horizontal);
03559 
03560                 m_currentGuide = gd;
03561                 mgr->select(gd);
03562                 m_lastGuidePoint = mapToScreen(pt);
03563             } else if (m_currentGuide) {
03564                 if (flag) {
03565                     // moved an existing guide.
03566                     KisMoveEvent kme(currentInputDevice(), pt, me->globalPos(), PRESSURE_DEFAULT, 0, 0, me->state());
03567                     canvasGotMoveEvent(&kme);
03568                 } else {
03569                     //  moved a guide out of the frame, destroy it
03570                     leaveEvent(0);
03571                     eraseGuides();
03572                     mgr->remove(m_currentGuide);
03573                     paintGuides();
03574                     m_currentGuide = 0;
03575                 }
03576             }
03577         } else if (e->type() == QEvent::MouseButtonRelease && m_currentGuide) {
03578             eraseGuides();
03579             mgr->unselect(m_currentGuide);
03580             paintGuides();
03581             m_currentGuide = 0;
03582             enterEvent(0);
03583             KisMoveEvent kme(currentInputDevice(), pt, me->globalPos(), PRESSURE_DEFAULT, 0, 0, Qt::NoButton);
03584             canvasGotMoveEvent(&kme);
03585         }
03586     }
03587 #endif
03588 
03589     return super::eventFilter(o, e);
03590 }
03591 
03592 #if 0
03593 void KisView::eraseGuides()
03594 {
03595     KisImageSP img = currentImg();
03596 
03597     if (img) {
03598         KisGuideMgr *mgr = img->guides();
03599 
03600         if (mgr)
03601             mgr->erase(&m_canvasPixmap, this, horzValue(), vertValue(), zoom());
03602     }
03603 }
03604 
03605 void KisView::paintGuides()
03606 {
03607     KisImageSP img = currentImg();
03608 
03609     if (img) {
03610         KisGuideMgr *mgr = img->guides();
03611 
03612         if (mgr)
03613             mgr->paint(&m_canvasPixmap, this, horzValue(), vertValue(), zoom());
03614     }
03615 }
03616 
03617 void KisView::updateGuides()
03618 {
03619     eraseGuides();
03620     paintGuides();
03621 }
03622 #endif
03623 
03624 //void KisView::viewGuideLines()
03625 //{
03626 //}
03627 
03628 QPoint KisView::mapToScreen(const QPoint& pt)
03629 {
03630     QPoint converted;
03631 
03632     converted.rx() = pt.x() + horzValue();
03633     converted.ry() = pt.y() + vertValue();
03634     return converted;
03635 }
03636 
03637 void KisView::attach(KisCanvasObserver *observer)
03638 {
03639     Q_ASSERT(observer);
03640     if (observer)
03641         m_observers.push_back(observer);
03642 }
03643 
03644 void KisView::detach(KisCanvasObserver *observer)
03645 {
03646     Q_ASSERT(observer);
03647     if (observer) {
03648         vKisCanvasObserver_it it = std::find(m_observers.begin(), m_observers.end(), observer);
03649 
03650         if (it != m_observers.end())
03651             m_observers.erase(it);
03652     }
03653 }
03654 
03655 void KisView::notifyObservers()
03656 {
03657     for (vKisCanvasObserver_it it = m_observers.begin(); it != m_observers.end(); ++it) {
03658         (*it)->update(this);
03659     }
03660 }
03661 
03662 KisImageSP KisView::currentImg() const
03663 {
03664     return m_image;
03665 }
03666 
03667 void KisView::setCurrentImage(KisImageSP image)
03668 {
03669     if(!image) return;
03670 
03671     disconnectCurrentImg();
03672     m_image = image;
03673 
03674     KisConfig cfg;
03675 
03676 #ifdef HAVE_GL
03677     if (cfg.useOpenGL()) {
03678         m_OpenGLImageContext = KisOpenGLImageContext::getImageContext(image, monitorProfile());
03679         m_canvas->createOpenGLCanvas(m_OpenGLImageContext->sharedContextWidget());
03680     }
03681 #endif
03682     connectCurrentImg();
03683     m_layerBox->setImage(currentImg());
03684 
03685     zoomAroundPoint(0, 0, 1.0);
03686 
03687     if (!currentImg())
03688         layersUpdated();
03689 
03690     imgUpdateGUI();
03691 
03692     image->blockSignals(false);
03693 }
03694 
03695 KisColor KisView::bgColor() const
03696 {
03697     return m_bg;
03698 }
03699 
03700 KisColor KisView::fgColor() const
03701 {
03702     return m_fg;
03703 }
03704 
03705 KisBrush *KisView::currentBrush() const
03706 {
03707     return m_brush;
03708 }
03709 
03710 KisPattern *KisView::currentPattern() const
03711 {
03712     return m_pattern;
03713 }
03714 
03715 KisGradient *KisView::currentGradient() const
03716 {
03717     return m_gradient;
03718 }
03719 
03720 KisID KisView::currentPaintop() const
03721 {
03722     return m_paintop;
03723 }
03724 
03725 const KisPaintOpSettings *KisView::currentPaintopSettings() const
03726 {
03727     return m_paintopSettings;
03728 }
03729 
03730 double KisView::zoomFactor() const
03731 {
03732     return zoom();
03733 }
03734 
03735 KisUndoAdapter *KisView::undoAdapter() const
03736 {
03737     return m_adapter;
03738 }
03739 
03740 KisCanvasController *KisView::canvasController() const
03741 {
03742     return const_cast<KisCanvasController*>(static_cast<const KisCanvasController*>(this));
03743 }
03744 
03745 KisToolControllerInterface *KisView::toolController() const
03746 {
03747     return const_cast<KisToolControllerInterface*>(static_cast<const KisToolControllerInterface*>(m_toolManager));
03748 }
03749 
03750 KisDoc *KisView::document() const
03751 {
03752     return m_doc;
03753 }
03754 
03755 KisProgressDisplayInterface *KisView::progressDisplay() const
03756 {
03757     return m_progress;
03758 }
03759 
03760 QCursor KisView::setCanvasCursor(const QCursor & cursor)
03761 {
03762     QCursor oldCursor = m_canvas->cursor();
03763     QCursor newCursor;
03764 
03765     KisConfig cfg;
03766 
03767     switch (cfg.cursorStyle()) {
03768     case CURSOR_STYLE_TOOLICON:
03769         newCursor = cursor;
03770         break;
03771     case CURSOR_STYLE_CROSSHAIR:
03772         newCursor = KisCursor::crossCursor();
03773         break;
03774     case CURSOR_STYLE_POINTER:
03775         newCursor = KisCursor::arrowCursor();
03776         break;
03777     case CURSOR_STYLE_OUTLINE:
03778         newCursor = cursor;
03779         break;
03780     default:
03781         newCursor = cursor;
03782     }
03783 
03784     m_canvas->setCursor(newCursor);
03785     return oldCursor;
03786 }
03787 
03788 float KisView::HDRExposure() const
03789 {
03790     return m_HDRExposure;
03791 }
03792 
03793 void KisView::setHDRExposure(float exposure)
03794 {
03795     if (exposure != m_HDRExposure) {
03796         m_HDRExposure = exposure;
03797         notifyObservers();
03798         updateCanvas();
03799     }
03800 }
03801 
03802 void KisView::createDockers()
03803 {
03804 
03805     m_birdEyeBox = new KisBirdEyeBox(this);
03806     m_birdEyeBox->setCaption(i18n("Overview"));
03807     m_paletteManager->addWidget( m_birdEyeBox, "birdeyebox", krita::CONTROL_PALETTE);
03808 
03809     m_hsvwidget = new KoHSVWidget(this, "hsv");
03810     m_hsvwidget->setCaption(i18n("HSV"));
03811 
03812     connect(m_hsvwidget, SIGNAL(sigFgColorChanged(const QColor &)), this, SLOT(slotSetFGQColor(const QColor &)));
03813     connect(m_hsvwidget, SIGNAL(sigBgColorChanged(const QColor &)), this, SLOT(slotSetBGQColor(const QColor &)));
03814     connect(this, SIGNAL(sigFGQColorChanged(const QColor &)), m_hsvwidget, SLOT(setFgColor(const QColor &)));
03815     connect(this, SIGNAL(sigBGQColorChanged(const QColor &)), m_hsvwidget, SLOT(setBgColor(const QColor &)));
03816     m_paletteManager->addWidget( m_hsvwidget, "hsvwidget", krita::COLORBOX, 0, PALETTE_DOCKER, true);
03817 
03818     m_rgbwidget = new KoRGBWidget(this, "rgb");
03819     m_rgbwidget->setCaption(i18n("RGB"));
03820     connect(m_rgbwidget, SIGNAL(sigFgColorChanged(const QColor &)), this, SLOT(slotSetFGQColor(const QColor &)));
03821     connect(m_rgbwidget, SIGNAL(sigBgColorChanged(const QColor &)), this, SLOT(slotSetBGQColor(const QColor &)));
03822     connect(this, SIGNAL(sigFGQColorChanged(const QColor &)), m_rgbwidget, SLOT(setFgColor(const QColor &)));
03823     connect(this, SIGNAL(sigBGQColorChanged(const QColor &)), m_rgbwidget, SLOT(setBgColor(const QColor &)));
03824     m_paletteManager->addWidget( m_rgbwidget, "rgbwidget", krita::COLORBOX);
03825 
03826     m_graywidget = new KoGrayWidget(this, "gray");
03827     m_graywidget->setCaption(i18n("Gray"));
03828     connect(m_graywidget, SIGNAL(sigFgColorChanged(const QColor &)), this, SLOT(slotSetFGQColor(const QColor &)));
03829     connect(m_graywidget, SIGNAL(sigBgColorChanged(const QColor &)), this, SLOT(slotSetBGQColor(const QColor &)));
03830     connect(this, SIGNAL(sigFGQColorChanged(const QColor &)), m_graywidget, SLOT(setFgColor(const QColor &)));
03831     connect(this, SIGNAL(sigBGQColorChanged(const QColor &)), m_graywidget, SLOT(setBgColor(const QColor &)));
03832     m_paletteManager->addWidget( m_graywidget, "graywidget", krita::COLORBOX);
03833 
03834     //make sure the color chooser get right default values
03835     emit sigFGQColorChanged(m_fg.toQColor());
03836     emit sigBGQColorChanged(m_bg.toQColor());
03837 
03838     m_palettewidget = new KisPaletteWidget(this);
03839     m_palettewidget->setCaption(i18n("Palettes"));
03840     connect(m_palettewidget, SIGNAL(colorSelected(const QColor &)),
03841             this, SLOT(slotSetFGQColor(const QColor &)));
03842     // No BGColor or reverse slotFGChanged->palette connections, since that's not useful here
03843 
03844     KisResourceServerBase* rServer;
03845     rServer = KisResourceServerRegistry::instance()->get("PaletteServer");
03846     QValueList<KisResource*> resources = rServer->resources();
03847     QValueList<KisResource*>::iterator it;
03848     for ( it = resources.begin(); it != resources.end(); ++it ) {
03849         m_palettewidget->slotAddPalette( *it );
03850     }
03851     connect(m_palettewidget, SIGNAL(colorSelected(const KisColor &)), this, SLOT(slotSetFGColor(const KisColor &)));
03852     m_paletteManager->addWidget( m_palettewidget, "palettewidget", krita::COLORBOX, 10, PALETTE_DOCKER, true);
03853 }
03854 
03855 QPoint KisView::applyViewTransformations(const QPoint& p) const {
03856     QPoint point(windowToView(p));
03857 
03858     if (m_hRuler->isShown())
03859         point.ry() += m_hRuler->height();
03860     if (m_vRuler -> isShown())
03861         point.rx() += m_vRuler->width();
03862 
03863     return point;
03864 }
03865 
03866 QPoint KisView::reverseViewTransformations(const QPoint& p) const {
03867     // Since we now zoom ourselves, the only thing super::~ does is nothing anymore.
03868     // Hence, zoom ourselves, like super would
03869     // viewToWindow doesn't take the rulers into account, do that ourselves
03870     QPoint point(p);
03871     if (m_hRuler -> isShown())
03872         point.ry() -= m_hRuler -> height();
03873     if (m_vRuler -> isShown())
03874         point.rx() -= m_vRuler -> width();
03875 
03876     return viewToWindow(point);
03877 }
03878 
03879 void KisView::canvasAddChild(KoViewChild *child) {
03880     super::canvasAddChild(child);
03881     connect(this, SIGNAL(viewTransformationsChanged()), child, SLOT(reposition()));
03882     m_vScroll->raise();
03883     m_hScroll->raise();
03884     m_vScroll->raise();
03885     m_hRuler->raise();
03886     m_vRuler->raise();
03887 }
03888 
03889 void KisView::slotLoadingFinished()
03890 {
03891     // Set the current image for real now everything is ready to go.
03892     setCurrentImage(document()->currentImage());
03893     m_paletteManager->showWidget( "layerbox" );
03894     m_canvas->show();
03895     disconnect(document(), SIGNAL(loadingFinished()), this, SLOT(slotLoadingFinished()));
03896 
03897     m_imageLoaded = true;
03898     startInitialZoomTimerIfReady();
03899 }
03900 
03901 void KisView::startInitialZoomTimerIfReady()
03902 {
03903     if (m_imageLoaded && m_showEventReceived && m_guiActivateEventReceived) {
03904         m_initialZoomTimer.start(250, true);
03905     }
03906 }
03907 
03908 void KisView::slotInitialZoomTimeout()
03909 {
03910     Q_ASSERT(!m_paintViewEnabled);
03911 
03912     m_paintViewEnabled = true;
03913     setInitialZoomLevel();
03914 }
03915 
03916 
03917 void KisView::slotCreateMask() {
03918     KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data());
03919     if (!layer)
03920         return;
03921 
03922     KNamedCommand *cmd = layer->createMaskCommand();
03923     cmd->execute();
03924     if (undoAdapter() && undoAdapter()->undo()) {
03925         undoAdapter()->addCommand(cmd);
03926     }
03927 }
03928 
03929 void KisView::slotMaskFromSelection() {
03930     KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data());
03931     if (!layer)
03932         return;
03933 
03934     KNamedCommand *cmd = layer->maskFromSelectionCommand();
03935     cmd->execute();
03936     if (undoAdapter() && undoAdapter()->undo()) {
03937         undoAdapter()->addCommand(cmd);
03938     }
03939 }
03940 
03941 void KisView::slotMaskToSelection() {
03942     KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data());
03943     if (!layer)
03944         return;
03945 
03946     KNamedCommand *cmd = layer->maskToSelectionCommand();
03947     cmd->execute();
03948     if (undoAdapter() && undoAdapter()->undo()) {
03949         undoAdapter()->addCommand(cmd);
03950     }
03951 }
03952 
03953 void KisView::slotApplyMask() {
03954     KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data());
03955     if (!layer)
03956         return;
03957 
03958     KNamedCommand *cmd = layer->applyMaskCommand();
03959     cmd->execute();
03960     if (undoAdapter() && undoAdapter()->undo()) {
03961         undoAdapter()->addCommand(cmd);
03962     }
03963 }
03964 
03965 void KisView::slotRemoveMask() {
03966     KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data());
03967     if (!layer)
03968         return;
03969 
03970     KNamedCommand *cmd = layer->removeMaskCommand();
03971     cmd->execute();
03972     if (undoAdapter() && undoAdapter()->undo()) {
03973         undoAdapter()->addCommand(cmd);
03974     }
03975 }
03976 
03977 void KisView::slotEditMask() {
03978     KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data());
03979     if (!layer)
03980         return;
03981 
03982     layer->setEditMask(m_editMask->isChecked());
03983 }
03984 
03985 void KisView::slotShowMask() {
03986     KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data());
03987     if (!layer)
03988         return;
03989 
03990     layer->setRenderMask(m_showMask->isChecked());
03991 }
03992 
03993 void KisView::maskUpdated() {
03994     KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data());
03995     if (!layer) {
03996         m_createMask->setEnabled(false);
03997         m_applyMask->setEnabled(false);
03998         m_removeMask->setEnabled(false);
03999         m_editMask->setEnabled(false);
04000         m_showMask->setEnabled(false);
04001         return;
04002     }
04003     m_createMask->setEnabled(!layer->hasMask());
04004     m_maskFromSelection->setEnabled(true); // Perhaps also update this to false when no selection?
04005     m_maskToSelection->setEnabled(layer->hasMask());
04006     m_applyMask->setEnabled(layer->hasMask());
04007     m_removeMask->setEnabled(layer->hasMask());
04008 
04009     m_editMask->setEnabled(layer->hasMask());
04010     m_editMask->setChecked(layer->editMask());
04011     m_showMask->setEnabled(layer->hasMask());
04012     m_showMask->setChecked(layer->renderMask());
04013 }
04014 
04015 #include "kis_view.moc"
04016 
KDE Home | KDE Accessibility Home | Description of Access Keys