File indexing completed on 2024-05-12 04:21:29
0001 0002 /* 0003 Copyright (c) 2003-2007 Clarence Dang <dang@kde.org> 0004 All rights reserved. 0005 0006 Redistribution and use in source and binary forms, with or without 0007 modification, are permitted provided that the following conditions 0008 are met: 0009 0010 1. Redistributions of source code must retain the above copyright 0011 notice, this list of conditions and the following disclaimer. 0012 2. Redistributions in binary form must reproduce the above copyright 0013 notice, this list of conditions and the following disclaimer in the 0014 documentation and/or other materials provided with the distribution. 0015 0016 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 0017 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 0018 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 0019 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 0020 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 0021 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0022 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0023 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0024 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 0025 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0026 */ 0027 0028 0029 #define DEBUG_KP_VIEW_MANAGER 0 0030 0031 0032 #include "views/manager/kpViewManager.h" 0033 #include "kpViewManagerPrivate.h" 0034 0035 0036 #include "kpLogCategories.h" 0037 0038 #include "kpDefs.h" 0039 #include "document/kpDocument.h" 0040 #include "mainWindow/kpMainWindow.h" 0041 #include "layers/tempImage/kpTempImage.h" 0042 #include "layers/selections/text/kpTextSelection.h" 0043 #include "tools/kpTool.h" 0044 #include "views/kpView.h" 0045 0046 //--------------------------------------------------------------------- 0047 0048 kpViewManager::kpViewManager (kpMainWindow *mainWindow) 0049 : d (new kpViewManagerPrivate ()) 0050 { 0051 Q_ASSERT (mainWindow); 0052 0053 d->mainWindow = mainWindow; 0054 0055 // d->views 0056 d->viewUnderCursor = nullptr; 0057 0058 // d->cursor 0059 0060 d->tempImage = nullptr; 0061 0062 d->selectionBorderVisible = false; 0063 d->selectionBorderFinished = false; 0064 0065 0066 d->textCursorBlinkTimer = nullptr; 0067 0068 d->textCursorRow = -1; 0069 d->textCursorCol = -1; 0070 0071 d->textCursorBlinkState = true; 0072 0073 0074 d->queueUpdatesCounter = d->fastUpdatesCounter = 0; 0075 0076 d->inputMethodEnabled = false; 0077 } 0078 0079 //--------------------------------------------------------------------- 0080 0081 kpViewManager::~kpViewManager () 0082 { 0083 unregisterAllViews (); 0084 0085 delete d->tempImage; 0086 delete d; 0087 } 0088 0089 //--------------------------------------------------------------------- 0090 0091 // private 0092 kpDocument *kpViewManager::document () const 0093 { 0094 return d->mainWindow->document (); 0095 } 0096 0097 //--------------------------------------------------------------------- 0098 0099 // public 0100 void kpViewManager::registerView (kpView *view) 0101 { 0102 #if DEBUG_KP_VIEW_MANAGER && 1 0103 qCDebug(kpLogViews) << "kpViewManager::registerView (" << view << ")"; 0104 #endif 0105 Q_ASSERT (view); 0106 Q_ASSERT (!d->views.contains (view)); 0107 0108 #if DEBUG_KP_VIEW_MANAGER && 1 0109 qCDebug(kpLogViews) << "\tadded view"; 0110 #endif 0111 view->setCursor (d->cursor); 0112 d->views.append (view); 0113 } 0114 0115 //--------------------------------------------------------------------- 0116 0117 // public 0118 void kpViewManager::unregisterView (kpView *view) 0119 { 0120 Q_ASSERT (view); 0121 Q_ASSERT (d->views.contains (view)); 0122 0123 if (view == d->viewUnderCursor) { 0124 d->viewUnderCursor = nullptr; 0125 } 0126 0127 view->unsetCursor (); 0128 d->views.removeAll (view); 0129 } 0130 0131 //--------------------------------------------------------------------- 0132 0133 // public 0134 void kpViewManager::unregisterAllViews () 0135 { 0136 d->views.clear (); 0137 } 0138 0139 //--------------------------------------------------------------------- 0140 0141 // public 0142 kpView *kpViewManager::viewUnderCursor (bool usingQt) const 0143 { 0144 if (!usingQt) 0145 { 0146 Q_ASSERT (!d->viewUnderCursor || d->views.contains (d->viewUnderCursor)); 0147 return d->viewUnderCursor; 0148 } 0149 0150 0151 for (kpView *view : std::as_const(d->views)) 0152 if ( view->underMouse() ) 0153 return view; 0154 0155 return nullptr; 0156 } 0157 0158 //--------------------------------------------------------------------- 0159 0160 // public 0161 void kpViewManager::setViewUnderCursor (kpView *view) 0162 { 0163 #if DEBUG_KP_VIEW_MANAGER && 1 0164 qCDebug(kpLogViews) << "kpViewManager::setViewUnderCursor (" 0165 << (view ? view->objectName () : "(none)") << ")" 0166 << " old=" << (d->viewUnderCursor ? d->viewUnderCursor->objectName () : "(none)"); 0167 #endif 0168 if (view == d->viewUnderCursor) { 0169 return; 0170 } 0171 0172 d->viewUnderCursor = view; 0173 0174 if (d->viewUnderCursor) { 0175 d->viewUnderCursor->setAttribute (Qt::WA_InputMethodEnabled, d->inputMethodEnabled); 0176 } 0177 0178 if (!d->viewUnderCursor) 0179 { 0180 // Hide the brush if the mouse cursor just left the view. 0181 if (d->tempImage && d->tempImage->isBrush ()) 0182 { 0183 #if DEBUG_KP_VIEW_MANAGER && 1 0184 qCDebug(kpLogViews) << "\thiding brush pixmap since cursor left view"; 0185 #endif 0186 updateViews (d->tempImage->rect ()); 0187 } 0188 } 0189 else 0190 { 0191 if (d->mainWindow->tool ()) 0192 { 0193 #if DEBUG_KP_VIEW_MANAGER && 1 0194 qCDebug(kpLogViews) << "\tnotify tool that something changed below cursor"; 0195 #endif 0196 d->mainWindow->tool ()->somethingBelowTheCursorChanged (); 0197 } 0198 } 0199 } 0200 0201 //--------------------------------------------------------------------- 0202 0203 // public 0204 bool kpViewManager::hasAViewWithFocus () const 0205 { 0206 for (kpView *view : std::as_const(d->views)) 0207 if ( view->isActiveWindow() ) 0208 return true; 0209 0210 return false; 0211 } 0212 0213 //--------------------------------------------------------------------- 0214 0215 // public 0216 void kpViewManager::setCursor(const QCursor &cursor) 0217 { 0218 for (kpView *view : std::as_const(d->views)) 0219 view->setCursor(cursor); 0220 0221 d->cursor = cursor; 0222 } 0223 0224 //--------------------------------------------------------------------- 0225 0226 // public 0227 void kpViewManager::unsetCursor() 0228 { 0229 for (kpView *view : std::as_const(d->views)) 0230 view->unsetCursor(); 0231 0232 d->cursor = QCursor(); 0233 } 0234 0235 //--------------------------------------------------------------------- 0236 0237 // public 0238 const kpTempImage *kpViewManager::tempImage () const 0239 { 0240 return d->tempImage; 0241 } 0242 0243 //--------------------------------------------------------------------- 0244 0245 // public 0246 void kpViewManager::setTempImage (const kpTempImage &tempImage) 0247 { 0248 #if DEBUG_KP_VIEW_MANAGER 0249 qCDebug(kpLogViews) << "kpViewManager::setTempImage(isBrush=" 0250 << tempImage.isBrush () 0251 << ",topLeft=" << tempImage.topLeft () 0252 << ",image.rect=" << tempImage.image ().rect () 0253 << ")"; 0254 #endif 0255 0256 QRect oldRect; 0257 0258 if (d->tempImage) 0259 { 0260 oldRect = d->tempImage->rect (); 0261 delete d->tempImage; 0262 d->tempImage = nullptr; 0263 } 0264 0265 d->tempImage = new kpTempImage (tempImage); 0266 0267 setQueueUpdates (); 0268 { 0269 if (oldRect.isValid ()) { 0270 updateViews (oldRect); 0271 } 0272 updateViews (d->tempImage->rect ()); 0273 } 0274 restoreQueueUpdates (); 0275 } 0276 0277 //--------------------------------------------------------------------- 0278 0279 // public 0280 void kpViewManager::invalidateTempImage () 0281 { 0282 if (!d->tempImage) { 0283 return; 0284 } 0285 0286 QRect oldRect = d->tempImage->rect (); 0287 0288 delete d->tempImage; 0289 d->tempImage = nullptr; 0290 0291 updateViews (oldRect); 0292 } 0293 0294 //--------------------------------------------------------------------- 0295 0296 // public 0297 bool kpViewManager::selectionBorderVisible () const 0298 { 0299 return d->selectionBorderVisible; 0300 } 0301 0302 //--------------------------------------------------------------------- 0303 0304 // public 0305 void kpViewManager::setSelectionBorderVisible (bool yes) 0306 { 0307 if (d->selectionBorderVisible == yes) { 0308 return; 0309 } 0310 0311 d->selectionBorderVisible = yes; 0312 0313 if (document ()->selection ()) { 0314 updateViews (document ()->selection ()->boundingRect ()); 0315 } 0316 } 0317 0318 //--------------------------------------------------------------------- 0319 0320 // public 0321 bool kpViewManager::selectionBorderFinished () const 0322 { 0323 return d->selectionBorderFinished; 0324 } 0325 0326 //--------------------------------------------------------------------- 0327 0328 // public 0329 void kpViewManager::setSelectionBorderFinished (bool yes) 0330 { 0331 if (d->selectionBorderFinished == yes) { 0332 return; 0333 } 0334 0335 d->selectionBorderFinished = yes; 0336 0337 if (document ()->selection ()) { 0338 updateViews (document ()->selection ()->boundingRect ()); 0339 } 0340 } 0341 0342 //--------------------------------------------------------------------- 0343 0344 void kpViewManager::setInputMethodEnabled (bool inputMethodEnabled) 0345 { 0346 d->inputMethodEnabled = inputMethodEnabled; 0347 if (d->viewUnderCursor) { 0348 d->viewUnderCursor->setAttribute (Qt::WA_InputMethodEnabled, inputMethodEnabled); 0349 } 0350 } 0351 0352 //--------------------------------------------------------------------- 0353 0354 #include "moc_kpViewManager.cpp"