goldendict-ng/src/ui/favoritespanewidget.hh

315 lines
8 KiB
C++

/* This file is (c) 2017 Abs62
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#ifndef __FAVORITIESPANEWIDGET_HH__INCLUDED__
#define __FAVORITIESPANEWIDGET_HH__INCLUDED__
#include <QWidget>
#include <QSize>
#include <QAbstractItemModel>
#include <QLabel>
#include <QHBoxLayout>
#include <QMenu>
#include <QDomNode>
#include <QList>
#include <QMimeData>
#include <QItemSelection>
#include <QTreeView>
#include <config.hh>
#include "delegate.hh"
class FavoritesModel;
class FavoritesPaneWidget: public QWidget
{
Q_OBJECT
public:
FavoritesPaneWidget( QWidget * parent = 0 ):
QWidget( parent ),
itemSelectionChanged( false ),
listItemDelegate( 0 ),
m_favoritesModel( 0 ),
timerId( 0 )
{
}
virtual ~FavoritesPaneWidget();
virtual QSize sizeHint() const
{
return QSize( 204, 204 );
}
void setUp( Config::Class * cfg, QMenu * menu );
void addHeadword( QString const & path, QString const & headword );
bool removeHeadword( QString const & path, QString const & headword );
// Export/import Favorites
void getDataInXml( QByteArray & dataStr );
void getDataInPlainText( QString & dataStr );
bool setDataFromXml( QString const & dataStr );
bool setDataFromTxt( QString const & dataStr );
void setFocusOnTree()
{
m_favoritesTree->setFocus();
}
// Set interval for periodical save
void setSaveInterval( unsigned interval );
// Return true if headwors is already presented in Favorites
bool isHeadwordPresent( QString const & path, QString const & headword );
void saveData();
signals:
void favoritesItemRequested( QString const & word, QString const & faforitesFolder );
protected:
virtual void timerEvent( QTimerEvent * ev );
private slots:
void emitFavoritesItemRequested( QModelIndex const & );
void onSelectionChanged( const QItemSelection & selected, const QItemSelection & deselected );
void onItemClicked( QModelIndex const & idx );
void showCustomMenu( QPoint const & pos );
void deleteSelectedItems();
void copySelectedItems();
void addFolder();
private:
virtual bool eventFilter( QObject *, QEvent * );
Config::Class * m_cfg;
QTreeView * m_favoritesTree;
QMenu * m_favoritesMenu;
QAction * m_deleteSelectedAction;
QAction * m_separator;
QAction * m_copySelectedToClipboard;
QAction * m_addFolder;
QWidget favoritesPaneTitleBar;
QHBoxLayout favoritesPaneTitleBarLayout;
QLabel favoritesLabel;
/// needed to avoid multiple notifications
/// when selecting items via mouse and keyboard
bool itemSelectionChanged;
WordListItemDelegate * listItemDelegate;
FavoritesModel * m_favoritesModel;
int timerId;
};
class TreeItem
{
public:
enum Type {
Word,
Folder,
Root
};
explicit TreeItem( const QVariant & data, TreeItem * parent = 0, Type type_ = Word );
~TreeItem();
void appendChild( TreeItem * child );
void insertChild( int row, TreeItem * item );
// Remove child from list and delete it
void deleteChild( int row );
TreeItem * child( int row ) const;
int childCount() const;
QVariant data() const;
void setData( const QVariant & newData );
int row() const;
TreeItem * parent();
Type type() const
{
return m_type;
}
Qt::ItemFlags flags() const;
void setExpanded( bool expanded )
{
m_expanded = expanded;
}
bool isExpanded() const
{
return m_expanded;
}
// Full path from root folder
QString fullPath() const;
// Duplicate item with all childs
TreeItem * duplicateItem( TreeItem * newParent ) const;
// Check if item is ancestor of this element
bool haveAncestor( TreeItem * item );
// Check if same item already presented between childs
bool haveSameItem( TreeItem * item, bool allowSelf );
// Retrieve text from all childs
QStringList getTextFromAllChilds() const;
private:
QList< TreeItem * > childItems;
QVariant itemData;
TreeItem * parentItem;
Type m_type;
bool m_expanded;
};
class FavoritesModel: public QAbstractItemModel
{
Q_OBJECT
public:
explicit FavoritesModel( QString favoritesFilename, QObject * parent = 0 );
~FavoritesModel();
QVariant data( const QModelIndex & index, int role ) const;
Qt::ItemFlags flags( const QModelIndex & index ) const;
QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
QModelIndex index( int row, int column, const QModelIndex & parent = QModelIndex() ) const;
QModelIndex parent( const QModelIndex & index ) const;
int rowCount( const QModelIndex & parent = QModelIndex() ) const;
int columnCount( const QModelIndex & parent = QModelIndex() ) const;
bool removeRows( int row, int count, const QModelIndex & parent );
bool setData( const QModelIndex & index, const QVariant & value, int role );
// Drag & drop support
Qt::DropActions supportedDropActions() const;
QStringList mimeTypes() const;
QMimeData * mimeData( const QModelIndexList & indexes ) const;
bool dropMimeData( const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & par );
// Restore nodes expanded state after data loading
void checkNodeForExpand( const TreeItem * item, const QModelIndex & parent );
void checkAllNodesForExpand();
// Retrieve text data for indexes
QStringList getTextForIndexes( QModelIndexList const & idxList ) const;
// Delete items for indexes
void removeItemsForIndexes( QModelIndexList const & idxList );
// Add new folder beside item and return its index
// or empty index if fail
QModelIndex addNewFolder( QModelIndex const & idx );
// Add new headword to given folder
// return false if it already exists there
bool addNewHeadword( QString const & path, QString const & headword );
// Remove headword from given folder
// return false if failed
bool removeHeadword( QString const & path, QString const & headword );
// Return true if headwors is already presented in Favorites
bool isHeadwordPresent( QString const & path, QString const & headword );
// Return path in the tree to item
QString pathToItem( QModelIndex const & idx );
TreeItem::Type itemType( QModelIndex const & idx )
{
return getItem( idx )->type();
}
// Export/import Favorites
void getDataInXml( QByteArray & dataStr );
void getDataInPlainText( QString & dataStr );
bool setDataFromXml( QString const & dataStr );
bool setDataFromTxt( QString const & dataStr );
void saveData();
public slots:
void itemCollapsed( const QModelIndex & index );
void itemExpanded( const QModelIndex & index );
signals:
void expandItem( const QModelIndex & index );
protected:
void readData();
void addFolder( TreeItem * parent, QDomNode & node );
void storeFolder( TreeItem * folder, QDomNode & node );
// Find item in folder
QModelIndex findItemInFolder( QString const & itemName, int itemType, QModelIndex const & parentIdx );
TreeItem * getItem( const QModelIndex & index ) const;
// Find folder with given name or create it if folder not exist
QModelIndex forceFolder( QString const & name, QModelIndex const & parentIdx );
// Add headword to given folder
// return false if such headwordalready exists
bool addHeadword( QString const & word, QModelIndex const & parentIdx );
// Return tree level for item
int level( QModelIndex const & idx );
private:
QString m_favoritesFilename;
TreeItem * rootItem;
QDomDocument dom;
bool dirty;
};
#define FAVORITES_MIME_TYPE "application/x-goldendict-tree-items"
class FavoritesMimeData: public QMimeData
{
Q_OBJECT
public:
FavoritesMimeData():
QMimeData()
{
}
virtual QStringList formats() const
{
return QStringList( QString::fromLatin1( FAVORITES_MIME_TYPE ) );
}
virtual bool hasFormat( const QString & mimetype ) const
{
return mimetype.compare( QString::fromLatin1( FAVORITES_MIME_TYPE ) ) == 0;
}
void setIndexesList( QModelIndexList const & list )
{
indexes.clear();
indexes = list;
}
QModelIndexList const & getIndexesList() const
{
return indexes;
}
private:
QStringList mimeFormats;
QModelIndexList indexes;
};
#endif // __FAVORITIESPANEWIDGET_HH__INCLUDED__