2 * This file is part of NeverNote
\r
3 * Copyright 2009 Randy Baumgarte
\r
5 * This file may be licensed under the terms of of the
\r
6 * GNU General Public License Version 2 (the ``GPL'').
\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
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
20 package cx.fbn.nevernote.gui;
\r
22 import java.util.ArrayList;
\r
23 import java.util.HashMap;
\r
24 import java.util.List;
\r
26 import com.evernote.edam.type.Notebook;
\r
27 import com.trolltech.qt.core.QByteArray;
\r
28 import com.trolltech.qt.core.QMimeData;
\r
29 import com.trolltech.qt.core.Qt;
\r
30 import com.trolltech.qt.core.Qt.SortOrder;
\r
31 import com.trolltech.qt.gui.QAbstractItemView;
\r
32 import com.trolltech.qt.gui.QAction;
\r
33 import com.trolltech.qt.gui.QBrush;
\r
34 import com.trolltech.qt.gui.QColor;
\r
35 import com.trolltech.qt.gui.QContextMenuEvent;
\r
36 import com.trolltech.qt.gui.QDragEnterEvent;
\r
37 import com.trolltech.qt.gui.QDragMoveEvent;
\r
38 import com.trolltech.qt.gui.QHeaderView;
\r
39 import com.trolltech.qt.gui.QIcon;
\r
40 import com.trolltech.qt.gui.QMenu;
\r
41 import com.trolltech.qt.gui.QTreeWidget;
\r
42 import com.trolltech.qt.gui.QTreeWidgetItem;
\r
43 import com.trolltech.qt.gui.QTreeWidgetItem.ChildIndicatorPolicy;
\r
45 import cx.fbn.nevernote.Global;
\r
46 import cx.fbn.nevernote.filters.NotebookCounter;
\r
47 import cx.fbn.nevernote.signals.NoteSignal;
\r
49 public class NotebookTreeWidget extends QTreeWidget {
\r
50 private QAction deleteAction;
\r
51 private QAction addAction;
\r
52 private QAction editAction;
\r
53 private QAction iconAction;
\r
54 public NoteSignal noteSignal;
\r
55 private HashMap<String, QIcon> icons;
\r
56 private final HashMap<String, QTreeWidgetItem> stacks;
\r
57 // private final QTreeWidgetItem previousMouseOver;
\r
58 // private boolean previousMouseOverWasSelected;
\r
60 public void setAddAction(QAction a) {
\r
64 public void setDeleteAction(QAction d) {
\r
68 public void setEditAction(QAction e) {
\r
72 public void setIconAction(QAction e) {
\r
76 public NotebookTreeWidget() {
\r
77 noteSignal = new NoteSignal();
\r
78 // setProperty("hideTree", true);
\r
79 List<String> labels = new ArrayList<String>();
\r
80 labels.add("Notebooks");
\r
82 setAcceptDrops(true);
\r
83 setDragEnabled(true);
\r
85 header().setResizeMode(0, QHeaderView.ResizeMode.ResizeToContents);
\r
86 header().setResizeMode(1, QHeaderView.ResizeMode.Stretch);
\r
87 header().setMovable(false);
\r
88 setHeaderLabels(labels);
\r
89 setDragDropMode(QAbstractItemView.DragDropMode.DragDrop);
\r
90 // If we want to mimic Evernote's notebook selection
\r
91 if (Global.mimicEvernoteInterface) {
\r
92 setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection);
\r
94 setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection);
\r
96 stacks = new HashMap<String, QTreeWidgetItem>();
\r
97 // int width = Global.getColumnWidth("notebookTreeName");
\r
99 // setColumnWidth(0, width);
\r
100 // previousMouseOver = new QTreeWidgetItem();
\r
103 public void selectNotebook(QTreeWidgetItem item) {
\r
104 QTreeWidgetItem root = invisibleRootItem();
\r
105 QTreeWidgetItem child;
\r
107 for (int i=0; i<root.childCount(); i++) {
\r
108 child = root.child(i);
\r
109 if (child.text(2).equals(item.text(2))) {
\r
110 child.setSelected(true);
\r
117 public boolean selectGuid(String guid) {
\r
118 QTreeWidgetItem root = invisibleRootItem();
\r
119 QTreeWidgetItem child;
\r
121 for (int i=0; i<root.childCount(); i++) {
\r
122 child = root.child(i);
\r
123 if (child.text(2).equals(guid)) {
\r
124 child.setSelected(true);
\r
131 public void setIcons(HashMap<String, QIcon> i) {
\r
135 public QIcon findDefaultIcon(String guid, String name, List<String> localBooks, boolean isPublished) {
\r
136 String iconPath = new String("classpath:cx/fbn/nevernote/icons/");
\r
137 QIcon blueIcon = new QIcon(iconPath+"notebook-blue.png");
\r
138 QIcon greenIcon = new QIcon(iconPath+"notebook-green.png");
\r
139 QIcon redIcon = new QIcon(iconPath+"notebook-red.png");
\r
140 QIcon yellowIcon = new QIcon(iconPath+"notebook-yellow.png");
\r
142 if (localBooks.contains(guid)) {
\r
146 if (localBooks.contains(guid) &&
\r
147 (name.equalsIgnoreCase("Conflicting Changes") ||
\r
148 name.equalsIgnoreCase("Conflicting Changes (Local)")))
\r
156 public void load(List<Notebook> books, List<String> localBooks) {
\r
158 QTreeWidgetItem child;
\r
163 Qt.Alignment ra = new Qt.Alignment(Qt.AlignmentFlag.AlignRight);
\r
164 for (int i=0; i<books.size(); i++) {
\r
165 book = books.get(i);
\r
166 child = new QTreeWidgetItem();
\r
167 child.setChildIndicatorPolicy(ChildIndicatorPolicy.DontShowIndicatorWhenChildless);
\r
168 child.setText(0, book.getName());
\r
169 if (icons != null && !icons.containsKey(book.getGuid())) {
\r
170 QIcon icon = findDefaultIcon(book.getGuid(), book.getName(), localBooks, book.isPublished());
\r
171 child.setIcon(0, icon);
\r
173 child.setIcon(0, icons.get(book.getGuid()));
\r
175 child.setTextAlignment(1, ra.value());
\r
176 child.setText(2, book.getGuid());
\r
177 if (book.getStack() == null || book.getStack().equalsIgnoreCase(""))
\r
178 addTopLevelItem(child);
\r
180 String stackName = book.getStack();
\r
181 QTreeWidgetItem parent;
\r
182 if (!stacks.containsKey(stackName)) {
\r
183 String iconPath = new String("classpath:cx/fbn/nevernote/icons/");
\r
184 QIcon stackIcon = new QIcon(iconPath+"books2.png");
\r
185 parent = new QTreeWidgetItem();
\r
186 stacks.put(stackName, parent);
\r
187 parent.setText(0, stackName);
\r
188 parent.setIcon(0, stackIcon);
\r
189 parent.setText(2, "STACK");
\r
190 parent.setTextAlignment(1, ra.value());
\r
191 addTopLevelItem(parent);
\r
193 parent = stacks.get(stackName);
\r
194 parent.addChild(child);
\r
199 sortItems(0, SortOrder.AscendingOrder);
\r
200 if (Global.mimicEvernoteInterface) {
\r
201 String iconPath = new String("classpath:cx/fbn/nevernote/icons/");
\r
202 QIcon greenIcon = new QIcon(iconPath+"notebook-green.png");
\r
204 child = new QTreeWidgetItem();
\r
205 child.setIcon(0, greenIcon);
\r
206 child.setText(0, "All Notebooks");
\r
207 child.setText(2, "");
\r
208 child.setTextAlignment(1, ra.value());
\r
209 insertTopLevelItem(0,child);
\r
211 resizeColumnToContents(0);
\r
212 resizeColumnToContents(1);
\r
215 // update the display with the current number of notes
\r
216 public void updateCounts(List<Notebook> books, List<NotebookCounter> counts) {
\r
217 QTreeWidgetItem root = invisibleRootItem();
\r
218 QTreeWidgetItem child;
\r
219 HashMap<String, Integer> stackCounts = new HashMap<String, Integer>();
\r
221 QBrush blue = new QBrush();
\r
222 QBrush black = new QBrush();
\r
223 black.setColor(QColor.black);
\r
224 if (Global.tagBehavior().equalsIgnoreCase("ColorActive") && !Global.mimicEvernoteInterface)
\r
225 blue.setColor(QColor.blue);
\r
227 blue.setColor(QColor.black);
\r
231 int size = books.size();
\r
232 if (Global.mimicEvernoteInterface)
\r
235 for (int i=0; i<size; i++) {
\r
236 child = root.child(i);
\r
237 if (child != null && child.childCount() > 0) {
\r
238 int count = child.childCount();
\r
239 QTreeWidgetItem parent = child;
\r
240 int localTotal = 0;
\r
241 for (int j=0; j<count; j++) {
\r
242 child = parent.child(j);
\r
243 int childCount = updateCounts(child, books, counts, blue, black);
\r
244 total = total+childCount;
\r
245 localTotal = localTotal+childCount;
\r
247 parent.setText(1, new Integer(localTotal).toString());
\r
249 total = total+updateCounts(child, books, counts, blue, black);
\r
252 for (int i=0; i<size; i++) {
\r
253 child = root.child(i);
\r
254 if (child != null) {
\r
255 String guid = child.text(2);
\r
256 if (guid.equals("") && Global.mimicEvernoteInterface)
\r
257 child.setText(1, new Integer(total).toString());
\r
262 private int updateCounts(QTreeWidgetItem child, List<Notebook> books, List<NotebookCounter> counts, QBrush blue, QBrush black) {
\r
264 if (child != null) {
\r
265 String guid = child.text(2);
\r
266 child.setText(1,"0");
\r
267 child.setForeground(0, black);
\r
268 child.setForeground(1, black);
\r
269 for (int j=0; j<counts.size(); j++) {
\r
270 if (counts.get(j).getGuid().equals(guid)) {
\r
271 child.setText(1, new Integer(counts.get(j).getCount()).toString());
\r
272 total = counts.get(j).getCount();
\r
273 if (counts.get(j).getCount() > 0) {
\r
274 child.setForeground(0, blue);
\r
275 child.setForeground(1, blue);
\r
283 // Return a list of the notebook guids, ordered by the current display order.
\r
284 public List<String> getNotebookGuids() {
\r
285 List<String> names = new ArrayList<String>();
\r
286 QTreeWidgetItem root = invisibleRootItem();
\r
287 QTreeWidgetItem child;
\r
288 for (int i=0; i<root.childCount(); i++) {
\r
289 child = root.child(i);
\r
290 String text = child.text(2);
\r
297 public void contextMenuEvent(QContextMenuEvent event) {
\r
298 QMenu menu = new QMenu(this);
\r
299 menu.addAction(addAction);
\r
300 menu.addAction(editAction);
\r
301 menu.addAction(deleteAction);
\r
302 menu.addSeparator();
\r
303 menu.addAction(iconAction);
\r
304 menu.exec(event.globalPos());
\r
309 public void dragEnterEvent(QDragEnterEvent event) {
\r
310 if (event.mimeData().hasFormat("application/x-nevernote-note")) {
\r
318 protected void dragMoveEvent(QDragMoveEvent event) {
\r
319 // if (event.mimeData().hasFormat("text/plain") &&
\r
320 //event.answerRect().intersects(dropFrame.geometry()))
\r
321 QTreeWidgetItem treeItem = itemAt(event.pos().x(), event.pos().y());
\r
322 if (treeItem != null) {
\r
323 /* if (!previousMouseOver.text(0).equalsIgnoreCase(treeItem.text(0))) {
\r
324 previousMouseOver.setSelected(previousMouseOverWasSelected);
\r
325 previousMouseOverWasSelected = treeItem.isSelected();
\r
326 previousMouseOver = treeItem;
\r
327 blockSignals(true);
\r
328 treeItem.setSelected(true);
\r
329 blockSignals(false);
\r
333 if (event.mimeData().hasFormat("application/x-nevernote-note")) {
\r
334 if (event.answerRect().intersects(childrenRect()))
\r
335 event.acceptProposedAction();
\r
342 public boolean dropMimeData(QTreeWidgetItem parent, int index, QMimeData data, Qt.DropAction action) {
\r
343 if (data.hasFormat("application/x-nevernote-note")) {
\r
344 QByteArray d = data.data("application/x-nevernote-note");
\r
345 String s = d.toString();
\r
346 String noteGuidArray[] = s.split(" ");
\r
347 for (String element : noteGuidArray) {
\r
348 if (!parent.text(0).equalsIgnoreCase("All Notebooks"))
\r
349 noteSignal.notebookChanged.emit(element.trim(), parent.text(2));
\r