1 // Copyright (c) 2016 The SigViewer Development Team
2 // Licensed under the GNU General Public License (GPL)
3 // https://www.gnu.org/licenses/gpl
4 
5 
6 #include "main_window_model_impl.h"
7 #include "main_window.h"
8 
9 #include "gui_impl/commands/open_file_gui_command.h"
10 
11 #include "gui_impl/signal_browser/signal_browser_model_4.h"
12 #include "gui_impl/signal_browser/signal_browser_view.h"
13 #include "gui_impl/event_table/event_table_widget.h"
14 
15 #include <QSettings>
16 #include <QDebug>
17 
18 namespace sigviewer
19 {
20 
21 int const MainWindowModelImpl::NUMBER_RECENT_FILES_ = 8;
22 
23 //-----------------------------------------------------------------------------
MainWindowModelImpl(QSharedPointer<ApplicationContext> application_context)24 MainWindowModelImpl::MainWindowModelImpl (QSharedPointer<ApplicationContext> application_context)
25 : application_context_ (application_context),
26   main_window_ (new MainWindow (application_context)),
27   tab_widget_ (0)
28 {
29     connect (main_window_, SIGNAL(recentFileActivated(QAction*)), SLOT(recentFileActivated(QAction*)));
30     connect (main_window_, SIGNAL(recentFileMenuAboutToShow()), SLOT(recentFileMenuAboutToShow()));
31     main_window_->show();
32     loadSettings();
33 }
34 
35 //-----------------------------------------------------------------------------
~MainWindowModelImpl()36 MainWindowModelImpl::~MainWindowModelImpl ()
37 {
38     qDebug () << "deleting MainWindowModelImpl";
39 }
40 
41 //-----------------------------------------------------------------------------
loadSettings()42 void MainWindowModelImpl::loadSettings()
43 {
44     QSettings settings;
45     settings.beginGroup("MainWindowModelImpl");
46 
47     int size = settings.beginReadArray("recent_file");
48     for (int i = 0; i < size; i++)
49     {
50         settings.setArrayIndex(i);
51         recent_file_list_.append(settings.value("name").toString());
52     }
53 
54     settings.endArray();
55 
56     settings.endGroup();
57 }
58 
59 //-----------------------------------------------------------------------------
saveSettings()60 void MainWindowModelImpl::saveSettings()
61 {
62     QSettings settings;
63     settings.beginGroup("MainWindowModelImpl");
64     settings.beginWriteArray("recent_file");
65 
66     for (int i = 0; i < recent_file_list_.size(); i++)
67     {
68         settings.setArrayIndex(i);
69         settings.setValue("name", recent_file_list_.at(i));
70     }
71 
72     settings.endArray();
73     settings.endGroup();
74 }
75 
76 //-----------------------------------------------------------------------------
tabChanged(int tab_index)77 void MainWindowModelImpl::tabChanged (int tab_index)
78 {
79     if (tab_contexts_.find(tab_index) != tab_contexts_.end ())
80     {
81         application_context_->setCurrentTabContext (tab_contexts_[tab_index]);
82         tab_contexts_[tab_index]->gotActive ();
83     }
84 }
85 
86 //-----------------------------------------------------------------------------
closeTab(int tab_index)87 void MainWindowModelImpl::closeTab (int tab_index)
88 {
89     if ((tab_index == 0) | (tab_index == 1))  // first two tabs are not closeable
90         return;
91     QWidget* widget = tab_widget_->widget (tab_index);
92     browser_models_.erase (tab_index);
93     tab_widget_->removeTab (tab_index);
94     delete widget;
95     int models_count = browser_models_.size();
96     if (models_count >= tab_index)
97     {
98         for (int index = tab_index + 1; index < models_count; index++)
99             browser_models_[index - 1] = browser_models_[index];
100     }
101     int event_views_count = event_views_.size();
102     if (event_views_count >= tab_index)
103     {
104         for (int index = tab_index + 1; index < event_views_count; index++)
105             if (event_views_.contains (index))
106                 event_views_[index - 1] = event_views_[index];
107     }
108 }
109 
110 //-----------------------------------------------------------------------------
recentFileMenuAboutToShow()111 void MainWindowModelImpl::recentFileMenuAboutToShow()
112 {
113     main_window_->setRecentFiles(recent_file_list_);
114 }
115 
116 //-----------------------------------------------------------------------------
recentFileActivated(QAction * recent_file_action)117 void MainWindowModelImpl::recentFileActivated(QAction* recent_file_action)
118 {
119     OpenFileGuiCommand::openFile (recent_file_action->text());
120 }
121 
122 //-----------------------------------------------------------------------------
storeAndInitTabContext(QSharedPointer<TabContext> context,int tab_index)123 void MainWindowModelImpl::storeAndInitTabContext (QSharedPointer<TabContext> context, int tab_index)
124 {
125     tab_contexts_[tab_index] = context;
126 
127     application_context_->setCurrentTabContext (context);
128 
129     context->setSelectionState (TAB_STATE_NO_EVENT_SELECTED);
130     context->setEditState (TAB_STATE_NO_REDO_NO_UNDO);
131 }
132 
133 //-------------------------------------------------------------------------
createSignalVisualisation(QString const & title,ChannelManager const & channel_manager)134 QSharedPointer<SignalVisualisationModel> MainWindowModelImpl::createSignalVisualisation (QString const& title, ChannelManager const& channel_manager)
135 {
136     int tab_index = createSignalVisualisationImpl (channel_manager, QSharedPointer<EventManager>(0));
137     tab_widget_->setTabText(tab_index, title);
138     tab_widget_->setCurrentIndex(tab_index);
139     return browser_models_[tab_index];
140 }
141 
142 //-----------------------------------------------------------------------------
createSignalVisualisationOfFile(QSharedPointer<FileContext> file_ctx)143 QSharedPointer<SignalVisualisationModel> MainWindowModelImpl::createSignalVisualisationOfFile (QSharedPointer<FileContext> file_ctx)
144 {
145     // waldesel:
146     // --begin
147     //   to be replaced as soon as multi file support is implemented
148     if (!(application_context_->getCurrentFileContext().isNull()))
149         GuiActionFactory::getInstance()->getQAction("Close")->trigger();
150     // --end
151 
152     if (!tab_widget_)
153     {
154         tab_widget_ = new QTabWidget (main_window_);
155         if (!connect (tab_widget_, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int))))
156             throw (Exception ("MainWindowModelImpl::createSignalVisualisationOfFile failed: connect (tab_widget_, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)))"));
157         connect (tab_widget_, SIGNAL(tabCloseRequested(int)), SLOT(closeTab(int)));
158         tab_widget_->setTabsClosable (true);
159     }
160 
161     recent_file_list_.removeAll (file_ctx->getFilePathAndName());
162     if (recent_file_list_.size() == NUMBER_RECENT_FILES_)
163         recent_file_list_.pop_back();
164     recent_file_list_.push_front (file_ctx->getFilePathAndName());
165 
166     saveSettings();
167 
168     // waldesel:
169     // --begin
170     //   to be replaced as soon as new zooming is implemented
171     main_window_->setStatusBarSignalLength (file_ctx->getChannelManager().getDurationInSec());
172     // --end
173 
174     main_window_->setStatusBarNrChannels (file_ctx->getChannelManager().getNumberChannels());
175     resetCurrentFileName (file_ctx->getFileName());
176     connect (file_ctx.data(), SIGNAL(fileNameChanged(QString const&)), SLOT(resetCurrentFileName(QString const&)));
177 
178     int tab_index = createSignalVisualisationImpl (file_ctx->getChannelManager(), file_ctx->getEventManager());
179     QString tab_title ("Signal Data");
180 
181     main_window_->setCentralWidget(tab_widget_);
182     tab_widget_->show();
183     tab_widget_->setTabText(tab_index, tab_title);
184     tab_widget_->tabBar()->setTabButton(0, QTabBar::RightSide, 0);
185     tab_widget_->tabBar()->setTabButton(0, QTabBar::LeftSide, 0);
186 
187     file_ctx->setMainVisualisationModel (browser_models_[tab_index]);
188     return browser_models_[tab_index];
189 }
190 
191 //-----------------------------------------------------------------------------
closeCurrentFileTabs()192 void MainWindowModelImpl::closeCurrentFileTabs ()
193 {
194     // waldesel:
195     // --begin
196     //   to be refactored as soon as multi file support is implemented
197     main_window_->setCentralWidget (0);
198     tab_widget_ = 0;
199     tab_contexts_.clear ();
200     // --end
201 
202     main_window_->setStatusBarSignalLength(-1);
203     main_window_->setStatusBarNrChannels(-1);
204     resetCurrentFileName ("");
205 }
206 
207 //-----------------------------------------------------------------------------
getCurrentSignalVisualisationModel()208 QSharedPointer<SignalVisualisationModel> MainWindowModelImpl::getCurrentSignalVisualisationModel ()
209 {
210     if (!tab_widget_)
211         return QSharedPointer<SignalVisualisationModel>(0);
212 
213     return browser_models_[tab_widget_->currentIndex()];
214 }
215 
216 //-------------------------------------------------------------------------
getCurrentEventView()217 QSharedPointer<EventView> MainWindowModelImpl::getCurrentEventView ()
218 {
219     if (!tab_widget_)
220         return QSharedPointer<EventView>(0);
221 
222     if (!event_views_.contains (tab_widget_->currentIndex()))
223         return QSharedPointer<EventView>(0);
224 
225     return event_views_[tab_widget_->currentIndex()];
226 }
227 
228 //-------------------------------------------------------------------------
resetCurrentFileName(QString const & file_name)229 void MainWindowModelImpl::resetCurrentFileName (QString const& file_name)
230 {
231     if (file_name.size() == 0)
232         main_window_->setWindowTitle (tr("SigViewer"));
233     else
234         main_window_->setWindowTitle (file_name + tr(" - SigViewer"));
235 }
236 
237 //-------------------------------------------------------------------------
createSignalVisualisationImpl(ChannelManager const & channel_manager,QSharedPointer<EventManager> event_manager)238 int MainWindowModelImpl::createSignalVisualisationImpl (ChannelManager const& channel_manager,
239                                                         QSharedPointer<EventManager> event_manager)
240 {
241     QSharedPointer<TabContext> tab_context (new TabContext);
242 
243     QSharedPointer<SignalBrowserModel> model (new SignalBrowserModel (event_manager,
244                                                                       channel_manager,
245                                                                       tab_context,
246                                                                       application_context_->getEventColorManager()));
247 
248     SignalBrowserView* view = new SignalBrowserView (model, event_manager, tab_context, main_window_->rect(), tab_widget_);
249 
250     int tab_index = tab_widget_->addTab (view, tr("Signal"));
251 
252     model->setSignalBrowserView (view);
253     browser_models_[tab_index] = model;
254     event_views_[tab_index] = model;
255 
256     if (!event_manager.isNull())
257     {
258         EventTableWidget* event_table_widget = new EventTableWidget (tab_context, event_manager, channel_manager);
259         int event_tab_index = tab_widget_->addTab (event_table_widget, tr("Events"));
260         browser_models_[event_tab_index] = QSharedPointer<SignalBrowserModel>(0);
261         event_views_[event_tab_index] = event_table_widget->getEventView();
262         tab_contexts_[event_tab_index] = tab_context;
263 
264         model->connect (event_manager.data(), SIGNAL(eventCreated(QSharedPointer<SignalEvent const>)),
265                                    SLOT(addEventItem(QSharedPointer<SignalEvent const>)));
266         model->connect (event_manager.data(), SIGNAL(eventRemoved(EventID)),
267                                    SLOT(removeEventItem(EventID)));
268         model->connect (event_manager.data(), SIGNAL(eventChanged(EventID)),
269                                    SLOT(updateEvent(EventID)));
270         tab_widget_->tabBar()->setTabButton(1, QTabBar::RightSide, 0);
271         tab_widget_->tabBar()->setTabButton(1, QTabBar::LeftSide, 0);
272     }
273     storeAndInitTabContext (tab_context, tab_index);
274     return tab_index;
275 }
276 
277 
278 }
279