1 // Copyright 2010-2018, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 #include "gui/config_dialog/keybinding_editor_delegate.h"
31 
32 #include <QtGui/QtGui>
33 #include <QtWidgets/QPushButton>
34 
35 #include <memory>
36 
37 #include "base/logging.h"
38 #include "gui/config_dialog/keybinding_editor.h"
39 
40 namespace mozc {
41 namespace gui {
42 
43 class KeyBindingEditorTriggerButton : public QPushButton {
44  public:
KeyBindingEditorTriggerButton(QWidget * parent)45   KeyBindingEditorTriggerButton(QWidget *parent) :
46       QPushButton(parent),
47       editor_(new KeyBindingEditor(parent, this)) {
48     editor_->setModal(true);   // create a modal dialog
49     setFocusProxy(editor_.get());
50     connect(this, SIGNAL(clicked()),
51             editor_.get(), SLOT(show()));
52   }
53 
mutable_editor()54   KeyBindingEditor *mutable_editor() {
55     return editor_.get();
56   }
57 
58  private:
59   std::unique_ptr<KeyBindingEditor> editor_;
60 };
61 
KeyBindingEditorDelegate(QObject * parent)62 KeyBindingEditorDelegate::KeyBindingEditorDelegate(QObject *parent)
63     : QItemDelegate(parent) {}
64 
~KeyBindingEditorDelegate()65 KeyBindingEditorDelegate::~KeyBindingEditorDelegate() {}
66 
createEditor(QWidget * parent,const QStyleOptionViewItem & option,const QModelIndex & index) const67 QWidget *KeyBindingEditorDelegate::createEditor(
68     QWidget *parent,
69     const QStyleOptionViewItem &option,
70     const QModelIndex &index) const {
71   KeyBindingEditorTriggerButton *button
72       = new KeyBindingEditorTriggerButton(parent);
73   CHECK(button);
74   connect(button->mutable_editor(), SIGNAL(accepted()),
75           this, SLOT(CommitAndCloseEditor()));
76   connect(button->mutable_editor(), SIGNAL(rejected()),
77           this, SLOT(CloseEditor()));
78   return button;
79 }
80 
setEditorData(QWidget * editor,const QModelIndex & index) const81 void KeyBindingEditorDelegate::setEditorData(
82     QWidget *editor,
83     const QModelIndex &index) const {
84   const QString str = index.model()->data(index, Qt::EditRole).toString();
85   KeyBindingEditorTriggerButton *button
86       = static_cast<KeyBindingEditorTriggerButton *>(editor);
87   if (button == NULL) {
88     return;
89   }
90   button->setText(str);
91   button->mutable_editor()->SetBinding(str);
92 }
93 
setModelData(QWidget * editor,QAbstractItemModel * model,const QModelIndex & index) const94 void KeyBindingEditorDelegate::setModelData(
95     QWidget *editor, QAbstractItemModel *model,
96     const QModelIndex &index) const {
97   KeyBindingEditorTriggerButton *button
98       = static_cast<KeyBindingEditorTriggerButton *>(editor);
99   if (model == NULL || button == NULL) {
100     return;
101   }
102   model->setData(index,
103                  button->mutable_editor()->GetBinding(),
104                  Qt::EditRole);
105 }
106 
updateEditorGeometry(QWidget * editor,const QStyleOptionViewItem & option,const QModelIndex & index) const107 void KeyBindingEditorDelegate::updateEditorGeometry(
108     QWidget *editor,
109     const QStyleOptionViewItem &option,
110     const QModelIndex &index) const {
111   if (editor == NULL) {
112     return;
113   }
114   editor->setGeometry(option.rect);
115 }
116 
CommitAndCloseEditor()117 void KeyBindingEditorDelegate::CommitAndCloseEditor() {
118   KeyBindingEditor *editor = qobject_cast<KeyBindingEditor *>(sender());
119   KeyBindingEditorTriggerButton *button =
120       static_cast<KeyBindingEditorTriggerButton *>(
121           editor->mutable_trigger_parent());
122   if (button == NULL) {
123     return;
124   }
125   emit commitData(button);
126   emit closeEditor(button);
127 }
128 
CloseEditor()129 void KeyBindingEditorDelegate::CloseEditor() {
130   KeyBindingEditor *editor = qobject_cast<KeyBindingEditor *>(sender());
131   KeyBindingEditorTriggerButton *button =
132       static_cast<KeyBindingEditorTriggerButton *>(
133           editor->mutable_trigger_parent());
134   if (button == NULL) {
135     return;
136   }
137   emit closeEditor(button);
138 }
139 }  // namespace gui
140 }  // namespace mozc
141