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.
basket/src/note.h

389 lines
13 KiB

/***************************************************************************
* Copyright (C) 2003 by S<EFBFBD>astien Laot *
* slaout@linux62.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. *
***************************************************************************/
#ifndef NOTE_H
#define NOTE_H
#include <tqstring.h>
#include <tqpixmap.h>
#include <kpixmap.h>
#include <tqdatetime.h>
#include "notecontent.h"
#include "tag.h"
class Basket;
class FilterData;
class HtmlExportData;
class NoteSelection;
class TQPainter;
class TQSimpleRichText;
/** Handle basket notes and groups!\n
* After creation, the note is a group. You should create a NoteContent with this Note
* as constructor parameter to transform it to a note with content. eg:
* @code
* Note *note = new Note(basket); // note is a group!
* new TextContent(note, fileName); // note is now a note with a text content!
* new ColorContent(note, TQt::red); // Should never be done!!!!! the old Content should be deleted...
* @endcode
* @author S<EFBFBD>astien Laot
*/
class Note
{
/// CONSTRUCTOR AND DESTRUCTOR:
public:
Note(Basket *parent);
~Note();
/// DOUBLY LINKED LIST:
private:
Note *m_prev;
Note *m_next;
public:
inline void setNext(Note *next) { m_next = next; }
inline void setPrev(Note *prev) { m_prev = prev; }
inline Note* next() { return m_next; }
inline Note* prev() { return m_prev; }
/// GEOMETRY MANAGEMENT:
private:
int m_x;
int m_y;
int m_width;
int m_height;
// int m_minContentWidth;
public:
void setWidth(int width);
void setWidthForceRelayout(int width);
void setInitialHeight(int height) { m_height = height; } /// << Do NEVER use it unless you know what you do!
void setX(int x);
void setY(int y);
void setXRecursivly(int x);
void setYRecursivly(int y);
inline int x() { return m_x; }
inline int y() { return m_y; }
inline int width() { return (isGroup() ? (isColumn() ? 0 : GROUP_WIDTH) : m_width); }
inline int height() { return m_height; }
inline int bottom() { return m_y + m_height - 1; }
TQRect rect();
TQRect resizerRect();
TQRect visibleRect();
void relayoutAt(int x, int y, bool animate);
int contentX();
int minWidth();
int minRight();
void unsetWidth();
void requestRelayout();
void setHeight(int height) { m_height = height; } /// << DO NEVER USE IT!!! Only available when moving notes, groups should be recreated with the exact same state as before!
/// FREE AND COLUMN LAYOUTS MANAGEMENT:
private:
int m_groupWidth;
public:
int groupWidth();
void setGroupWidth(int width);
int rightLimit();
int finalRightLimit();
bool isFree();
bool isColumn();
bool hasResizer();
int resizerHeight();
/// GROUPS MANAGEMENT:
private:
bool m_isFolded;
Note *m_firstChild;
Note *m_parentNote;
public:
inline bool isGroup() { return m_content == 0L; }
inline bool isFolded() { return m_isFolded; }
inline Note* firstChild() { return m_firstChild; }
inline Note* parentNote() { return m_parentNote; }
/*inline*/ bool showSubNotes();// { return !m_isFolded || !m_collapseFinished; }
inline void setParentNote(Note *note) { m_parentNote = note; }
inline void setFirstChild(Note *note) { m_firstChild = note; }
bool isShown();
void toggleFolded(bool animate);
Note* noteAt(int x, int y);
Note* firstRealChild();
Note* lastRealChild();
Note* lastChild();
Note* lastSibling();
int yExpander();
bool isAfter(Note *note);
bool contains(Note *note);
/// NOTES VARIOUS PROPERTIES: // CONTENT MANAGEMENT?
private:
Basket *m_basket;
NoteContent *m_content;
TQDateTime m_addedDate;
TQDateTime m_lastModificationDate;
public:
inline Basket* basket() { return m_basket; }
inline NoteContent* content() { return m_content; }
inline void setAddedDate(const TQDateTime &dateTime) { m_addedDate = dateTime; }
inline void setLastModificationDate(const TQDateTime &dateTime) { m_lastModificationDate = dateTime; }
inline void setParentBasket(Basket *basket) { m_basket = basket; }
TQDateTime addedDate() { return m_addedDate; }
TQDateTime lastModificationDate() { return m_lastModificationDate; }
TQString addedStringDate();
TQString lastModificationStringDate();
TQString toText(const TQString &cuttedFullPath);
bool saveAgain();
void deleteChilds();
protected:
void setContent(NoteContent *content);
friend class NoteContent;
friend class AnimationContent;
/// DRAWING:
private:
TQPixmap m_bufferedPixmap;
KPixmap m_bufferedSelectionPixmap;
public:
void draw(TQPainter *painter, const TQRect &clipRect);
void drawBufferOnScreen(TQPainter *painter, const TQPixmap &contentPixmap);
static void getGradientColors(const TQColor &originalBackground, TQColor *colorTop, TQColor *colorBottom);
static void drawExpander(TQPainter *painter, int x, int y, const TQColor &background, bool expand, Basket *basket);
void drawHandle( TQPainter *painter, int x, int y, int width, int height, const TQColor &background, const TQColor &foreground);
void drawResizer( TQPainter *painter, int x, int y, int width, int height, const TQColor &background, const TQColor &foreground, bool rounded);
void drawRoundings(TQPainter *painter, int x, int y, int type, int width = 0, int height = 0);
void unbufferizeAll();
void bufferizeSelectionPixmap();
inline void unbufferize() { m_bufferedPixmap.resize(0, 0); m_bufferedSelectionPixmap.resize(0, 0); }
inline bool isBufferized() { return !m_bufferedPixmap.isNull(); }
void recomputeBlankRects(TQValueList<TQRect> &blankAreas);
static void drawInactiveResizer(TQPainter *painter, int x, int y, int height, const TQColor &background, bool column);
/// VISIBLE AREAS COMPUTATION:
private:
TQValueList<TQRect> m_areas;
bool m_computedAreas;
bool m_onTop;
void recomputeAreas();
bool recomputeAreas(Note *note, bool noteIsAfterThis);
public:
void setOnTop(bool onTop);
inline bool isOnTop() { return m_onTop; }
bool isEditing();
/// MANAGE ANIMATION:
private:
int m_deltaX;
int m_deltaY;
int m_deltaHeight;
bool m_collapseFinished;
bool m_expandingFinished;
public:
inline int deltaX() { return m_deltaX; }
inline int deltaY() { return m_deltaY; }
inline int deltaHeight() { return m_deltaHeight; }
inline int finalX() { return m_x + m_deltaX; }
inline int finalY() { return m_y + m_deltaY; }
inline int finalHeight() { return m_height + m_deltaHeight; }
inline int finalBottom() { return finalY() + finalHeight() - 1; }
inline void cancelAnimation() { m_deltaX = 0; m_deltaY = 0; m_deltaHeight = 0; }
inline bool expandingOrCollapsing() { return !m_collapseFinished || !m_expandingFinished; }
void addAnimation(int deltaX, int deltaY, int deltaHeight = 0);
void setFinalPosition(int x, int y); /// << Convenient method for addAnimation()
bool advance();
void initAnimationLoad();
void setRecursivelyUnder(Note *under, bool animate);
/// USER INTERACTION:
public:
enum Zone { None = 0,
Handle, TagsArrow, Custom0, /*CustomContent1, CustomContent2, */Content, Link,
TopInsert, TopGroup, BottomInsert, BottomGroup, BottomColumn,
Resizer,
Group, GroupExpander,
Emblem0 }; // Emblem0 should be at end, because we add 1 to get Emblem1, 2 to get Emblem2...
inline void setHovered(bool hovered) { m_hovered = hovered; unbufferize(); }
void setHoveredZone(Zone zone);
inline bool hovered() { return m_hovered; }
inline Zone hoveredZone() { return m_hoveredZone; }
Zone zoneAt(const TQPoint &pos, bool toAdd = false);
TQRect zoneRect(Zone zone, const TQPoint &pos);
void setCursor(Zone zone);
TQString linkAt(const TQPoint &pos);
private:
bool m_hovered;
Zone m_hoveredZone;
/// SELECTION:
public:
NoteSelection* selectedNotes();
void setSelected(bool selected);
void setSelectedRecursivly(bool selected);
void invertSelectionRecursivly();
void selectIn(const TQRect &rect, bool invertSelection, bool unselectOthers = true);
void setFocused(bool focused);
inline bool isFocused() { return m_focused; }
inline bool isSelected() { return m_selected; }
bool allSelected();
void resetWasInLastSelectionRect();
void unselectAllBut(Note *toSelect);
void invertSelectionOf(Note *toSelect);
Note* theSelectedNote();
private:
bool m_focused;
bool m_selected;
bool m_wasInLastSelectionRect;
/// TAGS:
private:
State::List m_states;
State m_computedState;
int m_emblemsCount;
bool m_haveInvisibleTags;
public:
/*const */State::List& states() const;
inline int emblemsCount() { return m_emblemsCount; }
void addState(State *state, bool orReplace = true);
void addTag(Tag *tag);
void removeState(State *state);
void removeTag(Tag *tag);
void removeAllTags();
void addTagToSelectedNotes(Tag *tag);
void removeTagFromSelectedNotes(Tag *tag);
void removeAllTagsFromSelectedNotes();
void addStateToSelectedNotes(State *state, bool orReplace = true);
void changeStateOfSelectedNotes(State *state);
bool selectedNotesHaveTags();
void inheritTagsOf(Note *note);
bool hasTag(Tag *tag);
bool hasState(State *state);
State* stateOfTag(Tag *tag);
State* stateForEmblemNumber(int number);
bool stateForTagFromSelectedNotes(Tag *tag, State **state);
void recomputeStyle();
void recomputeAllStyles();
bool removedStates(const TQValueList<State*> &deletedStates);
TQFont font(); // Computed!
TQColor backgroundColor(); // Computed!
TQColor textColor(); // Computed!
/// FILTERING:
private:
bool m_matching;
public:
bool computeMatching(const FilterData &data);
int newFilter(const FilterData &data);
bool matching() { return m_matching; }
/// ADDED:
public:
void deleteSelectedNotes(bool deleteFilesToo = true);
int count();
int countDirectChilds();
TQString fullPath();
Note* noteForFullPath(const TQString &path);
void update();
void linkLookChanged();
void usedStates(TQValueList<State*> &states);
void listUsedTags(TQValueList<Tag*> &list);
Note* nextInStack();
Note* prevInStack();
Note* nextShownInStack();
Note* prevShownInStack();
Note* parentPrimaryNote(); // TODO: There are places in the code where this methods is hand-copied / hand-inlined instead of called.
Note* firstSelected();
Note* lastSelected();
Note* selectedGroup();
void groupIn(Note *group);
bool tryExpandParent();
bool tryFoldParent();
int distanceOnLeftRight(Note *note, int side);
int distanceOnTopBottom(Note *note, int side);
bool convertTexts();
void debug();
/// SPEED OPTIMIZATION
public:
void finishLazyLoad();
public:
// Values are provided here as info:
// Please see Settings::setBigNotes() to know whats values are assigned.
static int NOTE_MARGIN /*= 2*/;
static int INSERTION_HEIGHT /*= 5*/;
static int EXPANDER_WIDTH /*= 9*/;
static int EXPANDER_HEIGHT /*= 9*/;
static int GROUP_WIDTH /*= 2*NOTE_MARGIN + EXPANDER_WIDTH*/;
static int HANDLE_WIDTH /*= GROUP_WIDTH*/;
static int RESIZER_WIDTH /*= GROUP_WIDTH*/;
static int TAG_ARROW_WIDTH /*= 5*/;
static int EMBLEM_SIZE /*= 16*/;
static int MIN_HEIGHT /*= 2*NOTE_MARGIN + EMBLEM_SIZE*/;
};
/*class InsertionData
{
public:
enum Type { Free = 0, NoteRelative, ColumnBottom };
Type type;
InsertionData(int _x, int _y)
: type(Free),
x(_x), y(_y),
note(0), group(false), onTop(false),
column(0)
{}
int x;
int y;
InsertionData(Note *_note, bool _group, bool _onTop)
: type(NoteRelative),
x(0), y(0),
note(_note), group(_group), onTop(_onTop),
column(0)
{}
Note *note;
bool group;
bool onTop;
InsertionData(Note *_column)
: type(NoteRelative),
x(0), y(0),
note(0), group(false), onTop(false),
column(_column)
{}
Note *column;
};*/
#endif // NOTE_H