/* * about:profiles * * Copyright (C) 2017 Patrick McDermott * * This file is part of Marquee. * * Marquee 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, either version 3 of the License, or * (at your option) any later version. * * Marquee 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 Marquee. If not, see . */ #include #include #include #include "../../application.h" #include "../../config/profiles.h" #include "../../utils/html.h" #include "../../utils/profile-icon.h" #include "../about.h" #include "paths.h" static const gchar *styles = "div.profile > svg {\n" " width: 64px;\n" " height: 64px;\n" " border: 1px solid transparent;\n" " border-radius: 3px;\n" " padding: 6px;\n" " transition: all 250ms ease-in-out 0s;\n" " -moz-transition: all 250ms ease-in-out 0s;\n" " -wekbit-transition: all 250ms ease-in-out 0s;\n" " -o-transition: all 250ms ease-in-out 0s;\n" "}\n" "div.profile > label {\n" " display: inline;\n" " border: 1px solid #9F9F9F;\n" " border-radius: 3px;\n" " background-color: #DFDFDF;\n" " padding: 6px;\n" " color: #000000;\n" " transition: all 250ms ease-in-out 0s;\n" " -moz-transition: all 250ms ease-in-out 0s;\n" " -wekbit-transition: all 250ms ease-in-out 0s;\n" " -o-transition: all 250ms ease-in-out 0s;\n" "}\n" "div.profile > label:hover {\n" " border: 1px solid #4F8FCF;\n" " outline: 0;\n" " background-color: #EFEFEF;\n" "}\n" "div.profile {\n" " background-color: #CFCFCF;\n" " border: 1px solid #9F9F9F;\n" " border-radius: 3px;\n" "}\n" "div.profile > input[type=radio] {\n" " display: none;\n" "}\n" "div.profile > span {\n" " display: inline;\n" " position: absolute;\n" "}\n" "div.profile > span.current {\n" " font-weight: bold;\n" "}\n" "div.profile > input[type=text] {\n" " display: none;\n" " position: absolute;\n" "}\n" "div.profile > label {\n" " display: inline;\n" "}\n" "div.profile > label > span {\n" " margin: 0;\n" "}\n" "div.profile > input[type=submit]:last-child {\n" " display: none;\n" "}\n" "div.profile > input[type=radio]:checked ~ svg {\n" " border-color: #9F9F9F;\n" " background-color: #DFDFDF;\n" "}\n" "div.profile > input[type=radio]:checked ~ svg:hover {\n" " border-color: #4F8FCF;\n" " background-color: #EFEFEF;\n" "}\n" "div.profile > input[type=radio]:checked ~ span {\n" " display: none;\n" "}\n" "div.profile > input[type=radio]:checked ~ input[type=text] {\n" " display: inline;\n" "}\n" "div.profile > input[type=radio]:checked ~ label {\n" " display: none;\n" "}\n" "div.profile > input[type=radio]:checked ~ " " input[type=submit]:last-child {\n" " display: inline;\n" "}\n" "div.profile > label, div.profile > input[type=submit] {\n" " float: right;\n" "}\n" "div.color-picker {\n" " display: none;\n" " position: fixed;\n" " top: 50%;\n" " left: 50%;\n" " margin-top: -127px;\n" " margin-left: -127px;\n" " border: 1px solid #9F9F9F;\n" " border-radius: 3px;\n" " box-shadow: 0 0 12px #000000;\n" " background-color: #CFCFCF;\n" "}\n" "div.color-picker div.picker-wrapper,\n" "div.color-picker div.slide-wrapper {\n" " position: relative;\n" " float: left;\n" "}\n" "div.color-picker div.picker {\n" " float: left;\n" " margin: 0;\n" " width: 200px;\n" " height: 200px;\n" " cursor: crosshair;\n" "}\n" "div.color-picker div.slide {\n" " float: left;\n" " margin: 0;\n" " width: 30px;\n" " height: 200px;\n" " cursor: crosshair;\n" "}\n" "div.color-picker svg {\n" " margin: 0;\n" "}\n" "div.color-picker div.picker-indicator {\n" " position: absolute;\n" " top: -6px;\n" " left: -6px;\n" " margin: 0;\n" " border: 3px solid #9F9F9F;\n" " border-radius: 6px;\n" " width: 6px;\n" " height: 6px;\n" " opacity: 0.5;\n" " background-color: #FFFFFF;\n" " pointer-events: none;\n" "}\n" "div.color-picker div.slide-indicator {\n" " position: absolute;\n" " top: -6px;\n" " left: -3px;\n" " margin: 0;\n" " border: 3px solid #9F9F9F;\n" " border-radius: 6px;\n" " width: 100%;\n" " height: 6px;\n" " opacity: 0.5;\n" " background-color: #FFFFFF;\n" " pointer-events: none;\n" "}\n" "div.color-picker div.dialog-buttonbox {\n" " clear: left;\n" "}\n" "div.color-picker div.dialog-buttonbox * {\n" " line-height: 100%;\n" "}\n" ; static gchar * generate_div(MqProfiles *profiles, gchar *id) { gchar *name; gchar *color; gchar *editing_str; gchar *name_str; gchar *color_str; gchar *default_str; gchar *delete_str; gchar *save_str; gchar *div; gchar *current; gboolean is_current; /* name is freed by the mq_html_container() call to generate the name * . */ if (id) { name = mq_profiles_get_name(profiles, id); color = mq_profiles_get_color(profiles, id); } else { name = g_strdup("New Profile"); color = g_strdup("#00ff00"); } editing_str = g_strconcat("editing_", id, NULL); name_str = g_strconcat("name_", id, NULL); color_str = g_strconcat("color_", id, NULL); default_str = g_strconcat("default_", id, NULL); delete_str = g_strconcat("delete_", id, NULL); save_str = g_strconcat("save_", id, NULL); current = mq_profiles_get_current(profiles); is_current = (g_strcmp0(id, current) == 0); g_free(current); div = mq_html_container("div", "profile", mq_html_input_radio("editing", editing_str, id, NULL, id == NULL), mq_profile_icon_new(color), mq_html_input_hidden(color_str, color), mq_html_container("div", "color-picker", mq_html_container("div", "picker-wrapper", mq_html_container("div", "picker", NULL), mq_html_container("div", "picker-indicator", NULL), NULL), mq_html_container("div", "slide-wrapper", mq_html_container("div", "slide", NULL), mq_html_container("div", "slide-indicator", NULL), NULL), mq_html_buttonbox(NULL, "OK", NULL, "Cancel"), NULL), mq_html_container("span", is_current ? "current" : NULL, name, NULL), mq_html_input_text(name_str, NULL, name), mq_html_submit(default_str, "Make Default", !id || mq_profiles_is_default(profiles, id)), mq_html_submit(delete_str, "Delete", FALSE), mq_html_label(editing_str, "Edit", FALSE), mq_html_submit(save_str, "Save", FALSE), NULL); g_free(editing_str); g_free(name_str); g_free(default_str); g_free(delete_str); g_free(save_str); g_free(color); return div; } static gchar * generate_document(MqProfiles *profiles, gboolean adding) { gchar **ids; gsize length; gchar **divs; gsize i; gchar *cp_res; gchar *document; ids = mq_profiles_get_profiles(profiles, &length); divs = g_new(gchar *, length + (adding ? 1 : 0) + 1); for (i = 0; i < length; ++i) { divs[i] = generate_div(profiles, ids[i]); } if (adding) { divs[i++] = generate_div(profiles, NULL); } divs[i] = NULL; g_strfreev(ids); cp_res = g_strdup( "\n" ); document = mq_html_document("Profiles", styles, cp_res, mq_html_form_v("add", "Add Profile", NULL, NULL, divs), NULL); g_free(cp_res); return document; } static void edit_profiles(MqProfiles *profiles, GHashTable *query) { GList *keys; GList *key; gchar *id; gchar *input_key; keys = g_hash_table_get_keys(query); for (key = keys; key; key = key->next) { if (g_str_has_prefix(key->data, "save_")) { id = (gchar *) key->data + strlen("save_"); if (id[0]) { /* Edit existing profile. */ input_key = g_strconcat("name_", id, NULL); mq_profiles_set_name(profiles, id, g_hash_table_lookup(query, input_key)); g_free(input_key); } else { input_key = g_strconcat("name_", id, NULL); mq_profiles_insert(profiles, g_hash_table_lookup(query, input_key), "#00ff00"); g_free(input_key); } } else if (g_str_has_prefix(key->data, "delete_")) { id = (gchar *) key->data + strlen("delete_"); if (id[0]) { /* Don't remove new profile. */ mq_profiles_remove(profiles, id); } } else if (g_str_has_prefix(key->data, "default_")) { id = (gchar *) key->data + strlen("default_"); if (id[0]) { /* Don't set new profile as default. */ mq_profiles_set_default(profiles, id); } } } g_list_free(keys); mq_profiles_save(profiles); } void mq_about_profiles_response(MqApplication *application, GHashTable *query, WebKitURISchemeRequest *request) { MqProfiles *profiles; profiles = mq_application_get_profiles(application); if (!query) { mq_about_response(request, generate_document(profiles, FALSE)); } else if (g_hash_table_lookup(query, "add")) { mq_about_response(request, generate_document(profiles, TRUE)); } else { edit_profiles(profiles, query); mq_about_redirect(request, "mq-about:profiles"); } }