1 /* This file is (c) 2008-2012 Konstantin Isakov <ikm@goldendict.org>
2  * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
3 
4 #ifndef __GROUPS_WIDGETS_HH_INCLUDED__
5 #define __GROUPS_WIDGETS_HH_INCLUDED__
6 
7 // Various custom widgets used in the Groups dialog
8 
9 #include <vector>
10 
11 #include <QAction>
12 #include <QListWidget>
13 #include <QSortFilterProxyModel>
14 
15 #include "config.hh"
16 #include "dictionary.hh"
17 #include "extlineedit.hh"
18 
19 /// A model to be projected into the view, according to Qt's MVC model
20 class DictListModel: public QAbstractListModel
21 {
22   Q_OBJECT
23 
24 public:
25 
DictListModel(QWidget * parent)26   DictListModel( QWidget * parent ):
27     QAbstractListModel( parent ), isSource( false ), allDicts( 0 )
28   {}
29 
30   /// Populates the current model with the given dictionaries. This is
31   /// ought to be part of construction process.
32   void populate( std::vector< sptr< Dictionary::Class > > const & active,
33                  std::vector< sptr< Dictionary::Class > > const & available );
34   void populate( std::vector< sptr< Dictionary::Class > > const & active );
35 
36   /// Marks that this model is used as an immutable dictionary source
37   void setAsSource();
sourceModel() const38   bool sourceModel() const { return isSource; }
39 
40   /// Returns the dictionaries the model currently has listed
41   std::vector< sptr< Dictionary::Class > > const & getCurrentDictionaries() const;
42 
43   void removeSelectedRows( QItemSelectionModel * source );
44   void addSelectedUniqueFromModel( QItemSelectionModel * source );
45 
46   Qt::ItemFlags flags( QModelIndex const &index ) const;
47   int rowCount( QModelIndex const & parent ) const;
48   QVariant data( QModelIndex const & index, int role ) const;
49   bool insertRows( int row, int count, const QModelIndex & parent );
50   bool removeRows( int row, int count, const QModelIndex & parent );
51   bool setData( QModelIndex const & index, const QVariant & value, int role );
52 
53   void addRow(const QModelIndex & parent, sptr< Dictionary::Class > dict);
54 
55   Qt::DropActions supportedDropActions() const;
56 
57   void filterDuplicates();
58 
59 private:
60 
61   bool isSource;
62   std::vector< sptr< Dictionary::Class > > dictionaries;
63   std::vector< sptr< Dictionary::Class > > const * allDicts;
64 
65 signals:
66   void contentChanged();
67 };
68 
69 /// This widget is for dictionaries' lists, it handles drag-n-drop operations
70 /// with them etc.
71 class DictListWidget: public QListView
72 {
73   Q_OBJECT
74 public:
75   DictListWidget( QWidget * parent );
76   ~DictListWidget();
77 
78   /// Populates the current list with the given dictionaries.
79   void populate( std::vector< sptr< Dictionary::Class > > const & active,
80                  std::vector< sptr< Dictionary::Class > > const & available );
81   void populate( std::vector< sptr< Dictionary::Class > > const & active );
82 
83   /// Marks that this widget is used as an immutable dictionary source
84   void setAsSource();
85 
86   /// Returns the dictionaries the widget currently has listed
87   std::vector< sptr< Dictionary::Class > > const & getCurrentDictionaries() const;
88 
getModel()89   DictListModel * getModel()
90   { return & model; }
91 
92 signals:
93   void gotFocus();
94 
95 protected:
96   virtual void dropEvent( QDropEvent * event );
97   virtual void focusInEvent(QFocusEvent *);
98 
99   // We need these to to handle drag-and-drop focus issues
100   virtual void rowsInserted( QModelIndex const & parent, int start, int end );
101   virtual void rowsAboutToBeRemoved( QModelIndex const & parent, int start, int end );
102 
103 private:
104   DictListModel model;
105 };
106 
107 #include "ui_dictgroupwidget.h"
108 
109 /// A widget that is placed into each tab in the Groups dialog.
110 class DictGroupWidget: public QWidget
111 {
112   Q_OBJECT
113 
114 public:
115   DictGroupWidget( QWidget * parent,
116                    std::vector< sptr< Dictionary::Class > > const &,
117                    Config::Group const & );
118 
119   /// Makes the group's configuration out of the data currently held.
120   /// Since the group's name is not part of the widget by design right now
121   /// (it is known by the containing tab widget only), it is returned as empty.
122   Config::Group makeGroup() const;
123 
getModel() const124   DictListModel * getModel() const
125   { return ui.dictionaries->getModel(); }
126 
getSelectionModel() const127   QItemSelectionModel * getSelectionModel() const
128   { return ui.dictionaries->selectionModel(); }
129 
130 private slots:
131 
132   void groupIconActivated( int );
133   void showDictInfo( const QPoint & pos );
134   void removeCurrentItem( QModelIndex const & );
135 
136 private:
137   Ui::DictGroupWidget ui;
138   unsigned groupId;
139 
140 signals:
141   void showDictionaryInfo( QString const & id );
142 };
143 
144 /// A tab widget with groups inside
145 class DictGroupsWidget: public QTabWidget
146 {
147   Q_OBJECT
148 
149 public:
150 
151   DictGroupsWidget( QWidget * parent );
152 
153   /// Creates all the tabs with the groups
154   void populate( Config::Groups const &,
155                  std::vector< sptr< Dictionary::Class > > const & allDicts,
156                  std::vector< sptr< Dictionary::Class > > const & activeDicts );
157 
158   /// Creates new empty group with the given name
159   void addNewGroup( QString const & );
160 
161   /// Creates new empty group with the given name if no such group
162   /// and return it index
163   int addUniqueGroup( QString const & name );
164 
165   void addAutoGroups();
166 
167   /// Returns currently chosen group's name
168   QString getCurrentGroupName() const;
169 
170   /// Changes the name of the currently chosen group, if any, to the given one
171   void renameCurrentGroup( QString const & );
172 
173   /// Removes the currently chosen group, if any
174   void removeCurrentGroup();
175 
176   /// Removes all the groups
177   void removeAllGroups();
178 
179   /// Creates groups from what is currently set up
180   Config::Groups makeGroups() const;
181 
182   DictListModel * getCurrentModel() const;
183 
184   QItemSelectionModel * getCurrentSelectionModel() const;
185 
186 private:
187 
188   /// Add source group to target group
189   void combineGroups( int source, int target );
190 
191   unsigned nextId;
192   std::vector< sptr< Dictionary::Class > > const * allDicts;
193   std::vector< sptr< Dictionary::Class > > const * activeDicts;
194 
195 private slots:
196   void contextMenu( QPoint const & );
197   void tabDataChanged();
198 
199 signals:
200   void showDictionaryInfo( QString const & id );
201 };
202 
203 class QuickFilterLine: public ExtLineEdit
204 {
205   Q_OBJECT
206 
207 public:
208 
209   QuickFilterLine( QWidget * parent );
210   ~QuickFilterLine();
211 
212   /// Sets the source view to filter
213   void applyTo( QAbstractItemView * source );
214 
getFocusAction()215   QAction * getFocusAction() { return & m_focusAction; }
216 
217   QModelIndex mapToSource( QModelIndex const & idx );
218 
219 protected:
220   virtual void keyPressEvent( QKeyEvent * event );
221 
222 private:
223   QSortFilterProxyModel m_proxyModel;
224   QAction m_focusAction;
225   QAbstractItemView * m_source;
226 
227 private slots:
228   void filterChangedInternal();
229   void emitFilterChanged();
230   void focusFilterLine();
231 
232 signals:
233   void filterChanged(QString const & filter);
234 
235 
236 };
237 
238 #endif
239