OSDN Git Service

キーワード検索時に検索範囲を設定できるようにした
authoryuki <kimaira7@gmail.com>
Tue, 17 Dec 2013 09:35:00 +0000 (18:35 +0900)
committeryuki <kimaira7@gmail.com>
Tue, 17 Dec 2013 09:35:00 +0000 (18:35 +0900)
src/cx/fbn/nevernote/NeverNote.java
src/cx/fbn/nevernote/gui/SearchClearButton.java
src/cx/fbn/nevernote/gui/SearchEdit.java
src/cx/fbn/nevernote/icons/searchTarget.png [new file with mode: 0644]

index cec0514..4c8a78b 100644 (file)
@@ -1638,6 +1638,8 @@ public class NeverNote extends QMainWindow{
                
        List<QTreeWidgetItem> selections = notebookTree.selectedItems();
        selectedNotebookGUIDs.clear();
+       searchField.setTargetNotebook("");
+       searchField.setTargetStack("");
                String guid = "";
                String stackName = "";
                if (selections.size() > 0) {
@@ -1658,14 +1660,17 @@ public class NeverNote extends QMainWindow{
                        }
                }
        if (!guid.equals("") && !guid.equals("STACK")) {
-               selectedNotebookGUIDs.add(guid);
+               selectedNotebookGUIDs.add(stackName);
+               searchField.setTargetNotebook(guid);
                menuBar.notebookIconAction.setEnabled(true);
-       } else {
+       } else {        // スタック選択
+               searchField.setTargetStack(guid);
                menuBar.notebookIconAction.setEnabled(true);
                        for (int j=0; j<listManager.getNotebookIndex().size(); j++) {
                                Notebook book = listManager.getNotebookIndex().get(j);
-                               if (book.getStack() != null && book.getStack().equalsIgnoreCase(stackName))
+                               if (book.getStack() != null && book.getStack().equalsIgnoreCase(stackName)) {
                                        selectedNotebookGUIDs.add(book.getGuid());
+                               }
                        }
        }
        listManager.setSelectedNotebooks(selectedNotebookGUIDs);
@@ -1696,6 +1701,8 @@ public class NeverNote extends QMainWindow{
        menuBar.notebookEditAction.setEnabled(false);
        menuBar.notebookDeleteAction.setEnabled(false);
        selectedNotebookGUIDs.clear();
+       searchField.setTargetNotebook("");
+       searchField.setTargetStack("");
        listManager.setSelectedNotebooks(selectedNotebookGUIDs);
        notebookTree.blockSignals(false);
     }
@@ -1725,8 +1732,11 @@ public class NeverNote extends QMainWindow{
        notebookTree.load(books, listManager.getLocalNotebooks());
        for (int i=selectedNotebookGUIDs.size()-1; i>=0; i--) {
                boolean found = notebookTree.selectGuid(selectedNotebookGUIDs.get(i));
-               if (!found)
+               if (!found) {
                        selectedNotebookGUIDs.remove(i);
+                       searchField.setTargetNotebook("");
+                       searchField.setTargetStack("");
+               }
        }
        listManager.refreshCounters = true;
        listManager.refreshCounters();
@@ -2410,9 +2420,11 @@ public class NeverNote extends QMainWindow{
        List<QTreeWidgetItem> selections = tagTree.selectedItems();
        QTreeWidgetItem currentSelection;
        selectedTagGUIDs.clear();
+       searchField.getTargetTags().clear();
        for (int i=0; i<selections.size(); i++) {
                currentSelection = selections.get(i);
                selectedTagGUIDs.add(currentSelection.text(2));
+               searchField.addTargetTag(currentSelection.text(2));
        }
        if (selections.size() > 0) {
                menuBar.tagEditAction.setEnabled(true);
@@ -2456,8 +2468,10 @@ public class NeverNote extends QMainWindow{
 
        for (int i=selectedTagGUIDs.size()-1; i>=0; i--) {
                boolean found = tagTree.selectGuid(selectedTagGUIDs.get(i));
-               if (!found)
+               if (!found) {
                        selectedTagGUIDs.remove(i);
+                       searchField.getTargetTags().remove(i);
+               }
        }
        tagTree.blockSignals(false);
        
@@ -2585,6 +2599,7 @@ public class NeverNote extends QMainWindow{
                menuBar.tagDeleteAction.setEnabled(false);
                menuBar.tagIconAction.setEnabled(false);
                selectedTagGUIDs.clear();
+               searchField.getTargetTags().clear();
        listManager.setSelectedTags(selectedTagGUIDs);
        tagTree.blockSignals(false);
        }
@@ -3113,7 +3128,7 @@ public class NeverNote extends QMainWindow{
                QWebSettings.setMaximumPagesInCache(0);
                QWebSettings.setObjectCacheCapacities(0, 0, 0);
         
-               searchField.setdefaultText();
+               searchField.setDefaultText();
                saveNoteColumnPositions();
                saveNoteIndexWidth();
                noteIndexUpdated(true);
@@ -3159,8 +3174,8 @@ public class NeverNote extends QMainWindow{
        inkNoteCache.clear();
        saveNoteColumnPositions();
        saveNoteIndexWidth();
-       String text = searchField.text();
-       listManager.setEnSearch(text.trim());
+       String query = searchField.getSearchQuery();
+       listManager.setEnSearch(query.trim());
        listManager.loadNotesIndex();
        noteIndexUpdated(false);
 
@@ -3286,7 +3301,7 @@ public class NeverNote extends QMainWindow{
        toolBar.addWidget(spacerWidget);
        spacerWidget.setVisible(true);
        
-        searchField = new SearchEdit(iconPath);
+        searchField = new SearchEdit(iconPath, conn);
         searchField.setObjectName("searchField");
        searchField.returnPressed.connect(this, "searchFieldChanged()");
        searchField.textChanged.connect(this,"searchFieldTextChanged(String)");
index 243a15e..ccefe57 100644 (file)
@@ -1,3 +1,22 @@
+/*
+ * This file is part of NeighborNote
+ * Copyright 2013 Yuki Takahashi
+ * 
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+*/
+
 package cx.fbn.nevernote.gui;
 
 import com.trolltech.qt.core.QEvent;
index 081da74..419d884 100644 (file)
+/*
+ * This file is part of NeighborNote
+ * Copyright 2013 Yuki Takahashi
+ * 
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+*/
+
 package cx.fbn.nevernote.gui;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import com.trolltech.qt.core.QPoint;
 import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.core.Qt;
+import com.trolltech.qt.gui.QAction;
+import com.trolltech.qt.gui.QActionGroup;
+import com.trolltech.qt.gui.QCursor;
 import com.trolltech.qt.gui.QFocusEvent;
+import com.trolltech.qt.gui.QIcon;
 import com.trolltech.qt.gui.QLineEdit;
+import com.trolltech.qt.gui.QMenu;
+import com.trolltech.qt.gui.QPixmap;
 import com.trolltech.qt.gui.QResizeEvent;
 import com.trolltech.qt.gui.QStyle.PixelMetric;
+import com.trolltech.qt.gui.QToolButton;
+
+import cx.fbn.nevernote.sql.DatabaseConnection;
 
 public class SearchEdit extends QLineEdit {
        private final SearchClearButton clearButton;
+       private final QToolButton targetButton;
        private final String inactiveColor;
        private final String activeColor;
-       private final String defaultText;
+       private String defaultText;
+       private final QMenu targetMenu;
+       private final QAction allNotesAction;
+       private final QAction currentContextAction;
+       private String targetStackName;
+       private String targetNotebookGuid;
+       private final List<String> targetTagGuids;
+       private final DatabaseConnection conn;
+       
+       public enum SearchTarget {AllNotes, CurrentContext};
 
        
-       public SearchEdit(String iconPath) {
+       public SearchEdit(String iconPath, DatabaseConnection conn) {
+               this.conn = conn;
+               
                inactiveColor = new String("QLineEdit {color: gray; font:italic;} ");
                activeColor = new String("QLineEdit {color: black; font:normal;} ");
                
+               targetStackName = new String("");
+               targetNotebookGuid = new String("");
+               targetTagGuids = new ArrayList<String>();
+               
                this.clearButton = new SearchClearButton(this, iconPath);
                this.clearButton.clicked.connect(this, "clear()");
                
-               this.textChanged.connect(this, "updateClearButton(String)");
+               this.targetButton = new QToolButton(this);
+               QPixmap targetIcon = new QPixmap(iconPath + "searchTarget.png");
+               this.targetButton.setIcon(new QIcon(targetIcon));
+               this.targetButton.setIconSize(new QSize(24, 16));
+               this.targetButton.setCursor(new QCursor(Qt.CursorShape.ArrowCursor));
+               this.targetButton.setStyleSheet("QToolButton { background-color: #ffffff; padding: 0px; }");
+               this.targetButton.hide();
+               this.targetButton.clicked.connect(this, "targetButtonClicked()");
+               
                int frameWidth = this.style().pixelMetric(PixelMetric.PM_DefaultFrameWidth);
                this.setStyleSheet("QLineEdit { padding-right: " + (clearButton.sizeHint().width() + frameWidth + 1) + "px; } ");
-               defaultText = new String(tr("Search"));
-               this.setText(defaultText);
-               this.setStyleSheet(inactiveColor);
+               this.textChanged.connect(this, "updateClearButton(String)");
+               
+               // 検索対象切り替えメニュー
+               targetMenu = new QMenu(this);
+               QActionGroup targetGroup = new QActionGroup(this);
+               targetGroup.setExclusive(true);
+               allNotesAction = addContextAction(tr("Search All Notes"));
+               targetGroup.addAction(allNotesAction);
+               targetMenu.addAction(allNotesAction);
+               currentContextAction = addContextAction(tr("Search Current Context"));
+               targetGroup.addAction(currentContextAction);
+               targetMenu.addAction(currentContextAction);
+               targetGroup.triggered.connect(this, "toggleSearchTarget(QAction)");
+               
+               // 初期状態として「すべてのノートを検索」を選択
+               allNotesAction.setChecked(true);
+               toggleSearchTarget(allNotesAction);
+       }
+       
+       private void toggleSearchTarget(QAction action) {
+               if (action == allNotesAction) {
+                       defaultText = new String(tr("Search All Notes"));
+               } else if (action == currentContextAction) {
+                       defaultText = new String(tr("Search Current Context"));
+               }
+       setDefaultText();
+       this.clearFocus();
+       }
+       
+       public SearchTarget currentSearchTarget() {
+               if (allNotesAction.isChecked()) {
+                       return SearchTarget.AllNotes;
+               } else if (currentContextAction.isChecked()) {
+                       return SearchTarget.CurrentContext;
+               }
+               
+               return SearchTarget.AllNotes;   // デフォルト
        }
        
        @Override
        protected void resizeEvent(QResizeEvent event) {
-               QSize sz = clearButton.sizeHint();
-               int frameWidth = this.style().pixelMetric(PixelMetric.PM_DefaultFrameWidth);
-               clearButton.move(this.rect().right() - frameWidth - sz.width(), (this.rect().bottom() + 1 - sz.height()) / 2);
+               int frameWidth = style().pixelMetric(PixelMetric.PM_DefaultFrameWidth);
+               
+               QSize clearSize = clearButton.sizeHint();
+               clearButton.move(rect().right() - frameWidth - clearSize.width(), (rect().bottom() + 1 - clearSize.height()) / 2);
+               
+               setTextMargins(targetButton.sizeHint().width(), 0, clearSize.width() + frameWidth, 0);
+               targetButton.setFixedHeight(rect().bottom() + 1);
+               targetButton.move(0,0);
+               targetButton.setVisible(true);
        }
        
        @SuppressWarnings("unused")
@@ -40,18 +137,22 @@ public class SearchEdit extends QLineEdit {
                clearButton.setVisible(!text.isEmpty());
        }
        
-       public void setdefaultText() {
-               this.setText(defaultText);
-               this.setStyleSheet(inactiveColor);
+       public void setDefaultText() {
+               if (text().trim().equals("")) {
+                       blockSignals(true);
+                       setText(defaultText);
+                       setStyleSheet(inactiveColor);
+                       blockSignals(false);
+               }
        }
        
        @Override
        protected void focusInEvent(QFocusEvent event) {
                super.focusInEvent(event);
-               if (this.text().equals(defaultText)) {
-                       this.blockSignals(true);
-                       this.setText("");
-                       this.blockSignals(false);
+               if (text().equals(defaultText)) {
+                       blockSignals(true);
+                       setText("");
+                       blockSignals(false);
                }
                this.setStyleSheet(activeColor);
        }
@@ -59,11 +160,81 @@ public class SearchEdit extends QLineEdit {
        @Override
        protected void focusOutEvent(QFocusEvent event) {
                super.focusOutEvent(event);
-               if (this.text().trim().equals("")) {
-                       this.blockSignals(true);
-                       this.setText(defaultText);
-                       this.blockSignals(false);
-                       this.setStyleSheet(inactiveColor);
+               if (text().trim().equals("")) {
+                       blockSignals(true);
+                       setText(defaultText);
+                       blockSignals(false);
+                       setStyleSheet(inactiveColor);
                }
        }
+       
+       @SuppressWarnings("unused")
+       private void targetButtonClicked() {
+               QPoint globalPos = this.mapToGlobal(new QPoint(0, 0));
+               targetMenu.popup(new QPoint(globalPos.x(), globalPos.y() + rect().bottom() + 1));
+       }
+       
+    private QAction addContextAction(String name) {
+       QAction newAction = new QAction(this);
+               newAction.setText(name);
+               newAction.setCheckable(true);
+               return newAction;
+    }
+    
+    public String getSearchQuery() {
+       if (currentSearchTarget() == SearchTarget.AllNotes) {
+               return this.text();
+       } else if (currentSearchTarget() == SearchTarget.CurrentContext) {
+               return appendSearchQuery();
+       }
+       
+       return this.text();
+    }
+    
+       private String appendSearchQuery() {
+               StringBuilder query = new StringBuilder();
+               
+       String stack = getTargetStack();
+       if (!stack.trim().equals("")) {
+               query.append("stack:" + stack.trim() + " ");
+       }
+       String notebook = getTargetNotebook();
+       if (!notebook.trim().equals("")) {
+               String notebookName = conn.getNotebookTable().getNotebook(notebook).getName();
+               query.append("notebook:" + notebookName + " ");
+       }
+       for (String tag: getTargetTags()) {
+               if (!tag.trim().equals("")) {
+                       String tagName = conn.getTagTable().getTag(tag).getName();
+                       query.append("tag:" + tagName + " ");
+               }
+       }
+       query.append(this.text());
+       
+       return new String(query);
+    }
+
+       public String getTargetStack() {
+               return targetStackName;
+       }
+       
+       public void setTargetStack(String targetStack) {
+               this.targetStackName = new String(targetStack);
+       }
+
+       public String getTargetNotebook() {
+               return targetNotebookGuid;
+       }
+       
+       public void setTargetNotebook(String targetNotebook) {
+               this.targetNotebookGuid = new String(targetNotebook);
+       }
+
+       public List<String> getTargetTags() {
+               return targetTagGuids;
+       }
+       
+       public void addTargetTag(String targetTag) {
+               this.targetTagGuids.add(targetTag);
+       }
 }
diff --git a/src/cx/fbn/nevernote/icons/searchTarget.png b/src/cx/fbn/nevernote/icons/searchTarget.png
new file mode 100644 (file)
index 0000000..715fc38
Binary files /dev/null and b/src/cx/fbn/nevernote/icons/searchTarget.png differ