OSDN Git Service

Altered note table to use a display delegate to show dates rather than convert the...
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / gui / TableView.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 package cx.fbn.nevernote.gui;\r
20 \r
21 import java.util.List;\r
22 import java.util.SortedMap;\r
23 \r
24 import com.evernote.edam.type.Note;\r
25 import com.trolltech.qt.core.QByteArray;\r
26 import com.trolltech.qt.core.QModelIndex;\r
27 import com.trolltech.qt.core.Qt;\r
28 import com.trolltech.qt.core.Qt.SortOrder;\r
29 import com.trolltech.qt.gui.QAbstractItemView;\r
30 import com.trolltech.qt.gui.QAction;\r
31 import com.trolltech.qt.gui.QApplication;\r
32 import com.trolltech.qt.gui.QColor;\r
33 import com.trolltech.qt.gui.QContextMenuEvent;\r
34 import com.trolltech.qt.gui.QDragEnterEvent;\r
35 import com.trolltech.qt.gui.QDropEvent;\r
36 import com.trolltech.qt.gui.QFontMetrics;\r
37 import com.trolltech.qt.gui.QHeaderView;\r
38 import com.trolltech.qt.gui.QKeyEvent;\r
39 import com.trolltech.qt.gui.QKeySequence.StandardKey;\r
40 import com.trolltech.qt.gui.QMenu;\r
41 import com.trolltech.qt.gui.QTableView;\r
42 \r
43 import cx.fbn.nevernote.Global;\r
44 import cx.fbn.nevernote.filters.NoteSortFilterProxyModel;\r
45 import cx.fbn.nevernote.signals.NoteSignal;\r
46 import cx.fbn.nevernote.utilities.ApplicationLogger;\r
47 import cx.fbn.nevernote.utilities.ListManager;\r
48 \r
49 public class TableView extends QTableView {\r
50         private final ListManager                               runner;\r
51         private final ApplicationLogger         logger;\r
52     public NoteSortFilterProxyModel     proxyModel;             // note sort model\r
53     private QAction deleteAction;\r
54     private QAction addAction;\r
55     private QAction restoreAction;\r
56     private QAction noteHistoryAction;\r
57     private QAction duplicateAction;\r
58     private QAction     mergeNotesAction;\r
59     \r
60     // Note title colors\r
61     private QAction     noteTitleColorWhite;\r
62     private QAction     noteTitleColorRed;\r
63     private QAction     noteTitleColorBlue;\r
64     private QAction     noteTitleColorGreen;\r
65     private QAction     noteTitleColorYellow;\r
66     private QAction     noteTitleColorBlack;\r
67     private QAction     noteTitleColorGray;\r
68     private QAction     noteTitleColorCyan;\r
69     private QAction     noteTitleColorMagenta;\r
70 \r
71 \r
72     \r
73     public QHeaderView header;\r
74     int fontHeight;\r
75     public Signal1<String> rowChanged;\r
76     public Signal0      resetViewport;\r
77     public NoteSignal noteSignal;\r
78         \r
79         public TableView(ApplicationLogger l, ListManager m) {\r
80                 logger = l;\r
81                 header = horizontalHeader();\r
82                 header.setMovable(true);\r
83                 \r
84                 noteSignal = new NoteSignal();\r
85                 setAcceptDrops(true);\r
86                 setDragEnabled(true);\r
87                 setDragDropMode(QAbstractItemView.DragDropMode.DragDrop);\r
88                 setDropIndicatorShown(false);\r
89                 \r
90                 runner = m;     \r
91                 \r
92         runner.getNoteTableModel().setHeaderData(Global.noteTableCreationPosition, Qt.Orientation.Horizontal, tr("Date Created"), Qt.ItemDataRole.DisplayRole);\r
93         runner.getNoteTableModel().setHeaderData(Global.noteTableTagPosition, Qt.Orientation.Horizontal, tr("Tags"), Qt.ItemDataRole.DisplayRole);\r
94         runner.getNoteTableModel().setHeaderData(Global.noteTableGuidPosition, Qt.Orientation.Horizontal, tr("Guid"), Qt.ItemDataRole.DisplayRole);\r
95         runner.getNoteTableModel().setHeaderData(Global.noteTableNotebookPosition, Qt.Orientation.Horizontal, tr("Notebook"), Qt.ItemDataRole.DisplayRole);\r
96         runner.getNoteTableModel().setHeaderData(Global.noteTableTitlePosition, Qt.Orientation.Horizontal, tr("Title"), Qt.ItemDataRole.DisplayRole);\r
97         runner.getNoteTableModel().setHeaderData(Global.noteTableChangedPosition, Qt.Orientation.Horizontal, tr("Date Changed"), Qt.ItemDataRole.DisplayRole);\r
98         runner.getNoteTableModel().setHeaderData(Global.noteTableAuthorPosition, Qt.Orientation.Horizontal, tr("Author"), Qt.ItemDataRole.DisplayRole);\r
99         runner.getNoteTableModel().setHeaderData(Global.noteTableSourceUrlPosition, Qt.Orientation.Horizontal, tr("Source Url"), Qt.ItemDataRole.DisplayRole);\r
100         runner.getNoteTableModel().setHeaderData(Global.noteTableSubjectDatePosition, Qt.Orientation.Horizontal, tr("Subject Date"), Qt.ItemDataRole.DisplayRole);\r
101         runner.getNoteTableModel().setHeaderData(Global.noteTableSynchronizedPosition, Qt.Orientation.Horizontal, tr("Synchronized"), Qt.ItemDataRole.DisplayRole);\r
102         header.sortIndicatorChanged.connect(this, "resetViewport()");\r
103        \r
104         proxyModel = new NoteSortFilterProxyModel(this);\r
105         proxyModel.setSourceModel(runner.getNoteTableModel());\r
106         setAlternatingRowColors(false);\r
107         setModel(proxyModel);\r
108 //        setModel(runner.getNoteTableModel());\r
109         runner.getNoteTableModel().setSortProxyModel(proxyModel);\r
110                \r
111         setSortingEnabled(true);\r
112         int sortCol = proxyModel.sortColumn();\r
113                 SortOrder sortOrder = proxyModel.sortOrder();\r
114                 sortByColumn(sortCol, sortOrder);\r
115 \r
116                 setSelectionBehavior(SelectionBehavior.SelectRows);\r
117                 setSelectionMode(SelectionMode.SingleSelection);\r
118                 verticalHeader().setVisible(false);\r
119                 hideColumn(Global.noteTableGuidPosition);  // Hide the guid column\r
120                 setShowGrid(false);\r
121                 setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers);\r
122                 \r
123                 QFontMetrics f = QApplication.fontMetrics();\r
124                 fontHeight = f.height();\r
125                 rowChanged = new Signal1<String>();\r
126                 resetViewport = new Signal0();\r
127                 \r
128                 NoteTableDateDelegate dateDelegate = new NoteTableDateDelegate();\r
129                 setItemDelegateForColumn(Global.noteTableCreationPosition, dateDelegate);\r
130                 setItemDelegateForColumn(Global.noteTableChangedPosition, dateDelegate);\r
131                 setItemDelegateForColumn(Global.noteTableSubjectDatePosition, dateDelegate);\r
132                 \r
133         }\r
134         \r
135         // This should rescroll to the current item in the list when a column is \r
136         // sorted.  Somehow I can't get this to work, but this part is correct.\r
137         @SuppressWarnings("unused")\r
138         private void resetViewport() {\r
139 //              if (currentIndex() == null) \r
140 //                      return;\r
141                 \r
142 //              resetViewport.emit();\r
143         }\r
144         \r
145                 \r
146         public void load(boolean reload) {\r
147                 proxyModel.clear();\r
148                 setSortingEnabled(false);\r
149                 QFontMetrics f = QApplication.fontMetrics();\r
150                 verticalHeader().setDefaultSectionSize(f.height());\r
151                 for (int i=0; i<runner.getNoteIndex().size(); i++) {\r
152                         if (Global.showDeleted == true && !runner.getNoteIndex().get(i).isActive())\r
153                                 proxyModel.addGuid(runner.getNoteIndex().get(i).getGuid());\r
154                         if (!Global.showDeleted == true && runner.getNoteIndex().get(i).isActive())                     \r
155                                 proxyModel.addGuid(runner.getNoteIndex().get(i).getGuid());\r
156                 }\r
157 \r
158                 if (!reload) {\r
159                         logger.log(logger.EXTREME, "TableView.load() reload starting.");\r
160                         proxyModel.filter();\r
161                         setSortingEnabled(true);\r
162                         logger.log(logger.EXTREME, "TableView.load() leaving reload.");\r
163                         return;\r
164                 }\r
165                 logger.log(logger.EXTREME, "TableView.load() Filling table data from scratch");\r
166         \r
167                 for (int i=0; i<runner.getMasterNoteIndex().size(); i++) {\r
168                         if (runner.getMasterNoteIndex().get(i) != null) {       \r
169                                 insertRow(runner.getMasterNoteIndex().get(i), false, i);                                                        \r
170                         }\r
171                 } \r
172                 proxyModel.invalidate();\r
173                 \r
174                 int width;\r
175                 width = Global.getColumnWidth("noteTableCreationPosition");\r
176                 if (width>0) setColumnWidth(Global.noteTableCreationPosition, width);\r
177                 width = Global.getColumnWidth("noteTableChangedPosition");\r
178                 if (width>0) setColumnWidth(Global.noteTableChangedPosition, width);\r
179                 width = Global.getColumnWidth("noteTableTitlePosition");\r
180                 if (width>0) setColumnWidth(Global.noteTableTitlePosition, width);\r
181                 width = Global.getColumnWidth("noteTableTagPosition");\r
182                 if (width>0) setColumnWidth(Global.noteTableTagPosition, width);\r
183                 width = Global.getColumnWidth("noteTableGuidPosition");\r
184                 if (width>0) setColumnWidth(Global.noteTableGuidPosition, width);\r
185                 width = Global.getColumnWidth("noteTableNotebookPosition");\r
186                 if (width>0) setColumnWidth(Global.noteTableNotebookPosition, width);\r
187                 width = Global.getColumnWidth("noteTableSourceUrlPosition");\r
188                 if (width>0) setColumnWidth(Global.noteTableSourceUrlPosition, width);\r
189                 width = Global.getColumnWidth("noteTableAuthorPosition");\r
190                 if (width>0) setColumnWidth(Global.noteTableAuthorPosition, width);\r
191                 width = Global.getColumnWidth("noteTableSubjectDatePosition");\r
192                 if (width>0) setColumnWidth(Global.noteTableSubjectDatePosition, width);\r
193                 width = Global.getColumnWidth("noteTableSynchronizedPosition");\r
194                 if (width>0) setColumnWidth(Global.noteTableSynchronizedPosition, width);\r
195                 \r
196                 int from = header.visualIndex(Global.noteTableCreationPosition);\r
197                 int to = Global.getColumnPosition("noteTableCreationPosition");\r
198                 if (to>=0) header.moveSection(from, to);\r
199 \r
200                 from = header.visualIndex(Global.noteTableTitlePosition);\r
201                 to = Global.getColumnPosition("noteTableTitlePosition");\r
202                 if (to>=0) header.moveSection(from, to);\r
203                 \r
204                 from = header.visualIndex(Global.noteTableTagPosition);\r
205                 to = Global.getColumnPosition("noteTableTagPosition");\r
206                 if (to>=0) header.moveSection(from, to);\r
207                 \r
208                 from = header.visualIndex(Global.noteTableNotebookPosition);\r
209                 to = Global.getColumnPosition("noteTableNotebookPosition");\r
210                 if (to>=0) header.moveSection(from, to);\r
211                 \r
212                 from = header.visualIndex(Global.noteTableChangedPosition);\r
213                 to = Global.getColumnPosition("noteTableChangedPosition");\r
214                 if (to>=0) header.moveSection(from, to);\r
215                 \r
216                 from = header.visualIndex(Global.noteTableSourceUrlPosition);\r
217                 to = Global.getColumnPosition("noteTableSourceUrlPosition");\r
218                 if (to>=0) header.moveSection(from, to);\r
219                 \r
220                 from = header.visualIndex(Global.noteTableAuthorPosition);\r
221                 to = Global.getColumnPosition("noteTableAuthorPosition");\r
222                 if (to>=0) header.moveSection(from, to);\r
223                 \r
224                 from = header.visualIndex(Global.noteTableSubjectDatePosition);\r
225                 to = Global.getColumnPosition("noteTableSubjectDatePosition");\r
226                 if (to>=0) header.moveSection(from, to);\r
227                 \r
228                 from = header.visualIndex(Global.noteTableSynchronizedPosition);\r
229                 to = Global.getColumnPosition("noteTableSynchronizedPosition");\r
230                 if (to>=0) header.moveSection(from, to);\r
231 \r
232                 proxyModel.filter();\r
233                 \r
234                 setSortingEnabled(true);\r
235                 resetViewport.emit();\r
236         }\r
237 \r
238         public void insertRow(Note tempNote, boolean newNote, int row) {\r
239                 if (newNote)\r
240                         proxyModel.addGuid(tempNote.getGuid());\r
241                 \r
242                 if (row > runner.getNoteTableModel().rowCount())\r
243                         runner.getNoteTableModel().insertRow(0);\r
244                 \r
245                 if (row < 0) {\r
246                         row  = runner.getNoteTableModel().rowCount();\r
247                         runner.getNoteTableModel().insertRow(row);\r
248                 }\r
249                 \r
250                 if (newNote) {\r
251                         QFontMetrics f = QApplication.fontMetrics();\r
252                         fontHeight = f.height();\r
253                         for (int i=0; i<runner.getNoteTableModel().rowCount(); i++)\r
254                                 setRowHeight(i, fontHeight);\r
255                 }\r
256         }\r
257         protected boolean filterAcceptsRow(int sourceRow, QModelIndex sourceParent) {\r
258                 return true;\r
259         }\r
260 \r
261         public void setAddAction(QAction a) {\r
262                 addAction = a;\r
263         }\r
264         \r
265         public void setMergeNotesAction(QAction a) {\r
266                 mergeNotesAction = a;\r
267         }\r
268         \r
269         public void setNoteHistoryAction(QAction a) {\r
270                 noteHistoryAction = a;\r
271         }\r
272         \r
273         public void setDeleteAction(QAction d) {\r
274                 deleteAction = d;\r
275         }\r
276          \r
277         public void setRestoreAction(QAction r) {\r
278                 restoreAction = r;\r
279         }\r
280         public void setNoteDuplicateAction(QAction d) {\r
281                 duplicateAction = d;\r
282         }\r
283         \r
284         @Override\r
285         public void keyPressEvent(QKeyEvent e) {\r
286                 if (e.matches(StandardKey.MoveToStartOfDocument)) {\r
287                         if (runner.getNoteTableModel().rowCount() > 0) {\r
288                                 clearSelection();\r
289                                 selectRow(0);\r
290                         }\r
291                 }\r
292                 if (e.matches(StandardKey.MoveToEndOfDocument)) {\r
293                         if (runner.getNoteTableModel().rowCount() > 0) {\r
294                                 clearSelection();\r
295                                 selectRow(model().rowCount()-1);\r
296                         }\r
297                 }\r
298                 super.keyPressEvent(e);\r
299         }\r
300         \r
301         @Override\r
302         public void contextMenuEvent(QContextMenuEvent event) {\r
303                 QMenu menu = new QMenu(this);\r
304                 if (Global.showDeleted) {\r
305                         menu.addAction(restoreAction);\r
306                 } else {\r
307                         menu.addAction(addAction);\r
308                 }\r
309                 menu.addAction(deleteAction);\r
310                 menu.addSeparator();\r
311                 menu.addAction(duplicateAction);\r
312                 menu.addAction(noteHistoryAction);\r
313                 menu.addAction(mergeNotesAction);\r
314                 \r
315                 QMenu titleColorMenu = new QMenu();\r
316                 titleColorMenu.setTitle("Title Color");\r
317                 menu.addMenu(titleColorMenu);\r
318                 noteTitleColorWhite = new QAction(titleColorMenu);\r
319             noteTitleColorRed = new QAction(titleColorMenu);\r
320             noteTitleColorBlue = new QAction(titleColorMenu);\r
321             noteTitleColorGreen = new QAction(titleColorMenu);\r
322             noteTitleColorYellow = new QAction(titleColorMenu);\r
323             noteTitleColorBlack = new QAction(titleColorMenu);\r
324             noteTitleColorGray = new QAction(titleColorMenu);\r
325             noteTitleColorCyan = new QAction(titleColorMenu);\r
326             noteTitleColorMagenta = new QAction(titleColorMenu);\r
327     \r
328             noteTitleColorWhite.setText(tr("White"));\r
329             noteTitleColorRed.setText(tr("Red"));\r
330             noteTitleColorBlue.setText(tr("Blue"));\r
331             noteTitleColorGreen.setText(tr("Green"));\r
332             noteTitleColorYellow.setText(tr("Yellow"));\r
333             noteTitleColorBlack.setText(tr("Black"));\r
334             noteTitleColorGray.setText(tr("Gray"));\r
335             noteTitleColorCyan.setText(tr("Cyan"));\r
336             noteTitleColorMagenta.setText(tr("Magenta"));\r
337             \r
338             titleColorMenu.addAction(noteTitleColorWhite);\r
339             titleColorMenu.addAction(noteTitleColorRed);\r
340             titleColorMenu.addAction(noteTitleColorBlue);\r
341             titleColorMenu.addAction(noteTitleColorGreen);\r
342             titleColorMenu.addAction(noteTitleColorYellow);\r
343             titleColorMenu.addAction(noteTitleColorBlack);\r
344             titleColorMenu.addAction(noteTitleColorGray);\r
345             titleColorMenu.addAction(noteTitleColorCyan);\r
346             titleColorMenu.addAction(noteTitleColorMagenta);\r
347             \r
348             noteTitleColorWhite.triggered.connect(this, "titleColorWhite()");\r
349             \r
350             noteTitleColorWhite.triggered.connect(this, "titleColorWhite()");\r
351             noteTitleColorRed.triggered.connect(this, "titleColorRed()");\r
352             noteTitleColorBlue.triggered.connect(this, "titleColorBlue()");\r
353             noteTitleColorGreen.triggered.connect(this, "titleColorGreen()");\r
354             noteTitleColorYellow.triggered.connect(this, "titleColorYellow()");\r
355             noteTitleColorBlack.triggered.connect(this, "titleColorBlack()");\r
356             noteTitleColorGray.triggered.connect(this, "titleColorGray()");\r
357             noteTitleColorCyan.triggered.connect(this, "titleColorCyan()");\r
358             noteTitleColorMagenta.triggered.connect(this, "titleColorMagenta()");\r
359             \r
360                 menu.exec(event.globalPos());\r
361         }\r
362         \r
363         \r
364     @SuppressWarnings("unused")\r
365         private void titleColorWhite() {noteSignal.titleColorChanged.emit(QColor.white.rgb());}\r
366     @SuppressWarnings("unused")\r
367         private void titleColorRed() {noteSignal.titleColorChanged.emit(QColor.red.rgb());}\r
368     @SuppressWarnings("unused")\r
369         private void titleColorBlue() {noteSignal.titleColorChanged.emit(QColor.blue.rgb());}\r
370     @SuppressWarnings("unused")\r
371         private void titleColorGreen() {noteSignal.titleColorChanged.emit(QColor.green.rgb());}\r
372     @SuppressWarnings("unused")\r
373         private void titleColorYellow(){noteSignal.titleColorChanged.emit(QColor.yellow.rgb());}\r
374     @SuppressWarnings("unused")\r
375         private void titleColorBlack() {noteSignal.titleColorChanged.emit(QColor.black.rgb());}\r
376     @SuppressWarnings("unused")\r
377         private void titleColorGray() {noteSignal.titleColorChanged.emit(QColor.gray.rgb());}\r
378     @SuppressWarnings("unused")\r
379         private void titleColorCyan() {noteSignal.titleColorChanged.emit(QColor.cyan.rgb());}\r
380     @SuppressWarnings("unused")\r
381         private void titleColorMagenta() {noteSignal.titleColorChanged.emit(QColor.magenta.rgb());}\r
382         \r
383         \r
384 \r
385         @Override\r
386         public void dragEnterEvent(QDragEnterEvent event) {\r
387                 StringBuffer guid = new StringBuffer(1000);\r
388                 \r
389                 showColumn(Global.noteTableGuidPosition);\r
390                 List<QModelIndex> selections = selectionModel().selectedRows();\r
391                 hideColumn(Global.noteTableGuidPosition);\r
392                 \r
393         if (selections.size() > 0) {\r
394                 QModelIndex index;\r
395                 for (int i=0; i<selections.size(); i++) {\r
396                         int row = selections.get(i).row();\r
397                         index = proxyModel.index(row, Global.noteTableGuidPosition);\r
398                         SortedMap<Integer, Object> ix = proxyModel.itemData(index);\r
399                         guid.append((String)ix.values().toArray()[0]);\r
400                         guid.append(" ");\r
401                 }\r
402         }\r
403                 event.mimeData().setData("application/x-nevernote-note", new QByteArray(guid.toString()));\r
404                 event.accept();\r
405                                 \r
406         }\r
407         \r
408         @Override\r
409         public void dropEvent(QDropEvent event) {\r
410                 if (event.source() == this)\r
411                         event.ignore();\r
412         }\r
413         \r
414         // Return a column width\r
415         public int getColumnWidth(int col) {\r
416                 return columnWidth(col);\r
417         }\r
418 \r
419 /*\r
420     @Override\r
421         public void scrollTo(final QModelIndex index, ScrollHint hint) {\r
422         QRect area = viewport().rect();\r
423         QRect rect = visualRect(index);\r
424 \r
425         if (rect.top() < area.top())\r
426             verticalScrollBar().setValue(\r
427                 verticalScrollBar().value() + rect.top() - area.top());\r
428         else if (rect.bottom() > area.bottom())\r
429             verticalScrollBar().setValue(\r
430                 verticalScrollBar().value() + Math.min(\r
431                     rect.bottom() - area.bottom(), rect.top() - area.top()));\r
432         update();\r
433     }\r
434     \r
435     @Override\r
436         protected void updateGeometries() {\r
437         verticalScrollBar().setPageStep(viewport().height());\r
438         verticalScrollBar().setRange(0, Math.max(0, viewport().height()));\r
439     }\r
440     @Override\r
441     protected int verticalOffset() {\r
442         return verticalScrollBar().value();\r
443     }\r
444 */\r
445 }\r