/* * 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.Global; 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 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, 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.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; } "); 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)"); // 検索対象を初期状態をiniファイルから取得して設定 final SearchTarget target = Global.searchTarget(); if (target == SearchTarget.AllNotes) { allNotesAction.setChecked(true); toggleSearchTarget(allNotesAction); } else if (target == SearchTarget.CurrentContext) { currentContextAction.setChecked(true); toggleSearchTarget(currentContextAction); } } private void toggleSearchTarget(QAction action) { if (action == allNotesAction) { defaultText = new String(tr("Search All Notes")); Global.setSearchTarget(SearchTarget.AllNotes); } else if (action == currentContextAction) { defaultText = new String(tr("Search Current Context")); Global.setSearchTarget(SearchTarget.CurrentContext); } 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) { 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") private void updateClearButton(String text) { clearButton.setVisible(!text.isEmpty()); } 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 (text().equals(defaultText)) { blockSignals(true); setText(""); blockSignals(false); } this.setStyleSheet(activeColor); } @Override protected void focusOutEvent(QFocusEvent event) { super.focusOutEvent(event); 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); } }