diff --git a/scribus/CMakeLists.txt b/scribus/CMakeLists.txt index 33c757c1581ca747cb9ec97c6cf2ef38302cac92..d4c6ace2b3e2a42e36e09d8e76755a9939639a16 100644 --- a/scribus/CMakeLists.txt +++ b/scribus/CMakeLists.txt @@ -34,6 +34,7 @@ add_subdirectory(dtd) add_subdirectory(colormgmt) add_subdirectory(desaxe) add_subdirectory(fonts) +add_subdirectory(marks) add_subdirectory(styles) add_subdirectory(text) add_subdirectory(ui/qml) @@ -1127,6 +1128,7 @@ link_directories( ${CMAKE_CURRENT_BINARY_DIR}/colormgmt ${CMAKE_CURRENT_BINARY_DIR}/desaxe ${CMAKE_CURRENT_BINARY_DIR}/fonts + ${CMAKE_CURRENT_BINARY_DIR}/marks ${CMAKE_CURRENT_BINARY_DIR}/styles ${CMAKE_CURRENT_BINARY_DIR}/text ${CMAKE_CURRENT_BINARY_DIR}/third_party/wpg @@ -1156,6 +1158,7 @@ if(WITH_TESTS) else() set(SCRIBUS_TESTS_LIB "") endif() +set(SCRIBUS_MARKS_LIB "scribus_marks_lib") set(SCRIBUS_STYLES_LIB "scribus_styles_lib") set(SCRIBUS_FONTS_LIB "scribus_fonts_lib") set(SCRIBUS_DESAXE_LIB "scribus_desaxe_lib") @@ -1225,6 +1228,7 @@ if(HAVE_OSG) ${SCRIBUS_MAIN_CPP} ${SCRIBUS_UI_SOURCES} ${SCRIBUS_TEXT_SOURCES} + ${SCRIBUS_MARKS_SOURCES} ${SCRIBUS_STYLES_SOURCES} ${SCRIBUS_COLORMGMT_SOURCES} ${SCRIBUS_FONTS_SOURCES} @@ -1240,6 +1244,7 @@ else() ${SCRIBUS_MAIN_CPP} ${SCRIBUS_UI_SOURCES} ${SCRIBUS_TEXT_SOURCES} + ${SCRIBUS_MARKS_SOURCES} ${SCRIBUS_STYLES_SOURCES} ${SCRIBUS_COLORMGMT_SOURCES} ${SCRIBUS_FONTS_SOURCES} @@ -1356,6 +1361,7 @@ target_link_libraries(${EXE_NAME} ${SCRIBUS_COLORMGMT_LIB} ${SCRIBUS_DESAXE_LIB} ${SCRIBUS_TEXT_LIB} + ${SCRIBUS_MARKS_LIB} ${SCRIBUS_STYLES_LIB} ${SCRIBUS_FONTS_LIB} ${SCRIBUS_WPG_LIB} diff --git a/scribus/actionmanager.cpp b/scribus/actionmanager.cpp index 13328224ada0795d77f972e61a9dc9b0bda7bb36..bad1a36bbfa4728730bc944d0dcceb82baf1a6ab 100644 --- a/scribus/actionmanager.cpp +++ b/scribus/actionmanager.cpp @@ -31,6 +31,8 @@ for which a new license (GPL+exception) is in place. #include "urllauncher.h" #include "iconmanager.h" +#include "marks/anchor.h" + QMap ActionManager::defKeys; QVector< QPair > ActionManager::defMenuNames; QVector< QPair > ActionManager::defMenus; @@ -582,7 +584,7 @@ void ActionManager::initInsertMenuActions() connect( (*scrActions)["insertSampleText"], SIGNAL(triggered()), mainWindow, SLOT(insertSampleText()) ); connect( (*scrActions)["stickyTools"], SIGNAL(triggered()), mainWindow, SLOT(ToggleStickyTools()) ); - connect( (*scrActions)["insertMarkAnchor"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkAnchor()) ); + connect((*scrActions)["insertMarkAnchor"], &ScrAction::triggered, [](){ Marks::Anchor::insertSlot(); }); connect( (*scrActions)["insertMarkVariableText"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkVariableText()) ); connect( (*scrActions)["insertMarkItem"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkItem()) ); connect( (*scrActions)["insertMark2Mark"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMark2Mark()) ); diff --git a/scribus/marks/CMakeLists.txt b/scribus/marks/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..ebf06a1f91a7ee7803e725d89ed646e5cdb4b25a --- /dev/null +++ b/scribus/marks/CMakeLists.txt @@ -0,0 +1,36 @@ +include_directories( + ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/scribus + ${FREETYPE_INCLUDE_DIRS} +) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_FPIC}") + +set(SCRIBUS_MARKS_MOC_CLASSES + anchor.h + anchordialog.h +) + +set(SCRIBUS_MARKS_UI_SRC + anchordialog.ui +) + +set(SCRIBUS_MARKS_LIB_SOURCES + marks.cpp + anchor.cpp + anchordialog.cpp +) + +QT5_WRAP_CPP(SCRIBUS_MARKS_MOC_SOURCES ${SCRIBUS_MARKS_MOC_CLASSES}) +QT5_WRAP_UI(SCRIBUS_MARKS_UI_SOURCES ${SCRIBUS_MARKS_UI_SRC}) + +set(SCRIBUS_MARKS_LIB "scribus_marks_lib") +add_library(${SCRIBUS_MARKS_LIB} STATIC ${SCRIBUS_MARKS_LIB_SOURCES} ${SCRIBUS_MARKS_MOC_SOURCES} ${SCRIBUS_MARKS_UI_SOURCES}) + +# This is a convenience library that for linkage purposes is part of Scribus's +# main API. +set_target_properties(${SCRIBUS_MARKS_LIB} + PROPERTIES + COMPILE_FLAGS -DCOMPILE_SCRIBUS_MAIN_APP +) + diff --git a/scribus/marks/anchor.cpp b/scribus/marks/anchor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5f7223e01ac9a8bc3fb027b277163075590620c4 --- /dev/null +++ b/scribus/marks/anchor.cpp @@ -0,0 +1,80 @@ +#include "marks/anchor.h" + +#include "scribuscore.h" +#include "scribus.h" +#include "scribusdoc.h" +#include "undomanager.h" +#include "pageitem_textframe.h" +#include "util.h" + +#include "marks/marks.h" +#include "marks/anchordialog.h" + +namespace Marks { + +bool Anchor::insert(PageItem_TextFrame* textFrame, QString& label) +{ + auto doc = textFrame->doc(); + auto undoManager = UndoManager::instance(); + + // there cannot be bookmarks on master pages + if (doc->masterPageMode()) + return false; + + auto trans = undoManager->beginTransaction(); + // TODO: if there is a selection use it as the label, do not delete it + if (textFrame->HasSel) + { + trans = undoManager->beginTransaction(Um::Selection, Um::IDelete, Um::Delete, QString(), Um::IDelete); + textFrame->deleteSelectedTextFromFrame(); + } + + MarkData markdata; + markdata.itemName = textFrame->itemName(); + markdata.itemPtr = textFrame; + + Mark* mrk = doc->newMark(); + mrk->setValues(label, textFrame->OwnPage, MARKAnchorType, markdata); + // TODO: remove selection, insert mark, restore the selection + textFrame->itemText.insertMark(mrk); + mrk->OwnPage = textFrame->OwnPage; + + if (undoManager->undoEnabled()) + { + ScItemsState* is = new ScItemsState(undoManager->InsertMark); + is->set("ETEA", mrk->label); + is->set("label", mrk->label); + is->set("type", (int) mrk->getType()); + is->set("MARK", QString("new")); + is->set("strtxt", mrk->getString()); + is->set("at", textFrame->itemText.cursorPosition() -1); + is->insertItem("inItem", textFrame); + undoManager->action(doc, is); + + trans.commit(); + } + return true; +} + +void Anchor::insertSlot() +{ + auto win = ScCore->primaryMainWindow(); + if (!win->HaveDoc) + return; + + auto currItem = Marks::getTextFrameFromPage(win->doc); + if (!currItem) + return; + + AnchorDialog dialog(win); + if (!dialog.exec()) + return; + + QString label = dialog.getLabel(); + getUniqueName(label, win->doc->marksLabelsList(MARKAnchorType), "_"); + + if (insert(currItem, label)) + Marks::refreshView(currItem); +} + +} diff --git a/scribus/marks/anchor.h b/scribus/marks/anchor.h new file mode 100644 index 0000000000000000000000000000000000000000..a6709fb8da79ba4b735ea7875a0ce21bf3ab0edb --- /dev/null +++ b/scribus/marks/anchor.h @@ -0,0 +1,29 @@ +#ifndef MARKSANCHOR_H +#define MARKSANCHOR_H + +#include +#include +#include "scribusapi.h" + +class PageItem_TextFrame; + +namespace Marks { + +class SCRIBUS_API Anchor : public QObject +{ + Q_OBJECT + +private: + Anchor() = default; + ~Anchor() = default; + +public: + /** \return true if the mark was insterted */ + static bool insert(PageItem_TextFrame* pageItem, QString& label); +public slots: + static void insertSlot(); +}; + +} + +#endif // MARKSANCHOR_H diff --git a/scribus/marks/anchordialog.cpp b/scribus/marks/anchordialog.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c418ca2c97cc7e077d368148d469aa2d84050eb9 --- /dev/null +++ b/scribus/marks/anchordialog.cpp @@ -0,0 +1,29 @@ +#include "marks/anchordialog.h" +#include "marks/marks.h" + +namespace Marks { + +AnchorDialog::AnchorDialog(QWidget *parent) : + QDialog(parent), + ui{new Ui::AnchorDialog} +{ + ui->setupUi(this); +} + +AnchorDialog::~AnchorDialog() +{ + delete ui; +} + +QString AnchorDialog::getLabel() +{ + auto label = ui->labelEdit->text(); + return label.isEmpty() ? tr("Anchor mark") : label; +} + +void AnchorDialog::setLabel(const QString& label) +{ + ui->labelEdit->setText(label); +} + +} diff --git a/scribus/marks/anchordialog.h b/scribus/marks/anchordialog.h new file mode 100644 index 0000000000000000000000000000000000000000..7558f30fd0b5433d4a63710a8c4bbf9e999f58a1 --- /dev/null +++ b/scribus/marks/anchordialog.h @@ -0,0 +1,31 @@ +#ifndef MARKSANCHORDIALOG_H +#define MARKSANCHORDIALOG_H + +#include +#include "scribusapi.h" +#include "marks/ui_anchordialog.h" + + +namespace Marks { + +namespace Ui { class AnchorDialog; } + + +class SCRIBUS_API AnchorDialog : public QDialog +{ + Q_OBJECT + +public: + AnchorDialog(QWidget *parent = nullptr); + ~AnchorDialog(); + + QString getLabel(); + void setLabel(const QString& label); + +private: + Ui::AnchorDialog *ui; +}; + +} + +#endif // MARKSANCHORDIALOG_H diff --git a/scribus/marks/anchordialog.ui b/scribus/marks/anchordialog.ui new file mode 100644 index 0000000000000000000000000000000000000000..4913b08bb3035ef1fad3f753fa6a73dcaceaf6b2 --- /dev/null +++ b/scribus/marks/anchordialog.ui @@ -0,0 +1,92 @@ + + + Marks::AnchorDialog + + + + 0 + 0 + 400 + 81 + + + + + 0 + 0 + + + + + 0 + 81 + + + + + 16777215 + 81 + + + + Insert new Anchor + + + + + + Label: + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + Marks::AnchorDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Marks::AnchorDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/scribus/marks/marks.cpp b/scribus/marks/marks.cpp new file mode 100644 index 0000000000000000000000000000000000000000..de35775c3cde39903f378ade0f48bba65f54b46e --- /dev/null +++ b/scribus/marks/marks.cpp @@ -0,0 +1,45 @@ +#include "marks.h" + +#include "scribuscore.h" +#include "scribus.h" +#include "scribusdoc.h" +#include "pageitem.h" +#include "pageitem_textframe.h" +#include "selection.h" +#include "scribusview.h" + +namespace Marks { + +PageItem_TextFrame* Marks::getTextFrame(ScribusDoc* doc) +{ + if (doc->m_Selection->count() != 1) + return nullptr; + if (doc->appMode != modeEdit) + return nullptr; + auto currItem = doc->m_Selection->itemAt(0); + if (!currItem->isTextFrame()) + return nullptr; + return currItem->asTextFrame(); +} + +PageItem_TextFrame* Marks::getTextFrameFromPage(ScribusDoc* doc) +{ + if (doc->masterPageMode()) + return nullptr; + return getTextFrame(doc); +} + +void Marks::refreshView(PageItem_TextFrame* textFrame) +{ + auto doc = textFrame->doc(); + auto view = ScCore->primaryMainWindow()->view; + + view->updatesOn(false); + textFrame->invalidateLayout(); + textFrame->layout(); + doc->changed(); + view->updatesOn(true); + view->DrawNew(); +} + +} diff --git a/scribus/marks/marks.h b/scribus/marks/marks.h new file mode 100644 index 0000000000000000000000000000000000000000..020c7561713dc5c39340586fff88add918cae006 --- /dev/null +++ b/scribus/marks/marks.h @@ -0,0 +1,22 @@ +#ifndef MARKSMARKS_H +#define MARKSMARKS_H + +class PageItem_TextFrame; +class ScribusDoc; + +namespace Marks { + +class Marks +{ +public: + /** @brief return the currently selected text frame on the page or master page*/ + static PageItem_TextFrame* getTextFrame(ScribusDoc* doc); + /** @brief return the currently selected text frame on the page */ + static PageItem_TextFrame* getTextFrameFromPage(ScribusDoc* doc); + /** @brief refresh the layout */ + static void refreshView(PageItem_TextFrame* textFrame); +}; + +} + +#endif // Marks diff --git a/scribus/scribus.h b/scribus/scribus.h index 71cee3f2ba1c243606c81840f09d78a74dfaf8cc..45c90bbd16c43a2100df6007b1fe70689baa7c89 100644 --- a/scribus/scribus.h +++ b/scribus/scribus.h @@ -565,7 +565,6 @@ public slots: //inserting marks void slotInsertMark2Mark() { insertMark(MARK2MarkType); } - void slotInsertMarkAnchor() { insertMark(MARKAnchorType); } void slotInsertMarkVariableText() { insertMark(MARKVariableTextType); } void slotInsertMarkItem() { insertMark(MARK2ItemType); } void slotInsertMarkNote();