You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/chalk/ui/kis_view.cpp

4019 lines
117 KiB

/* This file is part of KimageShop^WKrayon^WChalk
*
* Copyright (c) 1999 Matthias Elter <me@kde.org>
* 1999 Michael Koch <koch@kde.org>
* 1999 Carsten Pfeiffer <pfeiffer@kde.org>
* 2002 Patrick Julien <freak@codepimps.org>
* 2003-2005 Boudewijn Rempt <boud@valdyas.org>
* 2004 Clarence Dang <dang@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <algorithm>
#include <cmath>
// TQt
#include <tqapplication.h>
#include <tqbutton.h>
#include <tqcursor.h>
#include <tqevent.h>
#include <tqpainter.h>
#include <tqscrollbar.h>
#include <tqspinbox.h>
#include <tqdockarea.h>
#include <tqstringlist.h>
#include <tqstyle.h>
#include <tqpopupmenu.h>
#include <tqvaluelist.h>
#include <tqstringlist.h>
#include <tqobjectlist.h>
// KDE
#include <kis_meta_registry.h>
#include <tdeglobalsettings.h>
#include <dcopobject.h>
#include <tdeaction.h>
#include <kcolordialog.h>
#include <kiconloader.h>
#include <tdefiledialog.h>
#include <tdelocale.h>
#include <tdemessagebox.h>
#include <knotifyclient.h>
#include <kprinter.h>
#include <kpushbutton.h>
#include <kstatusbar.h>
#include <kstdaction.h>
#include <kinputdialog.h>
#include <kurldrag.h>
#include <tdepopupmenu.h>
#include <kdebug.h>
#include <ksharedptr.h>
#include <tdetoolbar.h>
#include <tdeparts/plugin.h>
#include <kservice.h>
#include <ktrader.h>
#include <tdeparts/componentfactory.h>
#include <tdeparts/event.h>
// KOffice
#include <KoPartSelectAction.h>
#include <KoFilterManager.h>
#include <KoMainWindow.h>
#include <KoView.h>
#include <KoTabBar.h>
#include <ko_gray_widget.h>
#include <ko_hsv_widget.h>
#include <ko_rgb_widget.h>
#include <kopalettemanager.h>
#include <kopalette.h>
// Local
#include "kis_brush.h"
#include "kis_button_press_event.h"
#include "kis_button_release_event.h"
#include "kis_canvas.h"
#include "kis_canvas_painter.h"
#include "kis_color.h"
#include "kis_colorspace_factory_registry.h"
#include "kis_config.h"
#include "kis_controlframe.h"
#include "kis_cursor.h"
#include "kis_doc.h"
#include "kis_double_click_event.h"
#include "kis_factory.h"
#include "kis_filter_strategy.h"
#include "kis_gradient.h"
#include "kis_group_layer.h"
#include "kis_adjustment_layer.h"
#include "kis_paint_device.h"
#include "kis_tool_freehand.h"
//#include "kis_guide.h"
#include "kis_layerbox.h"
#include "kis_import_catcher.h"
#include "kis_layer.h"
#include "kis_paint_layer.h"
#include "kis_move_event.h"
#include "kis_paint_device.h"
#include "kis_painter.h"
#include "kis_paintop_registry.h"
#include "kis_part_layer.h"
#include "kis_part_layer_handler.h"
#include "kis_pattern.h"
#include "kis_profile.h"
#include "kis_rect.h"
#include "kis_resource.h"
#include "kis_palette.h"
#include "kis_ruler.h"
#include "kis_selection.h"
#include "KoToolBox.h"
#include "kis_tool.h"
#include "kis_tool_manager.h"
#include "kis_transaction.h"
#include "kis_selected_transaction.h"
#include "kis_types.h"
#include "kis_undo_adapter.h"
#include "kis_view.h"
#include "kis_view_iface.h"
#include "kis_label_progress.h"
#include "kis_opengl_image_context.h"
#include "kis_background.h"
#include "kis_paint_device_action.h"
#include "kis_filter_configuration.h"
#include "kis_transform_worker.h"
#include "kis_shear_visitor.h"
#include <kis_resourceserver.h>
#include <kis_resource_mediator.h>
#include "kis_icon_item.h"
#include "kis_palette_widget.h"
#include "kis_birdeye_box.h"
#include "kis_color.h"
#include "kis_factory.h"
// Dialog boxes
#include "kis_dlg_new_layer.h"
#include "kis_dlg_layer_properties.h"
#include "kis_dlg_preferences.h"
#include "kis_dlg_image_properties.h"
#include "kis_dlg_adjustment_layer.h"
#include "kis_dlg_adj_layer_props.h"
// Action managers
#include "kis_selection_manager.h"
#include "kis_filter_manager.h"
#include "kis_grid_manager.h"
#include "kis_perspective_grid_manager.h"
#include "kis_custom_palette.h"
#include "wdgpalettechooser.h"
#include <fixx11h.h>
// Time in ms that must pass after a tablet event before a mouse event is allowed to
// change the input device to the mouse. This is needed because mouse events are always
// sent to a receiver if it does not accept the tablet event.
#define MOUSE_CHANGE_EVENT_DELAY 100
KisView::KisView(KisDoc *doc, KisUndoAdapter *adapter, TQWidget *parent, const char *name)
: super(doc, parent, name)
, KXMLGUIBuilder( shell() )
, m_panning( false )
, m_oldTool( 0 )
, m_doc( doc )
, m_canvas( 0 )
, m_partHandler( 0 )
, m_gridManager( 0 )
, m_perspectiveGridManager( 0 )
, m_selectionManager( 0 )
, m_filterManager( 0 )
, m_paletteManager( 0 )
, m_toolManager( 0 )
, m_actLayerVis( false )
, m_hRuler( 0 )
, m_vRuler( 0 )
, m_imgFlatten( 0 )
, m_imgMergeLayer( 0 )
, m_imgRename( 0 )
, m_imgResizeToLayer( 0 )
, m_imgScan( 0 )
, m_actionPartLayer( 0 )
, m_layerAdd( 0 )
, m_layerBottom( 0 )
, m_layerDup( 0 )
, m_layerHide( 0 )
, m_layerLower( 0 )
, m_layerProperties( 0 )
, m_layerRaise( 0 )
, m_layerRm( 0 )
, m_layerSaveAs( 0 )
, m_layerTop( 0 )
, m_zoomIn( 0 )
, m_zoomOut( 0 )
, m_actualPixels( 0 )
, m_actualSize( 0 )
, m_fitToCanvas( 0 )
, m_fullScreen( 0 )
, m_imgProperties( 0 )
, m_RulerAction( 0 )
, m_guideAction( 0 )
, m_dcop( 0 )
, m_hScroll( 0 )
, m_vScroll( 0 )
, m_scrollX( 0 )
, m_scrollY( 0 )
, m_canvasXOffset( 0)
, m_canvasYOffset( 0)
, m_paintViewEnabled( false )
, m_guiActivateEventReceived( false )
, m_showEventReceived( false )
, m_imageLoaded( false )
// , m_currentGuide( 0 )
, m_adapter( adapter )
, m_statusBarZoomLabel( 0 )
, m_statusBarSelectionLabel( 0 )
, m_statusBarProfileLabel( 0 )
, m_progress( 0 )
, m_layerBox( 0 )
, m_toolBox( 0 )
, m_brush( 0 )
, m_pattern( 0 )
, m_gradient( 0 )
, m_toolIsPainting( false )
, m_monitorProfile( 0 )
, m_HDRExposure( 0 )
{
Q_ASSERT(doc);
Q_ASSERT(adapter);
Q_ASSERT(parent);
KisConfig cfg;
m_currentColorChooserDisplay = KisID("BLA");
setFocusPolicy( TQWidget::StrongFocus );
// Must come before input devices are referenced as this detects them.
#ifdef TQ_WS_X11
KisCanvasWidget::initX11Support();
#endif
// Install event filter before we create any child widgets so they can see
// the tablet events.
tqApp->installEventFilter(this);
m_tabletEventTimer.start();
m_inputDevice = KisInputDevice::mouse();
connect(&m_initialZoomTimer, TQ_SIGNAL(timeout()), TQ_SLOT(slotInitialZoomTimeout()));
m_paletteManager = new KoPaletteManager(this, actionCollection(), "Chalk palette manager");
if (cfg.fixDockerWidth()) m_paletteManager->setFixedWidth( 360 );
m_paletteManager->createPalette( chalk::CONTROL_PALETTE, i18n("Control box"));
m_paletteManager->createPalette( chalk::COLORBOX, i18n("Colors"));
m_paletteManager->createPalette( chalk::LAYERBOX, i18n("Layers"));
m_selectionManager = new KisSelectionManager(this, doc);
m_filterManager = new KisFilterManager(this, doc);
m_toolManager = new KisToolManager(canvasSubject(), getCanvasController());
m_gridManager = new KisGridManager(this);
m_perspectiveGridManager = new KisPerspectiveGridManager(this);
// This needs to be set before the dockers are created.
m_image = m_doc->currentImage();
KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getRGB8();
m_fg = KisColor(TQt::black, cs);
m_bg = KisColor(TQt::white, cs);
createDockers();
setInstance(KisFactory::instance(), false);
setClientBuilder( this );
if (!doc->isReadWrite())
setXMLFile("chalk_readonly.rc");
else
setXMLFile("chalk.rc");
KStdAction::keyBindings( mainWindow()->guiFactory(), TQ_SLOT( configureShortcuts() ), actionCollection() );
createLayerBox();
setupCanvas();
m_canvas->hide();
setupRulers();
setupScrollBars();
setupStatusBar();
setupActions();
dcopObject();
connect(this, TQ_SIGNAL(autoScroll(const TQPoint &)), TQ_SLOT(slotAutoScroll(const TQPoint &)));
setMouseTracking(true);
resetMonitorProfile();
layersUpdated();
m_brushesAndStuffToolBar = new KisControlFrame(mainWindow(), this);
// Load all plugins
TDETrader::OfferList offers = TDETrader::self()->query(TQString::fromLatin1("Chalk/ViewPlugin"),
TQString::fromLatin1("(Type == 'Service') and "
"([X-Chalk-Version] == 2)"));
TDETrader::OfferList::ConstIterator iter;
for(iter = offers.begin(); iter != offers.end(); ++iter)
{
KService::Ptr service = *iter;
int errCode = 0;
KParts::Plugin* plugin =
KParts::ComponentFactory::createInstanceFromService<KParts::Plugin> ( service, this, 0, TQStringList(), &errCode);
if ( plugin ) {
kdDebug(41006) << "found plugin " << service->property("Name").toString() << "\n";
insertChildClient(plugin);
}
else {
kdDebug(41006) << "found plugin " << service->property("Name").toString() << ", " << errCode << "\n";
if( errCode == KParts::ComponentFactory::ErrNoLibrary)
{
kdWarning(41006) << " Error loading plugin was : ErrNoLibrary " << KLibLoader::self()->lastErrorMessage() << endl;
}
}
}
if(!doc->isLoading())
{
slotLoadingFinished();
} else {
connect(doc, TQ_SIGNAL(loadingFinished()), this, TQ_SLOT(slotLoadingFinished()));
}
setFocus();
}
KisView::~KisView()
{
KisConfig cfg;
cfg.setShowRulers( m_RulerAction->isChecked() );
delete m_dcop;
delete m_paletteManager;
delete m_selectionManager;
delete m_filterManager;
delete m_toolManager;
}
static TQt::Dock stringToDock( const TQString& attrPosition )
{
TDEToolBar::Dock dock = TDEToolBar::DockTop;
if ( !attrPosition.isEmpty() ) {
if ( attrPosition == "top" )
dock = TQt::DockTop;
else if ( attrPosition == "left" )
dock = TQt::DockLeft;
else if ( attrPosition == "right" )
dock = TQt::DockRight;
else if ( attrPosition == "bottom" )
dock = TQt::DockBottom;
else if ( attrPosition == "floating" )
dock = TQt::DockTornOff;
else if ( attrPosition == "flat" )
dock = TQt::DockMinimized;
}
return dock;
}
TQWidget * KisView::createContainer( TQWidget *parent, int index, const TQDomElement &element, int &id )
{
if( element.attribute( "name" ) == "ToolBox" )
{
m_toolBox = new KoToolBox(mainWindow(), "ToolBox", KisFactory::instance(), NUMBER_OF_TOOLTYPES);
m_toolBox->setLabel(i18n("Chalk"));
m_toolManager->setUp(m_toolBox, m_paletteManager, actionCollection());
Dock dock = stringToDock( element.attribute( "position" ).lower() );
mainWindow()->addDockWindow( m_toolBox, dock, false);
mainWindow()->moveDockWindow( m_toolBox, dock, false, 0, 0 );
}
return KXMLGUIBuilder::createContainer( parent, index, element, id );
}
void KisView::removeContainer( TQWidget *container, TQWidget *parent, TQDomElement &element, int id )
{
Q_ASSERT(container);
if( shell() && container == m_toolBox )
{
delete m_toolBox;
m_toolManager->youAintGotNoToolBox();
}
else {
KXMLGUIBuilder::removeContainer( container, parent, element, id );
}
}
KoPaletteManager * KisView::paletteManager()
{
if (!m_paletteManager) {
m_paletteManager = new KoPaletteManager(this, actionCollection(), "Chalk palette manager");
TQ_CHECK_PTR(m_paletteManager);
}
return m_paletteManager;
}
void KisView::createLayerBox()
{
m_layerBox = new KisLayerBox(this);
m_layerBox->setCaption(i18n("Layers"));
connect(m_layerBox, TQ_SIGNAL(sigRequestLayer(KisGroupLayerSP, KisLayerSP)),
this, TQ_SLOT(addLayer(KisGroupLayerSP, KisLayerSP)));
connect(m_layerBox, TQ_SIGNAL(sigRequestGroupLayer(KisGroupLayerSP, KisLayerSP)),
this, TQ_SLOT(addGroupLayer(KisGroupLayerSP, KisLayerSP)));
connect(m_layerBox, TQ_SIGNAL(sigRequestAdjustmentLayer(KisGroupLayerSP, KisLayerSP)),
this, TQ_SLOT(addAdjustmentLayer(KisGroupLayerSP, KisLayerSP)));
connect(m_layerBox, TQ_SIGNAL(sigRequestPartLayer(KisGroupLayerSP, KisLayerSP, const KoDocumentEntry&)),
this, TQ_SLOT(addPartLayer(KisGroupLayerSP, KisLayerSP, const KoDocumentEntry&)));
connect(m_layerBox, TQ_SIGNAL(sigRequestLayerProperties(KisLayerSP)),
this, TQ_SLOT(showLayerProperties(KisLayerSP)));
connect(m_layerBox, TQ_SIGNAL(sigOpacityChanged(int, bool)), this, TQ_SLOT(layerOpacity(int, bool)));
connect(m_layerBox, TQ_SIGNAL(sigOpacityFinishedChanging(int, int)),
this, TQ_SLOT(layerOpacityFinishedChanging(int, int)));
connect(m_layerBox, TQ_SIGNAL(sigItemComposite(const KisCompositeOp&)), this, TQ_SLOT(layerCompositeOp(const KisCompositeOp&)));
paletteManager()->addWidget(m_layerBox, "layerbox", chalk::LAYERBOX, 0);
}
DCOPObject* KisView::dcopObject()
{
if (!m_dcop) {
m_dcop = new KisViewIface(this);
TQ_CHECK_PTR(m_dcop);
}
return m_dcop;
}
void KisView::setupScrollBars()
{
m_scrollX = 0;
m_scrollY = 0;
m_vScroll = new TQScrollBar(TQt::Vertical, this);
TQ_CHECK_PTR(m_vScroll);
m_hScroll = new TQScrollBar(TQt::Horizontal, this);
TQ_CHECK_PTR(m_hScroll);
m_vScroll->setGeometry(width() - 16, 20, 16, height() - 36);
m_hScroll->setGeometry(20, height() - 16, width() - 36, 16);
m_hScroll->setValue(0);
m_vScroll->setValue(0);
TQObject::connect(m_vScroll, TQ_SIGNAL(valueChanged(int)), this, TQ_SLOT(scrollV(int)));
TQObject::connect(m_hScroll, TQ_SIGNAL(valueChanged(int)), this, TQ_SLOT(scrollH(int)));
}
void KisView::setupRulers()
{
m_hRuler = new KisRuler(TQt::Horizontal, this);
TQ_CHECK_PTR(m_hRuler);
m_vRuler = new KisRuler(TQt::Vertical, this);
TQ_CHECK_PTR(m_vRuler);
m_hRuler->setGeometry(20, 0, width() - 20, 20);
m_vRuler->setGeometry(0, 20, 20, height() - 20);
if (statusBar()) {
m_hRuler->installEventFilter(this);
m_vRuler->installEventFilter(this);
}
}
#define EPSILON 1e-6
void KisView::updateStatusBarZoomLabel ()
{
if (zoom() < 1 - EPSILON) {
m_statusBarZoomLabel->setText(i18n("Zoom %1%").arg(zoom() * 100, 0, 'g', 4));
} else {
m_statusBarZoomLabel->setText(i18n("Zoom %1%").arg(zoom() * 100, 0, 'f', 0));
}
m_statusBarZoomLabel->setMaximumWidth(m_statusBarZoomLabel->fontMetrics().width(i18n("Zoom %1%").arg("0.8888 ")));
}
void KisView::updateStatusBarSelectionLabel()
{
if (m_statusBarSelectionLabel == 0) {
return;
}
KisImageSP img = currentImg();
if (img) {
KisPaintDeviceSP dev = img->activeDevice();
if (dev) {
if (dev->hasSelection()) {
TQRect r = dev->selection()->selectedExactRect();
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()));
return;
}
}
}
m_statusBarSelectionLabel->setText(i18n("No Selection"));
}
void KisView::updateStatusBarProfileLabel()
{
if (m_statusBarProfileLabel == 0) {
return;
}
KisImageSP img = currentImg();
if (!img) return;
if (img->getProfile() == 0) {
m_statusBarProfileLabel->setText(i18n("No profile"));
}
else {
m_statusBarProfileLabel->setText(img->colorSpace()->id().name() + " " + img->getProfile()->productName());
}
}
KisProfile * KisView::monitorProfile()
{
if (m_monitorProfile == 0) {
resetMonitorProfile();
}
return m_monitorProfile;
}
void KisView::resetMonitorProfile()
{
m_monitorProfile = KisProfile::getScreenProfile();
if (m_monitorProfile == 0) {
KisConfig cfg;
TQString monitorProfileName = cfg.monitorProfile();
m_monitorProfile = KisMetaRegistry::instance()->csRegistry()->getProfileByName(monitorProfileName);
}
}
void KisView::setupStatusBar()
{
KStatusBar *sb = statusBar();
if (sb) {
m_statusBarZoomLabel = new TQLabel(sb);
addStatusBarItem(m_statusBarZoomLabel,1);
updateStatusBarZoomLabel();
m_statusBarSelectionLabel = new KSqueezedTextLabel(sb);
addStatusBarItem(m_statusBarSelectionLabel,2);
updateStatusBarSelectionLabel();
m_statusBarProfileLabel = new KSqueezedTextLabel(sb);
addStatusBarItem(m_statusBarProfileLabel,3);
updateStatusBarProfileLabel();
//int height = m_statusBarProfileLabel->height();
m_progress = new KisLabelProgress(this);
m_progress->setMaximumWidth(225);
m_progress->setMinimumWidth(225);
m_progress->setMaximumHeight(fontMetrics().height() );
addStatusBarItem(m_progress, 2, true);
m_progress->hide();
}
}
void KisView::setupActions()
{
KisConfig cfg;
m_selectionManager->setup(actionCollection());
m_filterManager->setup(actionCollection());
m_gridManager->setup(actionCollection());
m_perspectiveGridManager->setup(actionCollection());
m_fullScreen = KStdAction::fullScreen( NULL, NULL, actionCollection(), this );
connect( m_fullScreen, TQ_SIGNAL( toggled( bool )), this, TQ_SLOT( slotUpdateFullScreen( bool )));
m_imgProperties = new TDEAction(i18n("Image Properties"), 0, this, TQ_SLOT(slotImageProperties()), actionCollection(), "img_properties");
m_imgScan = 0; // How the hell do I get a TDEAction to the scan plug-in?!?
m_imgResizeToLayer = new TDEAction(i18n("Resize Image to Size of Current Layer"), 0, this, TQ_SLOT(imgResizeToActiveLayer()), actionCollection(), "resizeimgtolayer");
// view actions
m_zoomIn = KStdAction::zoomIn(this, TQ_SLOT(slotZoomIn()), actionCollection(), "zoom_in");
m_zoomOut = KStdAction::zoomOut(this, TQ_SLOT(slotZoomOut()), actionCollection(), "zoom_out");
m_actualPixels = new TDEAction(i18n("Actual Pixels"), "Ctrl+0", this, TQ_SLOT(slotActualPixels()), actionCollection(), "actual_pixels");
m_actualSize = KStdAction::actualSize(this, TQ_SLOT(slotActualSize()), actionCollection(), "actual_size");
m_actualSize->setEnabled(false);
m_fitToCanvas = KStdAction::fitToPage(this, TQ_SLOT(slotFitToCanvas()), actionCollection(), "fit_to_canvas");
// layer actions
m_layerAdd = new TDEAction(i18n("&Add..."), "Ctrl+Shift+N", this, TQ_SLOT(layerAdd()), actionCollection(), "insert_layer");
m_actionPartLayer = new KoPartSelectAction( i18n( "&Object Layer" ), "frame_query",
this, TQ_SLOT( addPartLayer() ),
actionCollection(), "insert_part_layer" );
m_actionAdjustmentLayer = new TDEAction( i18n( "&Adjustment Layer" ), 0,
this, TQ_SLOT( addAdjustmentLayer() ),
actionCollection(), "insert_adjustment_layer" );
m_layerRm = new TDEAction(i18n("&Remove"), 0, this, TQ_SLOT(layerRemove()), actionCollection(), "remove_layer");
m_layerDup = new TDEAction(i18n("Duplicate"), 0, this, TQ_SLOT(layerDuplicate()), actionCollection(), "duplicate_layer");
m_layerHide = new TDEToggleAction(i18n("&Hide"), 0, this, TQ_SLOT(layerToggleVisible()), actionCollection(), "hide_layer");
m_layerHide->setCheckedState(KGuiItem(i18n("&Show")));
m_layerHide->setChecked(false);
m_layerRaise = new TDEAction(i18n("Raise"), "raise", "Ctrl+]", this, TQ_SLOT(layerRaise()), actionCollection(), "raiselayer");
m_layerLower = new TDEAction(i18n("Lower"), "lower", "Ctrl+[", this, TQ_SLOT(layerLower()), actionCollection(), "lowerlayer");
m_layerTop = new TDEAction(i18n("To Top"), "bring_forward", "Ctrl+Shift+]", this, TQ_SLOT(layerFront()), actionCollection(), "toplayer");
m_layerBottom = new TDEAction(i18n("To Bottom"), "send_backward", "Ctrl+Shift+[", this, TQ_SLOT(layerBack()), actionCollection(), "bottomlayer");
m_layerProperties = new TDEAction(i18n("Properties"), 0, this, TQ_SLOT(layerProperties()), actionCollection(), "layer_properties");
(void)new TDEAction(i18n("I&nsert Image as Layer..."), 0, this, TQ_SLOT(slotInsertImageAsLayer()), actionCollection(), "insert_image_as_layer");
m_layerSaveAs = new TDEAction(i18n("Save Layer as Image..."), "document-save", this, TQ_SLOT(saveLayerAsImage()), actionCollection(), "save_layer_as_image");
(void)new TDEAction(i18n("Flip on &X Axis"), "view_left_right", 0, this, TQ_SLOT(mirrorLayerX()), actionCollection(), "mirrorLayerX");
(void)new TDEAction(i18n("Flip on &Y Axis"), "view_top_bottom", 0, this, TQ_SLOT(mirrorLayerY()), actionCollection(), "mirrorLayerY");
m_createMask = new TDEAction(i18n("Create Mask"), 0, this,
TQ_SLOT(slotCreateMask()), actionCollection(), "create_mask");
m_maskFromSelection = new TDEAction(i18n("Mask From Selection"), 0, this,
TQ_SLOT(slotMaskFromSelection()), actionCollection(),
"mask_fromsel");
m_maskToSelection = new TDEAction(i18n("Mask to Selection"), 0, this,
TQ_SLOT(slotMaskToSelection()), actionCollection(), "mask_tosel");
m_applyMask = new TDEAction(i18n("Apply Mask"), 0, this, TQ_SLOT(slotApplyMask()),
actionCollection(), "apply_mask");
m_removeMask = new TDEAction(i18n("Remove Mask"), 0, this,
TQ_SLOT(slotRemoveMask()), actionCollection(), "remove_mask");
m_showMask = new TDEToggleAction(i18n( "Show Mask" ), 0, this,
TQ_SLOT(slotShowMask()), actionCollection(), "show_mask");
m_editMask = new TDEToggleAction(i18n( "Edit Mask" ), 0, this,
TQ_SLOT(slotEditMask()), actionCollection(), "edit_mask");
// image actions
m_imgFlatten = new TDEAction(i18n("&Flatten Image"), "Ctrl+Shift+E", this, TQ_SLOT(flattenImage()), actionCollection(), "flatten_image");
m_imgMergeLayer = new TDEAction(i18n("&Merge with Layer Below"), "Ctrl+E", this, TQ_SLOT(mergeLayer()), actionCollection(), "merge_layer");
// setting actions
KStdAction::preferences(this, TQ_SLOT(preferences()), actionCollection(), "preferences");
m_RulerAction = new TDEToggleAction( i18n( "Show Rulers" ), "Ctrl+R", this, TQ_SLOT( showRuler() ), actionCollection(), "view_ruler" );
m_RulerAction->setChecked(cfg.showRulers());
m_RulerAction->setCheckedState(i18n("Hide Rulers"));
m_RulerAction->setWhatsThis( i18n("The rulers show the horizontal and vertical positions of the mouse on the image "
"and can be used to position your mouse at the right place on the canvas. <p>Uncheck this to disable "
"the rulers from being displayed." ) );
//m_guideAction = new TDEToggleAction( i18n( "Guide Lines" ), 0, this, TQ_SLOT( viewGuideLines() ), actionCollection(), "view_guidelines" );
// Add new palette
new TDEAction(i18n("Add New Palette..."), 0, this, TQ_SLOT(slotAddPalette()),
actionCollection(), "add_palette");
new TDEAction(i18n("Edit Palette..."), 0, this, TQ_SLOT(slotEditPalette()),
actionCollection(), "edit_palette");
// XXX: This triggers a repaint of the image, but way too early
//showRuler();
}
void KisView::resizeEvent(TQResizeEvent *)
{
if (!m_paintViewEnabled) {
startInitialZoomTimerIfReady();
}
KisImageSP img = currentImg();
TQ_INT32 scrollBarExtent = style().pixelMetric(TQStyle::PM_ScrollBarExtent);
TQ_INT32 drawH;
TQ_INT32 drawW;
TQ_INT32 docW;
TQ_INT32 docH;
// if (img) {
// KisGuideMgr *mgr = img->guides();
// mgr->resize(size());
// }
docW = static_cast<TQ_INT32>(ceil(docWidth() * zoom()));
docH = static_cast<TQ_INT32>(ceil(docHeight() * zoom()));
m_rulerThickness = m_RulerAction->isChecked() ? RULER_THICKNESS : 0;
drawH = height() - m_rulerThickness;
drawW = width() - m_rulerThickness;
if (drawH < docH) {
// Will need vert scrollbar
drawW -= scrollBarExtent;
if (drawW < docW)
// Will need horiz scrollbar
drawH -= scrollBarExtent;
} else if (drawW < docW) {
// Will need horiz scrollbar
drawH -= scrollBarExtent;
if (drawH < docH)
// Will need vert scrollbar
drawW -= scrollBarExtent;
}
m_vScroll->setEnabled(docH > drawH);
m_hScroll->setEnabled(docW > drawW);
if (docH <= drawH && docW <= drawW) {
// we need no scrollbars
m_vScroll->hide();
m_hScroll->hide();
m_vScroll->setValue(0);
m_hScroll->setValue(0);
m_vScrollBarExtent = 0;
m_hScrollBarExtent = 0;
} else if (docH <= drawH) {
// we need a horizontal scrollbar only
m_vScroll->hide();
m_vScroll->setValue(0);
m_hScroll->setRange(0, docW - drawW);
m_hScroll->setGeometry(m_rulerThickness,
height() - scrollBarExtent,
width() - m_rulerThickness,
scrollBarExtent);
m_hScroll->show();
m_hScrollBarExtent = scrollBarExtent;
m_hScrollBarExtent = scrollBarExtent;
} else if(docW <= drawW) {
// we need a vertical scrollbar only
m_hScroll->hide();
m_hScroll->setValue(0);
m_vScroll->setRange(0, docH - drawH);
m_vScroll->setGeometry(width() - scrollBarExtent, m_rulerThickness, scrollBarExtent, height() - m_rulerThickness);
m_vScroll->show();
m_vScrollBarExtent = scrollBarExtent;
} else {
// we need both scrollbars
m_vScroll->setRange(0, docH - drawH);
m_vScroll->setGeometry(width() - scrollBarExtent,
m_rulerThickness,
scrollBarExtent,
height() -2* m_rulerThickness);
m_hScroll->setRange(0, docW - drawW);
m_hScroll->setGeometry(m_rulerThickness,
height() - scrollBarExtent,
width() - 2*m_rulerThickness,
scrollBarExtent);
m_vScroll->show();
m_hScroll->show();
m_vScrollBarExtent = scrollBarExtent;
m_hScrollBarExtent = scrollBarExtent;
}
TQ_INT32 oldCanvasXOffset = m_canvasXOffset;
TQ_INT32 oldCanvasYOffset = m_canvasYOffset;
if (docW < drawW) {
m_canvasXOffset = (drawW - docW) / 2;
} else {
m_canvasXOffset = 0;
}
if (docH < drawH) {
m_canvasYOffset = (drawH - docH) / 2;
} else {
m_canvasYOffset = 0;
}
//Check if rulers are visible
if( m_RulerAction->isChecked() )
m_canvas->setGeometry(m_rulerThickness, m_rulerThickness, drawW, drawH);
else
m_canvas->setGeometry(0, 0, drawW, drawH);
m_canvas->show();
if (!m_canvas->isOpenGLCanvas()) {
if (m_canvasPixmap.size() != TQSize(drawW, drawH)) {
TQ_INT32 oldCanvasWidth = m_canvasPixmap.width();
TQ_INT32 oldCanvasHeight = m_canvasPixmap.height();
TQ_INT32 newCanvasWidth = drawW;
TQ_INT32 newCanvasHeight = drawH;
TQRegion exposedRegion = TQRect(0, 0, newCanvasWidth, newCanvasHeight);
// Increase size first so that we can copy the old image area to the new one.
m_canvasPixmap.resize(TQMAX(oldCanvasWidth, newCanvasWidth), TQMAX(oldCanvasHeight, newCanvasHeight));
if (!m_canvasPixmap.isNull()) {
if (oldCanvasXOffset != m_canvasXOffset || oldCanvasYOffset != m_canvasYOffset) {
TQ_INT32 srcX;
TQ_INT32 srcY;
TQ_INT32 srcWidth;
TQ_INT32 srcHeight;
TQ_INT32 dstX;
TQ_INT32 dstY;
if (oldCanvasXOffset <= m_canvasXOffset) {
// Move to the right
srcX = 0;
dstX = m_canvasXOffset - oldCanvasXOffset;
srcWidth = oldCanvasWidth;
} else {
// Move to the left
srcX = oldCanvasXOffset - m_canvasXOffset;
dstX = 0;
srcWidth = newCanvasWidth;
}
if (oldCanvasYOffset <= m_canvasYOffset) {
// Move down
srcY = 0;
dstY = m_canvasYOffset - oldCanvasYOffset;
srcHeight = oldCanvasHeight;
} else {
// Move up
srcY = oldCanvasYOffset - m_canvasYOffset;
dstY = 0;
srcHeight = newCanvasHeight;
}
bitBlt(&m_canvasPixmap, dstX, dstY, &m_canvasPixmap, srcX, srcY, srcWidth, srcHeight);
exposedRegion -= TQRegion(TQRect(dstX, dstY, srcWidth, srcHeight));
} else {
exposedRegion -= TQRegion(TQRect(0, 0, oldCanvasWidth, oldCanvasHeight));
}
}
m_canvasPixmap.resize(newCanvasWidth, newCanvasHeight);
if (!m_canvasPixmap.isNull() && !exposedRegion.isEmpty()) {
TQMemArray<TQRect> rects = exposedRegion.rects();
for (unsigned int i = 0; i < rects.count(); i++) {
TQRect r = rects[i];
updateTQPaintDeviceCanvas(viewToWindow(r));
}
}
}
}
int fontheight = TQFontMetrics(TDEGlobalSettings::generalFont()).height() * 3;
m_vScroll->setPageStep(drawH);
m_vScroll->setLineStep(fontheight);
m_hScroll->setPageStep(drawW);
m_hScroll->setLineStep(fontheight);
m_hRuler->setGeometry(m_rulerThickness + m_canvasXOffset, 0, TQMIN(docW, drawW), m_rulerThickness);
m_vRuler->setGeometry(0, m_rulerThickness + m_canvasYOffset, m_rulerThickness, TQMIN(docH, drawH));
if (m_vScroll->isVisible())
m_vRuler->updateVisibleArea(0, m_vScroll->value());
else
m_vRuler->updateVisibleArea(0, 0);
if (m_hScroll->isVisible())
m_hRuler->updateVisibleArea(m_hScroll->value(), 0);
else
m_hRuler->updateVisibleArea(0, 0);
if( m_RulerAction->isChecked() )
{
m_hRuler->show();
m_vRuler->show();
}
else {
m_hRuler->hide();
m_vRuler->hide();
}
emit viewTransformationsChanged();
}
void KisView::styleChange(TQStyle& oldStyle)
{
Q_UNUSED(oldStyle);
m_canvas->updateGeometry();
refreshKisCanvas();
}
void KisView::paletteChange(const TQPalette& oldPalette)
{
Q_UNUSED(oldPalette);
refreshKisCanvas();
}
void KisView::showEvent(TQShowEvent *)
{
if (!m_showEventReceived) {
m_showEventReceived = true;
startInitialZoomTimerIfReady();
}
}
void KisView::updateReadWrite(bool readwrite)
{
layerUpdateGUI(readwrite);
}
TQ_INT32 KisView::horzValue() const
{
return m_hScroll->value() - m_canvasXOffset;
}
TQ_INT32 KisView::vertValue() const
{
return m_vScroll->value() - m_canvasYOffset;
}
void KisView::updateTQPaintDeviceCanvas(const TQRect& imageRect)
{
TQRect vr = windowToView(imageRect);
vr &= TQRect(0, 0, m_canvas->width(), m_canvas->height());
if (!vr.isEmpty()) {
TQPainter gc;
if (!m_canvasPixmap.isNull() && gc.begin(&m_canvasPixmap)) {
KisImageSP img = currentImg();
if (img && m_paintViewEnabled) {
TQRect wr = viewToWindow(vr);
if (wr.left() < 0 || wr.right() >= img->width() || wr.top() < 0 || wr.bottom() >= img->height()) {
// Erase areas outside document
TQRegion rg(vr);
rg -= TQRegion(windowToView(TQRect(0, 0, img->width(), img->height())));
TQMemArray<TQRect> rects = rg.rects();
for (unsigned int i = 0; i < rects.count(); i++) {
TQRect er = rects[i];
gc.fillRect(er, colorGroup().mid());
}
wr &= TQRect(0, 0, img->width(), img->height());
}
if (!wr.isEmpty()) {
KisImage::PaintFlags paintFlags = (KisImage::PaintFlags)KisImage::PAINT_BACKGROUND;
if (m_actLayerVis) {
paintFlags = (KisImage::PaintFlags)(paintFlags|KisImage::PAINT_MASKINACTIVELAYERS);
}
if (m_selectionManager->displaySelection())
{
paintFlags = (KisImage::PaintFlags)(paintFlags|KisImage::PAINT_SELECTION);
}
if (zoom() > 1.0 - EPSILON) {
gc.setWorldXForm(true);
gc.translate(-horzValue(), -vertValue());
gc.scale(zoomFactor(), zoomFactor());
m_image->renderToPainter(wr.left(), wr.top(),
wr.right(), wr.bottom(), gc, monitorProfile(),
paintFlags, HDRExposure());
} else {
TQRect canvasRect = windowToView(wr);
TQRect scaledImageRect = canvasRect;
scaledImageRect.moveBy(horzValue(), vertValue());
TQSize scaledImageSize(static_cast<TQ_INT32>(ceil(docWidth() * zoom())),
static_cast<TQ_INT32>(ceil(docHeight() * zoom())));
TQImage image = m_image->convertToTQImage(scaledImageRect, scaledImageSize,
monitorProfile(), paintFlags, HDRExposure());
gc.drawImage(canvasRect.topLeft(), image, image.rect());
// Set up for the grid drawer.
gc.setWorldXForm(true);
gc.translate(-horzValue(), -vertValue());
gc.scale(zoomFactor(), zoomFactor());
}
m_gridManager->drawGrid( wr, &gc );
m_perspectiveGridManager->drawGrid( wr, &gc );
}
// paintGuides();
} else {
gc.fillRect(vr, colorGroup().mid());
}
}
}
}
void KisView::paintTQPaintDeviceView(const TQRegion& canvasRegion)
{
Q_ASSERT(m_canvas->TQPaintDeviceWidget() != 0);
if (m_canvas->TQPaintDeviceWidget() != 0 && !m_canvasPixmap.isNull()) {
TQMemArray<TQRect> rects = canvasRegion.rects();
for (unsigned int i = 0; i < rects.count(); i++) {
TQRect r = rects[i];
bitBlt(m_canvas->TQPaintDeviceWidget(), r.x(), r.y(), &m_canvasPixmap,
r.x(), r.y(), r.width(), r.height());
}
paintToolOverlay(canvasRegion);
}
}
void KisView::updateOpenGLCanvas(const TQRect& imageRect)
{
#ifdef HAVE_GL
KisImageSP img = currentImg();
if (img && m_paintViewEnabled) {
Q_ASSERT(m_OpenGLImageContext != 0);
if (m_OpenGLImageContext != 0) {
m_OpenGLImageContext->update(imageRect);
}
}
#else
Q_UNUSED(imageRect);
#endif
}
void KisView::paintOpenGLView(const TQRect& canvasRect)
{
#ifdef HAVE_GL
if (!m_canvas->isUpdatesEnabled()) {
return;
}
m_canvas->OpenGLWidget()->makeCurrent();
glDrawBuffer(GL_BACK);
TQColor widgetBackgroundColor = colorGroup().mid();
glClearColor(widgetBackgroundColor.red() / 255.0, widgetBackgroundColor.green() / 255.0, widgetBackgroundColor.blue() / 255.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
KisImageSP img = currentImg();
if (img && m_paintViewEnabled) {
TQRect vr = canvasRect;
vr &= TQRect(0, 0, m_canvas->width(), m_canvas->height());
if (!vr.isNull()) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, m_canvas->width(), m_canvas->height());
glOrtho(0, m_canvas->width(), m_canvas->height(), 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, m_OpenGLImageContext->backgroundTexture());
glTranslatef(m_canvasXOffset, m_canvasYOffset, 0.0);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex2f(0.0, 0.0);
glTexCoord2f((img->width() * zoom()) / KisOpenGLImageContext::BACKGROUND_TEXTURE_WIDTH, 0.0);
glVertex2f(img->width() * zoom(), 0.0);
glTexCoord2f((img->width() * zoom()) / KisOpenGLImageContext::BACKGROUND_TEXTURE_WIDTH,
(img->height() * zoom()) / KisOpenGLImageContext::BACKGROUND_TEXTURE_HEIGHT);
glVertex2f(img->width() * zoom(), img->height() * zoom());
glTexCoord2f(0.0, (img->height() * zoom()) / KisOpenGLImageContext::BACKGROUND_TEXTURE_HEIGHT);
glVertex2f(0.0, img->height() * zoom());
glEnd();
glTranslatef(-m_canvasXOffset, -m_canvasYOffset, 0.0);
glTranslatef(-horzValue(), -vertValue(), 0.0);
glScalef(zoomFactor(), zoomFactor(), 1.0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
TQRect wr = viewToWindow(TQRect(0, 0, m_canvas->width(), m_canvas->height()));
wr &= TQRect(0, 0, img->width(), img->height());
m_OpenGLImageContext->setHDRExposure(HDRExposure());
m_canvas->OpenGLWidget()->makeCurrent();
for (int x = (wr.left() / m_OpenGLImageContext->imageTextureTileWidth()) * m_OpenGLImageContext->imageTextureTileWidth();
x <= wr.right();
x += m_OpenGLImageContext->imageTextureTileWidth()) {
for (int y = (wr.top() / m_OpenGLImageContext->imageTextureTileHeight()) * m_OpenGLImageContext->imageTextureTileHeight();
y <= wr.bottom();
y += m_OpenGLImageContext->imageTextureTileHeight()) {
glBindTexture(GL_TEXTURE_2D, m_OpenGLImageContext->imageTextureTile(x, y));
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex2f(x, y);
glTexCoord2f(1.0, 0.0);
glVertex2f(x + m_OpenGLImageContext->imageTextureTileWidth(), y);
glTexCoord2f(1.0, 1.0);
glVertex2f(x + m_OpenGLImageContext->imageTextureTileWidth(), y + m_OpenGLImageContext->imageTextureTileHeight());
glTexCoord2f(0.0, 1.0);
glVertex2f(x, y + m_OpenGLImageContext->imageTextureTileHeight());
glEnd();
}
}
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
m_gridManager->drawGrid(wr, 0, true);
m_perspectiveGridManager->drawGrid( wr, 0, true );
// Unbind the texture otherwise the ATI driver crashes when the canvas context is
// made current after the textures are deleted following an image resize.
glBindTexture(GL_TEXTURE_2D, 0);
//paintGuides();
}
}
m_canvas->OpenGLWidget()->swapBuffers();
paintToolOverlay(TQRegion(canvasRect));
#else
Q_UNUSED(canvasRect);
#endif
}
void KisView::setInputDevice(KisInputDevice inputDevice)
{
if (inputDevice != m_inputDevice) {
m_inputDevice = inputDevice;
m_toolManager->setToolForInputDevice(m_inputDevice, inputDevice);
if (m_toolManager->currentTool() == 0) {
m_toolManager->setCurrentTool(m_toolManager->findTool("tool_brush", m_inputDevice));
}
else {
m_toolManager->setCurrentTool(m_toolManager->currentTool());
}
m_toolManager->activateCurrentTool();
emit sigInputDeviceChanged(inputDevice);
}
}
KisInputDevice KisView::currentInputDevice() const
{
return m_inputDevice;
}
KisCanvas *KisView::kiscanvas() const
{
return m_canvas;
}
void KisView::updateCanvas()
{
if (m_image) {
updateCanvas(m_image->bounds());
}
}
void KisView::updateCanvas(TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h)
{
updateCanvas(TQRect(x, y, w, h));
}
void KisView::updateCanvas(const TQRect& imageRect)
{
if (m_canvas->isOpenGLCanvas()) {
updateOpenGLCanvas(imageRect);
paintOpenGLView(windowToView(imageRect));
} else {
updateTQPaintDeviceCanvas(imageRect);
//m_canvas->update(windowToView(imageRect));
m_canvas->repaint(windowToView(imageRect));
}
}
void KisView::refreshKisCanvas()
{
TQRect imageRect = viewToWindow(TQRect(0, 0, m_canvas->width(), m_canvas->height()));
if (m_image) {
imageRect |= m_image->bounds();
}
updateCanvas(imageRect);
// Enable this if updateCanvas does an m_canvas->update()
//m_canvas->repaint();
}
void KisView::selectionDisplayToggled(bool displaySelection)
{
#ifdef HAVE_GL
if (m_canvas->isOpenGLCanvas()) {
if (m_OpenGLImageContext) {
m_OpenGLImageContext->setSelectionDisplayEnabled(displaySelection);
}
}
#else
Q_UNUSED(displaySelection);
#endif
updateCanvas();
}
void KisView::layerUpdateGUI(bool enable)
{
KisImageSP img = currentImg();
KisLayerSP layer;
TQ_INT32 nlayers = 0;
TQ_INT32 nvisible = 0;
if (img) {
layer = img->activeLayer();
nlayers = img->nlayers();
nvisible = nlayers - img->nHiddenLayers();
}
KisPaintLayer * pl = dynamic_cast<KisPaintLayer*>(layer.data());
if (pl && ( m_currentColorChooserDisplay != KisID("BLA") ||
pl->paintDevice()->colorSpace()->id() != m_currentColorChooserDisplay)) {
if (pl->paintDevice()->colorSpace()->id() == KisID("WET")) {
m_paletteManager->hideWidget( "hsvwidget" );
m_paletteManager->hideWidget( "rgbwidget" );
m_paletteManager->hideWidget( "graywidget" );
m_paletteManager->hideWidget( "palettewidget" );
m_paletteManager->showWidget( "watercolor docker" );
}
else {
m_paletteManager->hideWidget( "watercolor docker" );
m_paletteManager->showWidget( "palettewidget" );
m_paletteManager->showWidget( "graywidget" );
m_paletteManager->showWidget( "rgbwidget" );
m_paletteManager->showWidget( "hsvwidget" );
}
m_currentColorChooserDisplay = pl->paintDevice()->colorSpace()->id();
}
enable = enable && img && layer && layer->visible() && !layer->locked();
m_layerDup->setEnabled(enable);
m_layerRm->setEnabled(enable);
m_layerHide->setEnabled(img && layer);
m_layerProperties->setEnabled(enable);
m_layerSaveAs->setEnabled(enable);
m_layerRaise->setEnabled(enable && layer->prevSibling());
m_layerLower->setEnabled(enable && layer->nextSibling());
m_layerTop->setEnabled(enable && nlayers > 1 && layer != img->rootLayer()->firstChild());
m_layerBottom->setEnabled(enable && nlayers > 1 && layer != img->rootLayer()->lastChild());
// XXX these should be named layer instead of img
m_imgFlatten->setEnabled(nlayers > 1);
m_imgMergeLayer->setEnabled(nlayers > 1 && layer && layer->nextSibling());
m_selectionManager->updateGUI();
m_filterManager->updateGUI();
m_toolManager->updateGUI();
m_gridManager->updateGUI();
m_perspectiveGridManager->updateGUI();
KisPartLayer * partLayer = dynamic_cast<KisPartLayer*>(layer.data());
if (partLayer) {
setCanvasCursor( KisCursor::arrowCursor() );
}
if (img && img->activeDevice())
emit currentColorSpaceChanged(img->activeDevice()->colorSpace());
imgUpdateGUI();
}
void KisView::imgUpdateGUI()
{
KisImageSP img = currentImg();
m_imgResizeToLayer->setEnabled(img && img->activeLayer());
updateStatusBarProfileLabel();
}
static const double zoomLevels[] = {
1.0 / 500,
1.0 / 333.333333,
1.0 / 250,
1.0 / 200,
1.0 / 150,
1.0 / 100,
1.0 / 66.666667,
1.0 / 50,
1.0 / 33.333333,
1.0 / 25,
1.0 / 20,
1.0 / 16,
1.0 / 12,
1.0 / 8,
1.0 / 6,
1.0 / 4,
1.0 / 3,
1.0 / 2,
1.0 / 1.5,
1,
2,
3,
4,
5,
6,
7,
8,
12,
16
};
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define NUM_ZOOM_LEVELS ARRAY_SIZE(zoomLevels)
#define FIRST_ZOOM_LEVEL_INDEX 0
#define LAST_ZOOM_LEVEL_INDEX (NUM_ZOOM_LEVELS - 1)
#define KISVIEW_MIN_ZOOM (zoomLevels[FIRST_ZOOM_LEVEL_INDEX])
#define KISVIEW_MAX_ZOOM (zoomLevels[LAST_ZOOM_LEVEL_INDEX])
double KisView::nextZoomInLevel() const
{
uint zoomLevelIndex = FIRST_ZOOM_LEVEL_INDEX;
while (zoom() >= zoomLevels[zoomLevelIndex] && zoomLevelIndex < LAST_ZOOM_LEVEL_INDEX) {
zoomLevelIndex++;
}
return zoomLevels[zoomLevelIndex];
}
double KisView::nextZoomOutLevel(double zoomLevel) const
{
int zoomLevelIndex = LAST_ZOOM_LEVEL_INDEX;
while (zoomLevel <= zoomLevels[zoomLevelIndex] && zoomLevelIndex > FIRST_ZOOM_LEVEL_INDEX) {
zoomLevelIndex--;
}
return zoomLevels[zoomLevelIndex];
}
double KisView::nextZoomOutLevel() const
{
return nextZoomOutLevel(zoom());
}
void KisView::zoomAroundPoint(double x, double y, double zf)
{
// Disable updates while we change the scrollbar settings.
m_canvas->setUpdatesEnabled(false);
m_hScroll->setUpdatesEnabled(false);
m_vScroll->setUpdatesEnabled(false);
if (x < 0 || y < 0) {
// Zoom about the centre of the current display
KisImageSP img = currentImg();
if (img) {
if (m_hScroll->isVisible()) {
KisPoint c = viewToWindow(KisPoint(m_canvas->width() / 2.0, m_canvas->height() / 2.0));
x = c.x();
}
else {
x = img->width() / 2.0;
}
if (m_vScroll->isVisible()) {
KisPoint c = viewToWindow(KisPoint(m_canvas->width() / 2.0, m_canvas->height() / 2.0));
y = c.y();
}
else {
y = img->height() / 2.0;
}
}
else {
x = 0;
y = 0;
}
}
setZoom(zf);
Q_ASSERT(m_zoomIn);
Q_ASSERT(m_zoomOut);
updateStatusBarZoomLabel ();
m_zoomIn->setEnabled(zf < KISVIEW_MAX_ZOOM);
m_zoomOut->setEnabled(zf > KISVIEW_MIN_ZOOM);
resizeEvent(0);
m_hRuler->setZoom(zf);
m_vRuler->setZoom(zf);
if (m_hScroll->isVisible()) {
double vcx = m_canvas->width() / 2.0;
TQ_INT32 scrollX = tqRound(x * zoom() - vcx);
m_hScroll->setValue(scrollX);
}
if (m_vScroll->isVisible()) {
double vcy = m_canvas->height() / 2.0;
TQ_INT32 scrollY = tqRound(y * zoom() - vcy);
m_vScroll->setValue(scrollY);
}
// Now update everything.
m_canvas->setUpdatesEnabled(true);
m_hScroll->setUpdatesEnabled(true);
m_vScroll->setUpdatesEnabled(true);
m_hScroll->update();
m_vScroll->update();
if (m_canvas->isOpenGLCanvas()) {
paintOpenGLView(TQRect(0, 0, m_canvas->width(), m_canvas->height()));
} else {
refreshKisCanvas();
}
emit viewTransformationsChanged();
}
void KisView::zoomTo(const KisRect& r)
{
if (!r.isNull()) {
double wZoom = fabs(m_canvas->width() / r.width());
double hZoom = fabs(m_canvas->height() / r.height());
double zf = kMin(wZoom, hZoom);
if (zf < KISVIEW_MIN_ZOOM) {
zf = KISVIEW_MIN_ZOOM;
}
else
if (zf > KISVIEW_MAX_ZOOM) {
zf = KISVIEW_MAX_ZOOM;
}
zoomAroundPoint(r.center().x(), r.center().y(), zf);
}
}
void KisView::zoomTo(const TQRect& r)
{
zoomTo(KisRect(r));
}
void KisView::zoomTo(TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h)
{
zoomTo(KisRect(x, y, w, h));
}
void KisView::zoomIn(TQ_INT32 x, TQ_INT32 y)
{
zoomAroundPoint(x, y, nextZoomInLevel());
}
void KisView::zoomOut(TQ_INT32 x, TQ_INT32 y)
{
zoomAroundPoint(x, y, nextZoomOutLevel());
}
void KisView::zoomIn()
{
slotZoomIn();
}
void KisView::zoomOut()
{
slotZoomOut();
}
void KisView::slotZoomIn()
{
zoomIn(-1, -1);
}
void KisView::slotZoomOut()
{
zoomOut(-1, -1);
}
void KisView::slotActualPixels()
{
zoomAroundPoint(-1, -1, 1.0);
}
void KisView::slotActualSize()
{
//XXX later this should be update to take screen res and image res into consideration
zoomAroundPoint(-1, -1, 1.0);
}
double KisView::fitToCanvasZoomLevel() const
{
int fullCanvasWidth = width();
if (m_vRuler->isVisible()) {
fullCanvasWidth -= m_vRuler->width();
}
int fullCanvasHeight = height();
if (m_hRuler->isVisible()) {
fullCanvasHeight -= m_hRuler->height();
}
KisImageSP img = currentImg();
if (img) {
double xZoomLevel = static_cast<double>(fullCanvasWidth) / img->width();
double yZoomLevel = static_cast<double>(fullCanvasHeight) / img->height();
return TQMIN(xZoomLevel, yZoomLevel);
}
else {
return 1;
}
}
void KisView::slotFitToCanvas()
{
zoomAroundPoint(-1, -1, fitToCanvasZoomLevel());
}
void KisView::setInitialZoomLevel()
{
double zoomLevel = fitToCanvasZoomLevel();
if (zoomLevel > 1) {
zoomLevel = 1;
} else {
zoomLevel = nextZoomOutLevel(zoomLevel);
}
zoomAroundPoint(-1, -1, zoomLevel);
}
void KisView::imgResizeToActiveLayer()
{
KisImageSP img = currentImg();
KisLayerSP layer;
if (img && (layer = img->activeLayer())) {
if (m_adapter && m_adapter->undo()) {
m_adapter->beginMacro(i18n("Resize Image to Size of Current Layer"));
}
img->lock();
TQRect r = layer->exactBounds();
img->resize(r.width(), r.height(), r.x(), r.y(), true);
img->unlock();
if (m_adapter && m_adapter->undo()) {
m_adapter->endMacro();
}
}
}
void KisView::slotImageProperties()
{
KisImageSP img = currentImg();
if (!img) return;
KisDlgImageProperties dlg(img, this);
if (dlg.exec() == TQDialog::Accepted) {
if (dlg.imageWidth() != img->width() ||
dlg.imageHeight() != img->height()) {
resizeCurrentImage(dlg.imageWidth(),
dlg.imageHeight());
}
TQ_INT32 opacity = dlg.opacity();
opacity = opacity * 255 / 100;
img->setName(dlg.imageName());
img->setColorSpace(dlg.colorSpace());
img->setResolution(dlg.resolution(), dlg.resolution());
img->setDescription(dlg.description());
img->setProfile(dlg.profile());
}
}
void KisView::slotInsertImageAsLayer()
{
if (importImage() > 0)
m_doc->setModified(true);
}
void KisView::slotAddPalette()
{
KDialogBase* base = new KDialogBase(this, 0, true, i18n("Add Palette"), KDialogBase::Ok | KDialogBase::Cancel);
KisCustomPalette* p = new KisCustomPalette(base, "add palette", i18n("Add Palette"), this);
base->setMainWidget(p);
base->show();
}
void KisView::slotEditPalette()
{
KisPaletteChooser chooser(this);
KisResourceServerBase* srv = KisResourceServerRegistry::instance()->get("PaletteServer");
if (!srv) {
return;
}
TQValueList<KisResource*> resources = srv->resources();
TQValueList<KisPalette*> palettes;
for(uint i = 0; i < resources.count(); i++) {
KisPalette* palette = dynamic_cast<KisPalette*>(*resources.at(i));
chooser.paletteList->insertItem(palette->name());
palettes.append(palette);
}
if (chooser.exec() != TQDialog::Accepted ) {
return;
}
int index = chooser.paletteList->currentItem();
if (index < 0) {
KMessageBox::error(this, i18n("No palette selected."), i18n("Palette"));
return;
}
KDialogBase* base = new KDialogBase(this, 0, true, i18n("Edit Palette") , KDialogBase::Ok);
KisCustomPalette* cp = new KisCustomPalette(base, "edit palette",
i18n("Edit Palette"), this);
cp->setEditMode(true);
cp->setPalette(*palettes.at(index));
base->setMainWidget(cp);
base->show();
}
void KisView::saveLayerAsImage()
{
TQStringList listMimeFilter = KoFilterManager::mimeFilter("application/x-chalk", KoFilterManager::Export);
TQString mimelist = listMimeFilter.join(" ");
KFileDialog fd (TQString(), mimelist, this, "Export Layer", true);
fd.setCaption(i18n("Export Layer"));
fd.setMimeFilter(listMimeFilter);
fd.setOperationMode(KFileDialog::Saving);
if (!fd.exec()) return;
KURL url = fd.selectedURL();
TQString mimefilter = fd.currentMimeFilter();
if (url.isEmpty())
return;
KisImageSP img = currentImg();
if (!img) return;
KisLayerSP l = img->activeLayer();
if (!l) return;
TQRect r = l->exactBounds();
KisDoc d;
d.prepareForImport();
KisImageSP dst = new KisImage(d.undoAdapter(), r.width(), r.height(), img->colorSpace(), l->name());
d.setCurrentImage( dst );
dst->addLayer(l->clone(),dst->rootLayer(),0);
d.setOutputMimeType(mimefilter.latin1());
d.exp0rt(url);
}
TQ_INT32 KisView::importImage(const KURL& urlArg)
{
KisImageSP currentImage = currentImg();
if (!currentImage) {
return 0;
}
KURL::List urls;
TQ_INT32 rc = 0;
if (urlArg.isEmpty()) {
TQString mimelist = KoFilterManager::mimeFilter("application/x-chalk", KoFilterManager::Import).join(" ");
urls = KFileDialog::getOpenURLs(TQString(), mimelist, 0, i18n("Import Image"));
} else {
urls.push_back(urlArg);
}
if (urls.empty())
return 0;
for (KURL::List::iterator it = urls.begin(); it != urls.end(); ++it) {
new KisImportCatcher( *it, currentImage );
}
updateCanvas();
return rc;
}
void KisView::rotateLayer180()
{
rotateLayer( M_PI );
}
void KisView::rotateLayerLeft90()
{
rotateLayer( M_PI/2 - 2*M_PI );
}
void KisView::rotateLayerRight90()
{
rotateLayer( M_PI/2 );
}
void KisView::mirrorLayerX()
{
if (!currentImg()) return;
KisPaintDeviceSP dev = currentImg()->activeDevice();
if (!dev) return;
KisTransaction * t = 0;
if (undoAdapter() && undoAdapter()->undo()) {
t = new KisTransaction(i18n("Mirror Layer X"), dev);
TQ_CHECK_PTR(t);
}
dev->mirrorX();
if (t) undoAdapter()->addCommand(t);
m_doc->setModified(true);
layersUpdated();
updateCanvas();
}
void KisView::mirrorLayerY()
{
if (!currentImg()) return;
KisPaintDeviceSP dev = currentImg()->activeDevice();
if (!dev) return;
KisTransaction * t = 0;
if (undoAdapter() && undoAdapter()->undo()) {
t = new KisTransaction(i18n("Mirror Layer Y"), dev);
TQ_CHECK_PTR(t);
}
dev->mirrorY();
if (t) undoAdapter()->addCommand(t);
m_doc->setModified(true);
layersUpdated();
updateCanvas();
}
void KisView::scaleLayer(double sx, double sy, KisFilterStrategy *filterStrategy)
{
if (!currentImg()) return;
KisPaintDeviceSP dev = currentImg()->activeDevice();
if (!dev) return;
KisSelectedTransaction * t = 0;
if (undoAdapter() && undoAdapter()->undo()) {
t = new KisSelectedTransaction(i18n("Scale Layer"), dev);
TQ_CHECK_PTR(t);
}
KisTransformWorker worker(dev, sx, sy, 0, 0, 0.0, 0, 0, m_progress, filterStrategy);
worker.run();
if (t) undoAdapter()->addCommand(t);
currentImg()->rootLayer()->setDirty(false);
m_doc->setModified(true);
layersUpdated();
updateCanvas();
}
void KisView::rotateLayer(double radians)
{
if (!currentImg()) return;
KisPaintDeviceSP dev = currentImg()->activeDevice();
if (!dev) return;
KisSelectedTransaction * t = 0;
if (undoAdapter() && undoAdapter()->undo()) {
t = new KisSelectedTransaction(i18n("Rotate Layer"), dev);
TQ_CHECK_PTR(t);
}
KisFilterStrategy *filter = KisFilterStrategyRegistry::instance()->get(KisID("Triangle"));
TQRect r;
if(dev->hasSelection())
r = dev->selection()->selectedExactRect();
else
r = dev->exactBounds();
double cx = r.x()+r.width()/2.0;
double cy = r.y()+r.height()/2.0;
TQ_INT32 tx = TQ_INT32(cx*cos(radians) - cy*sin(radians) - cx + 0.5);
TQ_INT32 ty = TQ_INT32(cy*cos(radians) + cx*sin(radians) - cy + 0.5);
KisTransformWorker tw(dev, 1.0, 1.0, 0, 0, radians, -tx, -ty, m_progress, filter);
tw.run();
if (t) undoAdapter()->addCommand(t);
m_doc->setModified(true);
layersUpdated();
updateCanvas();
}
void KisView::shearLayer(double angleX, double angleY)
{
if (!currentImg()) return;
KisLayerSP layer = currentImg()->activeLayer();
if (!layer) return;
KisUndoAdapter * undo = 0;
if ((undo = currentImg()->undoAdapter())) {
undo->beginMacro(i18n("Shear layer"));
}
KisShearVisitor v(angleX, angleY, m_progress);
v.setUndoAdapter(undo);
layer->accept(v);
if (undo) undo->endMacro();
m_doc->setModified(true);
layersUpdated();
updateCanvas();
}
void KisView::flattenImage()
{
KisImageSP img = currentImg();
if (img) {
bool doIt = true;
if (img->nHiddenLayers() > 0) {
int answer = KMessageBox::warningYesNo(this,
i18n("The image contains hidden layers that will be lost."),
i18n("Flatten Image"),
i18n("&Flatten Image"),
KStdGuiItem::cancel());
if (answer != KMessageBox::Yes) {
doIt = false;
}
}
if (doIt) {
img->flatten();
}
}
}
void KisView::mergeLayer()
{
KisImageSP img = currentImg();
if (!img) return;
KisLayerSP layer = img->activeLayer();
if (!layer) return;
img->mergeLayer(layer);
}
void KisView::preferences()
{
#ifdef HAVE_GL
bool canvasWasOpenGL = m_canvas->isOpenGLCanvas();
#endif
if (PreferencesDialog::editPreferences())
{
KisConfig cfg;
m_paletteManager->slotResetFont();
resetMonitorProfile();
#ifdef HAVE_GL
if (cfg.useOpenGL() != canvasWasOpenGL) {
disconnectCurrentImg();
//XXX: Need to notify other views that this global setting has changed.
if (cfg.useOpenGL()) {
m_OpenGLImageContext = KisOpenGLImageContext::getImageContext(m_image, monitorProfile());
m_canvas->createOpenGLCanvas(m_OpenGLImageContext->sharedContextWidget());
} else
{
m_OpenGLImageContext = 0;
m_canvas->createTQPaintDeviceCanvas();
}
connectCurrentImg();
resizeEvent(0);
}
if (cfg.useOpenGL()) {
m_OpenGLImageContext->setMonitorProfile(monitorProfile());
}
#endif
refreshKisCanvas();
if (m_toolManager->currentTool()) {
setCanvasCursor(m_toolManager->currentTool()->cursor());
}
#if defined(EXTENDED_X11_TABLET_SUPPORT)
m_canvas->selectTabletDeviceEvents();
#endif
}
}
void KisView::layerCompositeOp(const KisCompositeOp& compositeOp)
{
KisImageSP img = currentImg();
if (!img) return;
KisLayerSP layer = img->activeLayer();
if (!layer) return;
if (img->undo()) {
KNamedCommand *cmd = layer->setCompositeOpCommand(compositeOp);
cmd->execute();
undoAdapter()->addCommand(cmd);
}
}
// range: 0 - 100
void KisView::layerOpacity(int opacity, bool dontundo)
{
KisImageSP img = currentImg();
if (!img) return;
KisLayerSP layer = img->activeLayer();
if (!layer) return;
opacity = int(float(opacity * 255) / 100 + 0.5);
if (opacity > 255)
opacity = 255;
if (opacity == layer->opacity()) return;
if (dontundo)
layer->setOpacity( opacity );
else
{
if (img->undo()) {
KNamedCommand *cmd = layer->setOpacityCommand(opacity);
cmd->execute();
undoAdapter()->addCommand(cmd);
}
}
}
void KisView::layerOpacityFinishedChanging( int previous, int opacity )
{
KisImageSP img = currentImg();
if (!img) return;
KisLayerSP layer = img->activeLayer();
if (!layer) return;
opacity = int(float(opacity * 255) / 100 + 0.5);
if (opacity > 255)
opacity = 255;
previous = int(float(previous * 255) / 100 + 0.5);
if (previous > 255)
previous = 255;
if (previous == opacity) return;
if (img->undo()) {
KNamedCommand *cmd = layer->setOpacityCommand(previous, opacity);
m_adapter->addCommand(cmd);
}
}
void KisView::showRuler()
{
if( m_RulerAction->isChecked() )
{
m_hRuler->show();
m_vRuler->show();
}
else
{
m_hRuler->hide();
m_vRuler->hide();
}
resizeEvent(0);
refreshKisCanvas();
}
void KisView::slotUpdateFullScreen(bool toggle)
{
if (KoView::shell()) {
uint newState = KoView::shell()->windowState();
if (toggle) {
newState |= TQt::WindowFullScreen;
} else {
newState &= ~TQt::WindowFullScreen;
}
KoView::shell()->setWindowState(newState);
}
}
TQ_INT32 KisView::docWidth() const
{
return currentImg() ? currentImg()->width() : 0;
}
TQ_INT32 KisView::docHeight() const
{
return currentImg() ? currentImg()->height() : 0;
}
void KisView::scrollTo(TQ_INT32 x, TQ_INT32 y)
{
if (m_hScroll->isVisible()) {
m_hScroll->setValue(x);
}
if (m_vScroll->isVisible()) {
m_vScroll->setValue(y);
}
}
void KisView::brushActivated(KisResource *brush)
{
m_brush = dynamic_cast<KisBrush*>(brush);
if (m_brush )
{
emit brushChanged(m_brush);
notifyObservers();
}
}
void KisView::patternActivated(KisResource *pattern)
{
m_pattern = dynamic_cast<KisPattern*>(pattern);
if (m_pattern) {
emit patternChanged(m_pattern);
notifyObservers();
}
}
void KisView::gradientActivated(KisResource *gradient)
{
m_gradient = dynamic_cast<KisGradient*>(gradient);
if (m_gradient) {
emit gradientChanged(m_gradient);
notifyObservers();
}
}
void KisView::paintopActivated(const KisID & paintop, const KisPaintOpSettings *paintopSettings)
{
if (paintop.id().isNull() || paintop.id().isEmpty()) {
return;
}
m_paintop = paintop;
m_paintopSettings = paintopSettings;
emit paintopChanged(m_paintop, paintopSettings);
notifyObservers();
}
void KisView::setBGColor(const KisColor& c)
{
m_bg = c;
notifyObservers();
emit sigBGQColorChanged( c.toTQColor() );
}
void KisView::setFGColor(const KisColor& c)
{
m_fg = c;
notifyObservers();
emit sigFGQColorChanged( c.toTQColor() );
}
void KisView::slotSetFGColor(const KisColor& c)
{
m_fg = c;
notifyObservers();
}
void KisView::slotSetBGColor(const KisColor& c)
{
m_bg = c;
notifyObservers();
}
void KisView::slotSetFGQColor(const TQColor& c)
{
KisColorSpace * monitorSpace = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA"), m_monitorProfile);
setFGColor(KisColor(c, monitorSpace));
emit sigFGQColorChanged(c);
}
void KisView::slotSetBGQColor(const TQColor& c)
{
KisColorSpace * monitorSpace = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA"), m_monitorProfile);
setBGColor(KisColor(c, monitorSpace));
emit sigBGQColorChanged(c);
}
void KisView::setupPrinter(KPrinter& printer)
{
KisImageSP img = currentImg();
if (img) {
printer.setPageSelection(KPrinter::ApplicationSide);
printer.setPageSize(KPrinter::A4);
printer.setOrientation(KPrinter::Portrait);
}
}
void KisView::print(KPrinter& printer)
{
TQPainter gc(&printer);
KisImageSP img = currentImg();
if (!img) return;
printer.setFullPage(true);
gc.setClipping(false);
KisConfig cfg;
TQString printerProfileName = cfg.printerProfile();
KisProfile * printerProfile = KisMetaRegistry::instance()->csRegistry() ->getProfileByName(printerProfileName);
TQRect r = img->bounds();
img->renderToPainter(r.x(), r.y(), r.width(), r.height(), gc, printerProfile, KisImage::PAINT_IMAGE_ONLY, HDRExposure());
}
void KisView::paintToolOverlay(const TQRegion& region)
{
if (!region.isEmpty() && m_toolManager->currentTool() && !m_toolIsPainting) {
KisCanvasPainter gc(m_canvas);
gc.setClipRegion(region);
gc.setClipping(true);
// Prevent endless loop if the tool needs to have the canvas repainted
m_toolIsPainting = true;
m_toolManager->currentTool()->paint(gc, region.boundingRect());
m_toolIsPainting = false;
}
}
void KisView::canvasGotPaintEvent(TQPaintEvent *event)
{
if (m_canvas->isOpenGLCanvas()) {
paintOpenGLView(event->rect());
} else {
paintTQPaintDeviceView(event->region());
}
}
void KisView::canvasGotButtonPressEvent(KisButtonPressEvent *e)
{
#if defined(EXTENDED_X11_TABLET_SUPPORT)
// The event filter doesn't see tablet events going to the canvas.
if (e->device() != KisInputDevice::mouse()) {
m_tabletEventTimer.start();
}
#endif // EXTENDED_X11_TABLET_SUPPORT
if (e->device() != currentInputDevice()) {
if (e->device() == KisInputDevice::mouse()) {
if (m_tabletEventTimer.elapsed() > MOUSE_CHANGE_EVENT_DELAY) {
setInputDevice(KisInputDevice::mouse());
}
} else {
setInputDevice(e->device());
}
}
KisImageSP img = currentImg();
// if (img) {
// TQPoint pt = mapToScreen(e->pos().floorTQPoint());
// KisGuideMgr *mgr = img->guides();
//
// m_lastGuidePoint = mapToScreen(e->pos().floorTQPoint());
// m_currentGuide = 0;
//
// if ((e->state() & ~TQt::ShiftButton) == TQt::NoButton) {
// KisGuideSP gd = mgr->find(static_cast<TQ_INT32>(pt.x() / zoom()), static_cast<TQ_INT32>(pt.y() / zoom()), TQMAX(2.0, 2.0 / zoom()));
//
// if (gd) {
// m_currentGuide = gd;
//
// if ((e->button() == TQt::RightButton) || ((e->button() & TQt::ShiftButton) == TQt::ShiftButton)) {
// if (gd->isSelected())
// mgr->unselect(gd);
// else
// mgr->select(gd);
// } else {
// if (!gd->isSelected()) {
// mgr->unselectAll();
// mgr->select(gd);
// }
// }
//
// updateGuides();
// return;
// }
// }
// }
if (e->button() == TQt::RightButton) {
TQPopupMenu * m_popup = 0;
if (factory()) {
Q_ASSERT(factory());
m_popup = (TQPopupMenu *)factory()->container("image_popup", this);
}
if (m_popup) {
m_popup->popup(e->globalPos().roundTQPoint());
}
}
else if (e->device() == currentInputDevice() && m_toolManager->currentTool()) {
KisPoint p = viewToWindow(e->pos());
// somewhat of a hack: we should actually test if we intersect with the scrollers,
// but the globalPos seems to be off by a few pixels
if (m_vScroll->draggingSlider() || m_hScroll->draggingSlider())
return;
if (m_toolManager->currentTool()->wantsAutoScroll()) {
enableAutoScroll();
}
KisButtonPressEvent ev(e->device(), p, e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), e->button(), e->state());
m_toolManager->currentTool()->buttonPress(&ev);
}
}
void KisView::canvasGotMoveEvent(KisMoveEvent *e)
{
#if defined(EXTENDED_X11_TABLET_SUPPORT)
// The event filter doesn't see tablet events going to the canvas.
if (e->device() != KisInputDevice::mouse()) {
m_tabletEventTimer.start();
}
#endif // EXTENDED_X11_TABLET_SUPPORT
if (e->device() != currentInputDevice()) {
if (e->device() == KisInputDevice::mouse()) {
if (m_tabletEventTimer.elapsed() > MOUSE_CHANGE_EVENT_DELAY) {
setInputDevice(KisInputDevice::mouse());
}
} else {
setInputDevice(e->device());
}
}
KisImageSP img = currentImg();
m_hRuler->updatePointer(e->pos().floorX() - m_canvasXOffset, e->pos().floorY() - m_canvasYOffset);
m_vRuler->updatePointer(e->pos().floorX() - m_canvasXOffset, e->pos().floorY() - m_canvasYOffset);
KisPoint wp = viewToWindow(e->pos());
#if 0
if (img && m_currentGuide) {
TQPoint p = mapToScreen(e->pos().floorTQPoint());
KisGuideMgr *mgr = img->guides();
if (((e->state() & TQt::LeftButton) == TQt::LeftButton) && mgr->hasSelected()) {
eraseGuides();
p -= m_lastGuidePoint;
if (p.x())
mgr->moveSelectedByX(p.x() / zoom());
if (p.y())
mgr->moveSelectedByY(p.y() / zoom());
m_doc->setModified(true);
paintGuides();
}
} else
#endif
if (e->device() == currentInputDevice() && m_toolManager->currentTool()) {
KisMoveEvent ev(e->device(), wp, e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), e->state());
m_toolManager->currentTool()->move(&ev);
}
// m_lastGuidePoint = mapToScreen(e->pos().floorTQPoint());
emit cursorPosition(wp.floorX(), wp.floorY());
}
int KisView::leftBorder() const
{
return m_rulerThickness;
}
int KisView::rightBorder() const
{
return m_hScrollBarExtent;
}
int KisView::topBorder() const
{
return m_rulerThickness;
}
int KisView::bottomBorder() const
{
return m_vScrollBarExtent;
}
void KisView::mouseMoveEvent(TQMouseEvent *e)
{
KisMoveEvent ke(currentInputDevice(), KisPoint(e->pos()), KisPoint(e->globalPos()), PRESSURE_DEFAULT, 0, 0, e->state());
canvasGotMoveEvent(&ke);
}
void KisView::slotAutoScroll(const TQPoint &p)
{
scrollTo(horzValue()+p.x(), vertValue()+p.y());
}
void KisView::canvasGotButtonReleaseEvent(KisButtonReleaseEvent *e)
{
#if defined(EXTENDED_X11_TABLET_SUPPORT)
// The event filter doesn't see tablet events going to the canvas.
if (e->device() != KisInputDevice::mouse()) {
m_tabletEventTimer.start();
}
#endif // EXTENDED_X11_TABLET_SUPPORT
if (e->device() != currentInputDevice()) {
if (e->device() == KisInputDevice::mouse()) {
if (m_tabletEventTimer.elapsed() > MOUSE_CHANGE_EVENT_DELAY) {
setInputDevice(KisInputDevice::mouse());
}
} else {
setInputDevice(e->device());
}
}
KisImageSP img = currentImg();
// if (img && m_currentGuide) {
// m_currentGuide = 0;
// } else
if (e->device() == currentInputDevice() && m_toolManager->currentTool()) {
KisPoint p = viewToWindow(e->pos());
KisButtonReleaseEvent ev(e->device(), p, e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), e->button(), e->state());
disableAutoScroll();
if (m_toolManager->currentTool()) {
m_toolManager->currentTool()->buttonRelease(&ev);
}
}
}
void KisView::canvasGotDoubleClickEvent(KisDoubleClickEvent *e)
{
#if defined(EXTENDED_X11_TABLET_SUPPORT)
// The event filter doesn't see tablet events going to the canvas.
if (e->device() != KisInputDevice::mouse()) {
m_tabletEventTimer.start();
}
#endif // EXTENDED_X11_TABLET_SUPPORT
if (e->device() != currentInputDevice()) {
if (e->device() == KisInputDevice::mouse()) {
if (m_tabletEventTimer.elapsed() > MOUSE_CHANGE_EVENT_DELAY) {
setInputDevice(KisInputDevice::mouse());
}
} else {
setInputDevice(e->device());
}
}
if (e->device() == currentInputDevice() && m_toolManager->currentTool()) {
KisPoint p = viewToWindow(e->pos());
KisDoubleClickEvent ev(e->device(), p, e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), e->button(), e->state());
if (m_toolManager->currentTool()) {
m_toolManager->currentTool()->doubleClick(&ev);
}
}
}
void KisView::canvasGotEnterEvent(TQEvent *e)
{
Q_UNUSED( e );
}
void KisView::canvasGotLeaveEvent (TQEvent *e)
{
Q_UNUSED( e );
}
void KisView::canvasGotMouseWheelEvent(TQWheelEvent *event)
{
//if(event->state() == ControlButton )
//{
if(event->delta() / 120 != 0)
{
if(event->delta() > 0)
{
zoomIn();
} else {
zoomOut();
}
if (m_oldTool) {
KisCanvasPainter gc(m_canvas);
m_oldTool->paint(gc);
}
}
//} else {
// TQApplication::sendEvent(m_vScroll, event);
//}
}
void KisView::canvasGotKeyPressEvent(TQKeyEvent *event)
{
if (!m_toolManager->currentTool()) {
event->ignore();
return;
}
if (event->key() == TQt::Key_Space) {
if (!m_panning) {
// Set tool temporarily to pan
m_panning = true;
m_oldTool = m_toolManager->currentTool();
m_toolManager->setCurrentTool( "tool_pan" );
}
else {
// Unset panning
m_panning = false;
m_toolManager->setCurrentTool( m_oldTool );
m_oldTool = 0;
}
}
if (m_toolManager->currentTool())
m_toolManager->currentTool()->keyPress(event);
}
void KisView::canvasGotKeyReleaseEvent(TQKeyEvent *event)
{
if (m_toolManager->currentTool())
m_toolManager->currentTool()->keyRelease(event);
}
void KisView::canvasGotDragEnterEvent(TQDragEnterEvent *event)
{
bool accept = false;
// Only accept drag if we're not busy, particularly as we may
// be showing a progress bar and calling tqApp->processEvents().
if (KURLDrag::canDecode(event) && TQApplication::overrideCursor() == 0) {
accept = true;
}
event->accept(accept);
}
void KisView::canvasGotDropEvent(TQDropEvent *event)
{
KURL::List urls;
if (KURLDrag::decode(event, urls))
{
if (urls.count() > 0) {
enum enumActionId {
addLayerId = 1,
addDocumentId = 2,
cancelId
};
TDEPopupMenu popup(this, "drop_popup");
if (urls.count() == 1) {
if (currentImg() != 0) {
popup.insertItem(i18n("Insert as New Layer"), addLayerId);
}
popup.insertItem(i18n("Open in New Document"), addDocumentId);
}
else {
if (currentImg() != 0) {
popup.insertItem(i18n("Insert as New Layers"), addLayerId);
}
popup.insertItem(i18n("Open in New Documents"), addDocumentId);
}
popup.insertSeparator();
popup.insertItem(i18n("Cancel"), cancelId);
int actionId = popup.exec(TQCursor::pos());
if (actionId >= 0 && actionId != cancelId) {
for (KURL::List::ConstIterator it = urls.begin (); it != urls.end (); ++it) {
KURL url = *it;
switch (actionId) {
case addLayerId:
importImage(url);
break;
case addDocumentId:
if (shell() != 0) {
shell()->openDocument(url);
}
break;
}
}
}
}
}
}
void KisView::layerProperties()
{
if (currentImg() && currentImg()->activeLayer())
showLayerProperties(currentImg()->activeLayer());
}
namespace {
class KisChangeFilterCmd : public KNamedCommand {
typedef KNamedCommand super;
public:
// The TQStrings are the _serialized_ configs
KisChangeFilterCmd(KisAdjustmentLayerSP layer,
KisFilterConfiguration* config,
const TQString& before,
const TQString& after) : super(i18n("Change Filter"))
{
m_layer = layer;
m_config = config;
m_before = before;
m_after = after;
}
public:
virtual void execute()
{
TQApplication::setOverrideCursor(KisCursor::waitCursor());
m_config->fromXML(m_after);
//Q_ASSERT(m_after == m_config->toString());
m_layer->setFilter(m_config);
m_layer->setDirty();
TQApplication::restoreOverrideCursor();
}
virtual void unexecute()
{
TQApplication::setOverrideCursor(KisCursor::waitCursor());
m_config->fromXML(m_before);
//Q_ASSERT(m_before == m_config->toString());
m_layer->setFilter(m_config);
m_layer->setDirty();
TQApplication::restoreOverrideCursor();
}
private:
KisAdjustmentLayerSP m_layer;
KisFilterConfiguration* m_config;
TQString m_before;
TQString m_after;
};
}
void KisView::showLayerProperties(KisLayerSP layer)
{
Q_ASSERT( layer );
if ( !layer ) return;
KisColorSpace * cs = 0;
KisPaintLayer * pl = dynamic_cast<KisPaintLayer*>( layer.data() );
if ( pl ) {
cs = pl->paintDevice()->colorSpace();
}
else {
cs = layer->image()->colorSpace();
}
if (KisAdjustmentLayerSP alayer = dynamic_cast<KisAdjustmentLayer*>(layer.data()))
{
KisDlgAdjLayerProps dlg(alayer, alayer->name(), i18n("Adjustment Layer Properties"), this, "dlgadjlayerprops");
TQString before = dlg.filterConfiguration()->toString();
if (dlg.exec() == TQDialog::Accepted)
{
KisChangeFilterCmd * cmd = new KisChangeFilterCmd(alayer,
dlg.filterConfiguration(),
before,
dlg.filterConfiguration()->toString());
cmd->execute();
m_adapter->addCommand(cmd);
m_doc->setModified( true );
}
}
else
{
KisDlgLayerProperties dlg(layer->name(),
layer->opacity(),
layer->compositeOp(),
cs);
if (dlg.exec() == TQDialog::Accepted)
{
if (layer->name() != dlg.getName() ||
layer->opacity() != dlg.getOpacity() ||
layer->compositeOp() != dlg.getCompositeOp())
{
TQApplication::setOverrideCursor(KisCursor::waitCursor());
m_adapter->beginMacro(i18n("Property Changes"));
layer->image()->setLayerProperties(layer, dlg.getOpacity(), dlg.getCompositeOp(), dlg.getName());
layer->setDirty();
m_adapter->endMacro();
TQApplication::restoreOverrideCursor();
m_doc->setModified( true );
}
}
}
}
void KisView::layerAdd()
{
KisImageSP img = currentImg();
if (img && img->activeLayer()) {
addLayer(img->activeLayer()->parent(), img->activeLayer());
}
else if (img)
addLayer(static_cast<KisGroupLayer*>(img->rootLayer().data()), 0);
}
void KisView::addLayer(KisGroupLayerSP parent, KisLayerSP above)
{
KisImageSP img = currentImg();
if (img) {
KisConfig cfg;
TQString profilename;
if(img->colorSpace()->getProfile())
profilename = img->colorSpace()->getProfile()->productName();
NewLayerDialog dlg(img->colorSpace()->id(), profilename, img->nextLayerName(), this);
if (dlg.exec() == TQDialog::Accepted) {
KisColorSpace* cs = KisMetaRegistry::instance()-> csRegistry() ->
getColorSpace(dlg.colorSpaceID(),dlg.profileName());
KisLayerSP layer = new KisPaintLayer(img, dlg.layerName(), dlg.opacity(), cs);
if (layer) {
layer->setCompositeOp(dlg.compositeOp());
img->addLayer(layer, parent.data(), above);
updateCanvas();
} else {
KMessageBox::error(this, i18n("Could not add layer to image."), i18n("Layer Error"));
}
}
else {
img->rollBackLayerName();
}
}
}
void KisView::addGroupLayer(KisGroupLayerSP parent, KisLayerSP above)
{
KisImageSP img = currentImg();
if (img) {
TQString profilename;
if(img->colorSpace()->getProfile())
profilename = img->colorSpace()->getProfile()->productName();
KisConfig cfg;
NewLayerDialog dlg(img->colorSpace()->id(), profilename, img->nextLayerName(), this);
dlg.setColorSpaceEnabled(false);
if (dlg.exec() == TQDialog::Accepted) {
KisLayerSP layer = new KisGroupLayer(img, dlg.layerName(), dlg.opacity());
if (layer) {
layer->setCompositeOp(dlg.compositeOp());
img->addLayer(layer, parent.data(), above);
updateCanvas();
} else {
KMessageBox::error(this, i18n("Could not add layer to image."), i18n("Layer Error"));
}
}
}
}
void KisView::addPartLayer()
{
KisImageSP img = currentImg();
if (!img) return;
addPartLayer(img->rootLayer(), img->rootLayer()->firstChild(), m_actionPartLayer->documentEntry());
}
void KisView::addPartLayer(KisGroupLayerSP parent, KisLayerSP above, const KoDocumentEntry& entry)
{
delete m_partHandler; // Only one at a time
m_partHandler = new KisPartLayerHandler(this, entry, parent, above);
disconnect(m_canvas, TQ_SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent*)), this, 0);
disconnect(m_canvas, TQ_SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent*)), this, 0);
disconnect(m_canvas, TQ_SIGNAL(sigGotMoveEvent(KisMoveEvent*)), this, 0);
disconnect(m_canvas, TQ_SIGNAL(sigGotKeyPressEvent(TQKeyEvent*)), this, 0);
connect(m_canvas, TQ_SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent*)),
m_partHandler, TQ_SLOT(gotButtonPressEvent(KisButtonPressEvent*)));
connect(m_canvas, TQ_SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent*)),
m_partHandler, TQ_SLOT(gotButtonReleaseEvent(KisButtonReleaseEvent*)));
connect(m_canvas, TQ_SIGNAL(sigGotMoveEvent(KisMoveEvent*)),
m_partHandler, TQ_SLOT(gotMoveEvent(KisMoveEvent*)));
connect(m_canvas, TQ_SIGNAL(sigGotKeyPressEvent(TQKeyEvent*)),
m_partHandler, TQ_SLOT(gotKeyPressEvent(TQKeyEvent*)));
connect(m_partHandler, TQ_SIGNAL(sigGotMoveEvent(KisMoveEvent*)),
this, TQ_SLOT(canvasGotMoveEvent(KisMoveEvent*)));
connect(m_partHandler, TQ_SIGNAL(sigGotKeyPressEvent(TQKeyEvent*)),
this, TQ_SLOT(canvasGotKeyPressEvent(TQKeyEvent*)));
connect(m_partHandler, TQ_SIGNAL(handlerDone()),
this, TQ_SLOT(reconnectAfterPartInsert()));
}
void KisView::insertPart(const TQRect& viewRect, const KoDocumentEntry& entry,
KisGroupLayerSP parent, KisLayerSP above) {
KisImageSP img = currentImg();
if (!img) return;
KoDocument* doc = entry.createDoc(m_doc);
if ( !doc )
return;
if ( !doc->showEmbedInitDialog(this) )
return;
TQRect rect = viewToWindow(viewRect);
KisChildDoc * childDoc = m_doc->createChildDoc(rect, doc);
KisPartLayerImpl* partLayer = new KisPartLayerImpl(img, childDoc);
partLayer->setDocType(entry.service()->genericName());
img->addLayer(partLayer, parent, above);
m_doc->setModified(true);
reconnectAfterPartInsert();
}
void KisView::reconnectAfterPartInsert() {
connect(m_canvas, TQ_SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent*)),
this, TQ_SLOT(canvasGotButtonPressEvent(KisButtonPressEvent*)));
connect(m_canvas, TQ_SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent*)),
this, TQ_SLOT(canvasGotButtonReleaseEvent(KisButtonReleaseEvent*)));
connect(m_canvas, TQ_SIGNAL(sigGotMoveEvent(KisMoveEvent*)),
this, TQ_SLOT(canvasGotMoveEvent(KisMoveEvent*)));
connect(m_canvas, TQ_SIGNAL(sigGotKeyPressEvent(TQKeyEvent*)),
this, TQ_SLOT(canvasGotKeyPressEvent(TQKeyEvent*)));
delete m_partHandler;
m_partHandler = 0;
}
void KisView::addAdjustmentLayer()
{
KisImageSP img = currentImg();
if (!img) return;
addAdjustmentLayer( img->activeLayer()->parent(), img->activeLayer() );
}
void KisView::addAdjustmentLayer(KisGroupLayerSP parent, KisLayerSP above)
{
Q_ASSERT(parent);
Q_ASSERT(above);
KisImageSP img = currentImg();
if (!img) return;
KisLayerSP l = img->activeLayer();
KisPaintDeviceSP dev;
// Argh! I hate having to cast, cast and cast again to see what kind of a layer I've got!
KisPaintLayer * pl = dynamic_cast<KisPaintLayer*>(l.data());
if (pl) {
dev = pl->paintDevice();
}
else {
KisGroupLayer * gl = dynamic_cast<KisGroupLayer*>(l.data());
if (gl) {
dev = gl->projection(img->bounds());
}
else {
KisAdjustmentLayer * al = dynamic_cast<KisAdjustmentLayer*>(l.data());
if (al) {
dev = al->cachedPaintDevice();
}
else {
return;
}
}
}
KisDlgAdjustmentLayer dlg(img, img->nextLayerName(), i18n("New Adjustment Layer"), this, "dlgadjustmentlayer");
if (dlg.exec() == TQDialog::Accepted) {
KisSelectionSP selection = 0;
if (dev->hasSelection()) {
selection = dev->selection();
}
KisFilterConfiguration * filter = dlg.filterConfiguration();
TQString name = dlg.layerName();
addAdjustmentLayer( parent, above, name, filter, selection);
}
}
void KisView::addAdjustmentLayer(KisGroupLayerSP parent, KisLayerSP above, const TQString & name,
KisFilterConfiguration * filter, KisSelectionSP selection)
{
Q_ASSERT(parent);
Q_ASSERT(above);
Q_ASSERT(filter);
KisImageSP img = currentImg();
if (!img) return;
KisAdjustmentLayer * l = new KisAdjustmentLayer(img, name, filter, selection);
img->addLayer(l, parent, above);
}
void KisView::slotChildActivated(bool a) {
// It should be so that the only part (child) we can activate, is the current layer:
if (currentImg() && currentImg()->activeLayer())
{
if (a) {
currentImg()->activeLayer()->activate();
} else {
currentImg()->activeLayer()->deactivate();
}
}
super::slotChildActivated(a);
}
void KisView::layerRemove()
{
KisImageSP img = currentImg();
if (img) {
KisLayerSP layer = img->activeLayer();
if (layer) {
img->removeLayer(layer);
if (layer->parent())
layer->parent()->setDirty(layer->extent());
updateCanvas();
layerUpdateGUI(img->activeLayer() != 0);
}
}
}
void KisView::layerDuplicate()
{
KisImageSP img = currentImg();
if (!img)
return;
KisLayerSP active = img->activeLayer();
if (!active)
return;
KisLayerSP dup = active->clone();
dup->setName(i18n("Duplicate of '%1'").arg(active->name()));
img->addLayer(dup, active->parent().data(), active);
if (dup) {
img->activate( dup );
updateCanvas();
} else {
KMessageBox::error(this, i18n("Could not add layer to image."), i18n("Layer Error"));
}
}
void KisView::layerRaise()
{
KisImageSP img = currentImg();
KisLayerSP layer;
if (!img)
return;
layer = img->activeLayer();
img->raiseLayer(layer);
}
void KisView::layerLower()
{
KisImageSP img = currentImg();
KisLayerSP layer;
if (!img)
return;
layer = img->activeLayer();
img->lowerLayer(layer);
}
void KisView::layerFront()
{
KisImageSP img = currentImg();
KisLayerSP layer;
if (!img)
return;
layer = img->activeLayer();
img->toTop(layer);
}
void KisView::layerBack()
{
KisImageSP img = currentImg();
if (!img) return;
KisLayerSP layer;
layer = img->activeLayer();
img->toBottom(layer);
}
void KisView::layersUpdated()
{
KisImageSP img = currentImg();
if (!img) return;
KisLayerSP layer = img->activeLayer();
layerUpdateGUI(img && layer);
notifyObservers();
}
void KisView::layerToggleVisible()
{
KisImageSP img = currentImg();
if (!img) return;
KisLayerSP layer = img->activeLayer();
if (!layer) return;
layer->setVisible(!layer->visible());
}
void KisView::layerToggleLocked()
{
KisImageSP img = currentImg();
if (!img) return;
KisLayerSP layer = img->activeLayer();
if (!layer) return;
layer->setLocked(!layer->locked());
}
void KisView::actLayerVisChanged(int show)
{
m_actLayerVis = (show != 0);
}
bool KisView::activeLayerHasSelection()
{
return m_image && m_image->activeDevice() && m_image->activeDevice()->hasSelection();
}
void KisView::scrollH(int value)
{
m_hRuler->updateVisibleArea(value, 0);
int xShift = m_scrollX - value;
m_scrollX = value;
if (m_canvas->isUpdatesEnabled()) {
if (xShift > 0) {
if (m_canvas->isOpenGLCanvas()) {
paintOpenGLView(TQRect(0, 0, m_canvas->width(), m_canvas->height()));
} else {
TQRect drawRect(0, 0, xShift, m_canvasPixmap.height());
bitBlt(&m_canvasPixmap, xShift, 0, &m_canvasPixmap, 0, 0, m_canvasPixmap.width() - xShift, m_canvasPixmap.height());
updateTQPaintDeviceCanvas(viewToWindow(drawRect));
m_canvas->repaint();
}
} else if (xShift < 0) {
TQRect drawRect(m_canvasPixmap.width() + xShift, 0, -xShift, m_canvasPixmap.height());
if (m_canvas->isOpenGLCanvas()) {
paintOpenGLView(TQRect(0, 0, m_canvas->width(), m_canvas->height()));
} else {
bitBlt(&m_canvasPixmap, 0, 0, &m_canvasPixmap, -xShift, 0, m_canvasPixmap.width() + xShift, m_canvasPixmap.height());
updateTQPaintDeviceCanvas(viewToWindow(drawRect));
m_canvas->repaint();
}
}
if (m_oldTool) {
KisCanvasPainter gc(m_canvas);
m_oldTool->paint(gc);
}
}
if (xShift != 0) {
// XXX do sth with the childframe or so
}
emit viewTransformationsChanged();
}
void KisView::scrollV(int value)
{
m_vRuler->updateVisibleArea(0, value);
int yShift = m_scrollY - value;
m_scrollY = value;
if (m_canvas->isUpdatesEnabled()) {
if (yShift > 0) {
if (m_canvas->isOpenGLCanvas()) {
paintOpenGLView(TQRect(0, 0, m_canvas->width(), m_canvas->height()));
} else {
TQRect drawRect(0, 0, m_canvasPixmap.width(), yShift);
bitBlt(&m_canvasPixmap, 0, yShift, &m_canvasPixmap, 0, 0, m_canvasPixmap.width(), m_canvasPixmap.height() - yShift);
updateTQPaintDeviceCanvas(viewToWindow(drawRect));
m_canvas->repaint();
}
} else if (yShift < 0) {
if (m_canvas->isOpenGLCanvas()) {
paintOpenGLView(TQRect(0, 0, m_canvas->width(), m_canvas->height()));
} else {
TQRect drawRect(0, m_canvasPixmap.height() + yShift, m_canvasPixmap.width(), -yShift);
bitBlt(&m_canvasPixmap, 0, 0, &m_canvasPixmap, 0, -yShift, m_canvasPixmap.width(), m_canvasPixmap.height() + yShift);
updateTQPaintDeviceCanvas(viewToWindow(drawRect));
m_canvas->repaint();
}
}
if (m_oldTool) {
KisCanvasPainter gc(m_canvas);
m_oldTool->paint(gc);
}
}
if (yShift != 0) {
// XXX do sth with the childframe or so
}
emit viewTransformationsChanged();
}
void KisView::setupCanvas()
{
m_canvas = new KisCanvas(this, "kis_canvas");
m_canvas->setFocusPolicy( TQWidget::StrongFocus );
TQObject::connect(m_canvas, TQ_SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent*)), this, TQ_SLOT(canvasGotButtonPressEvent(KisButtonPressEvent*)));
TQObject::connect(m_canvas, TQ_SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent*)), this, TQ_SLOT(canvasGotButtonReleaseEvent(KisButtonReleaseEvent*)));
TQObject::connect(m_canvas, TQ_SIGNAL(sigGotDoubleClickEvent(KisDoubleClickEvent*)), this, TQ_SLOT(canvasGotDoubleClickEvent(KisDoubleClickEvent*)));
TQObject::connect(m_canvas, TQ_SIGNAL(sigGotMoveEvent(KisMoveEvent*)), this, TQ_SLOT(canvasGotMoveEvent(KisMoveEvent*)));
TQObject::connect(m_canvas, TQ_SIGNAL(sigGotPaintEvent(TQPaintEvent*)), this, TQ_SLOT(canvasGotPaintEvent(TQPaintEvent*)));
TQObject::connect(m_canvas, TQ_SIGNAL(sigGotEnterEvent(TQEvent*)), this, TQ_SLOT(canvasGotEnterEvent(TQEvent*)));
TQObject::connect(m_canvas, TQ_SIGNAL(sigGotLeaveEvent(TQEvent*)), this, TQ_SLOT(canvasGotLeaveEvent(TQEvent*)));
TQObject::connect(m_canvas, TQ_SIGNAL(sigGotMouseWheelEvent(TQWheelEvent*)), this, TQ_SLOT(canvasGotMouseWheelEvent(TQWheelEvent*)));
TQObject::connect(m_canvas, TQ_SIGNAL(sigGotKeyPressEvent(TQKeyEvent*)), this, TQ_SLOT(canvasGotKeyPressEvent(TQKeyEvent*)));
TQObject::connect(m_canvas, TQ_SIGNAL(sigGotKeyReleaseEvent(TQKeyEvent*)), this, TQ_SLOT(canvasGotKeyReleaseEvent(TQKeyEvent*)));
TQObject::connect(m_canvas, TQ_SIGNAL(sigGotDragEnterEvent(TQDragEnterEvent*)), this, TQ_SLOT(canvasGotDragEnterEvent(TQDragEnterEvent*)));
TQObject::connect(m_canvas, TQ_SIGNAL(sigGotDropEvent(TQDropEvent*)), this, TQ_SLOT(canvasGotDropEvent(TQDropEvent*)));
}
void KisView::connectCurrentImg()
{
if (m_image) {
connect(m_image, TQ_SIGNAL(sigActiveSelectionChanged(KisImageSP)), m_selectionManager, TQ_SLOT(imgSelectionChanged(KisImageSP)));
connect(m_image, TQ_SIGNAL(sigActiveSelectionChanged(KisImageSP)), this, TQ_SLOT(updateCanvas()));
connect(m_image, TQ_SIGNAL(sigColorSpaceChanged(KisColorSpace *)), this, TQ_SLOT(updateStatusBarProfileLabel()));
connect(m_image, TQ_SIGNAL(sigProfileChanged(KisProfile * )), TQ_SLOT(profileChanged(KisProfile * )));
connect(m_image, TQ_SIGNAL(sigLayersChanged(KisGroupLayerSP)), TQ_SLOT(layersUpdated()));
connect(m_image, TQ_SIGNAL(sigMaskInfoChanged()), TQ_SLOT(maskUpdated()));
connect(m_image, TQ_SIGNAL(sigLayerAdded(KisLayerSP)), TQ_SLOT(layersUpdated()));
connect(m_image, TQ_SIGNAL(sigLayerRemoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)), TQ_SLOT(layersUpdated()));
connect(m_image, TQ_SIGNAL(sigLayerMoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)), TQ_SLOT(layersUpdated()));
connect(m_image, TQ_SIGNAL(sigLayerActivated(KisLayerSP)), TQ_SLOT(layersUpdated()));
connect(m_image, TQ_SIGNAL(sigLayerActivated(KisLayerSP)), TQ_SLOT(updateCanvas()));
connect(m_image, TQ_SIGNAL(sigLayerPropertiesChanged(KisLayerSP)), TQ_SLOT(layersUpdated()));
KisConnectPartLayerVisitor v(m_image, this, true);
m_image->rootLayer()->accept(v);
connect(m_image, TQ_SIGNAL(sigLayerAdded(KisLayerSP)),
TQ_SLOT(handlePartLayerAdded(KisLayerSP)));
maskUpdated();
#ifdef HAVE_GL
if (m_OpenGLImageContext != 0) {
connect(m_OpenGLImageContext, TQ_SIGNAL(sigImageUpdated(TQRect)), TQ_SLOT(slotOpenGLImageUpdated(TQRect)));
connect(m_OpenGLImageContext, TQ_SIGNAL(sigSizeChanged(TQ_INT32, TQ_INT32)), TQ_SLOT(slotImageSizeChanged(TQ_INT32, TQ_INT32)));
} else
#endif
{
connect(m_image, TQ_SIGNAL(sigImageUpdated(TQRect)), TQ_SLOT(imgUpdated(TQRect)));
connect(m_image, TQ_SIGNAL(sigSizeChanged(TQ_INT32, TQ_INT32)), TQ_SLOT(slotImageSizeChanged(TQ_INT32, TQ_INT32)));
}
}
m_layerBox->setImage(m_image);
m_birdEyeBox->setImage(m_image);
}
void KisView::disconnectCurrentImg()
{
if (m_image) {
m_image->disconnect(this);
m_layerBox->setImage(0);
m_birdEyeBox->setImage(0);
KisConnectPartLayerVisitor v(m_image, this, false);
m_image->rootLayer()->accept(v);
}
#ifdef HAVE_GL
if (m_OpenGLImageContext != 0) {
m_OpenGLImageContext->disconnect(this);
}
#endif
}
void KisView::handlePartLayerAdded(KisLayerSP layer)
{
KisPartLayer* l = dynamic_cast<KisPartLayer*>(layer.data());
if (!l)
return;
connect(this, TQ_SIGNAL(childActivated(KoDocumentChild*)),
layer, TQ_SLOT(childActivated(KoDocumentChild*)));
}
void KisView::imgUpdated(TQRect rc)
{
updateCanvas(rc);
}
void KisView::slotOpenGLImageUpdated(TQRect rc)
{
paintOpenGLView(windowToView(rc));
}
void KisView::profileChanged(KisProfile * /*profile*/)
{
updateStatusBarProfileLabel();
}
void KisView::slotImageSizeChanged(TQ_INT32 /*w*/, TQ_INT32 /*h*/)
{
resizeEvent(0);
refreshKisCanvas();
}
void KisView::resizeCurrentImage(TQ_INT32 w, TQ_INT32 h, bool cropLayers)
{
if (!currentImg()) return;
currentImg()->resize(w, h, cropLayers);
m_doc->setModified(true);
layersUpdated();
}
void KisView::scaleCurrentImage(double sx, double sy, KisFilterStrategy *filterStrategy)
{
if (!currentImg()) return;
currentImg()->scale(sx, sy, m_progress, filterStrategy);
m_doc->setModified(true);
layersUpdated();
}
void KisView::rotateCurrentImage(double radians)
{
if (!currentImg()) return;
currentImg()->rotate(radians, m_progress);
m_doc->setModified(true);
layersUpdated();
}
void KisView::shearCurrentImage(double angleX, double angleY)
{
if (!currentImg()) return;
currentImg()->shear(angleX, angleY, m_progress);
m_doc->setModified(true);
layersUpdated();
}
TQPoint KisView::viewToWindow(const TQPoint& pt)
{
TQPoint converted;
converted.rx() = static_cast<int>((pt.x() + horzValue()) / zoom());
converted.ry() = static_cast<int>((pt.y() + vertValue()) / zoom());
return converted;
}
TQPoint KisView::viewToWindow(const TQPoint& pt) const
{
TQPoint converted;
converted.rx() = static_cast<int>((pt.x() + horzValue()) / zoom());
converted.ry() = static_cast<int>((pt.y() + vertValue()) / zoom());
return converted;
}
KisPoint KisView::viewToWindow(const KisPoint& pt)
{
KisPoint converted;
converted.setX((pt.x() + horzValue()) / zoom());
converted.setY((pt.y() + vertValue()) / zoom());
return converted;
}
TQRect KisView::viewToWindow(const TQRect& rc)
{
TQRect r;
r.setTopLeft(viewToWindow(rc.topLeft()));
r.setRight((int)(ceil((rc.right() + 1.0 + horzValue()) / zoom()) - 1));
r.setBottom((int)(ceil((rc.bottom() + 1.0 + vertValue()) / zoom()) - 1));
return r;
}
KisRect KisView::viewToWindow(const KisRect& rc)
{
KisRect r;
KisPoint p = viewToWindow(KisPoint(rc.x(), rc.y()));
r.setX(p.x());
r.setY(p.y());
r.setWidth(rc.width() / zoom());
r.setHeight(rc.height() / zoom());
return r;
}
void KisView::viewToWindow(TQ_INT32 *x, TQ_INT32 *y)
{
if (x && y) {
TQPoint p = viewToWindow(TQPoint(*x, *y));
*x = p.x();
*y = p.y();
}
}
TQPoint KisView::windowToView(const TQPoint& pt)
{
TQPoint p;
p.setX(static_cast<int>(pt.x() * zoom() - horzValue()));
p.setY(static_cast<int>(pt.y() * zoom() - vertValue()));
return p;
}
TQPoint KisView::windowToView(const TQPoint& pt) const
{
TQPoint p;
p.setX(static_cast<int>(pt.x() * zoom() - horzValue()));
p.setY(static_cast<int>(pt.y() * zoom() - vertValue()));
return p;
}
KisPoint KisView::windowToView(const KisPoint& pt)
{
KisPoint p;
p.setX(pt.x() * zoom() - horzValue());
p.setY(pt.y() * zoom() - vertValue());
return p;
}
TQRect KisView::windowToView(const TQRect& rc)
{
TQRect r;
r.setTopLeft(windowToView(rc.topLeft()));
r.setRight((int)(ceil((rc.right() + 1.0) * zoom()) - horzValue() - 1));
r.setBottom((int)(ceil((rc.bottom() + 1.0) * zoom()) - vertValue() - 1));
return r;
}
KisRect KisView::windowToView(const KisRect& rc)
{
KisRect r;
KisPoint p = windowToView(KisPoint(rc.x(), rc.y()));
r.setX(p.x());
r.setY(p.y());
r.setWidth(rc.width() * zoom());
r.setHeight(rc.height() * zoom());
return r;
}
void KisView::windowToView(TQ_INT32 *x, TQ_INT32 *y)
{
if (x && y) {
TQPoint p = windowToView(TQPoint(*x, *y));
*x = p.x();
*y = p.y();
}
}
void KisView::guiActivateEvent(KParts::GUIActivateEvent *event)
{
Q_ASSERT(event);
if (event->activated()) {
KStatusBar *sb = statusBar();
if (sb) {
sb->show();
}
if (!m_guiActivateEventReceived) {
m_guiActivateEventReceived = true;
startInitialZoomTimerIfReady();
}
}
super::guiActivateEvent(event);
}
bool KisView::eventFilter(TQObject *o, TQEvent *e)
{
Q_ASSERT(o);
Q_ASSERT(e);
switch (e->type()) {
case TQEvent::TabletMove:
case TQEvent::TabletPress:
case TQEvent::TabletRelease:
{
TQTabletEvent *te = static_cast<TQTabletEvent*>(e);
KisInputDevice device;
switch (te->device()) {
default:
case TQTabletEvent::Stylus:
case TQTabletEvent::NoDevice:
device = KisInputDevice::stylus();
break;
case TQTabletEvent::Puck:
device = KisInputDevice::puck();
break;
case TQTabletEvent::Eraser:
device = KisInputDevice::eraser();
break;
}
setInputDevice(device);
// We ignore device change due to mouse events for a short duration
// after a tablet event, since these are almost certainly mouse events
// sent to receivers that don't accept the tablet event.
m_tabletEventTimer.start();
break;
}
case TQEvent::MouseButtonPress:
case TQEvent::MouseMove:
case TQEvent::MouseButtonRelease:
{
#ifdef EXTENDED_X11_TABLET_SUPPORT
KisInputDevice device = KisCanvasWidget::findActiveInputDevice();
if (device != KisInputDevice::mouse()) {
setInputDevice(device);
m_tabletEventTimer.start();
} else
#endif
{
if (currentInputDevice() != KisInputDevice::mouse() && m_tabletEventTimer.elapsed() > MOUSE_CHANGE_EVENT_DELAY) {
setInputDevice(KisInputDevice::mouse());
}
}
break;
}
case TQEvent::KeyPress:
case TQEvent::KeyRelease:
{
if (m_canvas->cursorIsOverCanvas()) {
m_canvas->handleKeyEvent(e);
return true;
}
break;
}
#if 0
// This code is unnecessary now that there's an application event filter
// This eventFilter is called for all widgets already, no need to install event filters multiple times
// Even worse: with multiple views, they would all install event filters on each other's widgets,
// due to the qapp event filter triggering in all views!
case TQEvent::ChildInserted:
{
TQChildEvent *childEvent = static_cast<TQChildEvent *>(e);
TQObject *child = childEvent->child();
if ( child->isWidgetType() ) {
child->installEventFilter(this);
TQObjectList *objectList = child->queryList("TQWidget");
TQObjectListIt it(*objectList);
TQObject *obj;
while ((obj = it.current()) != 0) {
obj->installEventFilter(this);
++it;
}
delete objectList;
}
}
#endif
default:
// Ignore
break;
}
#if 0
if ((o == m_hRuler || o == m_vRuler) && (e->type() == TQEvent::MouseMove || e->type() == TQEvent::MouseButtonRelease)) {
TQMouseEvent *me = dynamic_cast<TQMouseEvent*>(e);
TQPoint pt = mapFromGlobal(me->globalPos());
KisImageSP img = currentImg();
KisGuideMgr *mgr;
if (!img)
return super::eventFilter(o, e);
mgr = img->guides();
if (e->type() == TQEvent::MouseMove && (me->state() & TQt::LeftButton)) {
bool flag = geometry().contains(pt);
KisGuideSP gd;
if (m_currentGuide == 0 && flag) {
// No guide is being edited and moving mouse over the canvas.
// Create a new guide.
enterEvent(0);
eraseGuides();
mgr->unselectAll();
if (o == m_vRuler)
gd = mgr->add((pt.x() - m_vRuler->width() + horzValue()) / zoom(), TQt::Vertical);
else
gd = mgr->add((pt.y() - m_hRuler->height() + vertValue()) / zoom(), TQt::Horizontal);
m_currentGuide = gd;
mgr->select(gd);
m_lastGuidePoint = mapToScreen(pt);
} else if (m_currentGuide) {
if (flag) {
// moved an existing guide.
KisMoveEvent kme(currentInputDevice(), pt, me->globalPos(), PRESSURE_DEFAULT, 0, 0, me->state());
canvasGotMoveEvent(&kme);
} else {
// moved a guide out of the frame, destroy it
leaveEvent(0);
eraseGuides();
mgr->remove(m_currentGuide);
paintGuides();
m_currentGuide = 0;
}
}
} else if (e->type() == TQEvent::MouseButtonRelease && m_currentGuide) {
eraseGuides();
mgr->unselect(m_currentGuide);
paintGuides();
m_currentGuide = 0;
enterEvent(0);
KisMoveEvent kme(currentInputDevice(), pt, me->globalPos(), PRESSURE_DEFAULT, 0, 0, TQt::NoButton);
canvasGotMoveEvent(&kme);
}
}
#endif
return super::eventFilter(o, e);
}
#if 0
void KisView::eraseGuides()
{
KisImageSP img = currentImg();
if (img) {
KisGuideMgr *mgr = img->guides();
if (mgr)
mgr->erase(&m_canvasPixmap, this, horzValue(), vertValue(), zoom());
}
}
void KisView::paintGuides()
{
KisImageSP img = currentImg();
if (img) {
KisGuideMgr *mgr = img->guides();
if (mgr)
mgr->paint(&m_canvasPixmap, this, horzValue(), vertValue(), zoom());
}
}
void KisView::updateGuides()
{
eraseGuides();
paintGuides();
}
#endif
//void KisView::viewGuideLines()
//{
//}
TQPoint KisView::mapToScreen(const TQPoint& pt)
{
TQPoint converted;
converted.rx() = pt.x() + horzValue();
converted.ry() = pt.y() + vertValue();
return converted;
}
void KisView::attach(KisCanvasObserver *observer)
{
Q_ASSERT(observer);
if (observer)
m_observers.push_back(observer);
}
void KisView::detach(KisCanvasObserver *observer)
{
Q_ASSERT(observer);
if (observer) {
vKisCanvasObserver_it it = std::find(m_observers.begin(), m_observers.end(), observer);
if (it != m_observers.end())
m_observers.erase(it);
}
}
void KisView::notifyObservers()
{
for (vKisCanvasObserver_it it = m_observers.begin(); it != m_observers.end(); ++it) {
(*it)->update(this);
}
}
KisImageSP KisView::currentImg() const
{
return m_image;
}
void KisView::setCurrentImage(KisImageSP image)
{
if(!image) return;
disconnectCurrentImg();
m_image = image;
KisConfig cfg;
#ifdef HAVE_GL
if (cfg.useOpenGL()) {
m_OpenGLImageContext = KisOpenGLImageContext::getImageContext(image, monitorProfile());
m_canvas->createOpenGLCanvas(m_OpenGLImageContext->sharedContextWidget());
}
#endif
connectCurrentImg();
m_layerBox->setImage(currentImg());
zoomAroundPoint(0, 0, 1.0);
if (!currentImg())
layersUpdated();
imgUpdateGUI();
image->blockSignals(false);
}
KisColor KisView::bgColor() const
{
return m_bg;
}
KisColor KisView::fgColor() const
{
return m_fg;
}
KisBrush *KisView::currentBrush() const
{
return m_brush;
}
KisPattern *KisView::currentPattern() const
{
return m_pattern;
}
KisGradient *KisView::currentGradient() const
{
return m_gradient;
}
KisID KisView::currentPaintop() const
{
return m_paintop;
}
const KisPaintOpSettings *KisView::currentPaintopSettings() const
{
return m_paintopSettings;
}
double KisView::zoomFactor() const
{
return zoom();
}
KisUndoAdapter *KisView::undoAdapter() const
{
return m_adapter;
}
KisCanvasController *KisView::canvasController() const
{
return const_cast<KisCanvasController*>(static_cast<const KisCanvasController*>(this));
}
KisToolControllerInterface *KisView::toolController() const
{
return const_cast<KisToolControllerInterface*>(static_cast<const KisToolControllerInterface*>(m_toolManager));
}
KisDoc *KisView::document() const
{
return m_doc;
}
KisProgressDisplayInterface *KisView::progressDisplay() const
{
return m_progress;
}
TQCursor KisView::setCanvasCursor(const TQCursor & cursor)
{
TQCursor oldCursor = m_canvas->cursor();
TQCursor newCursor;
KisConfig cfg;
switch (cfg.cursorStyle()) {
case CURSOR_STYLE_TOOLICON:
newCursor = cursor;
break;
case CURSOR_STYLE_CROSSHAIR:
newCursor = KisCursor::crossCursor();
break;
case CURSOR_STYLE_POINTER:
newCursor = KisCursor::arrowCursor();
break;
case CURSOR_STYLE_OUTLINE:
newCursor = cursor;
break;
default:
newCursor = cursor;
}
m_canvas->setCursor(newCursor);
return oldCursor;
}
float KisView::HDRExposure() const
{
return m_HDRExposure;
}
void KisView::setHDRExposure(float exposure)
{
if (exposure != m_HDRExposure) {
m_HDRExposure = exposure;
notifyObservers();
updateCanvas();
}
}
void KisView::createDockers()
{
m_birdEyeBox = new KisBirdEyeBox(this);
m_birdEyeBox->setCaption(i18n("Overview"));
m_paletteManager->addWidget( m_birdEyeBox, "birdeyebox", chalk::CONTROL_PALETTE);
m_hsvwidget = new KoHSVWidget(this, "hsv");
m_hsvwidget->setCaption(i18n("HSV"));
connect(m_hsvwidget, TQ_SIGNAL(sigFgColorChanged(const TQColor &)), this, TQ_SLOT(slotSetFGQColor(const TQColor &)));
connect(m_hsvwidget, TQ_SIGNAL(sigBgColorChanged(const TQColor &)), this, TQ_SLOT(slotSetBGQColor(const TQColor &)));
connect(this, TQ_SIGNAL(sigFGQColorChanged(const TQColor &)), m_hsvwidget, TQ_SLOT(setFgColor(const TQColor &)));
connect(this, TQ_SIGNAL(sigBGQColorChanged(const TQColor &)), m_hsvwidget, TQ_SLOT(setBgColor(const TQColor &)));
m_paletteManager->addWidget( m_hsvwidget, "hsvwidget", chalk::COLORBOX, 0, PALETTE_DOCKER, true);
m_rgbwidget = new KoRGBWidget(this, "rgb");
m_rgbwidget->setCaption(i18n("RGB"));
connect(m_rgbwidget, TQ_SIGNAL(sigFgColorChanged(const TQColor &)), this, TQ_SLOT(slotSetFGQColor(const TQColor &)));
connect(m_rgbwidget, TQ_SIGNAL(sigBgColorChanged(const TQColor &)), this, TQ_SLOT(slotSetBGQColor(const TQColor &)));
connect(this, TQ_SIGNAL(sigFGQColorChanged(const TQColor &)), m_rgbwidget, TQ_SLOT(setFgColor(const TQColor &)));
connect(this, TQ_SIGNAL(sigBGQColorChanged(const TQColor &)), m_rgbwidget, TQ_SLOT(setBgColor(const TQColor &)));
m_paletteManager->addWidget( m_rgbwidget, "rgbwidget", chalk::COLORBOX);
m_graywidget = new KoGrayWidget(this, "gray");
m_graywidget->setCaption(i18n("Gray"));
connect(m_graywidget, TQ_SIGNAL(sigFgColorChanged(const TQColor &)), this, TQ_SLOT(slotSetFGQColor(const TQColor &)));
connect(m_graywidget, TQ_SIGNAL(sigBgColorChanged(const TQColor &)), this, TQ_SLOT(slotSetBGQColor(const TQColor &)));
connect(this, TQ_SIGNAL(sigFGQColorChanged(const TQColor &)), m_graywidget, TQ_SLOT(setFgColor(const TQColor &)));
connect(this, TQ_SIGNAL(sigBGQColorChanged(const TQColor &)), m_graywidget, TQ_SLOT(setBgColor(const TQColor &)));
m_paletteManager->addWidget( m_graywidget, "graywidget", chalk::COLORBOX);
//make sure the color chooser get right default values
emit sigFGQColorChanged(m_fg.toTQColor());
emit sigBGQColorChanged(m_bg.toTQColor());
m_palettewidget = new KisPaletteWidget(this);
m_palettewidget->setCaption(i18n("Palettes"));
connect(m_palettewidget, TQ_SIGNAL(colorSelected(const TQColor &)),
this, TQ_SLOT(slotSetFGQColor(const TQColor &)));
// No BGColor or reverse slotFGChanged->palette connections, since that's not useful here
KisResourceServerBase* rServer;
rServer = KisResourceServerRegistry::instance()->get("PaletteServer");
TQValueList<KisResource*> resources = rServer->resources();
TQValueList<KisResource*>::iterator it;
for ( it = resources.begin(); it != resources.end(); ++it ) {
m_palettewidget->slotAddPalette( *it );
}
connect(m_palettewidget, TQ_SIGNAL(colorSelected(const KisColor &)), this, TQ_SLOT(slotSetFGColor(const KisColor &)));
m_paletteManager->addWidget( m_palettewidget, "palettewidget", chalk::COLORBOX, 10, PALETTE_DOCKER, true);
}
TQPoint KisView::applyViewTransformations(const TQPoint& p) const {
TQPoint point(windowToView(p));
if (m_hRuler->isShown())
point.ry() += m_hRuler->height();
if (m_vRuler -> isShown())
point.rx() += m_vRuler->width();
return point;
}
TQPoint KisView::reverseViewTransformations(const TQPoint& p) const {
// Since we now zoom ourselves, the only thing super::~ does is nothing anymore.
// Hence, zoom ourselves, like super would
// viewToWindow doesn't take the rulers into account, do that ourselves
TQPoint point(p);
if (m_hRuler -> isShown())
point.ry() -= m_hRuler -> height();
if (m_vRuler -> isShown())
point.rx() -= m_vRuler -> width();
return viewToWindow(point);
}
void KisView::canvasAddChild(KoViewChild *child) {
super::canvasAddChild(child);
connect(this, TQ_SIGNAL(viewTransformationsChanged()), child, TQ_SLOT(reposition()));
m_vScroll->raise();
m_hScroll->raise();
m_vScroll->raise();
m_hRuler->raise();
m_vRuler->raise();
}
void KisView::slotLoadingFinished()
{
// Set the current image for real now everything is ready to go.
setCurrentImage(document()->currentImage());
m_paletteManager->showWidget( "layerbox" );
m_canvas->show();
disconnect(document(), TQ_SIGNAL(loadingFinished()), this, TQ_SLOT(slotLoadingFinished()));
m_imageLoaded = true;
startInitialZoomTimerIfReady();
}
void KisView::startInitialZoomTimerIfReady()
{
if (m_imageLoaded && m_showEventReceived && m_guiActivateEventReceived) {
m_initialZoomTimer.start(250, true);
}
}
void KisView::slotInitialZoomTimeout()
{
Q_ASSERT(!m_paintViewEnabled);
m_paintViewEnabled = true;
setInitialZoomLevel();
}
void KisView::slotCreateMask() {
KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data());
if (!layer)
return;
KNamedCommand *cmd = layer->createMaskCommand();
cmd->execute();
if (undoAdapter() && undoAdapter()->undo()) {
undoAdapter()->addCommand(cmd);
}
}
void KisView::slotMaskFromSelection() {
KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data());
if (!layer)
return;
KNamedCommand *cmd = layer->maskFromSelectionCommand();
cmd->execute();
if (undoAdapter() && undoAdapter()->undo()) {
undoAdapter()->addCommand(cmd);
}
}
void KisView::slotMaskToSelection() {
KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data());
if (!layer)
return;
KNamedCommand *cmd = layer->maskToSelectionCommand();
cmd->execute();
if (undoAdapter() && undoAdapter()->undo()) {
undoAdapter()->addCommand(cmd);
}
}
void KisView::slotApplyMask() {
KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data());
if (!layer)
return;
KNamedCommand *cmd = layer->applyMaskCommand();
cmd->execute();
if (undoAdapter() && undoAdapter()->undo()) {
undoAdapter()->addCommand(cmd);
}
}
void KisView::slotRemoveMask() {
KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data());
if (!layer)
return;
KNamedCommand *cmd = layer->removeMaskCommand();
cmd->execute();
if (undoAdapter() && undoAdapter()->undo()) {
undoAdapter()->addCommand(cmd);
}
}
void KisView::slotEditMask() {
KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data());
if (!layer)
return;
layer->setEditMask(m_editMask->isChecked());
}
void KisView::slotShowMask() {
KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data());
if (!layer)
return;
layer->setRenderMask(m_showMask->isChecked());
}
void KisView::maskUpdated() {
KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data());
if (!layer) {
m_createMask->setEnabled(false);
m_applyMask->setEnabled(false);
m_removeMask->setEnabled(false);
m_editMask->setEnabled(false);
m_showMask->setEnabled(false);
return;
}
m_createMask->setEnabled(!layer->hasMask());
m_maskFromSelection->setEnabled(true); // Perhaps also update this to false when no selection?
m_maskToSelection->setEnabled(layer->hasMask());
m_applyMask->setEnabled(layer->hasMask());
m_removeMask->setEnabled(layer->hasMask());
m_editMask->setEnabled(layer->hasMask());
m_editMask->setChecked(layer->editMask());
m_showMask->setEnabled(layer->hasMask());
m_showMask->setChecked(layer->renderMask());
}
#include "kis_view.moc"