diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/app.c | 15 | ||||
-rw-r--r-- | src/ui/certimportwidget.c | 225 | ||||
-rw-r--r-- | src/ui/certimportwidget.h | 30 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 4 | ||||
-rw-r--r-- | src/ui/documentwidget.h | 1 | ||||
-rw-r--r-- | src/ui/util.c | 57 | ||||
-rw-r--r-- | src/ui/util.h | 1 | ||||
-rw-r--r-- | src/ui/window.c | 8 |
8 files changed, 270 insertions, 71 deletions
@@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
30 | #include "gmdocument.h" | 30 | #include "gmdocument.h" |
31 | #include "gmutil.h" | 31 | #include "gmutil.h" |
32 | #include "history.h" | 32 | #include "history.h" |
33 | #include "ui/certimportwidget.h" | ||
33 | #include "ui/color.h" | 34 | #include "ui/color.h" |
34 | #include "ui/command.h" | 35 | #include "ui/command.h" |
35 | #include "ui/documentwidget.h" | 36 | #include "ui/documentwidget.h" |
@@ -994,14 +995,6 @@ static iBool handleIdentityCreationCommands_(iWidget *dlg, const char *cmd) { | |||
994 | return iFalse; | 995 | return iFalse; |
995 | } | 996 | } |
996 | 997 | ||
997 | iBool handleCertificateImportCommands_(iWidget *dlg, const char *cmd) { | ||
998 | if (equal_Command(cmd, "certimport.accept") || equal_Command(cmd, "cancel")) { | ||
999 | destroy_Widget(dlg); | ||
1000 | return iTrue; | ||
1001 | } | ||
1002 | return iFalse; | ||
1003 | } | ||
1004 | |||
1005 | iBool willUseProxy_App(const iRangecc scheme) { | 998 | iBool willUseProxy_App(const iRangecc scheme) { |
1006 | return schemeProxy_App(scheme) != NULL; | 999 | return schemeProxy_App(scheme) != NULL; |
1007 | } | 1000 | } |
@@ -1412,8 +1405,10 @@ iBool handleCommand_App(const char *cmd) { | |||
1412 | return iTrue; | 1405 | return iTrue; |
1413 | } | 1406 | } |
1414 | else if (equal_Command(cmd, "ident.import")) { | 1407 | else if (equal_Command(cmd, "ident.import")) { |
1415 | iWidget *dlg = makeCertificateImport_Widget(); | 1408 | iCertImportWidget *imp = new_CertImportWidget(); |
1416 | setCommandHandler_Widget(dlg, handleCertificateImportCommands_); | 1409 | setPageContent_CertImportWidget(imp, sourceContent_DocumentWidget(document_App())); |
1410 | addChild_Widget(d->window->root, iClob(imp)); | ||
1411 | postRefresh_App(); | ||
1417 | return iTrue; | 1412 | return iTrue; |
1418 | } | 1413 | } |
1419 | else if (equal_Command(cmd, "ident.signin")) { | 1414 | else if (equal_Command(cmd, "ident.signin")) { |
diff --git a/src/ui/certimportwidget.c b/src/ui/certimportwidget.c new file mode 100644 index 00000000..51743e89 --- /dev/null +++ b/src/ui/certimportwidget.c | |||
@@ -0,0 +1,225 @@ | |||
1 | /* Copyright 2021 Jaakko Keränen <jaakko.keranen@iki.fi> | ||
2 | |||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions are met: | ||
5 | |||
6 | 1. Redistributions of source code must retain the above copyright notice, this | ||
7 | list of conditions and the following disclaimer. | ||
8 | 2. Redistributions in binary form must reproduce the above copyright notice, | ||
9 | this list of conditions and the following disclaimer in the documentation | ||
10 | and/or other materials provided with the distribution. | ||
11 | |||
12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||
16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | ||
22 | |||
23 | #include "certimportwidget.h" | ||
24 | #include "labelwidget.h" | ||
25 | #include "inputwidget.h" | ||
26 | #include "color.h" | ||
27 | #include "text.h" | ||
28 | #include "ui/util.h" | ||
29 | #include "app.h" | ||
30 | |||
31 | #include <the_Foundation/tlsrequest.h> | ||
32 | #include <SDL_clipboard.h> | ||
33 | |||
34 | iDefineObjectConstruction(CertImportWidget) | ||
35 | |||
36 | struct Impl_CertImportWidget { | ||
37 | iWidget widget; | ||
38 | iLabelWidget *info; | ||
39 | iLabelWidget *crtLabel; | ||
40 | iLabelWidget *keyLabel; | ||
41 | iInputWidget *filename; | ||
42 | iInputWidget *notes; | ||
43 | iTlsCertificate *cert; | ||
44 | }; | ||
45 | |||
46 | static const char *infoText_ = "Paste a PEM-encoded certificate and/or private key,\n" | ||
47 | "or drop a .crt/.key file on the window."; | ||
48 | |||
49 | static iBool tryImport_CertImportWidget_(iCertImportWidget *d, const iBlock *data) { | ||
50 | iBool ok = iFalse; | ||
51 | iString pem; | ||
52 | initBlock_String(&pem, data); | ||
53 | iTlsCertificate *newCert = newPemKey_TlsCertificate(&pem, &pem); | ||
54 | const iBool gotNewCrt = !isEmpty_TlsCertificate(newCert); | ||
55 | const iBool gotNewKey = hasPrivateKey_TlsCertificate(newCert); | ||
56 | if (d->cert && (gotNewCrt ^ gotNewKey)) { /* One new part? Merge with existing. */ | ||
57 | const iString *crt = collect_String(pem_TlsCertificate(gotNewCrt ? newCert : d->cert)); | ||
58 | const iString *key = collect_String(privateKeyPem_TlsCertificate(gotNewKey ? newCert : d->cert)); | ||
59 | delete_TlsCertificate(d->cert); | ||
60 | delete_TlsCertificate(newCert); | ||
61 | d->cert = newPemKey_TlsCertificate(crt, key); | ||
62 | ok = iTrue; | ||
63 | } | ||
64 | else if (gotNewCrt || gotNewKey) { | ||
65 | delete_TlsCertificate(d->cert); | ||
66 | d->cert = newCert; | ||
67 | ok = iTrue; | ||
68 | } | ||
69 | else { | ||
70 | delete_TlsCertificate(newCert); | ||
71 | } | ||
72 | deinit_String(&pem); | ||
73 | /* Update the labels. */ { | ||
74 | if (d->cert && !isEmpty_TlsCertificate(d->cert)) { | ||
75 | setTextCStr_LabelWidget( | ||
76 | d->crtLabel, | ||
77 | format_CStr("%s%s", | ||
78 | uiTextAction_ColorEscape, | ||
79 | cstrCollect_String(subject_TlsCertificate(d->cert)))); | ||
80 | setFrameColor_Widget(as_Widget(d->crtLabel), uiTextAction_ColorId); | ||
81 | } | ||
82 | else { | ||
83 | setTextCStr_LabelWidget(d->crtLabel, uiTextCaution_ColorEscape "No Certificate"); | ||
84 | setFrameColor_Widget(as_Widget(d->crtLabel), uiTextCaution_ColorId); | ||
85 | } | ||
86 | if (d->cert && hasPrivateKey_TlsCertificate(d->cert)) { | ||
87 | iString *fng = collect_String( | ||
88 | hexEncode_Block(collect_Block(privateKeyFingerprint_TlsCertificate(d->cert)))); | ||
89 | insertData_Block(&fng->chars, size_String(fng) / 2, "\n", 1); | ||
90 | setTextCStr_LabelWidget( | ||
91 | d->keyLabel, format_CStr("%s%s", uiTextAction_ColorEscape, cstr_String(fng))); | ||
92 | setFrameColor_Widget(as_Widget(d->keyLabel), uiTextAction_ColorId); | ||
93 | } | ||
94 | else { | ||
95 | setTextCStr_LabelWidget(d->keyLabel, uiTextCaution_ColorEscape "No Private Key"); | ||
96 | setFrameColor_Widget(as_Widget(d->keyLabel), uiTextCaution_ColorId); | ||
97 | } | ||
98 | } | ||
99 | return ok; | ||
100 | } | ||
101 | |||
102 | void init_CertImportWidget(iCertImportWidget *d) { | ||
103 | iWidget *w = as_Widget(d); | ||
104 | init_Widget(w); | ||
105 | setId_Widget(w, "certimport"); | ||
106 | d->cert = NULL; | ||
107 | /* This should behave similar to sheets. */ { | ||
108 | setPadding1_Widget(w, 3 * gap_UI); | ||
109 | setFrameColor_Widget(w, uiSeparator_ColorId); | ||
110 | setBackgroundColor_Widget(w, uiBackground_ColorId); | ||
111 | setFlags_Widget(w, | ||
112 | mouseModal_WidgetFlag | keepOnTop_WidgetFlag | arrangeVertical_WidgetFlag | | ||
113 | arrangeSize_WidgetFlag | centerHorizontal_WidgetFlag | | ||
114 | overflowScrollable_WidgetFlag, | ||
115 | iTrue); | ||
116 | } | ||
117 | addChildFlags_Widget(w, | ||
118 | iClob(new_LabelWidget(uiHeading_ColorEscape "IMPORT IDENTITY", NULL)), | ||
119 | frameless_WidgetFlag); | ||
120 | d->info = addChildFlags_Widget(w, iClob(new_LabelWidget(infoText_, NULL)), frameless_WidgetFlag); | ||
121 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); | ||
122 | d->crtLabel = new_LabelWidget("", NULL); { | ||
123 | setFont_LabelWidget(d->crtLabel, uiContent_FontId); | ||
124 | addChildFlags_Widget(w, iClob(d->crtLabel), 0); | ||
125 | setFrameColor_Widget(as_Widget(d->crtLabel), uiTextCaution_ColorId); | ||
126 | } | ||
127 | d->keyLabel = new_LabelWidget("", NULL); { | ||
128 | setFont_LabelWidget(d->keyLabel, uiContent_FontId); | ||
129 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); | ||
130 | addChildFlags_Widget(w, iClob(d->keyLabel), 0); | ||
131 | setFrameColor_Widget(as_Widget(d->keyLabel), uiTextCaution_ColorId); | ||
132 | } | ||
133 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); | ||
134 | iWidget *page = new_Widget(); { | ||
135 | setFlags_Widget(page, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue); | ||
136 | iWidget *headings = addChildFlags_Widget( | ||
137 | page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag); | ||
138 | iWidget *values = addChildFlags_Widget( | ||
139 | page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag); | ||
140 | addChild_Widget(headings, iClob(makeHeading_Widget("Save as:"))); | ||
141 | addChild_Widget(values, iClob(d->filename = new_InputWidget(0))); | ||
142 | setHint_InputWidget(d->filename, "filename (no extension)"); | ||
143 | addChild_Widget(headings, iClob(makeHeading_Widget("Notes:"))); | ||
144 | addChild_Widget(values, iClob(d->notes = new_InputWidget(0))); | ||
145 | setHint_InputWidget(d->notes, "e.g., site name"); | ||
146 | as_Widget(d->filename)->rect.size.x = gap_UI * 70; | ||
147 | as_Widget(d->notes)->rect.size.x = gap_UI * 70; | ||
148 | } | ||
149 | addChild_Widget(w, iClob(page)); | ||
150 | arrange_Widget(w); | ||
151 | setSize_Widget(as_Widget(d->crtLabel), init_I2(width_Widget(w) - 6.5 * gap_UI, gap_UI * 12)); | ||
152 | setSize_Widget(as_Widget(d->keyLabel), init_I2(width_Widget(w) - 6.5 * gap_UI, gap_UI * 12)); | ||
153 | /* Buttons. */ | ||
154 | iWidget *div = new_Widget(); { | ||
155 | setFlags_Widget(div, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue); | ||
156 | addChild_Widget(div, iClob(newKeyMods_LabelWidget("Cancel", SDLK_ESCAPE, 0, "cancel"))); | ||
157 | iLabelWidget *accept = addChild_Widget( | ||
158 | div, | ||
159 | iClob(newKeyMods_LabelWidget( | ||
160 | uiTextAction_ColorEscape "Import", SDLK_RETURN, KMOD_PRIMARY, "certimport.accept"))); | ||
161 | setFont_LabelWidget(accept, uiLabelBold_FontId); | ||
162 | } | ||
163 | addChild_Widget(w, iClob(div)); | ||
164 | arrange_Widget(w); | ||
165 | } | ||
166 | |||
167 | void deinit_CertImportWidget(iCertImportWidget *d) { | ||
168 | delete_TlsCertificate(d->cert); | ||
169 | } | ||
170 | |||
171 | static iBool isComplete_CertImportWidget_(const iCertImportWidget *d) { | ||
172 | return d->cert && !isEmpty_TlsCertificate(d->cert) && hasPrivateKey_TlsCertificate(d->cert); | ||
173 | } | ||
174 | |||
175 | void setPageContent_CertImportWidget(iCertImportWidget *d, const iBlock *content) { | ||
176 | if (tryImport_CertImportWidget_(d, content)) { | ||
177 | setTextCStr_LabelWidget(d->info, infoText_); | ||
178 | if (isComplete_CertImportWidget_(d)) { | ||
179 | setFocus_Widget(as_Widget(d->filename)); | ||
180 | } | ||
181 | } | ||
182 | else { | ||
183 | setTextCStr_LabelWidget( | ||
184 | d->info, format_CStr("No certificate/key found on the current page.\n%s", infoText_)); | ||
185 | } | ||
186 | arrange_Widget(as_Widget(d)); | ||
187 | } | ||
188 | |||
189 | static iBool processEvent_CertImportWidget_(iCertImportWidget *d, const SDL_Event *ev) { | ||
190 | iWidget *w = as_Widget(d); | ||
191 | if (ev->type == SDL_KEYDOWN) { | ||
192 | const int key = ev->key.keysym.sym; | ||
193 | const int mods = keyMods_Sym(ev->key.keysym.mod); | ||
194 | if (key == SDLK_v && mods == KMOD_PRIMARY) { | ||
195 | if (!tryImport_CertImportWidget_( | ||
196 | d, collect_Block(newCStr_Block(SDL_GetClipboardText())))) { | ||
197 | makeMessage_Widget(uiTextCaution_ColorEscape "PASTED FROM CLIPBOARD", | ||
198 | "No certificate or private key was found."); | ||
199 | } | ||
200 | postRefresh_App(); | ||
201 | return iTrue; | ||
202 | } | ||
203 | } | ||
204 | if (isCommand_Widget(w, ev, "cancel")) { | ||
205 | destroy_Widget(w); | ||
206 | return iTrue; | ||
207 | } | ||
208 | if (isCommand_Widget(w, ev, "certimport.accept")) { | ||
209 | if (d->cert) { | ||
210 | destroy_Widget(w); | ||
211 | } | ||
212 | return iTrue; | ||
213 | } | ||
214 | return processEvent_Widget(w, ev); | ||
215 | } | ||
216 | |||
217 | static void draw_CertImportWidget_(const iCertImportWidget *d) { | ||
218 | const iWidget *w = constAs_Widget(d); | ||
219 | draw_Widget(w); | ||
220 | } | ||
221 | |||
222 | iBeginDefineSubclass(CertImportWidget, Widget) | ||
223 | .processEvent = (iAny *) processEvent_CertImportWidget_, | ||
224 | .draw = (iAny *) draw_CertImportWidget_, | ||
225 | iEndDefineSubclass(CertImportWidget) | ||
diff --git a/src/ui/certimportwidget.h b/src/ui/certimportwidget.h new file mode 100644 index 00000000..65548846 --- /dev/null +++ b/src/ui/certimportwidget.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* Copyright 2020 Jaakko Keränen <jaakko.keranen@iki.fi> | ||
2 | |||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions are met: | ||
5 | |||
6 | 1. Redistributions of source code must retain the above copyright notice, this | ||
7 | list of conditions and the following disclaimer. | ||
8 | 2. Redistributions in binary form must reproduce the above copyright notice, | ||
9 | this list of conditions and the following disclaimer in the documentation | ||
10 | and/or other materials provided with the distribution. | ||
11 | |||
12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||
16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | ||
22 | |||
23 | #pragma once | ||
24 | |||
25 | #include "widget.h" | ||
26 | |||
27 | iDeclareWidgetClass(CertImportWidget) | ||
28 | iDeclareObjectConstruction(CertImportWidget) | ||
29 | |||
30 | void setPageContent_CertImportWidget (iCertImportWidget *, const iBlock *); | ||
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 1c95593b..8603f1fe 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -3219,6 +3219,10 @@ const iGmDocument *document_DocumentWidget(const iDocumentWidget *d) { | |||
3219 | return d->doc; | 3219 | return d->doc; |
3220 | } | 3220 | } |
3221 | 3221 | ||
3222 | const iBlock *sourceContent_DocumentWidget(const iDocumentWidget *d) { | ||
3223 | return &d->sourceContent; | ||
3224 | } | ||
3225 | |||
3222 | const iString *feedTitle_DocumentWidget(const iDocumentWidget *d) { | 3226 | const iString *feedTitle_DocumentWidget(const iDocumentWidget *d) { |
3223 | if (!isEmpty_String(title_GmDocument(d->doc))) { | 3227 | if (!isEmpty_String(title_GmDocument(d->doc))) { |
3224 | return title_GmDocument(d->doc); | 3228 | return title_GmDocument(d->doc); |
diff --git a/src/ui/documentwidget.h b/src/ui/documentwidget.h index 55c0a6ed..91337a24 100644 --- a/src/ui/documentwidget.h +++ b/src/ui/documentwidget.h | |||
@@ -39,6 +39,7 @@ iHistory * history_DocumentWidget (iDocumentWidget *); | |||
39 | 39 | ||
40 | const iString * url_DocumentWidget (const iDocumentWidget *); | 40 | const iString * url_DocumentWidget (const iDocumentWidget *); |
41 | iBool isRequestOngoing_DocumentWidget (const iDocumentWidget *); | 41 | iBool isRequestOngoing_DocumentWidget (const iDocumentWidget *); |
42 | const iBlock * sourceContent_DocumentWidget (const iDocumentWidget *); | ||
42 | const iGmDocument * document_DocumentWidget (const iDocumentWidget *); | 43 | const iGmDocument * document_DocumentWidget (const iDocumentWidget *); |
43 | const iString * bookmarkTitle_DocumentWidget (const iDocumentWidget *); | 44 | const iString * bookmarkTitle_DocumentWidget (const iDocumentWidget *); |
44 | const iString * feedTitle_DocumentWidget (const iDocumentWidget *); | 45 | const iString * feedTitle_DocumentWidget (const iDocumentWidget *); |
diff --git a/src/ui/util.c b/src/ui/util.c index d8a66bab..fd297ce2 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -744,8 +744,8 @@ iBool filePathHandler_(iWidget *dlg, const char *cmd) { | |||
744 | 744 | ||
745 | iWidget *makeSheet_Widget(const char *id) { | 745 | iWidget *makeSheet_Widget(const char *id) { |
746 | iWidget *sheet = new_Widget(); | 746 | iWidget *sheet = new_Widget(); |
747 | setPadding1_Widget(sheet, 3 * gap_UI); | ||
748 | setId_Widget(sheet, id); | 747 | setId_Widget(sheet, id); |
748 | setPadding1_Widget(sheet, 3 * gap_UI); | ||
749 | setFrameColor_Widget(sheet, uiSeparator_ColorId); | 749 | setFrameColor_Widget(sheet, uiSeparator_ColorId); |
750 | setBackgroundColor_Widget(sheet, uiBackground_ColorId); | 750 | setBackgroundColor_Widget(sheet, uiBackground_ColorId); |
751 | setFlags_Widget(sheet, | 751 | setFlags_Widget(sheet, |
@@ -1442,58 +1442,3 @@ iWidget *makeIdentityCreation_Widget(void) { | |||
1442 | centerSheet_Widget(dlg); | 1442 | centerSheet_Widget(dlg); |
1443 | return dlg; | 1443 | return dlg; |
1444 | } | 1444 | } |
1445 | |||
1446 | iWidget *makeCertificateImport_Widget(void) { | ||
1447 | iWidget *dlg = makeSheet_Widget("certimport"); | ||
1448 | setId_Widget( | ||
1449 | addChildFlags_Widget(dlg, | ||
1450 | iClob(new_LabelWidget(uiHeading_ColorEscape "IMPORT CERTIFICATE", NULL)), | ||
1451 | frameless_WidgetFlag), | ||
1452 | "certimport.heading"); | ||
1453 | addAction_Widget(dlg, SDLK_v, KMOD_PRIMARY, "certimport.paste"); | ||
1454 | addChild_Widget(dlg, iClob(makePadding_Widget(gap_UI))); | ||
1455 | iLabelWidget *crt = new_LabelWidget("No Certificate", NULL); | ||
1456 | setFont_LabelWidget(crt, uiContent_FontId); | ||
1457 | addChildFlags_Widget(dlg, iClob(crt), 0); | ||
1458 | setFrameColor_Widget(as_Widget(crt), uiTextDim_ColorId); | ||
1459 | iLabelWidget *key = new_LabelWidget("No Private Key", NULL); | ||
1460 | setFont_LabelWidget(key, uiContent_FontId); | ||
1461 | addChild_Widget(dlg, iClob(makePadding_Widget(gap_UI))); | ||
1462 | addChildFlags_Widget(dlg, iClob(key), 0); | ||
1463 | setFrameColor_Widget(as_Widget(key), uiTextDim_ColorId); | ||
1464 | addChild_Widget(dlg, iClob(makePadding_Widget(gap_UI))); | ||
1465 | iWidget *page = new_Widget(); { | ||
1466 | setFlags_Widget(page, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue); | ||
1467 | iWidget *headings = addChildFlags_Widget( | ||
1468 | page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag); | ||
1469 | iWidget *values = addChildFlags_Widget( | ||
1470 | page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag); | ||
1471 | addChild_Widget(headings, iClob(makeHeading_Widget("Save as:"))); | ||
1472 | void *inputs[2]; | ||
1473 | addChild_Widget(values, iClob(inputs[0] = new_InputWidget(0))); | ||
1474 | setHint_InputWidget(inputs[0], "filename (no extension)"); | ||
1475 | addChild_Widget(headings, iClob(makeHeading_Widget("Notes:"))); | ||
1476 | addChild_Widget(values, iClob(inputs[1] = new_InputWidget(0))); | ||
1477 | setHint_InputWidget(inputs[1], "e.g., site name"); | ||
1478 | as_Widget(inputs[0])->rect.size.x = gap_UI * 60; | ||
1479 | as_Widget(inputs[1])->rect.size.x = gap_UI * 60; | ||
1480 | } | ||
1481 | addChild_Widget(dlg, iClob(page)); | ||
1482 | arrange_Widget(dlg); | ||
1483 | setSize_Widget(as_Widget(crt), init_I2(width_Widget(dlg), gap_UI * 15)); | ||
1484 | setSize_Widget(as_Widget(key), init_I2(width_Widget(dlg), gap_UI * 15)); | ||
1485 | /* Buttons. */ | ||
1486 | iWidget *div = new_Widget(); { | ||
1487 | setFlags_Widget(div, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue); | ||
1488 | addChild_Widget(div, iClob(newKeyMods_LabelWidget("Cancel", SDLK_ESCAPE, 0, "cancel"))); | ||
1489 | iLabelWidget *accept = addChild_Widget( | ||
1490 | div, | ||
1491 | iClob(newKeyMods_LabelWidget( | ||
1492 | uiTextAction_ColorEscape "Import", SDLK_RETURN, KMOD_PRIMARY, "certimport.accept"))); | ||
1493 | setFont_LabelWidget(accept, uiLabelBold_FontId); | ||
1494 | } | ||
1495 | addChild_Widget(dlg, iClob(div)); | ||
1496 | addChild_Widget(get_Window()->root, iClob(dlg)); | ||
1497 | centerSheet_Widget(dlg); | ||
1498 | return dlg; | ||
1499 | } | ||
diff --git a/src/ui/util.h b/src/ui/util.h index 5b701e08..a280fedb 100644 --- a/src/ui/util.h +++ b/src/ui/util.h | |||
@@ -204,5 +204,4 @@ iWidget * makePreferences_Widget (void); | |||
204 | iWidget * makeBookmarkEditor_Widget (void); | 204 | iWidget * makeBookmarkEditor_Widget (void); |
205 | iWidget * makeBookmarkCreation_Widget (const iString *url, const iString *title, iChar icon); | 205 | iWidget * makeBookmarkCreation_Widget (const iString *url, const iString *title, iChar icon); |
206 | iWidget * makeIdentityCreation_Widget (void); | 206 | iWidget * makeIdentityCreation_Widget (void); |
207 | iWidget * makeCertificateImport_Widget(void); | ||
208 | iWidget * makeFeedSettings_Widget (uint32_t bookmarkId); | 207 | iWidget * makeFeedSettings_Widget (uint32_t bookmarkId); |
diff --git a/src/ui/window.c b/src/ui/window.c index a447340b..a4734675 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -163,23 +163,23 @@ static const iMenuItem viewMenuItems_[] = { | |||
163 | 163 | ||
164 | static iMenuItem bookmarksMenuItems_[] = { | 164 | static iMenuItem bookmarksMenuItems_[] = { |
165 | { "Bookmark This Page...", SDLK_d, KMOD_PRIMARY, "bookmark.add" }, | 165 | { "Bookmark This Page...", SDLK_d, KMOD_PRIMARY, "bookmark.add" }, |
166 | { "Subscribe to This Page...", subscribeToPage_KeyModifier, "feeds.subscribe" }, | ||
166 | { "---", 0, 0, NULL }, | 167 | { "---", 0, 0, NULL }, |
167 | { "Import All Links on Page...", 0, 0, "bookmark.links confirm:1" }, | 168 | { "Import All Links on Page...", 0, 0, "bookmark.links confirm:1" }, |
168 | { "---", 0, 0, NULL }, | 169 | { "---", 0, 0, NULL }, |
169 | { "List All", 0, 0, "open url:about:bookmarks" }, | 170 | { "List All", 0, 0, "open url:about:bookmarks" }, |
170 | { "List by Tag", 0, 0, "open url:about:bookmarks?tags" }, | 171 | { "List by Tag", 0, 0, "open url:about:bookmarks?tags" }, |
171 | { "List by Creation Time", 0, 0, "open url:about:bookmarks?created" }, | 172 | { "List by Creation Time", 0, 0, "open url:about:bookmarks?created" }, |
172 | { "Refresh Remote Sources", 0, 0, "bookmarks.reload.remote" }, | ||
173 | { "---", 0, 0, NULL }, | ||
174 | { "Subscribe to This Page...", subscribeToPage_KeyModifier, "feeds.subscribe" }, | ||
175 | { "Show Feed Entries", 0, 0, "open url:about:feeds" }, | 173 | { "Show Feed Entries", 0, 0, "open url:about:feeds" }, |
174 | { "---", 0, 0, NULL }, | ||
175 | { "Refresh Remote Bookmarks", 0, 0, "bookmarks.reload.remote" }, | ||
176 | { "Refresh Feeds", SDLK_r, KMOD_PRIMARY | KMOD_SHIFT, "feeds.refresh" }, | 176 | { "Refresh Feeds", SDLK_r, KMOD_PRIMARY | KMOD_SHIFT, "feeds.refresh" }, |
177 | }; | 177 | }; |
178 | 178 | ||
179 | static const iMenuItem identityMenuItems_[] = { | 179 | static const iMenuItem identityMenuItems_[] = { |
180 | { "New Identity...", SDLK_n, KMOD_PRIMARY | KMOD_SHIFT, "ident.new" }, | 180 | { "New Identity...", SDLK_n, KMOD_PRIMARY | KMOD_SHIFT, "ident.new" }, |
181 | { "---", 0, 0, NULL }, | 181 | { "---", 0, 0, NULL }, |
182 | { "Import...", 0, 0, "ident.import" }, | 182 | { "Import...", SDLK_i, KMOD_PRIMARY | KMOD_SHIFT, "ident.import" }, |
183 | }; | 183 | }; |
184 | 184 | ||
185 | static const iMenuItem helpMenuItems_[] = { | 185 | static const iMenuItem helpMenuItems_[] = { |