OSDN Git Service

NeverNote 0.88.
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / gui / TagTreeWidget.java
1 /*\r
2  * This file is part of NeverNote \r
3  * Copyright 2009 Randy Baumgarte\r
4  * \r
5  * This file may be licensed under the terms of of the\r
6  * GNU General Public License Version 2 (the ``GPL'').\r
7  *\r
8  * Software distributed under the License is distributed\r
9  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
10  * express or implied. See the GPL for the specific language\r
11  * governing rights and limitations.\r
12  *\r
13  * You should have received a copy of the GPL along with this\r
14  * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
15  * or write to the Free Software Foundation, Inc.,\r
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
17  *\r
18 */\r
19 \r
20 package cx.fbn.nevernote.gui;\r
21 \r
22 import java.util.ArrayList;\r
23 import java.util.List;\r
24 \r
25 import com.evernote.edam.type.Tag;\r
26 import com.trolltech.qt.core.QByteArray;\r
27 import com.trolltech.qt.core.QMimeData;\r
28 import com.trolltech.qt.core.Qt;\r
29 import com.trolltech.qt.core.Qt.MatchFlag;\r
30 import com.trolltech.qt.core.Qt.MatchFlags;\r
31 import com.trolltech.qt.core.Qt.SortOrder;\r
32 import com.trolltech.qt.gui.QAbstractItemView;\r
33 import com.trolltech.qt.gui.QAction;\r
34 import com.trolltech.qt.gui.QBrush;\r
35 import com.trolltech.qt.gui.QColor;\r
36 import com.trolltech.qt.gui.QContextMenuEvent;\r
37 import com.trolltech.qt.gui.QDragEnterEvent;\r
38 import com.trolltech.qt.gui.QDragMoveEvent;\r
39 import com.trolltech.qt.gui.QHeaderView;\r
40 import com.trolltech.qt.gui.QIcon;\r
41 import com.trolltech.qt.gui.QMenu;\r
42 import com.trolltech.qt.gui.QTreeWidget;\r
43 import com.trolltech.qt.gui.QTreeWidgetItem;\r
44 \r
45 import cx.fbn.nevernote.Global;\r
46 import cx.fbn.nevernote.filters.TagCounter;\r
47 import cx.fbn.nevernote.signals.NoteSignal;\r
48 import cx.fbn.nevernote.signals.TagSignal;\r
49 import cx.fbn.nevernote.sql.DatabaseConnection;\r
50 \r
51 public class TagTreeWidget extends QTreeWidget {\r
52         private QAction editAction;\r
53         private QAction deleteAction;\r
54         private QAction addAction;\r
55         public TagSignal tagSignal;\r
56         public NoteSignal noteSignal;\r
57         private boolean showAllTags;\r
58         private final DatabaseConnection db;\r
59         \r
60         \r
61         public TagTreeWidget(DatabaseConnection d) {\r
62                 List<String> headers = new ArrayList<String>();\r
63                 if (Global.tagBehavior().equalsIgnoreCase("HideInactiveCount"))\r
64                         headers.add("Tags");\r
65                 else\r
66                         headers.add("Tags");\r
67                 headers.add("");\r
68                 showAllTags = true;\r
69                 setAcceptDrops(true);\r
70                 setDragEnabled(true);\r
71                 setColumnCount(2);\r
72                 header().setResizeMode(0, QHeaderView.ResizeMode.ResizeToContents);\r
73                 header().setResizeMode(1, QHeaderView.ResizeMode.Stretch);\r
74                 header().setMovable(false);\r
75                 db = d;\r
76                 tagSignal = new TagSignal();\r
77                 noteSignal = new NoteSignal();\r
78                 setDragDropMode(QAbstractItemView.DragDropMode.DragDrop);\r
79         setHeaderLabels(headers);\r
80         setSelectionMode(QAbstractItemView.SelectionMode.MultiSelection);\r
81         \r
82                 int width = Global.getColumnWidth("tagTreeName");\r
83                 if (width>0)\r
84                         setColumnWidth(0, width);\r
85 \r
86         }\r
87         \r
88         public void setEditAction(QAction e) {\r
89                 editAction = e;\r
90         }\r
91         public void setDeleteAction(QAction d) {\r
92                 deleteAction = d;\r
93         }\r
94         public void setAddAction(QAction a) {\r
95                 addAction = a;\r
96         }\r
97         \r
98         public void load(List<Tag> tags) {\r
99         Tag tag;\r
100         List<QTreeWidgetItem> index = new ArrayList<QTreeWidgetItem>();\r
101         QTreeWidgetItem child;\r
102                         \r
103         //Clear out the tree & reload\r
104         clear();\r
105         String iconPath = new String("classpath:cx/fbn/nevernote/icons/");\r
106                 QIcon icon = new QIcon(iconPath+"tag.png");\r
107         \r
108                 Qt.Alignment ra = new Qt.Alignment(Qt.AlignmentFlag.AlignRight);\r
109         \r
110                 // Create a copy.  We delete them out as they are found\r
111                 List<Tag> tempList = new ArrayList<Tag>();\r
112                 for (int i=0; i<tags.size(); i++) {\r
113                         tempList.add(tags.get(i));\r
114                 }\r
115                 \r
116         while (tempList.size() > 0) {\r
117                 for (int i=0; i<tempList.size(); i++) {\r
118                         tag = tempList.get(i);\r
119                         if (tag.getParentGuid()==null || tag.getParentGuid().equals("")) {\r
120                                 child = new QTreeWidgetItem();\r
121                                 child.setText(0, tag.getName());\r
122                                 child.setIcon(0,icon);\r
123                                 child.setText(2, tag.getGuid());\r
124                                 child.setTextAlignment(1, ra.value());\r
125                                 index.add(child);\r
126                                 addTopLevelItem(child);\r
127                                 tempList.remove(i);\r
128                         } else {\r
129                                 // We need to find the parent\r
130                                 for (int j=0; j<index.size(); j++) {\r
131                                         if (index.get(j).text(2).equals(tag.getParentGuid())) {\r
132                                         child = new QTreeWidgetItem();\r
133                                         child.setText(0, tag.getName());\r
134                                         child.setIcon(0, icon);\r
135                                         child.setText(2, tag.getGuid());\r
136                                         child.setTextAlignment(1, ra.value());\r
137                                         tempList.remove(i);\r
138                                         index.add(child);                                               \r
139                                         index.get(j).addChild(child);\r
140                                         }\r
141                                 }\r
142                         }\r
143                 } \r
144         }\r
145         resizeColumnToContents(0);\r
146         resizeColumnToContents(1);\r
147         sortItems(0, SortOrder.AscendingOrder);\r
148         }\r
149         // Show (unhide) all tags\r
150         public void showAllTags(boolean value) {\r
151                 showAllTags = value;\r
152         }\r
153         public void unhideAllTags() {\r
154                 MatchFlags flags = new MatchFlags();\r
155                 flags.set(MatchFlag.MatchWildcard);\r
156                 flags.set(MatchFlag.MatchRecursive);\r
157                 List <QTreeWidgetItem>  children = findItems("*", flags);\r
158                 for (int i=0; i<children.size(); i++) {\r
159                         children.get(i).setHidden(false);\r
160                 }\r
161         }\r
162         // update the display with the current number of notes\r
163         public void updateCounts(List<TagCounter> counts) {\r
164                                 \r
165                 MatchFlags flags = new MatchFlags();\r
166                 flags.set(MatchFlag.MatchWildcard);\r
167                 flags.set(MatchFlag.MatchRecursive);\r
168 //              List<QTreeWidgetItem> children = new ArrayList<QTreeWidgetItem>();\r
169                 List <QTreeWidgetItem>  children = findItems("*", flags);\r
170                 \r
171                 QBrush black = new QBrush();\r
172                 black.setColor(QColor.black);\r
173                 QBrush blue = new QBrush();\r
174                 blue.setColor(QColor.blue);\r
175                 if (!Global.tagBehavior().equalsIgnoreCase("ColorActive"))\r
176                         blue.setColor(QColor.black);\r
177                 \r
178                 for (int i=0; i<children.size(); i++) {\r
179                         children.get(i).setText(1,"0");\r
180                         children.get(i).setForeground(0, black);                        \r
181                         children.get(i).setForeground(1, black);\r
182                         if (!showAllTags && (Global.tagBehavior().equalsIgnoreCase("HideInactiveCount") || Global.tagBehavior().equalsIgnoreCase("HideInactiveNoCount")))\r
183                                 children.get(i).setHidden(true);\r
184                         else\r
185                                 children.get(i).setHidden(false);\r
186                         if (children.get(i).isSelected())\r
187                                 children.get(i).setHidden(false);\r
188                 }\r
189                 for (int i=0; i<counts.size(); i++) {\r
190                         for (int j=0; j<children.size(); j++) {\r
191                                 String guid = children.get(j).text(2);\r
192                                 if (counts.get(i).getGuid().equals(guid)) {\r
193                                         children.get(j).setText(1, new Integer(counts.get(i).getCount()).toString());\r
194                                         if (counts.get(i).getCount() > 0 || children.get(j).isSelected()) {\r
195                                                 children.get(j).setForeground(0, blue);                 \r
196                                                 children.get(j).setForeground(1, blue);\r
197                                                 QTreeWidgetItem parent = children.get(j);\r
198                                                 while (parent != null) {\r
199                                                         parent.setForeground(0, blue);                  \r
200                                                         parent.setForeground(1, blue);\r
201                                                         parent.setHidden(false);\r
202                                                         parent = parent.parent();\r
203                                                 }\r
204                                         }\r
205                                 }\r
206                         }\r
207                 }\r
208         }\r
209 \r
210         \r
211         public boolean selectGuid(String guid) {\r
212                 MatchFlags flags = new MatchFlags();\r
213                 flags.set(MatchFlag.MatchWildcard);\r
214                 flags.set(MatchFlag.MatchRecursive);\r
215 //              List<QTreeWidgetItem> children = new ArrayList<QTreeWidgetItem>();\r
216                 List <QTreeWidgetItem>  children = findItems("*", flags);\r
217 \r
218                 for (int i=0; i<children.size(); i++) {\r
219                         if (children.get(i).text(2).equals(guid)) {\r
220                                 children.get(i).setSelected(true);\r
221                                 return true;\r
222                         }\r
223                 }\r
224                 return false;\r
225         }\r
226         \r
227          @Override\r
228          protected void dragMoveEvent(QDragMoveEvent event) {\r
229                 if (event.mimeData().hasFormat("application/x-nevernote-note")) {\r
230                         if (event.answerRect().intersects(childrenRect()))\r
231                                 event.acceptProposedAction();\r
232                         return;\r
233                 }\r
234          }\r
235 \r
236         \r
237         @Override\r
238         public void dragEnterEvent(QDragEnterEvent event) {\r
239                 if (event.mimeData().hasFormat("application/x-nevernote-note")) {\r
240                         event.accept();\r
241                         return;\r
242                 }\r
243                 if (event.source() == this) {\r
244                         event.mimeData().setData("application/x-nevernote-tag", new QByteArray(currentItem().text(2)));\r
245                         event.accept();\r
246                         return;\r
247                 }\r
248                 event.ignore();\r
249         }\r
250 \r
251         @Override\r
252         public boolean dropMimeData(QTreeWidgetItem parent, int index, QMimeData data, Qt.DropAction action) {\r
253                 if (data.hasFormat("application/x-nevernote-tag")) {\r
254                         QByteArray d = data.data("application/x-nevernote-tag");\r
255                         String current = d.toString();\r
256                         \r
257                         // Check we don't do a dumb thing like move a parent to a child of itself\r
258                         if (!checkParent(parent, current))\r
259                                 return false;\r
260                         QTreeWidgetItem newChild;\r
261                         if (parent == null) {\r
262                                 tagSignal.changeParent.emit(current, "");\r
263                                 db.getTagTable().updateTagParent(current, "");\r
264                                 newChild = new QTreeWidgetItem(this);\r
265                         } else {\r
266                                 tagSignal.changeParent.emit(current, parent.text(2));\r
267                                 db.getTagTable().updateTagParent(current, parent.text(2));\r
268                                 newChild = new QTreeWidgetItem(parent);\r
269                         }\r
270                         copyTreeItem(currentItem(), newChild);\r
271                         currentItem().setHidden(true);\r
272                         sortItems(0, SortOrder.AscendingOrder);\r
273                         return true;\r
274                 }\r
275                 if (data.hasFormat("application/x-nevernote-note")) {\r
276                         QByteArray d = data.data("application/x-nevernote-note");\r
277                         String s = d.toString();\r
278                         String noteGuidArray[] = s.split(" ");\r
279                         for (String element : noteGuidArray) {\r
280                                 if (!db.getNoteTable().noteTagsTable.checkNoteNoteTags(element.trim(), parent.text(2))) {\r
281                                         db.getNoteTable().noteTagsTable.saveNoteTag(element.trim(), parent.text(2));\r
282                                         noteSignal.tagsAdded.emit(element.trim(), parent.text(2));\r
283                                 }\r
284                         }\r
285                         //tagSignal.listChanged.emit();\r
286                         \r
287                         return true;\r
288                 }\r
289                 return false;\r
290         }\r
291         \r
292         @Override\r
293         public void contextMenuEvent(QContextMenuEvent event) {\r
294                 QMenu menu = new QMenu(this);\r
295                 menu.addAction(addAction);\r
296                 menu.addAction(editAction);\r
297                 menu.addAction(deleteAction);\r
298                 menu.exec(event.globalPos());\r
299         }\r
300         \r
301         // Copy an individual item within the tree.  I need to do this because\r
302         // Qt doesn't call the dropMimeData on a move, just a copy.\r
303         private void copyTreeItem(QTreeWidgetItem source, QTreeWidgetItem target) {\r
304                 target.setText(0, source.text(0));\r
305                 target.setIcon(0, source.icon(0));\r
306                 target.setText(1, source.text(1));\r
307                 target.setText(2, source.text(2));\r
308                 Qt.Alignment ra = new Qt.Alignment(Qt.AlignmentFlag.AlignRight);\r
309                 target.setTextAlignment(1, ra.value());\r
310                 \r
311                 for (int i=0; i<source.childCount(); i++) {\r
312                         QTreeWidgetItem newChild = new QTreeWidgetItem(target);\r
313                         copyTreeItem(source.child(i), newChild);\r
314                         source.child(i).setHidden(true);\r
315                 }\r
316                 return;\r
317         }\r
318         \r
319         // Check that we don't copy a parent as a child of a current child.\r
320         private boolean checkParent(QTreeWidgetItem parent, String child) {\r
321                 if (parent != null)\r
322                         if (parent.text(2).equals(child))\r
323                                 return false;\r
324                 if (parent == null)\r
325                         return true;\r
326                 return checkParent(parent.parent(), child);\r
327         }\r
328 \r
329 \r
330         public void selectSavedSearch(QTreeWidgetItem item) {\r
331                 MatchFlags flags = new MatchFlags();\r
332                 flags.set(MatchFlag.MatchWildcard);\r
333                 flags.set(MatchFlag.MatchRecursive);\r
334                 List <QTreeWidgetItem>  children = findItems("*", flags);\r
335                 \r
336                 for (int j=0; j<children.size(); j++) {\r
337                         String guid = children.get(j).text(2);\r
338                         if (item.text(2).equals(guid)) {\r
339                                 children.get(j).setSelected(true);\r
340                         }\r
341                 }\r
342         }\r
343 }\r