1 /*
2  * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/>
3  *           (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com>
4  *
5  * This file is part of lsp-plugins
6  * Created on: 20 нояб. 2017 г.
7  *
8  * lsp-plugins is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * any later version.
12  *
13  * lsp-plugins is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #include <ui/ui.h>
23 
24 namespace lsp
25 {
26     namespace ctl
27     {
28         const ctl_class_t CtlSaveFile::metadata = { "CtlSaveFile", &CtlWidget::metadata };
29 
CtlSaveFile(CtlRegistry * reg,LSPSaveFile * save)30         CtlSaveFile::CtlSaveFile(CtlRegistry *reg, LSPSaveFile *save):
31             CtlWidget(reg, save)
32         {
33             pClass          = &metadata;
34             pFile           = NULL;
35             pPath           = NULL;
36             pStatus         = NULL;
37             pCommand        = NULL;
38             pProgress       = NULL;
39 
40             pPathID         = NULL;
41         }
42 
~CtlSaveFile()43         CtlSaveFile::~CtlSaveFile()
44         {
45             if (pPathID != NULL)
46             {
47                 free(pPathID);
48                 pPathID = NULL;
49             }
50         }
51 
update_state()52         void CtlSaveFile::update_state()
53         {
54             LSPSaveFile *save   = widget_cast<LSPSaveFile>(pWidget);
55             if (save == NULL)
56                 return;
57             if (pStatus == NULL)
58                 return;
59 
60             size_t status = pStatus->get_value();
61             if (status == STATUS_UNSPECIFIED)
62                 save->set_state(SFS_SELECT);
63             else if (status == STATUS_OK)
64             {
65                 save->set_state(SFS_SAVED);
66                 if (pCommand != NULL)
67                 {
68                     pCommand->set_value(0.0f);
69                     pCommand->notify_all();
70                 }
71             }
72             else if (status == STATUS_LOADING)
73             {
74                 save->set_state(SFS_SAVING);
75                 if (pProgress != NULL)
76                     save->set_progress(pProgress->get_value());
77             }
78             else
79             {
80                 save->set_state(SFS_ERROR);
81                 if (pCommand != NULL)
82                 {
83                     pCommand->set_value(0.0f);
84                     pCommand->notify_all();
85                 }
86             }
87         }
88 
slot_on_file_submit(LSPWidget * sender,void * ptr,void * data)89         status_t CtlSaveFile::slot_on_file_submit(LSPWidget *sender, void *ptr, void *data)
90         {
91             CtlSaveFile *_this   = static_cast<CtlSaveFile *>(ptr);
92             return (_this != NULL) ? _this->commit_state() : STATUS_BAD_ARGUMENTS;
93         }
94 
commit_state()95         status_t CtlSaveFile::commit_state()
96         {
97             LSPSaveFile *save   = widget_cast<LSPSaveFile>(pWidget);
98             if (save == NULL)
99                 return STATUS_OK;
100 
101             const char *path = save->file_name();
102             if (pFile != NULL)
103             {
104                 pFile->write(path, strlen(path));
105                 pFile->notify_all();
106             }
107             if (pCommand != NULL)
108             {
109                 pCommand->set_value(1.0f);
110                 pCommand->notify_all();
111             }
112 
113             return STATUS_OK;
114         }
115 
set(widget_attribute_t att,const char * value)116         void CtlSaveFile::set(widget_attribute_t att, const char *value)
117         {
118             LSPSaveFile *save   = widget_cast<LSPSaveFile>(pWidget);
119 
120             switch (att)
121             {
122                 case A_ID:
123                     BIND_PORT(pRegistry, pFile, value);
124                     break;
125                 case A_PATH_ID:
126                     if (pPathID != NULL)
127                         free(pPathID);
128                     pPathID = (value != NULL) ? strdup(value) : NULL;
129                     break;
130                 case A_STATUS_ID:
131                     BIND_PORT(pRegistry, pStatus, value);
132                     break;
133                 case A_COMMAND_ID:
134                     BIND_PORT(pRegistry, pCommand, value);
135                     break;
136                 case A_PROGRESS_ID:
137                     BIND_PORT(pRegistry, pProgress, value);
138                     break;
139                 case A_FORMAT:
140                     if (save != NULL)
141                         parse_file_formats(value, save->filter());
142                     break;
143                 case A_FORMAT_ID:
144                     BIND_EXPR(sFormat, value);
145                     break;
146                 case A_SIZE:
147                     if (save != NULL)
148                         PARSE_INT(value, save->set_size(__) );
149                     break;
150                 default:
151                 {
152                     CtlWidget::set(att, value);
153                     break;
154                 }
155             }
156         }
157 
end()158         void CtlSaveFile::end()
159         {
160             LSPSaveFile *save   = widget_cast<LSPSaveFile>(pWidget);
161             if (save != NULL)
162             {
163                 save->slots()->bind(LSPSLOT_ACTIVATE, slot_on_activate, this);
164                 save->slots()->bind(LSPSLOT_SUBMIT, slot_on_file_submit, this);
165                 save->slots()->bind(LSPSLOT_CLOSE, slot_on_close, this);
166             }
167 
168             const char *path = (pPathID != NULL) ? pPathID : DEFAULT_PATH_PORT;
169             BIND_PORT(pRegistry, pPath, path);
170 
171             update_state();
172 
173             CtlWidget::end();
174         }
175 
slot_on_activate(LSPWidget * sender,void * ptr,void * data)176         status_t CtlSaveFile::slot_on_activate(LSPWidget *sender, void *ptr, void *data)
177         {
178             CtlSaveFile *ctl    = static_cast<CtlSaveFile *>(ptr);
179             if ((ctl == NULL) || (ctl->pPath == NULL))
180                 return STATUS_BAD_ARGUMENTS;
181             LSPSaveFile *save   = widget_cast<LSPSaveFile>(ctl->pWidget);
182             if (save == NULL)
183                 return STATUS_BAD_STATE;
184 
185             save->set_path(ctl->pPath->get_buffer<char>());
186             return STATUS_OK;
187         }
188 
slot_on_close(LSPWidget * sender,void * ptr,void * data)189         status_t CtlSaveFile::slot_on_close(LSPWidget *sender, void *ptr, void *data)
190         {
191             CtlSaveFile *ctl = static_cast<CtlSaveFile *>(ptr);
192             if (ctl == NULL)
193                 return STATUS_BAD_ARGUMENTS;
194             ctl->update_path();
195             return STATUS_OK;
196         }
197 
update_path()198         void CtlSaveFile::update_path()
199         {
200             LSPSaveFile *save   = widget_cast<LSPSaveFile>(pWidget);
201             if ((save == NULL) || (pPath == NULL))
202                 return;
203 
204             LSPString path;
205             if (save->get_path(&path) != STATUS_OK)
206                 return;
207 
208             if (path.length() <= 0)
209                 return;
210 
211             pPath->write(path.get_native(), path.length());
212             pPath->notify_all();
213         }
214 
notify(CtlPort * port)215         void CtlSaveFile::notify(CtlPort *port)
216         {
217             CtlWidget::notify(port);
218 
219             if ((port == pStatus) ||
220                 (port == pProgress))
221                 update_state();
222 
223             LSPSaveFile *save   = widget_cast<LSPSaveFile>(pWidget);
224             if (save == NULL)
225                 return;
226 
227             if (sFormat.valid())
228                 save->filter()->set_default(sFormat.evaluate());
229         }
230     } /* namespace ctl */
231 } /* namespace lsp */
232