3 Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
10 1. Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 #include <kpPixmapFX.h>
51 class kpDocumentEnvironment
;
52 class kpDocumentSaveOptions
;
53 class kpDocumentMetaInfo
;
54 class kpAbstractImageSelection
;
55 class kpAbstractSelection
;
56 class kpTextSelection
;
59 // REFACTOR: rearrange method order to make sense and reflect kpDocument_*.cpp split.
60 class kpDocument
: public QObject
65 // REFACTOR: Hide constructor and have 2 factory methods:
67 // Method 1. Creates a blank document with dimensions <w>x<h>.
69 // Method 2. Calls open(). <w> and <h> (aka constructorWidth()
70 // and constructorHeight()) need not be specified.
73 kpDocument (int w
, int h
, kpDocumentEnvironment
*environ
);
76 kpDocumentEnvironment
*environ () const;
77 void setEnviron (kpDocumentEnvironment
*environ
);
84 // Wraps kpPixmapFX::convertToPixmapAsLosslessAsPossible() but also
85 // returns document meta information.
86 static QPixmap
convertToPixmapAsLosslessAsPossible (
88 const kpPixmapFX::WarnAboutLossInfo
&wali
= kpPixmapFX::WarnAboutLossInfo (),
89 kpDocumentSaveOptions
*saveOptions
= 0,
90 kpDocumentMetaInfo
*metaInfo
= 0);
92 static QPixmap
getPixmapFromFile (const KUrl
&url
, bool suppressDoesntExistDialog
,
94 kpDocumentSaveOptions
*saveOptions
= 0,
95 kpDocumentMetaInfo
*metaInfo
= 0);
96 // REFACTOR: fix: open*() should only be called once.
97 // Create a new kpDocument() if you want to open again.
98 void openNew (const KUrl
&url
);
99 bool open (const KUrl
&url
, bool newDocSameNameIfNotExist
= false);
106 static bool lossyPromptContinue (const QPixmap
&pixmap
,
107 const kpDocumentSaveOptions
&saveOptions
,
109 static bool savePixmapToDevice (const QPixmap
&pixmap
,
111 const kpDocumentSaveOptions
&saveOptions
,
112 const kpDocumentMetaInfo
&metaInfo
,
115 bool *userCancelled
= 0);
116 static bool savePixmapToFile (const QPixmap
&pixmap
,
118 const kpDocumentSaveOptions
&saveOptions
,
119 const kpDocumentMetaInfo
&metaInfo
,
120 bool overwritePrompt
,
123 bool save (bool overwritePrompt
= false, bool lossyPrompt
= false);
124 bool saveAs (const KUrl
&url
,
125 const kpDocumentSaveOptions
&saveOptions
,
126 bool overwritePrompt
= true,
127 bool lossyPrompt
= true);
130 // Returns whether save() or saveAs() have ever been called and returned true
131 bool savedAtLeastOnceBefore () const;
134 void setURL (const KUrl
&url
, bool isFromURL
);
136 // Returns whether the document's image was successfully opened from
137 // or saved to the URL returned by url(). This is not true for a
138 // new kpDocument and in the case of open() being passed
139 // "newDocSameNameIfNotExist = true" when the URL doesn't exist.
141 // If this returns true and the kpDocument hasn't been modified,
142 // this gives a pretty good indication that the image stored at url()
143 // is equal to image() (unless the something has happened to that url
144 // outside of KolourPaint).
146 // e.g. If the user types "kolourpaint doesnotexist.png" to start
147 // KolourPaint, this method will return false.
148 bool isFromURL (bool checkURLStillExists
= true) const;
150 // (will convert: empty Url --> "Untitled")
151 QString
prettyUrl () const;
153 // (will convert: empty Url --> "Untitled")
154 QString
prettyFilename () const;
156 // (guaranteed to return valid pointer)
158 const kpDocumentSaveOptions
*saveOptions () const;
159 void setSaveOptions (const kpDocumentSaveOptions
&saveOptions
);
161 const kpDocumentMetaInfo
*metaInfo () const;
162 void setMetaInfo (const kpDocumentMetaInfo
&metaInfo
);
166 * Properties (modified, width, height, color depth...)
169 void setModified (bool yes
= true);
170 bool isModified () const;
171 bool isEmpty () const;
173 // REFACTOR: Rename to originalWidth()?
174 int constructorWidth () const; // as passed to the constructor
175 int width (bool ofSelection
= false) const;
176 int oldWidth () const; // only valid in a slot connected to sizeChanged()
177 void setWidth (int w
, const kpColor
&backgroundColor
);
179 // REFACTOR: Rename to originalHeight()?
180 int constructorHeight () const; // as passed to the constructor
181 int height (bool ofSelection
= false) const;
182 int oldHeight () const; // only valid in a slot connected to sizeChanged()
183 void setHeight (int h
, const kpColor
&backgroundColor
);
185 QRect
rect (bool ofSelection
= false) const;
192 // Returns a copy of part of the document's image (not including the
194 kpImage
getImageAt (const QRect
&rect
) const;
196 void setImageAt (const kpImage
&image
, const QPoint
&at
);
198 void paintImageAt (const kpImage
&image
, const QPoint
&at
);
200 // "image(false)" returns a copy of the document's image, ignoring any
201 // floating selection.
203 // "image(true)" returns a copy of a floating image selection's base
204 // image (i.e. before selection transparency is applied), which may be
205 // null if the image selection is a just a border.
207 // ASSUMPTION: For <ofSelection> == true only, an image selection exists.
208 kpImage
image (bool ofSelection
= false) const;
209 kpImage
*imagePointer () const;
211 void setImage (const kpImage
&image
);
212 // ASSUMPTION: If setting the selection's image, the selection must be
213 // an image selection.
214 void setImage (bool ofSelection
, const kpImage
&image
);
222 kpAbstractSelection
*selection () const;
223 kpAbstractImageSelection
*imageSelection () const;
224 kpTextSelection
*textSelection () const;
226 // Sets the document's selection to the given one and changes to the
227 // matching selection tool. Tool changes occur in the following situations:
229 // 1. Setting a <selection> when a selection tool is not active.
231 // 2. Setting an image <selection> when the text tool is active.
232 // ASSUMPTION: There is no text selection active when calling this
233 // method (push it onto the document before calling this,
234 // to avoid this problem).
236 // 3. Setting a text <selection> when an image selection tool is active.
237 // ASSUMPTION: There is no image selection active when calling this
238 // method (push it onto the document before calling this,
239 // to avoid this problem).
241 // The justification for the above assumptions are to reduce the complexity
242 // of this method's implementation -- changing from an image selection tool
243 // to a text selection tool, or vice-versa, calls the end() method of the
244 // current tool, which pushes any active selection onto the document. Since
245 // this method sets the selection, losing the old selection in the middle of
246 // the method would be tricky to work around.
248 // WARNING: Before calling this, you must ensure that the UI (kpMainWindow)
249 // has the <selection>'s selection transparency or
250 // for a text selection, its text style, selected.
251 // TODO: Why can't we change it for them, if we change tool automatically for them already?
252 void setSelection (const kpAbstractSelection
&selection
);
254 // Returns the base image of the current image selection. If this is
255 // null (because the selection is still a border), it extracts the
256 // pixels of the document marked out by the border of the selection.
258 // ASSUMPTION: There is an imageSelection().
260 // TODO: this always returns base image - need ver that applies selection
262 kpImage
getSelectedBaseImage () const;
264 // Sets the base image of the current image selection to the pixels
265 // of the document marked out by the border of the selection.
267 // ASSUMPTION: There is an imageSelection() that is just a border
269 void imageSelectionPullFromDocument (const kpColor
&backgroundColor
);
271 // Deletes the current selection.
273 // ASSUMPTION: There is a selection().
274 void selectionDelete ();
276 // Stamps a copy of the selection onto the document.
278 // For image selections, <applySelTransparency> set to true, means that
279 // the transparent image of the selection is used. If set to false,
280 // the base image of the selection is used. This argument is ignored
281 // for non-image selections.
283 // ASSUMPTION: There is a selection() with content.
284 void selectionCopyOntoDocument (bool applySelTransparency
= true);
286 // Same as selectionCopyOntoDocument() but deletes the selection
288 void selectionPushOntoDocument (bool applySelTransparency
= true);
291 // Same as image() but returns a _copy_ of the document image
292 // + any (even non-image) selection pasted on top.
294 // Even if the selection has no content, it is still pasted:
296 // 1. For an image selection, this makes no difference.
298 // 2. For a text selection:
300 // a) with an opaque background: the background rectangle is
301 // included -- this is necessary since the rectangle is visually
302 // there after all, and the intention of this method is to report
305 // b) with a transparent background: this makes no difference.
307 kpImage
imageWithSelection () const;
312 * (convenience only - you could achieve the same effect (and more) with
313 * kpPixmapFX: these functions do not affect the selection)
316 void fill (const kpColor
&color
);
317 void resize (int w
, int h
, const kpColor
&backgroundColor
);
321 // these will emit signals!
322 void slotContentsChanged (const QRect
&rect
);
323 void slotSizeChanged (int newWidth
, int newHeight
);
324 void slotSizeChanged (const QSize
&newSize
);
327 void documentOpened ();
328 void documentSaved ();
330 // Emitted whenever the isModified() flag changes from false to true.
331 // This is the _only_ signal that may be emitted in addition to the others.
332 void documentModified ();
334 void contentsChanged (const QRect
&rect
);
335 void sizeChanged (int newWidth
, int newHeight
); // see oldWidth(), oldHeight()
336 void sizeChanged (const QSize
&newSize
);
338 void selectionEnabled (bool on
);
340 // Emitted when setSelection() is given a selection such that we change
341 // from a non-text-selection tool to the text selection tool or vice-versa.
342 // <isText> reports whether the new selection is text (and therefore,
343 // whether we've switched to the text tool).
344 void selectionIsTextChanged (bool isText
);
347 int m_constructorWidth
, m_constructorHeight
;
352 bool m_savedAtLeastOnceBefore
;
354 kpDocumentSaveOptions
*m_saveOptions
;
355 kpDocumentMetaInfo
*m_metaInfo
;
359 kpAbstractSelection
*m_selection
;
361 int m_oldWidth
, m_oldHeight
;
363 // There is no need to maintain binary compatibility at this stage.
364 // The d-pointer is just so that you can experiment without recompiling
366 struct kpDocumentPrivate
*d
;
370 #endif // KP_DOCUMENT_H