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 #ifndef MOZC_GUI_DICTIONARY_TOOL_DICTIONARY_TOOL_H_
31 #define MOZC_GUI_DICTIONARY_TOOL_DICTIONARY_TOOL_H_
32 
33 #include <QtWidgets/QLabel>
34 #include <QtWidgets/QPushButton>
35 #include <QtWidgets/QSplitterHandle>
36 #include <QtWidgets/QSplitter>
37 
38 #include <memory>
39 #include <string>
40 #include <vector>
41 
42 #include "base/port.h"
43 #include "gui/dictionary_tool/ui_dictionary_tool.h"
44 #include "dictionary/user_dictionary_importer.h"
45 
46 namespace mozc {
47 
48 class POSListProviderInterface;
49 
50 namespace client {
51 class ClientInterface;
52 }  // namespace client
53 
54 namespace user_dictionary {
55 class UserDictionarySession;
56 }  // namespace user_dictionary
57 
58 namespace gui {
59 
60 class ImportDialog;
61 class FindDialog;
62 
63 class DictionaryTool : public QMainWindow,
64                        private Ui::DictionaryTool {
65   Q_OBJECT
66 
67  public:
68   explicit DictionaryTool(QWidget *parent = 0);
69   virtual ~DictionaryTool();
70 
71   // return true DictionaryTool is available.
IsAvailable()72   bool IsAvailable() const {
73     return is_available_;
74   }
75 
76  protected:
77   // Override the default implementation to check unsaved
78   // modifications on data before closing the window.
79   void closeEvent(QCloseEvent *event);
80 
81   bool eventFilter(QObject *obj, QEvent *event);
82 
83  private slots:
84   void CreateDictionary();
85   void DeleteDictionary();
86   void RenameDictionary();
87   void ImportAndCreateDictionary();
88   void ImportAndAppendDictionary();
89   void ImportFromDefaultIME();
90   void ExportDictionary();
91   void AddWord();
92   void DeleteWord();
93   void CloseWindow();
94   void UpdateUIStatus();
95 
96   // Signals to be connected with a particular action by the user.
97   void OnDictionarySelectionChanged();
98   void OnItemChanged(QTableWidgetItem *unused_item);
99   void OnHeaderClicked(int logicalIndex);
100   void OnDeactivate();
101 
102   // We customize the default behavior of context menu on the table
103   // widget for dictionary contents so that the menu is shown only
104   // when there is an item under the mouse cursor.
105   void OnContextMenuRequestedForContent(const QPoint &pos);
106   void OnContextMenuRequestedForList(const QPoint &pos);
107 
108  private:
109   // Data type to provide information on a dictionary.
110   struct DictionaryInfo {
111     int row;                // Row in the list widget.
112     uint64 id;              // ID of the dictionary.
113     QListWidgetItem *item;  // Item object for the dictionary.
114   };
115 
116   // Returns information on the current dictionary.
117   DictionaryInfo current_dictionary() const;
118 
119   // Save content of the current dictionary to the UserDictionaryStorage
120   void SyncToStorage();
121 
122   // Setup GUI components to edit dictionary contents for a given
123   // dictionary.
124   void SetupDicContentEditor(const DictionaryInfo &dic_info);
125 
126   // It's used internally to create a dictionary.
127   void CreateDictionaryHelper(const QString &dic_name);
128 
129   bool InitDictionaryList();
130 
131   // Show a dialog and get text for dictionary name from the user. The
132   // first parameter is default text printed in a form. The second is
133   // message printed on the dialog. It returns an empty stirng
134   // whenever a proper value for dictionary name is input.
135   QString PromptForDictionaryName(const QString &text,
136                                   const QString &label);
137 
138   // Check storage_->GetLastError() and displays an
139   // appropriate error message.
140   void ReportError();
141 
142   // These two functions are to start/stop monitoring data on the
143   // table widget being changed. We validate the value on the widget
144   // when the user edit it but the data can be modified
145   // programatically and validation is not necessary.
146   void StartMonitoringUserEdit();
147   void StopMonitoringUserEdit();
148 
149   // Show a special dialog message according to the result
150   // of UserDictionaryImporter.
151   void ReportImportError(UserDictionaryImporter::ErrorType error,
152                          const string &dic_name,
153                          int added_entries_size);
154 
155   void ImportHelper(uint64 dic_id,
156                     const string &dic_name,
157                     const string &file_name,
158                     UserDictionaryImporter::IMEType,
159                     UserDictionaryImporter::EncodingType encoding_type);
160 
161   // Save storage contents into the disk and
162   // send Reload command to the server.
163   void SaveAndReloadServer();
164 
165   // 1. Shows a dialog box and get new |commnet|.
166   // 2. Changes the comemnt of all selected.
167   void EditComment();
168 
169   // Changes the POS of all selected items to |pos|.
170   void EditPOS(const string &pos);
171 
172   // Moves selected items to the dictionary whose row is |dictionary_row|.
173   void MoveTo(int dictionary_row);
174 
175   // Helper functions to check if a file with given name is readable
176   // to import or writable to export without trying to open it.
177   static bool IsWritableToExport(const string &file_name);
178   static bool IsReadableToImport(const string &file_name);
179 
180   // Helper function for DeleteWord and MoveTo.
181   // Fills selected word entry rows as a unique sorted sequence.
182   void GetSortedSelectedRows(std::vector<int> *rows) const;
183 
184   // Returns a pointer to the first selected dictionary.
185   // Returns NULL if no dictionary is selected.
186   QListWidgetItem *GetFirstSelectedDictionary() const;
187 
188   ImportDialog *import_dialog_;
189   FindDialog   *find_dialog_;
190   std::unique_ptr<mozc::user_dictionary::UserDictionarySession> session_;
191 
192   // ID of current selected dictionary. This needs to be maintained
193   // separate from selection on the list widget because data is saved
194   // on the previous dictionary after the selection on the widget is
195   // changed. It takes -1 when no dictionary is selected.
196   uint64 current_dic_id_;
197 
198   // Whether any change has been made on the current dictionary and
199   // not been saved.
200   bool modified_;
201 
202   // Holds information on whether dictionary entires are sorted, key
203   // column of sort and order of sort.
204   //
205   // Current implementation of sort may not be perfect. It doesn't
206   // check if entries are already sorted when they are loaded nor
207   // whether modification is made keeping sorted entires sorted.
208   struct SortState {
209     bool sorted;
210     int column;
211     Qt::SortOrder order;
212   } sort_state_;
213 
214   // See comment above StartMonitoringUserEdit() for role of the
215   // variable.
216   bool monitoring_user_edit_;
217 
218   // POS shown in the combo box by default.
219   QString default_pos_;
220 
221   QString window_title_;
222 
223   // Buttons
224   QPushButton *dic_menu_button_;
225   QPushButton *new_word_button_;
226   QPushButton *delete_word_button_;
227 
228   // Menu for managing dictionary.
229   QMenu *dic_menu_;
230 
231   // Action inside menu.
232   // Sine we have to disable/enable the actions according to the
233   // numbers of active dictionary, we define them as a member.
234   QAction *new_action_;
235   QAction *rename_action_;
236   QAction *delete_action_;
237   QAction *find_action_;
238   QAction *import_create_action_;
239   QAction *import_append_action_;
240   QAction *export_action_;
241   QAction *import_default_ime_action_;
242 
243   // status message
244   QString statusbar_message_;
245 
246   std::unique_ptr<client::ClientInterface> client_;
247 
248   bool is_available_;
249 
250   // The maximum number of entries for a dictionary currently selected.
251   int max_entry_size_;
252 
253   std::unique_ptr<const POSListProviderInterface> pos_list_provider_;
254 };
255 
256 }  // namespace gui
257 }  // namespace mozc
258 
259 #endif  // MOZC_GUI_DICTIONARY_TOOL_DICTIONARY_TOOL_H_
260