/***************************************************************************
* 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