1 /*************************************************************************** 2 * Copyright (C) 2003 by Sébastien Laoût * 3 * slaout@linux62.org * 4 * * 5 * This program is free software; you can redistribute it and/or modify * 6 * it under the terms of the GNU General Public License as published by * 7 * the Free Software Foundation; either version 2 of the License, or * 8 * (at your option) any later version. * 9 * * 10 * This program is distributed in the hope that it will be useful, * 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 * GNU General Public License for more details. * 14 * * 15 * You should have received a copy of the GNU General Public License * 16 * along with this program; if not, write to the * 17 * Free Software Foundation, Inc., * 18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 19 ***************************************************************************/ 20 21 #ifndef NOTE_H 22 #define NOTE_H 23 24 #include <QtCore/QList> 25 #include <QtCore/QSet> 26 #include <QtCore/QDateTime> 27 #include <QGraphicsItemGroup> 28 29 #include "basket_export.h" 30 #include "tag.h" 31 32 class BasketScene; 33 class FilterData; 34 35 class NoteContent; 36 class NoteSelection; 37 38 class QPainter; 39 class QPixmap; 40 class QString; 41 class QGraphicsItemAnimation; 42 class QTimeLine; 43 44 class NotePrivate; 45 46 /** Handle basket notes and groups!\n 47 * After creation, the note is a group. You should create a NoteContent with this Note 48 * as constructor parameter to transform it to a note with content. eg: 49 * @code 50 * Note *note = new Note(basket); // note is a group! 51 * new TextContent(note, fileName); // note is now a note with a text content! 52 * new ColorContent(note, Qt::red); // Should never be done!!!!! the old Content should be deleted... 53 * @endcode 54 * @author Sébastien Laoût 55 */ 56 class BASKET_EXPORT Note : public QGraphicsItemGroup 57 { 58 /// CONSTRUCTOR AND DESTRUCTOR: 59 public: 60 Note(BasketScene *parent = 0); 61 ~Note(); 62 63 private: 64 NotePrivate* d; 65 66 /// DOUBLY LINKED LIST: 67 public: 68 void setNext(Note *next); 69 void setPrev(Note *prev); 70 Note* next() const; 71 Note* prev() const; 72 73 public: 74 void setWidth(qreal width); 75 void setWidthForceRelayout(qreal width); 76 //! Do not use it unless you know what you do! 77 void setInitialHeight(qreal height); 78 79 void setXRecursively(qreal ax); 80 void setYRecursively(qreal ay); 81 void hideRecursively(); 82 qreal width() const; 83 qreal height() const; 84 qreal bottom() const; 85 QRectF rect(); 86 QRectF resizerRect(); 87 QRectF visibleRect(); 88 QRectF boundingRect() const; 89 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, 90 QWidget *widget); 91 void relayoutAt(qreal ax, qreal ay, bool animate); 92 qreal contentX() const; 93 qreal minWidth() const; 94 qreal minRight(); 95 void unsetWidth(); 96 void requestRelayout(); 97 /** << DO NEVER USE IT!!! Only available when moving notes, groups should be recreated with the exact same state as before! */ 98 void setHeight(qreal height); 99 100 /// FREE AND COLUMN LAYOUTS MANAGEMENT: 101 private: 102 qreal m_groupWidth; 103 public: 104 qreal groupWidth() const; 105 void setGroupWidth(qreal width); 106 qreal rightLimit() const; 107 qreal finalRightLimit() const; 108 bool isFree() const; 109 bool isColumn() const; 110 bool hasResizer() const; 111 qreal resizerHeight() const; 112 113 /// GROUPS MANAGEMENT: 114 private: 115 bool m_isFolded; 116 Note *m_firstChild; 117 Note *m_parentNote; 118 public: isGroup()119 inline bool isGroup() const { 120 return m_content == 0L; 121 } isFolded()122 inline bool isFolded() { 123 return m_isFolded; 124 } firstChild()125 inline Note* firstChild() { 126 return m_firstChild; 127 } parentNote()128 inline Note* parentNote() const { 129 return m_parentNote; 130 } 131 /*inline*/ bool showSubNotes();// { return !m_isFolded || !m_collapseFinished; } setParentNote(Note * note)132 inline void setParentNote(Note *note) { 133 m_parentNote = note; 134 } setFirstChild(Note * note)135 inline void setFirstChild(Note *note) { 136 m_firstChild = note; 137 } 138 bool isShown(); 139 bool toggleFolded(); 140 141 Note* noteAt(QPointF pos); 142 Note* firstRealChild(); 143 Note* lastRealChild(); 144 Note* lastChild(); 145 Note* lastSibling(); 146 qreal yExpander(); 147 bool isAfter(Note *note); 148 bool containsNote(Note *note); 149 150 /// NOTES VARIOUS PROPERTIES: // CONTENT MANAGEMENT? 151 private: 152 BasketScene *m_basket; 153 NoteContent *m_content; 154 QDateTime m_addedDate; 155 QDateTime m_lastModificationDate; 156 public: basket()157 inline BasketScene* basket() const { 158 return m_basket; 159 } content()160 inline NoteContent* content() { 161 return m_content; 162 } setAddedDate(const QDateTime & dateTime)163 inline void setAddedDate(const QDateTime &dateTime) { 164 m_addedDate = dateTime; 165 } setLastModificationDate(const QDateTime & dateTime)166 inline void setLastModificationDate(const QDateTime &dateTime) { 167 m_lastModificationDate = dateTime; 168 } 169 170 void setParentBasket(BasketScene *basket); 171 addedDate()172 QDateTime addedDate() { 173 return m_addedDate; 174 } lastModificationDate()175 QDateTime lastModificationDate() { 176 return m_lastModificationDate; 177 } 178 QString addedStringDate(); 179 QString lastModificationStringDate(); 180 QString toText(const QString &cuttedFullPath); 181 bool saveAgain(); 182 void deleteChilds(); 183 184 protected: 185 void setContent(NoteContent *content); 186 friend class NoteContent; 187 friend class AnimationContent; 188 189 /// DRAWING: 190 private: 191 QPixmap m_bufferedPixmap; 192 QPixmap m_bufferedSelectionPixmap; 193 public: 194 void draw(QPainter *painter, const QRectF &clipRect); 195 void drawBufferOnScreen(QPainter *painter, const QPixmap &contentPixmap); 196 static void getGradientColors(const QColor &originalBackground, QColor *colorTop, QColor *colorBottom); 197 static void drawExpander(QPainter *painter, qreal x, qreal y, const QColor &background, bool expand, BasketScene *basket); 198 void drawHandle(QPainter *painter, qreal x, qreal y, qreal width, qreal height, const QColor &background, const QColor &foreground); 199 void drawResizer(QPainter *painter, qreal x, qreal y, qreal width, qreal height, const QColor &background, const QColor &foreground, bool rounded); 200 void drawRoundings(QPainter *painter, qreal x, qreal y, int type, qreal width = 0, qreal height = 0); 201 void unbufferizeAll(); unbufferize()202 inline void unbufferize() { 203 m_bufferedPixmap = QPixmap(); m_bufferedSelectionPixmap = QPixmap(); 204 } isBufferized()205 inline bool isBufferized() { 206 return !m_bufferedPixmap.isNull(); 207 } 208 void recomputeBlankRects(QList<QRectF> &blankAreas); 209 static void drawInactiveResizer(QPainter *painter, qreal x, qreal y, qreal height, const QColor &background, bool column); 210 QPalette palette() const; 211 212 /// VISIBLE AREAS COMPUTATION: 213 private: 214 QList<QRectF> m_areas; 215 bool m_computedAreas; 216 bool m_onTop; 217 void recomputeAreas(); 218 bool recomputeAreas(Note *note, bool noteIsAfterThis); 219 public: 220 void setOnTop(bool onTop); isOnTop()221 inline bool isOnTop() { 222 return m_onTop; 223 } 224 bool isEditing(); 225 226 /// MANAGE ANIMATION: 227 private: 228 QGraphicsItemAnimation *m_animation; 229 public: 230 bool initAnimationLoad(QTimeLine *timeLine); 231 void animationFinished(); 232 233 /// USER INTERACTION: 234 public: 235 enum Zone { None = 0, 236 Handle, TagsArrow, Custom0, /*CustomContent1, CustomContent2, */Content, Link, 237 TopInsert, TopGroup, BottomInsert, BottomGroup, BottomColumn, 238 Resizer, 239 Group, GroupExpander, 240 Emblem0 241 }; // Emblem0 should be at end, because we add 1 to get Emblem1, 2 to get Emblem2... setHovered(bool hovered)242 inline void setHovered(bool hovered) { 243 m_hovered = hovered; unbufferize(); 244 } 245 void setHoveredZone(Zone zone); hovered()246 inline bool hovered() { 247 return m_hovered; 248 } hoveredZone()249 inline Zone hoveredZone() { 250 return m_hoveredZone; 251 } 252 Zone zoneAt(const QPointF &pos, bool toAdd = false); 253 QRectF zoneRect(Zone zone, const QPointF &pos); 254 Qt::CursorShape cursorFromZone(Zone zone) const; 255 QString linkAt(const QPointF &pos); 256 private: 257 bool m_hovered; 258 Zone m_hoveredZone; 259 260 /// SELECTION: 261 public: 262 NoteSelection* selectedNotes(); 263 void setSelected(bool selected); 264 void setSelectedRecursively(bool selected); 265 void invertSelectionRecursively(); 266 void selectIn(const QRectF &rect, bool invertSelection, bool unselectOthers = true); 267 void setFocused(bool focused); isFocused()268 inline bool isFocused() { 269 return m_focused; 270 } isSelected()271 inline bool isSelected() { 272 return m_selected; 273 } 274 bool allSelected(); 275 void resetWasInLastSelectionRect(); 276 void unselectAllBut(Note *toSelect); 277 void invertSelectionOf(Note *toSelect); 278 Note* theSelectedNote(); 279 private: 280 bool m_focused; 281 bool m_selected; 282 bool m_wasInLastSelectionRect; 283 284 /// TAGS: 285 private: 286 State::List m_states; 287 State m_computedState; 288 int m_emblemsCount; 289 bool m_haveInvisibleTags; 290 public: 291 /*const */State::List& states() const; emblemsCount()292 inline int emblemsCount() { 293 return m_emblemsCount; 294 } 295 void addState(State *state, bool orReplace = true); 296 void addTag(Tag *tag); 297 void removeState(State *state); 298 void removeTag(Tag *tag); 299 void removeAllTags(); 300 void addTagToSelectedNotes(Tag *tag); 301 void removeTagFromSelectedNotes(Tag *tag); 302 void removeAllTagsFromSelectedNotes(); 303 void addStateToSelectedNotes(State *state, bool orReplace = true); 304 void changeStateOfSelectedNotes(State *state); 305 bool selectedNotesHaveTags(); 306 void inheritTagsOf(Note *note); 307 bool hasTag(Tag *tag); 308 bool hasState(State *state); 309 State* stateOfTag(Tag *tag); 310 State* stateForEmblemNumber(int number) const; 311 bool stateForTagFromSelectedNotes(Tag *tag, State **state); 312 void recomputeStyle(); 313 void recomputeAllStyles(); 314 bool removedStates(const QList<State*> &deletedStates); 315 QFont font(); // Computed! 316 QColor backgroundColor(); // Computed! 317 QColor textColor(); // Computed! 318 bool allowCrossReferences(); 319 320 /// FILTERING: 321 private: 322 bool m_matching; 323 public: 324 bool computeMatching(const FilterData &data); 325 int newFilter(const FilterData &data); matching()326 bool matching() { 327 return m_matching; 328 } 329 330 /// ADDED: 331 public: 332 /** 333 * @return true if this note could be deleted 334 **/ 335 void deleteSelectedNotes(bool deleteFilesToo = true, QSet<Note*> *notesToBeDeleted = 0); 336 int count(); 337 int countDirectChilds(); 338 339 QString fullPath(); 340 Note* noteForFullPath(const QString &path); 341 342 //void update(); 343 void linkLookChanged(); 344 345 void usedStates(QList<State*> &states); 346 347 void listUsedTags(QList<Tag*> &list); 348 349 350 Note* nextInStack(); 351 Note* prevInStack(); 352 Note* nextShownInStack(); 353 Note* prevShownInStack(); 354 355 Note* parentPrimaryNote(); // TODO: There are places in the code where this methods is hand-copied / hand-inlined instead of called. 356 357 Note* firstSelected(); 358 Note* lastSelected(); 359 Note* selectedGroup(); 360 void groupIn(Note *group); 361 362 bool tryExpandParent(); 363 bool tryFoldParent(); 364 365 qreal distanceOnLeftRight(Note *note, int side); 366 qreal distanceOnTopBottom(Note *note, int side); 367 368 bool convertTexts(); 369 370 void debug(); 371 372 /// SPEED OPTIMIZATION 373 public: 374 void finishLazyLoad(); 375 376 public: 377 // Values are provided here as info: 378 // Please see Settings::setBigNotes() to know whats values are assigned. 379 static qreal NOTE_MARGIN /*= 2*/; 380 static qreal INSERTION_HEIGHT /*= 5*/; 381 static qreal EXPANDER_WIDTH /*= 9*/; 382 static qreal EXPANDER_HEIGHT /*= 9*/; 383 static qreal GROUP_WIDTH /*= 2*NOTE_MARGIN + EXPANDER_WIDTH*/; 384 static qreal HANDLE_WIDTH /*= GROUP_WIDTH*/; 385 static qreal RESIZER_WIDTH /*= GROUP_WIDTH*/; 386 static qreal TAG_ARROW_WIDTH /*= 5*/; 387 static qreal EMBLEM_SIZE /*= 16*/; 388 static qreal MIN_HEIGHT /*= 2*NOTE_MARGIN + EMBLEM_SIZE*/; 389 }; 390 391 /* 392 * Convenience functions: 393 */ 394 void drawGradient(QPainter *p, const QColor &colorTop, const QColor & colorBottom, 395 qreal x, qreal y, qreal w, qreal h, 396 bool sunken, bool horz, bool flat); 397 398 extern void substractRectOnAreas(const QRectF &rectToSubstract, 399 QList<QRectF> &areas, bool andRemove = true); 400 401 #endif // NOTE_H 402