File: utilities.h

package info (click to toggle)
mysql-workbench 6.3.8%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 113,932 kB
  • ctags: 87,814
  • sloc: ansic: 955,521; cpp: 427,465; python: 59,728; yacc: 59,129; xml: 54,204; sql: 7,091; objc: 965; makefile: 638; sh: 613; java: 237; perl: 30; ruby: 6; php: 1
file content (365 lines) | stat: -rw-r--r-- 16,147 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
/* 
 * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of the
 * License.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301  USA
 */

#pragma once

/**
 * Implementation some miscellaneous stuff needed in mforms.
 */

#include <mforms/base.h>
#include <boost/function.hpp>

#include "cairo/cairo.h"

#ifdef __GNUC__
#define WARN_UNUSED_RETURN_VALUE __attribute__((warn_unused_result))
#else
#define WARN_UNUSED_RETURN_VALUE
#endif

namespace mforms {
  // Constants for special folders on a system.
  enum MFORMS_EXPORT FolderType {
    Documents,          //!<< The path to the user's documents folder.
    Desktop,            //!<< The physical path to the user's desktop.
    ApplicationData,    //!<< Path to folder to store application specifc data for a user.

    // Platform specific folders.
    WinProgramFiles,    //!<< Windows only, 64 bit applications.
    WinProgramFilesX86, //!<< Windows only, 32 bit applications.

    ApplicationSettings //!<< Full path to App specific folder inside ApplicationData where config files and others are kept
  };

  enum MFORMS_EXPORT PasswordStoreScheme
  {
    SessionStorePasswordScheme = 1,
    PersistentStorePasswordScheme = 2
  };

  /**
   * Flags which describe which modifier key was pressed during a event.
   */
  enum ModifierKey {
    ModifierNoModifier =      0,
    ModifierControl    = 1 << 0,
    ModifierShift      = 1 << 1,
    ModifierCommand    = 1 << 2, // Command on Mac, Windows key on Windows.
    ModifierAlt        = 1 << 3,
  };

#ifndef SWIG
  inline ModifierKey operator| (ModifierKey a, ModifierKey b)
  {
    return (ModifierKey) ((int) a | (int) b);
  }
#endif

  enum DialogResult {
    ResultOk     =  1,
    ResultCancel =  0,
    ResultOther  = -1,
    ResultUnknown = -2
  };

  // Describes the type of message, confirmation etc. we want to show to the user.
  enum DialogType
  {
    DialogMessage,
    DialogError,
    DialogWarning,
    DialogQuery,
    DialogSuccess, // Like DialogMessage but with a special icon to signal a successful operation.
  };
  
  class Box;
  class Button;

  typedef int TimeoutHandle;

#ifndef DOXYGEN_SHOULD_SKIP_THIS
#ifndef SWIG
  struct MFORMS_EXPORT UtilitiesImplPtrs
  {
    void (*beep) ();
    int (*show_message)(const std::string &title, const std::string &text,
                        const std::string &ok, const std::string &cancel,
                        const std::string &other);
    int (*show_error)(const std::string &title, const std::string &text,
                      const std::string &ok, const std::string &cancel,
                      const std::string &other);
    int (*show_warning)(const std::string &title, const std::string &text,
                        const std::string &ok, const std::string &cancel,
                        const std::string &other);
    int (*show_message_with_checkbox)(const std::string &title, const std::string &text,
                                      const std::string &ok, const std::string &cancel,
                                      const std::string &other,
                                      const std::string &checkbox_text, // empty text = default "Don't show this message again" text
                                      bool &remember_checked);

    void (*show_wait_message)(const std::string &title, const std::string &text);
    bool (*hide_wait_message)();
    bool (*run_cancelable_wait_message)(const std::string &title, const std::string &text,
                                                  const boost::function<void ()> &start_task, const boost::function<bool ()> &cancel_task);
    void (*stop_cancelable_wait_message)();
    
    void (*set_clipboard_text)(const std::string &text);
    std::string (*get_clipboard_text)();
    std::string (*get_special_folder)(mforms::FolderType type);
    
    void (*open_url)(const std::string &url);
    void (*reveal_file)(const std::string &url);
    bool (*move_to_trash)(const std::string &path);
    
    TimeoutHandle (*add_timeout)(float delay, const boost::function<bool ()> &callback);
    void (*cancel_timeout)(TimeoutHandle handle);

    void (*store_password)(const std::string &service, const std::string &account, const std::string &password);
    bool (*find_password)(const std::string &service, const std::string &account, std::string &password);
    void (*forget_password)(const std::string &service, const std::string &account);

    void* (*perform_from_main_thread)(const boost::function<void* ()> &slot, bool wait_completion);
    void (*set_thread_name)(const std::string &name);

    double (*get_text_width)(const std::string &text, const std::string &font);
  };
#endif
#endif

    /** Various Utility functions */
  class MFORMS_EXPORT Utilities
  {
#ifdef SWIG
%ignore show_message(const std::string &title, const std::string &text, const std::string &ok, const std::string &cancel);
%ignore show_message(const std::string &title, const std::string &text, const std::string &ok);
%ignore show_warning(const std::string &title, const std::string &text, const std::string &ok, const std::string &cancel);
%ignore show_warning(const std::string &title, const std::string &text, const std::string &ok);
%ignore show_error(const std::string &title, const std::string &text, const std::string &ok, const std::string &cancel);
%ignore show_error(const std::string &title, const std::string &text, const std::string &ok);
#endif
  public:
    /** Plays the system's default error sound. */
    static void beep(); // TODO: Mac, Linux

    /** Show a message dialog. Return value is from the DialogResult enum.
     * In Python, all arguments are mandatory. */
    static int show_message(const std::string &title, const std::string &text,
                            const std::string &ok, const std::string &cancel = "",
                            const std::string &other = "");

    /** Show an error dialog. Return value is from the DialogResult enum.
     * In Python, all arguments are mandatory. */
    static int show_error(const std::string &title, const std::string &text,
                            const std::string &ok, const std::string &cancel="",
                            const std::string &other="");

    /** Show a warning dialog. Return value is from the DialogResult enum.
     * In Python, all arguments are mandatory. */
    static int show_warning(const std::string &title, const std::string &text,
                            const std::string &ok, const std::string &cancel="",
                            const std::string &other="");

    /** Show a message dialog and save the answer, if the checkbox is enabled.
     * In Python, all arguments are mandatory. */
    static int show_message_and_remember(const std::string &title, const std::string &text,
                                         const std::string &ok, const std::string &cancel,
                                         const std::string &other,
                                         const std::string &answer_id, const std::string &checkbox_text);
    static void forget_message_answers();
    static void set_message_answers_storage_path(const std::string &path);

    static void show_wait_message(const std::string &title, const std::string &text);
    static bool hide_wait_message();
    
    static bool run_cancelable_task(const std::string &title, const std::string &text,
                                    const boost::function<void* ()> &task,
                                    const boost::function<bool ()> &cancel_task,
                                    void *&task_result);

    /** Asks the user to enter a string, which is returned to the caller.
     * @param title - the title of the input dialog
     * @param description - description of the value to enter.
     * @param default_value - an initial value for the edit control
     * @param ret_value - the string the user entered, can be empty or the default string too
     *
     * @return true if user presses ok or false if its canceled.
     */
    static bool request_input(const std::string &title, const std::string &description,
      const std::string &default_value, std::string &ret_value);

    /** Prompts the user for a password and whether it should be stored.
     * @param title - the title of the password dialog
     * @param service - the service the password refers to (ie sudo@hostname, Mysql@hostname etc)
     * @param username - the username the password corresponds to, if empty the user will be able to enter it
     * @param ret_password - the password the user typed
     * @param ret_store - true if the user clicks in "Store Password" checkbox
     * 
     * @return true if user presses ok or false if its canceled.
     * In Python, ret_password and ret_store are returned as a tuple.
     */
    static bool ask_for_password_check_store(const std::string &title, const std::string &service,
      std::string &username /*in/out*/, std::string &ret_password /*out*/, bool &ret_store /*out*/);

    /** Prompts the user for a password.
     * @param title - the title of the password dialog
     * @param service - the service the password refers to (ie sudo@hostname, Mysql@hostname etc)
     * @param username - the username the password corresponds to
     * @param ret_password - the password the user typed
     * 
     * @return true if user presses ok or false if its canceled.
     * If you need the username to be editable by the user, use credentials_for_service()
     * In Python, ret_password is returned by the function.
     */
    static bool ask_for_password(const std::string &title, const std::string &service, const std::string &username,
                                 std::string &ret_password /*out*/);

    /** Tries to find a previously stored password and prompts the user if not found.
     * @param title - the title of the password dialog
     * @param service - the service the password refers to (ie sudo@hostname, Mysql@hostname etc)
     * @param username - the username the password corresponds to, if empty the user will be able to enter it
     * @param reset_password - whether the password should be reset without looking for a stored one
     * @param ret_password - the password the user typed
     *
     * @return true if user presses ok or false if its canceled.
     * In Python, ret_password and ret_store are returned as a tuple.
     */
    static bool find_or_ask_for_password(const std::string &title, const std::string &service, const std::string &username,
                                         bool reset_password, std::string &ret_password /*out*/)
    {
      std::string tmp(username);
      return credentials_for_service(title, service, tmp, reset_password, ret_password);
    }

#ifndef SWIG
    /**
     * Function similar to ask_for_password, but it also allows to enter a user name if none is given on call.
     */
    static bool credentials_for_service(const std::string &title, const std::string &service, std::string &username /*in/out*/,
                                         bool reset_password, std::string &ret_password /*out*/);
#endif

    /** Store the password for the given service and account.
     * @li In Windows, an encrypted Vault file is used.
     * @li In Mac, the secure KeyChain is used.
     * @li In Linux, the gnome-keychain is used, unless it's not available (such as in KDE).
     * In that case, passwords will be forgotten when the application exits.
     */
    static void store_password(const std::string &service, const std::string &account, const std::string &password);

    /** Locates the password for the given service and account. 
     * @return true if password was found else false.
     */
    static bool find_password(const std::string &service, const std::string &account, std::string &ret_password);
    
    /** Locates the password for the given service and account in the in-memory cache only.
     * @return true if password was found else false.
     */
    static bool find_cached_password(const std::string &service, const std::string &account, std::string &ret_password);

    /** Clears the stored password for the given service and account from in-memory cache only
     */
    static void forget_cached_password(const std::string &service, const std::string &account);

    /** Clears the stored password for the given service and account */
    static void forget_password(const std::string &service, const std::string &account);
    
    /** Sets the given text to the system clipboard */
    static void set_clipboard_text(const std::string &text);
    /** Gets the text stored in the system clipboard */
    static std::string get_clipboard_text();

    /** Gets the path of the requested special folder: documents, desktop etc. */
    static std::string get_special_folder(FolderType type);

    /** Opens the given URL in the default system browser. */
    static void open_url(const std::string &url);
    
    /** Moves the given file or folder to the trash. The file might be permanently
     deleted instead of being moved to trash, under some circumstances. */
    static bool move_to_trash(const std::string &path);

    /** Shows the given file path in the OS Finder/Explorer */
    static void reveal_file(const std::string &path);

#ifndef SWIG
    /** Sets up a callback to be called after a given interval. 
     
     Interval is in seconds, with fractional values allowed.
     The callback must return true if it wants to be triggered again
     */
    static TimeoutHandle add_timeout(float interval, const boost::function<bool ()> &callback) WARN_UNUSED_RETURN_VALUE;
#endif
    static void cancel_timeout(TimeoutHandle handle);

    /** Convenience function to add an OK and Cancel buttons in a box. 
     
     This function will reorder buttons according to the standard order in the platform
     (ie OK Cancel in Windows and Cancel OK elsewhere).
     */
    static void add_end_ok_cancel_buttons(mforms::Box *box, mforms::Button *ok, mforms::Button *cancel);

#ifndef SWIG
    // Don't wrap this from mforms, because the typeinfo isnt getting shared across
    // modules... uncomment this if that's solved
    static cairo_surface_t* load_icon(const std::string& name, bool allow_hidpi=false);
    static bool is_hidpi_icon(cairo_surface_t *s);
    static bool icon_needs_reload(cairo_surface_t *s);

    static void paint_icon(cairo_t *cr, cairo_surface_t *icon, double x, double y, float alpha = 1.0);
    static void get_icon_size(cairo_surface_t *icon, int &w, int &h);

    static std::string shorten_string(cairo_t* cr, const std::string& text, double width);

    static double get_text_width(const std::string &text, const std::string &font);
#endif

#ifndef SWIG
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#ifdef _WIN32
  public:
    static void enter_modal_loop();
    static void leave_modal_loop();
    static bool in_modal_loop();
#endif
#endif
    
    static void *perform_from_main_thread(const boost::function<void* ()> &slot, bool wait_completion = true);
#endif // !SWIG

    static bool in_main_thread();
    static void set_thread_name(const std::string &name);


    // Should be called at the end of python thread, when there was some query involved.
    static void driver_shutdown();

#ifndef SWIG
#ifndef DOXYGEN_SHOULD_SKIP_THIS
    static void add_driver_shutdown_callback(const boost::function<void ()> &slot);
#endif
#endif

  private:
    static boost::function<void()> _driver_shutdown_cb;

    static void save_message_answers();
  };

};