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();
};
};
|