2 * \file GuiEmbeddedFiles.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
8 * Full author contact details are available in file CREDITS.
13 #include "GuiEmbeddedFiles.h"
17 #include "FuncRequest.h"
23 #include "frontend_helpers.h"
24 #include "frontends/LyXView.h"
26 #include "support/FileFilterList.h"
34 using support::FileFilterList;
36 EmbeddedFilesWidget::EmbeddedFilesWidget
37 (GuiEmbeddedFiles & controller)
38 : controller_(controller)
41 setWindowTitle("LyX: " + qt_("Embedded Files"));
43 // FIXME: Temporary icons.
44 selectPB->setIcon(QIcon(":/images/tabular-feature_set-all-lines.png"));
45 unselectPB->setIcon(QIcon(":/images/tabular-feature_unset-all-lines.png"));
46 addPB->setIcon(QIcon(":/images/file-open.png"));
47 extractPB->setIcon(QIcon(":/images/depth-decrement.png"));
48 updatePB->setIcon(QIcon(":/images/depth-increment.png"));
54 void EmbeddedFilesWidget::on_filesLW_itemChanged(QListWidgetItem* item)
56 EmbeddedFiles & files = controller_.embeddedFiles();
57 if (item->checkState() == Qt::Checked) {
58 if (files[filesLW->row(item)].embedded())
60 // this should not be needed after EmbeddedFiles are updated correctly.
62 controller_.setEmbed(files[filesLW->row(item)], true, files.enabled());
64 if (!files[filesLW->row(item)].embedded())
66 // this should not be needed after EmbeddedFiles are updated correctly.
68 controller_.setEmbed(files[filesLW->row(item)], false, files.enabled());
73 void EmbeddedFilesWidget::on_filesLW_itemSelectionChanged()
75 if (controller_.isReadonly())
78 QList<QListWidgetItem *> selection = filesLW->selectedItems();
80 if (selection.empty()) {
81 fullpathLE->setEnabled(false);
82 selectPB->setEnabled(false);
83 unselectPB->setEnabled(false);
84 extractPB->setEnabled(false);
85 updatePB->setEnabled(false);
89 fullpathLE->setEnabled(selection.size() == 1);
91 // try to find a common embedding status
92 bool hasSelected = false;
93 bool hasUnselected = false;
94 QList<QListWidgetItem*>::iterator it = selection.begin();
95 QList<QListWidgetItem*>::iterator it_end = selection.end();
96 for (; it != it_end; ++it) {
97 if ((*it)->checkState() == Qt::Checked)
100 hasUnselected = true;
102 selectPB->setEnabled(hasUnselected);
103 unselectPB->setEnabled(hasSelected);
107 void EmbeddedFilesWidget::on_filesLW_itemClicked(QListWidgetItem* item)
109 EmbeddedFiles & files = controller_.embeddedFiles();
110 int idx = filesLW->row(item);
111 fullpathLE->setText(toqstr(files[idx].absFilename()));
112 if (files[idx].refCount() > 1) {
113 // if multiple insets are referred, click again will move
115 int k = item->data(Qt::UserRole).toInt();
116 controller_.goTo(files[idx], k);
117 k = (k + 1) % files[idx].refCount();
118 item->setData(Qt::UserRole, k);
120 QString label = toqstr(files[idx].inzipName())
121 + QString(" (%1/%2)").arg(k + 1).arg(files[idx].refCount());
122 item->setText(label);
123 } else if (files[idx].refCount() == 1)
124 controller_.goTo(files[idx], 0);
128 void EmbeddedFilesWidget::on_filesLW_itemDoubleClicked(QListWidgetItem* item)
130 EmbeddedFiles & files = controller_.embeddedFiles();
131 controller_.view(files[filesLW->row(item)]);
135 void EmbeddedFilesWidget::updateView()
137 bool readOnly = controller_.isReadonly();
138 fullpathLE->setEnabled(!readOnly);
139 selectPB->setEnabled(!readOnly);
140 unselectPB->setEnabled(!readOnly);
141 addPB->setEnabled(!readOnly);
142 extractPB->setEnabled(!readOnly);
143 updatePB->setEnabled(!readOnly);
144 enableCB->setEnabled(!readOnly);
147 EmbeddedFiles const & files = controller_.embeddedFiles();
148 enableCB->setCheckState(files.enabled() ? Qt::Checked : Qt::Unchecked);
149 EmbeddedFiles::EmbeddedFileList::const_iterator it = files.begin();
150 EmbeddedFiles::EmbeddedFileList::const_iterator it_end = files.end();
151 for (; it != it_end; ++it) {
152 QString label = toqstr(it->inzipName());
153 if (it->refCount() > 1)
154 label += " (1/" + QString::number(it->refCount()) + ")";
155 QListWidgetItem * item = new QListWidgetItem(label);
156 Qt::ItemFlags flag = Qt::ItemIsSelectable;
158 flag |= Qt::ItemIsUserCheckable;
160 flag |= Qt::ItemIsEnabled;
161 item->setFlags(flag);
163 item->setCheckState(Qt::Checked);
165 item->setCheckState(Qt::Unchecked);
166 // index of the currently used ParConstIterator
167 item->setData(Qt::UserRole, 0);
168 filesLW->addItem(item);
173 void EmbeddedFilesWidget::on_selectPB_clicked()
175 EmbeddedFiles & files = controller_.embeddedFiles();
176 // this should not be needed after EmbeddedFiles are updated correctly.
178 QList<QListWidgetItem *> selection = filesLW->selectedItems();
179 for (QList<QListWidgetItem*>::iterator it = selection.begin();
180 it != selection.end(); ++it) {
181 (*it)->setCheckState(Qt::Checked);
182 controller_.setEmbed(files[filesLW->row(*it)], true, files.enabled());
184 controller_.dispatchMessage("Embedding files");
188 void EmbeddedFilesWidget::on_unselectPB_clicked()
190 EmbeddedFiles & files = controller_.embeddedFiles();
191 // this should not be needed after EmbeddedFiles are updated correctly.
193 QList<QListWidgetItem *> selection = filesLW->selectedItems();
194 for (QList<QListWidgetItem*>::iterator it = selection.begin();
195 it != selection.end(); ++it) {
196 (*it)->setCheckState(Qt::Checked);
197 controller_.setEmbed(files[filesLW->row(*it)], false, files.enabled());
199 controller_.dispatchMessage("Stop embedding files");
203 void EmbeddedFilesWidget::on_addPB_clicked()
205 if (controller_.browseAndAddFile())
210 void EmbeddedFilesWidget::on_extractPB_clicked()
212 EmbeddedFiles const & files = controller_.embeddedFiles();
213 QList<QListWidgetItem *> selection = filesLW->selectedItems();
214 for (QList<QListWidgetItem*>::iterator it = selection.begin();
215 it != selection.end(); ++it)
216 controller_.extract(files[filesLW->row(*it)]);
217 // FIXME: collect extraction status and display a dialog
218 controller_.dispatchMessage("Extract embedded files");
222 void EmbeddedFilesWidget::on_updatePB_clicked()
224 EmbeddedFiles const & files = controller_.embeddedFiles();
225 QList<QListWidgetItem *> selection = filesLW->selectedItems();
226 for (QList<QListWidgetItem*>::iterator it = selection.begin();
227 it != selection.end(); ++it)
228 controller_.update(files[filesLW->row(*it)]);
229 // FIXME: collect update status and display a dialog
230 controller_.dispatchMessage("Update embedded files from external file");
235 void EmbeddedFilesWidget::on_enableCB_toggled(bool enable)
237 controller_.setEmbedding(enable);
242 GuiEmbeddedFiles::GuiEmbeddedFiles(GuiViewBase & parent,
243 Qt::DockWidgetArea area, Qt::WindowFlags flags)
244 : DockView(parent, "embedded", area, flags)
246 widget_ = new EmbeddedFilesWidget(*this);
248 setWindowTitle(widget_->windowTitle());
252 void GuiEmbeddedFiles::updateView()
254 widget_->updateView();
258 EmbeddedFiles & GuiEmbeddedFiles::embeddedFiles()
260 return buffer().embeddedFiles();
264 bool GuiEmbeddedFiles::initialiseParams(string const &)
270 void GuiEmbeddedFiles::updateEmbeddedFiles()
272 // copy buffer embeddedFiles to a local copy
273 buffer().embeddedFiles().update();
274 buffer().embeddingChanged();
278 void GuiEmbeddedFiles::dispatchMessage(string const & msg)
280 // FIXME: the right thing to do? QT guys?
281 // lyx view will only be updated if we do something to the main window. :-)
282 dispatch(FuncRequest(LFUN_MESSAGE, msg));
286 bool GuiEmbeddedFiles::isReadonly()
288 return buffer().isReadonly();
292 void GuiEmbeddedFiles::setEmbedding(bool enable)
294 if (embeddedFiles().enabled() == enable)
296 embeddedFiles().enable(enable);
297 buffer().markDirty();
299 dispatchMessage("Stop saving in bundled format.");
301 dispatchMessage("Save in bundled format.");
305 void GuiEmbeddedFiles::goTo(EmbeddedFile const & item, int idx)
307 BOOST_ASSERT(idx < item.refCount());
308 item.saveBookmark(&buffer(), idx);
309 lyxview().dispatch(FuncRequest(LFUN_BOOKMARK_GOTO, "0"));
313 void GuiEmbeddedFiles::view(EmbeddedFile const & item)
315 formats.view(buffer(), item, formats.getFormatFromFile(item));
319 void GuiEmbeddedFiles::setEmbed(EmbeddedFile & item, bool embed, bool update)
321 if (item.embedded() == embed)
323 item.setEmbed(embed);
326 item.updateFromExternalFile(&buffer());
328 item.extract(&buffer());
329 item.updateInsets(&buffer());
330 // FIXME: unless we record the type of file item, we will
331 // need to update all possible dialogs (bibtex etc).
332 updateDialog("graphics");
335 dispatchMessage("Embed file " + item.outputFilename(buffer().filePath()));
337 dispatchMessage("Stop embedding file " + item.outputFilename(buffer().filePath()));
338 buffer().markDirty();
342 bool GuiEmbeddedFiles::browseAndAddFile()
344 std::pair<docstring, docstring> dir1(_("Documents|#o#O"),
345 from_utf8(lyxrc.document_path));
346 FileFilterList const filter(_("All file (*.*)"));
347 docstring const file = browseRelFile(docstring(), from_utf8(bufferFilepath()),
348 _("Select a file to embed"),
349 filter, false, dir1);
351 EmbeddedFile & ef = embeddedFiles().registerFile(to_utf8(file), true);
352 if (embeddedFiles().enabled())
353 ef.updateFromExternalFile(&buffer());
354 buffer().markDirty();
355 dispatchMessage("Add an embedded file" + to_utf8(file));
362 bool GuiEmbeddedFiles::extract(EmbeddedFile const & item)
365 return item.extract(&buffer());
371 bool GuiEmbeddedFiles::update(EmbeddedFile const & item)
374 return item.updateFromExternalFile(&buffer());
380 Dialog * createGuiEmbeddedFiles(LyXView & lv)
382 GuiViewBase & guiview = static_cast<GuiViewBase &>(lv);
384 // On Mac show as a drawer at the right
385 return new GuiEmbeddedFiles(guiview, Qt::RightDockWidgetArea, Qt::Drawer);
387 return new GuiEmbeddedFiles(guiview, Qt::RightDockWidgetArea);
392 } // namespace frontend
395 #include "GuiEmbeddedFiles_moc.cpp"