diff --git a/CalligraProducts.cmake b/CalligraProducts.cmake index 7d8938ac63b..0942c533f0c 100644 --- a/CalligraProducts.cmake +++ b/CalligraProducts.cmake @@ -1,639 +1,639 @@ ### DEFINITION OF PRODUCTS, FEATURES AND PRODUCTSETS #################################################### # When building Calligra a lot of different things are created and installed. To # describe them and their internal dependencies the concepts of "product", # "feature" and "product set" are used. # A "product" is the smallest functional unit which can be created in the build # and which is useful on its own when installed. Examples are e.g. libraries, # plugins or executables. Products have external and internal required # dependencies at build-time. Internal dependencies are noted in terms of other # products or features (see below) and could be e.g. other libraries to link # against or build tools needed to generate source files. # A product gets defined by setting an identifier, a descriptive fullname and # the needed internal build-time requirements. Any other product or feature # listed as requirement must have been defined before. # A "feature" is not a standalone product, but adds abilities to one or multiple # given products. One examples is e.g. scriptability. Features have external and # internal required dependencies at build-time. Internal dependencies are noted # in terms of other products or features and could be e.g. other libraries to # link against or build tools needed to generate source files. # A feature gets defined by setting an identifier, a descriptive fullname and # the needed internal build-time requirements. Any other product or feature # listed as requirement must have been defined before. # A "productset" is a selection of products and features which should be build # together. The products and features can be either essential or optional to the # set. If essential (REQUIRES), the whole productset will not be build if a # product or feature is missing another internal or external dependency. If # optional (OPTIONAL), the rest of the set will still be build in that case. # The products and features to include in a set can be listed directly or # indirectly: they can be named explicitly, but also by including other # productsets in a set, whose products and features will then be part of the # first set as well. # Products, features and productsets can be listed as dependencies in multiple # product sets. As with dependencies for products or features, they must have # been defined before. # Products, features and product sets are in the same namespace, so a given # identifier can be only used either for a product or for a feature or for a # product set. # The ids of products and features (but not sets) are used to generate cmake # variables SHOULD_BUILD_${ID}, which then are used to control what is build and # how. ############################################# #### Product definitions #### ############################################# # For defining new products see end of this file, "How to add another product?" # IDEA: also add headers/sdk for all the libs ("_DEVEL"?) # IDEA: note external deps for products, so they are only checked if needed # There can be required or optional external deps, required will also result # in automatic disabling of product building # TODO: some products have multiple optional requirements, but need at least one. # See APP_CONVERTER, FILEMANAGER_* # building tools calligra_define_product(BUILDTOOL_RNG2CPP "rng2cpp") # Calligra-independent utility libs calligra_define_product(LIB_KOVECTORIMAGE "libkovectorimage") # calligra libs calligra_define_product(LIB_CALLIGRA "Calligra core libs" REQUIRES BUILDTOOL_RNG2CPP) calligra_define_product(LIB_KOMAIN "Lib for one-file-per-window apps" REQUIRES LIB_CALLIGRA) calligra_define_product(LIB_KOPAGEAPP "Lib for paged documents" REQUIRES LIB_CALLIGRA LIB_KOMAIN) calligra_define_product(LIB_KOODF2 "libkoodf2" REQUIRES LIB_CALLIGRA) calligra_define_product(LIB_KOODFREADER "libkoodfreader" REQUIRES LIB_KOODF2 LIB_CALLIGRA) calligra_define_product(LIB_MSO "libmso" REQUIRES LIB_CALLIGRA) calligra_define_product(LIB_KOMSOOXML "libkomsooxml" REQUIRES LIB_CALLIGRA LIB_KOODF2 LIB_KOMAIN) # features calligra_define_feature(FEATURE_SCRIPTING UNMAINTAINED "Scripting feature") calligra_define_feature(FEATURE_RDF UNMAINTAINED "RDF feature") # plugins calligra_define_product(PLUGIN_TEXTSHAPE "Text shape plugin" REQUIRES LIB_CALLIGRA) calligra_define_product(PLUGIN_PICTURESHAPE "Picture shape plugin" REQUIRES LIB_CALLIGRA) # parts calligra_define_product(PART_WORDS "Words engine" REQUIRES LIB_CALLIGRA LIB_KOMAIN PLUGIN_TEXTSHAPE) calligra_define_product(PART_STAGE "Stage engine" REQUIRES LIB_CALLIGRA LIB_KOMAIN LIB_KOPAGEAPP PLUGIN_TEXTSHAPE PLUGIN_PICTURESHAPE) calligra_define_product(PART_SHEETS "Sheets engine" REQUIRES LIB_CALLIGRA LIB_KOMAIN) calligra_define_product(PART_QTQUICK "QtQuick Plugin that provides Calligra components" UNPORTED REQUIRES PART_WORDS PART_STAGE)# SHEETS_PART) calligra_define_product(PART_COMPONENTS "QtQuick2 Plugin that provides Calligra components" REQUIRES PART_WORDS PART_STAGE PART_SHEETS) # apps calligra_define_product(APP_WORDS "Words app (for Desktop)" REQUIRES PART_WORDS) calligra_define_product(APP_STAGE "Stage app (for Desktop)" REQUIRES PART_STAGE) calligra_define_product(APP_SHEETS "Sheets app (for Desktop)" REQUIRES PART_SHEETS) -calligra_define_product(APP_KARBON "Karbon app (for Desktop)" REQUIRES LIB_CALLIGRA LIB_KOMAIN) +calligra_define_product(APP_KARBON "Karbon app (for Desktop)" REQUIRES LIB_CALLIGRA LIB_KOMAIN LIB_KOPAGEAPP) calligra_define_product(APP_FLOW "Flow app (for Desktop)" REQUIRES LIB_CALLIGRA LIB_KOMAIN LIB_KOPAGEAPP) calligra_define_product(APP_BRAINDUMP "Braindump app (for Desktop)" UNMAINTAINED REQUIRES LIB_CALLIGRA LIB_KOMAIN) calligra_define_product(DOC "Calligra Documentations" STAGING) # staging apps calligra_define_product(APP_GEMINI "The Calligra Gemini application" REQUIRES PART_COMPONENTS) # TODO: this needs to be split up by app products # extras calligra_define_product(APP_CONVERTER "Format converter for commandline" REQUIRES LIB_CALLIGRA LIB_KOMAIN) calligra_define_product(FILEMANAGER_PROPERTIES "Plugin for the KDE file properties dialog" REQUIRES LIB_CALLIGRA) calligra_define_product(FILEMANAGER_THUMBNAIL "Plugins for KDE filesystem thumbnailing" REQUIRES LIB_CALLIGRA LIB_KOMAIN) calligra_define_product(FILEMANAGER_QUICKPRINT "Plugin for the filemanager adding a \"Print\" action") calligra_define_product(FILEMANAGER_TEMPLATES "File templates for filemanager") calligra_define_product(OKULAR_GENERATOR_ODP "Plugin for Okular adding support for ODP" REQUIRES PART_STAGE) calligra_define_product(OKULAR_GENERATOR_ODT "Plugin for Okular adding support for ODT" REQUIRES PART_WORDS) # more plugins calligra_define_product(PLUGIN_COLORENGINES "Colorengine plugins" REQUIRES LIB_CALLIGRA) calligra_define_product(PLUGIN_MUSICSHAPE "Music shape plugin" REQUIRES LIB_CALLIGRA) calligra_define_product(PLUGIN_SPACENAVIGATOR "SpaceNavigator input plugin" REQUIRES LIB_CALLIGRA) calligra_define_product(PLUGIN_ARTISTICTEXTSHAPE "Artistic shape plugin" REQUIRES LIB_CALLIGRA) calligra_define_product(PLUGIN_DOCKERS "Default dockers plugin" REQUIRES LIB_CALLIGRA) calligra_define_product(PLUGIN_TEXTEDITING "Textediting plugins" REQUIRES LIB_CALLIGRA) calligra_define_product(PLUGIN_DEFAULTTOOLS "Default Flake tools plugin" REQUIRES LIB_CALLIGRA) calligra_define_product(PLUGIN_PATHSHAPES "Path shape plugins" REQUIRES LIB_CALLIGRA) calligra_define_product(PLUGIN_VARIABLES "Text variables plugin" REQUIRES LIB_CALLIGRA) calligra_define_product(PLUGIN_CHARTSHAPE "Chart shape plugin" REQUIRES LIB_CALLIGRA LIB_KOMAIN) calligra_define_product(PLUGIN_PLUGINSHAPE "Plugin shape plugin" REQUIRES LIB_CALLIGRA LIB_KOMAIN) calligra_define_product(PLUGIN_FORMULASHAPE "Formula shape plugin" REQUIRES LIB_CALLIGRA LIB_KOMAIN) calligra_define_product(PLUGIN_VIDEOSHAPE "Plugin for handling videos in Calligra" REQUIRES LIB_CALLIGRA) calligra_define_product(PLUGIN_VECTORSHAPE "Vectorgraphic shape plugin" REQUIRES LIB_CALLIGRA LIB_KOVECTORIMAGE) calligra_define_product(PLUGIN_SEMANTICITEMS "Semantic items plugins" REQUIRES FEATURE_RDF LIB_CALLIGRA) calligra_define_product(PLUGIN_SHAPEFILTEREFFECTS "Default shape filtereffects plugin" REQUIRES LIB_CALLIGRA) calligra_define_product(PLUGIN_STENCILSDOCKER "Stencils docker plugin" REQUIRES LIB_CALLIGRA) calligra_define_product(PLUGIN_KARBONPLUGINS "Semantic items plugins" REQUIRES LIB_CALLIGRA) calligra_define_product(PLUGIN_CALLIGRAGEMINI_GIT "Git support plugin for Calligra Gemini") # staging plugins calligra_define_product(PLUGIN_THREEDSHAPE "3D shape plugin" STAGING REQUIRES LIB_CALLIGRA) # Sheets filters calligra_define_product(FILTER_XLSX_TO_ODS "XLSX to ODS filter" REQUIRES LIB_KOMSOOXML PART_SHEETS) calligra_define_product(FILTER_XLS_TO_SHEETS "Sheets XLS import filter" REQUIRES LIB_MSO LIB_KOMSOOXML PART_SHEETS) calligra_define_product(FILTER_SHEETS_TO_XLS "Sheets XLS export filter" REQUIRES LIB_MSO LIB_KOMSOOXML PART_SHEETS) calligra_define_product(FILTER_CSV_TO_SHEETS "Sheets CSV import filter" REQUIRES PART_SHEETS) calligra_define_product(FILTER_SHEETS_TO_CSV "Sheets CSV export filter" REQUIRES PART_SHEETS) calligra_define_product(FILTER_APPLIXSPREAD_TO_KSPREAD "Applix Spreadsheet to KSpread filter" REQUIRES PART_SHEETS) calligra_define_product(FILTER_DBASE_TO_KSPREAD "dBASE to KSpread filter" REQUIRES LIB_KOMAIN) calligra_define_product(FILTER_GNUMERIC_TO_SHEETS "Sheets GNUMERIC import filter" REQUIRES PART_SHEETS) calligra_define_product(FILTER_SHEETS_TO_GNUMERIC "Sheets GNUMERIC import filter" REQUIRES PART_SHEETS) calligra_define_product(FILTER_OPENCALC_TO_SHEETS "Sheets OpenOffice.org Calc import filter" REQUIRES PART_SHEETS) calligra_define_product(FILTER_SHEETS_TO_OPENCALC "Sheets OpenOffice.org Calc export filter" REQUIRES PART_SHEETS) calligra_define_product(FILTER_QUATTROPRO_TO_SHEETS "Sheets Quattro Pro import filter" REQUIRES PART_SHEETS) calligra_define_product(FILTER_HTML_TO_ODS "HTML to ODS filter" REQUIRES LIB_KOMAIN) calligra_define_product(FILTER_SHEETS_TO_HTML "Sheets HTML export filter" REQUIRES PART_SHEETS) calligra_define_product(FILTER_KSPREAD_TO_LATEX "KSpread to LaTeX filter" REQUIRES LIB_KOMAIN) # Flow filters calligra_define_product(FILTER_VISIO_TO_ODG "Visio to ODG filter" REQUIRES LIB_KOMAIN) calligra_define_product(FILTER_WPG_TO_ODG "WPG to ODG filter" REQUIRES LIB_KOMAIN) # Stage filters calligra_define_product(FILTER_KEY_TO_ODP "Apple Keynote to ODP filter" REQUIRES LIB_KOMAIN) calligra_define_product(FILTER_KPR_TO_ODP "KPresenter to ODP filter" REQUIRES LIB_KOMAIN) calligra_define_product(FILTER_PPT_TO_ODP "PPT to OPD filter" REQUIRES LIB_MSO LIB_KOMAIN) calligra_define_product(FILTER_PPTX_TO_ODP "PPTX to ODP filter" REQUIRES LIB_KOMSOOXML LIB_KOODF2 LIB_KOMAIN) # Words filters calligra_define_product(FILTER_DOC_TO_ODT "DOC to ODT filter" REQUIRES LIB_MSO LIB_KOMSOOXML LIB_KOMAIN) calligra_define_product(FILTER_DOCX_TO_ODT "DOCX to ODT filter" REQUIRES LIB_KOMSOOXML LIB_KOODF2 LIB_KOMAIN) calligra_define_product(FILTER_ODT_TO_DOCX "ODT to DOCX filter" REQUIRES LIB_KOODFREADER LIB_KOODF2 LIB_KOMAIN) calligra_define_product(FILTER_WORDPERFECT_TO_ODT "Word Perfect to ODT filter" REQUIRES LIB_KOMAIN) calligra_define_product(FILTER_WORKS_TO_ODT "MS Works to ODT filter" REQUIRES LIB_KOMAIN) calligra_define_product(FILTER_APPLIXWORD_TO_ODT "Applixword to ODT filter" REQUIRES LIB_KOMAIN) calligra_define_product(FILTER_ASCII_TO_WORDS "Words ASCII import filter" REQUIRES PART_WORDS LIB_KOODF2 LIB_KOMAIN) calligra_define_product(FILTER_ODT_TO_ASCII "ODT to ASCII filter" REQUIRES LIB_KOODFREADER LIB_KOMAIN) calligra_define_product(FILTER_RTF_TO_ODT "RTF to ODT filter" REQUIRES LIB_KOMAIN) calligra_define_product(FILTER_ODT_TO_MOBI "Mobi export filter" REQUIRES LIB_KOMAIN) calligra_define_product(FILTER_ODT_TO_EPUB2 "ODT Epub2 export filter" REQUIRES LIB_KOVECTORIMAGE LIB_KOMAIN) calligra_define_product(FILTER_ODT_TO_HTML "ODT HTML export filter" REQUIRES LIB_KOVECTORIMAGE LIB_KOMAIN) calligra_define_product(FILTER_ODT_TO_WIKI "ODT Wiki export filter" REQUIRES LIB_KOODFREADER LIB_KOODF2 LIB_KOMAIN) # Karbon filters calligra_define_product(FILTER_EPS_TO_SVG_AI "EPS to SVG/AI filter" REQUIRES LIB_KOMAIN) calligra_define_product(FILTER_XFIG_TO_ODG "XFig to ODG filter" REQUIRES LIB_KOMAIN) calligra_define_product(FILTER_PDF_TO_SVG "PDF to SVG filter" REQUIRES LIB_KOMAIN) calligra_define_product(FILTER_WPG_TO_SVG "WPG to SVG filter" REQUIRES LIB_KOMAIN) calligra_define_product(FILTER_KARBON_TO_IMAGE "Karbon image export filter" REQUIRES APP_KARBON) calligra_define_product(FILTER_KARBON_TO_SVG "Karbon SVG export filter" REQUIRES APP_KARBON) calligra_define_product(FILTER_SVG_TO_KARBON "Karbon SVG import filter" REQUIRES APP_KARBON) calligra_define_product(FILTER_KARBON_TO_WMF "Karbon WMF export filter" REQUIRES APP_KARBON) calligra_define_product(FILTER_WMF_TO_SVG "WMF to SVG filter" REQUIRES LIB_KOVECTORIMAGE LIB_KOMAIN) calligra_define_product(FILTER_KARBON1X_TO_KARBON "Karbon 1.x import filter" REQUIRES APP_KARBON) # meta apps calligra_define_product(APP_CALLIGRA "General Calligra app starter" REQUIRES LIB_CALLIGRA LIB_KOMAIN) # more extras calligra_define_product(OKULAR_GENERATOR_PPT "Plugin for Okular extended with support for PPT" REQUIRES OKULAR_GENERATOR_ODP FILTER_PPT_TO_ODP) calligra_define_product(OKULAR_GENERATOR_PPTX "Plugin for Okular extended with support for PPTX" REQUIRES OKULAR_GENERATOR_ODP FILTER_PPTX_TO_ODP) calligra_define_product(OKULAR_GENERATOR_DOC "Plugin for Okular extended with support for DOC" REQUIRES OKULAR_GENERATOR_ODT FILTER_DOC_TO_ODT) calligra_define_product(OKULAR_GENERATOR_DOCX "Plugin for Okular extended with support for DOCX" REQUIRES OKULAR_GENERATOR_ODT FILTER_DOCX_TO_ODT) calligra_define_product(OKULAR_GENERATOR_RTF "Plugin for Okular extended with support for RTF" REQUIRES OKULAR_GENERATOR_ODT FILTER_RTF_TO_ODT) calligra_define_product(OKULAR_GENERATOR_WORDPERFECT "Plugin for Okular extended with support for WORDPERFECT" REQUIRES OKULAR_GENERATOR_ODT FILTER_WORDPERFECT_TO_ODT) # developer utils calligra_define_product(APP_SLIDECOMPARE "slidecompare" REQUIRES LIB_CALLIGRA LIB_KOMAIN FILTER_PPT_TO_ODP) calligra_define_product(APP_DEVTOOLS "Tools for developers") calligra_define_product(APP_CSTESTER "cstester" REQUIRES PART_SHEETS PART_STAGE PART_WORDS) # development calligra_define_product(DEVEL_HEADERS "Headers of libraries" UNPORTED) ############################################# #### Product set definitions #### ############################################# # For defining new productsets see end of this file, # "How to add another productset?" # filter sets calligra_define_productset(FILTERS_SHEETS_IMPORT "All Sheets import filters" OPTIONAL FILTER_XLSX_TO_ODS FILTER_XLS_TO_SHEETS FILTER_CSV_TO_SHEETS FILTER_APPLIXSPREAD_TO_KSPREAD FILTER_DBASE_TO_KSPREAD FILTER_GNUMERIC_TO_SHEETS FILTER_OPENCALC_TO_SHEETS FILTER_QUATTROPRO_TO_SHEETS FILTER_HTML_TO_ODS ) calligra_define_productset(FILTERS_SHEETS_EXPORT "All Sheets export filters" OPTIONAL FILTER_SHEETS_TO_XLS FILTER_SHEETS_TO_CSV FILTER_SHEETS_TO_GNUMERIC FILTER_SHEETS_TO_OPENCALC FILTER_SHEETS_TO_HTML FILTER_KSPREAD_TO_LATEX ) calligra_define_productset(FILTERS_SHEETS "All Sheets filters" OPTIONAL FILTERS_SHEETS_IMPORT FILTERS_SHEETS_EXPORT ) calligra_define_productset(FILTERS_FLOW_IMPORT "All Flow import filters" OPTIONAL FILTER_VISIO_TO_ODG FILTER_WPG_TO_ODG ) #calligra_define_productset(FILTERS_FLOW_EXPORT "All Flow export filters" OPTIONAL ) none currently calligra_define_productset(FILTERS_FLOW "All Flow filters" OPTIONAL FILTERS_FLOW_IMPORT # FILTERS_FLOW_EXPORT ) calligra_define_productset(FILTERS_STAGE_IMPORT "All Stage import filters" OPTIONAL FILTER_KEY_TO_ODP FILTER_KPR_TO_ODP FILTER_PPT_TO_ODP FILTER_PPTX_TO_ODP ) #calligra_define_productset(FILTERS_STAGE_EXPORT "All Stage export filters" OPTIONAL ) none currently calligra_define_productset(FILTERS_STAGE "All Stage filters" OPTIONAL FILTERS_STAGE_IMPORT # FILTERS_STAGE_EXPORT ) calligra_define_productset(FILTERS_WORDS_IMPORT "All Words import filters" OPTIONAL FILTER_DOC_TO_ODT FILTER_DOCX_TO_ODT FILTER_WORDPERFECT_TO_ODT FILTER_WORKS_TO_ODT FILTER_APPLIXWORD_TO_ODT FILTER_ASCII_TO_WORDS FILTER_RTF_TO_ODT ) calligra_define_productset(FILTERS_WORDS_EXPORT "All Words export filters" OPTIONAL FILTER_ODT_TO_ASCII FILTER_ODT_TO_MOBI FILTER_ODT_TO_EPUB2 FILTER_ODT_TO_HTML FILTER_ODT_TO_DOCX FILTER_ODT_TO_WIKI ) calligra_define_productset(FILTERS_WORDS "All Words filters" OPTIONAL FILTERS_WORDS_IMPORT FILTERS_WORDS_EXPORT ) calligra_define_productset(FILTERS_KARBON_IMPORT "All Karbon import filters" OPTIONAL FILTER_EPS_TO_SVG_AI FILTER_XFIG_TO_ODG FILTER_PDF_TO_SVG FILTER_WPG_TO_SVG FILTER_SVG_TO_KARBON FILTER_WMF_TO_SVG FILTER_KARBON1X_TO_KARBON ) calligra_define_productset(FILTERS_KARBON_EXPORT "All Karbon export filters" OPTIONAL FILTER_KARBON_TO_IMAGE FILTER_KARBON_TO_SVG FILTER_KARBON_TO_WMF ) calligra_define_productset(FILTERS_KARBON "All Karbon filters" OPTIONAL FILTERS_KARBON_IMPORT FILTERS_KARBON_EXPORT ) # filemanager calligra_define_productset(FILEMANAGER "Extensions for the filemanager" OPTIONAL FILEMANAGER_PROPERTIES FILEMANAGER_QUICKPRINT FILEMANAGER_TEMPLATES FILEMANAGER_THUMBNAIL ) # apps calligra_define_productset(BRAINDUMP "Full Braindump (for Desktop)" REQUIRES APP_BRAINDUMP OPTIONAL # plugins PLUGIN_ARTISTICTEXTSHAPE PLUGIN_CHARTSHAPE PLUGIN_DEFAULTTOOLS PLUGIN_DOCKERS PLUGIN_FORMULASHAPE PLUGIN_MUSICSHAPE PLUGIN_PATHSHAPES PLUGIN_PICTURESHAPE PLUGIN_PLUGINSHAPE PLUGIN_TEXTEDITING PLUGIN_TEXTSHAPE PLUGIN_THREEDSHAPE PLUGIN_VARIABLES PLUGIN_VECTORSHAPE PLUGIN_VIDEOSHAPE ) calligra_define_productset(FLOW "Full Flow (for Desktop)" REQUIRES APP_FLOW OPTIONAL # extras FILEMANAGER # plugins PLUGIN_ARTISTICTEXTSHAPE PLUGIN_CHARTSHAPE PLUGIN_DEFAULTTOOLS PLUGIN_DOCKERS PLUGIN_FORMULASHAPE PLUGIN_PATHSHAPES PLUGIN_PICTURESHAPE PLUGIN_PLUGINSHAPE PLUGIN_TEXTEDITING PLUGIN_TEXTSHAPE PLUGIN_VARIABLES PLUGIN_VECTORSHAPE # filters FILTERS_FLOW ) calligra_define_productset(KARBON "Full Karbon (for Desktop)" REQUIRES APP_KARBON PLUGIN_KARBONPLUGINS PLUGIN_STENCILSDOCKER PLUGIN_SHAPEFILTEREFFECTS OPTIONAL # extras FILEMANAGER # plugins PLUGIN_ARTISTICTEXTSHAPE PLUGIN_CHARTSHAPE PLUGIN_DEFAULTTOOLS PLUGIN_DOCKERS PLUGIN_FORMULASHAPE PLUGIN_PATHSHAPES PLUGIN_PICTURESHAPE PLUGIN_PLUGINSHAPE PLUGIN_TEXTEDITING PLUGIN_TEXTSHAPE PLUGIN_VARIABLES PLUGIN_VECTORSHAPE # filters FILTERS_KARBON ) calligra_define_productset(SHEETS "Full Sheets (for Desktop)" REQUIRES APP_SHEETS OPTIONAL # extras FILEMANAGER # feature FEATURE_SCRIPTING # plugins PLUGIN_ARTISTICTEXTSHAPE PLUGIN_CHARTSHAPE PLUGIN_DEFAULTTOOLS PLUGIN_DOCKERS PLUGIN_FORMULASHAPE PLUGIN_PATHSHAPES PLUGIN_PICTURESHAPE PLUGIN_PLUGINSHAPE PLUGIN_TEXTEDITING PLUGIN_TEXTSHAPE PLUGIN_VARIABLES PLUGIN_VECTORSHAPE # filters FILTERS_SHEETS ) calligra_define_productset(STAGE "Full Stage (for Desktop)" REQUIRES APP_STAGE OPTIONAL # extras FILEMANAGER # plugins PLUGIN_ARTISTICTEXTSHAPE PLUGIN_CHARTSHAPE PLUGIN_DEFAULTTOOLS PLUGIN_DOCKERS PLUGIN_FORMULASHAPE PLUGIN_PATHSHAPES PLUGIN_PICTURESHAPE PLUGIN_PLUGINSHAPE PLUGIN_TEXTEDITING PLUGIN_TEXTSHAPE PLUGIN_VARIABLES PLUGIN_VECTORSHAPE PLUGIN_VIDEOSHAPE # filters FILTERS_STAGE ) calligra_define_productset(WORDS "Full Words (for Desktop)" REQUIRES APP_WORDS OPTIONAL # extras FILEMANAGER # plugins PLUGIN_ARTISTICTEXTSHAPE PLUGIN_CHARTSHAPE PLUGIN_DEFAULTTOOLS PLUGIN_DOCKERS PLUGIN_FORMULASHAPE PLUGIN_PATHSHAPES PLUGIN_PICTURESHAPE PLUGIN_PLUGINSHAPE PLUGIN_SEMANTICITEMS PLUGIN_TEXTEDITING PLUGIN_TEXTSHAPE PLUGIN_VARIABLES PLUGIN_VECTORSHAPE # filters FILTERS_WORDS ) calligra_define_productset(GEMINI "Calligra for 2:1 devices" REQUIRES APP_GEMINI OPTIONAL # plugins PLUGIN_ARTISTICTEXTSHAPE PLUGIN_CALLIGRAGEMINI_GIT PLUGIN_CHARTSHAPE PLUGIN_DEFAULTTOOLS PLUGIN_DOCKERS PLUGIN_FORMULASHAPE PLUGIN_PATHSHAPES PLUGIN_PICTURESHAPE PLUGIN_PLUGINSHAPE PLUGIN_TEXTEDITING PLUGIN_TEXTSHAPE PLUGIN_VARIABLES PLUGIN_VECTORSHAPE PLUGIN_VIDEOSHAPE # filters FILTERS_WORDS FILTERS_STAGE ) # okular support calligra_define_productset(OKULAR "Okular generators" OPTIONAL OKULAR_GENERATOR_ODP OKULAR_GENERATOR_PPT OKULAR_GENERATOR_PPTX OKULAR_GENERATOR_ODT OKULAR_GENERATOR_DOC OKULAR_GENERATOR_DOCX OKULAR_GENERATOR_RTF OKULAR_GENERATOR_WORDPERFECT ) # How to add another product? # =========================== # # 1. Define the product by a call of calligra_define_product, # e.g. # # calligra_define_product(MYPRODUCT "title of product") # # For the product id use a proper prefix (LIB_, PLUGIN_, FILTER_, APP_, PART_, # ...), whatever is appropriate. # # 2. Extend that call with a REQUIRES argument section, if the product has # hard internal build-time dependencies on other products or features. # Products/features that are listed as dependencies have to be defined before # (see also the API doc in cmake/modules/CalligraProductSetMacros.cmake) # E.g. # # calligra_define_product(MYPRODUCT "title of product" REQUIRES P1 P2) # # 3. Add a rule when to not build the product, in the section "Detect which # products/features can be compiled" of the toplevel CMakeLists.txt. Each # product should have their own boolean expression when to set the build flag # to FALSE, e.g. # # if (PLATFORMX OR NOT EXTERNAL_DEP_X_FOUND) # set(SHOULD_BUILD_MYPRODUCT FALSE) # endif () # # 4. Wrap everything belonging to the product with the build flag of the product. # Ideally this is done around subdirectory inclusions, results in easier code. # e.g. # # if (SHOULD_BUILD_MYPRODUCT) # add_subdirectory(myproduct) # endif () # # 5. Tag the product as STAGING, if it is not yet ready for release, but already # integrated in the master branch, e.g. # # calligra_define_product(MYPRODUCT "title of product" STAGING REQUIRES P1) # # 6. Add the product to all products, features and product sets which have this # product as REQUIRED or OPTIONAL dependency. # # # How to add another feature? # =========================== # # 1. Define the feature by a call of calligra_define_feature, # e.g. # # calligra_define_feature(MYFEATURE "title of feature") # # For the feature id use a proper prefix (FEATURE_, ...), whatever is # appropriate. # # 2. Extend that call with a REQUIRES argument section, if the feature has # hard internal build-time dependencies on other products or features. # Products or features that are listed as dependencies have to be defined # before # (see also the API doc in cmake/modules/CalligraProductSetMacros.cmake) # E.g. # # calligra_define_feature(MYFEATURE "title of feature" REQUIRES P1 F1) # # 3. Add a rule when to not build the feature, in the section "Detect which # products/features can be compiled" of the toplevel CMakeLists.txt. Each # feature should have their own boolean expression when to set the build flag # to FALSE, e.g. # # if (PLATFORMX OR NOT EXTERNAL_DEP_X_FOUND) # set(SHOULD_BUILD_MYFEATURE FALSE) # endif () # # 4. Wrap everything belonging to the feature with the build flag of the feature. # Ideally this is done around subdirectory inclusions, results in easier code. # e.g. # # if (SHOULD_BUILD_MYFEATURE) # add_subdirectory(myproduct) # endif () # # 5. Tag the feature as STAGING, if it is not yet ready for release, but already # integrated in the master branch, e.g. # # calligra_define_product(MYFEATURE "title of feature" STAGING REQUIRES P1 F1) # # 6. Add the feature to all products, features and product sets which have this # product as REQUIRED or OPTIONAL dependency. # # # How to add another productset? # ============================== # # There are two possible places to put a productset definition. The first is to # add it to this file, which should be done for more generic sets that are # useful for many people. The second is a file of its own, in the directory # "cmake/productsets", which should be done for more special ones or for those # which should not be added to the repository. # The file must be named with the name of the productset in lowercase and have # the extension ".cmake". # # 1. Define the productset by a call of calligra_define_productset, # e.g. # # calligra_define_productset(MYPRODUCTSET "title of productset") # # 2. Extend that call with REQUIRES or OPTIONAL argument sections, if the productset # has hard or soft internal dependencies on other products, features or # productsets. # Products, features or productsets that are listed as dependencies have to # be defined before # (see also the API doc in cmake/modules/CalligraProductSetMacros.cmake) # E.g. # # calligra_define_productset(MYPRODUCT "title of product" # REQUIRES P1 P2 F1 PS1 # OPTIONAL P3 F2 PS2) # # 3. Add the productset to all product sets which have this product set as # REQUIRED or OPTIONAL dependency. # # Example for a file-based productset definition: # You want a productset "MYWORDS". For that you add a file named # "mywords.cmake" into the directory "cmake/productsets", with the content: # --- 8< --- # calligra_define_productset(MYWORDS "My Words" # REQUIRES # APP_WORDS # PLUGIN_DEFAULTTOOLS # PLUGIN_DOCKERS # PLUGIN_PATHSHAPES # PLUGIN_VARIABLES # PLUGIN_TEXTSHAPE # PLUGIN_PLUGINSHAPE # PLUGIN_FORMULASHAPE # ) # --- 8< --- diff --git a/filters/karbon/CMakeLists.txt b/filters/karbon/CMakeLists.txt index 67666260d5a..3adbb4f67b2 100644 --- a/filters/karbon/CMakeLists.txt +++ b/filters/karbon/CMakeLists.txt @@ -1,39 +1,40 @@ include_directories( ${KOTEXT_INCLUDES} ${KOMAIN_INCLUDES} ${FLAKE_INCLUDES} + ${KOPAGEAPP_INCLUDES} ${CMAKE_SOURCE_DIR}/karbon ${CMAKE_SOURCE_DIR}/karbon/common ${CMAKE_SOURCE_DIR}/karbon/ui ${CMAKE_BINARY_DIR}/karbon ${CMAKE_SOURCE_DIR}/plugins/ ) if(SHOULD_BUILD_FILTER_KARBON_TO_IMAGE) add_subdirectory( image ) endif() add_subdirectory( svg ) if(SHOULD_BUILD_FILTER_WPG_TO_SVG) add_subdirectory( wpg ) endif() add_subdirectory( wmf ) if(SHOULD_BUILD_FILTER_KARBON1X_TO_KARBON) add_subdirectory( karbon1.x ) endif() if(SHOULD_BUILD_FILTER_EPS_TO_SVG_AI) add_subdirectory( eps ) endif() if (SHOULD_BUILD_FILTER_PDF_TO_SVG) add_subdirectory( pdf ) endif () if(SHOULD_BUILD_FILTER_XFIG_TO_ODG) add_subdirectory( xfig ) endif() diff --git a/filters/karbon/image/CMakeLists.txt b/filters/karbon/image/CMakeLists.txt index 1f1ded54153..4c1b00a7933 100644 --- a/filters/karbon/image/CMakeLists.txt +++ b/filters/karbon/image/CMakeLists.txt @@ -1,17 +1,14 @@ -include_directories( ${CMAKE_SOURCE_DIR}/karbon ) - - ########### next target ############### set(karbon2image_PART_SRCS ImageExport.cpp ImageExportOptionsWidget.cpp ) ki18n_wrap_ui( karbon2image_PART_SRCS ImageExportOptionsWidget.ui ) add_library(calligra_filter_karbon2image MODULE ${karbon2image_PART_SRCS}) calligra_filter_desktop_to_json(calligra_filter_karbon2image calligra_filter_karbon2image.desktop) -target_link_libraries(calligra_filter_karbon2image karbonui komain) +target_link_libraries(calligra_filter_karbon2image karbonui komain kopageapp) install(TARGETS calligra_filter_karbon2image DESTINATION ${PLUGIN_INSTALL_DIR}/calligra/formatfilters) diff --git a/filters/karbon/image/ImageExport.cpp b/filters/karbon/image/ImageExport.cpp index 68271940649..6dda2c6b422 100644 --- a/filters/karbon/image/ImageExport.cpp +++ b/filters/karbon/image/ImageExport.cpp @@ -1,128 +1,134 @@ /* This file is part of the KDE project Copyright (C) 2002-2004 Rob Buis Copyright (C) 2002 Lennart Kudling Copyright (C) 2002 Werner Trobin Copyright (C) 2004 Nicolas Goutte Copyright (C) 2005 Tim Beaulen Copyright (C) 2005 Thomas Zander Copyright (C) 2005-2006 David Faure Copyright (C) 2006 Inge Wallin Copyright (C) 2006 Laurent Montel Copyright (C) 2006 Christian Mueller Copyright (C) 2007-2008,2012 Jan Hambrecht This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ImageExport.h" #include "ImageExportOptionsWidget.h" #include #include #include #include #include #include #include #include #include +#include #include #include K_PLUGIN_FACTORY_WITH_JSON(PngExportFactory, "calligra_filter_karbon2image.json", registerPlugin();) ImageExport::ImageExport(QObject*parent, const QVariantList&) : KoFilter(parent) { } KoFilter::ConversionStatus ImageExport::convert(const QByteArray& from, const QByteArray& to) { QString format; if (to == "image/png") { format = "PNG"; } else if(to == "image/jpeg") { format = "JPG"; } if (format.isEmpty()) { return KoFilter::NotImplemented; } if (from != "application/vnd.oasis.opendocument.graphics") { return KoFilter::NotImplemented; } KoDocument* document = m_chain->inputDocument(); if (! document) return KoFilter::ParsingError; KarbonDocument* doc = dynamic_cast(document); if (doc) { KoShapePainter painter; - painter.setShapes(doc->shapes()); + QList pages = doc->pages(); + if (pages.isEmpty()) { + return KoFilter::WrongFormat; + } + // TODO: Handle multiple pages + painter.setShapes(pages.at(0)->shapes()); // get the bounding rect of the content QRectF shapesRect = painter.contentRect(); // get the size in point QSizeF pointSize = shapesRect.size(); // get the size in pixel (100% zoom) KoZoomHandler zoomHandler; QSize pixelSize = zoomHandler.documentToView(pointSize).toSize(); //transparent white by default QColor backgroundColor(QColor(255, 255, 255, 0)); if (! m_chain->manager()->getBatchMode()) { ImageExportOptionsWidget * widget = new ImageExportOptionsWidget(pointSize); widget->setUnit(document->unit()); widget->setBackgroundColor(backgroundColor); widget->enableBackgroundOpacity(format == "PNG"); KoDialog dlg; dlg.setCaption(i18n("PNG Export Options")); dlg.setButtons(KoDialog::Ok | KoDialog::Cancel); dlg.setMainWidget(widget); if (dlg.exec() != QDialog::Accepted) return KoFilter::UserCancelled; pixelSize = widget->pixelSize(); backgroundColor = widget->backgroundColor(); } QImage image(pixelSize, QImage::Format_ARGB32); // draw the background of the image image.fill(backgroundColor.rgba()); // paint the shapes painter.paint(image); if(!image.save(m_chain->outputFile(), format.toLatin1())) { return KoFilter::CreationError; } } else { return KoFilter::WrongFormat; } return KoFilter::OK; } #include "ImageExport.moc" diff --git a/filters/karbon/svg/CMakeLists.txt b/filters/karbon/svg/CMakeLists.txt index 77cf58e351f..555b222bee4 100644 --- a/filters/karbon/svg/CMakeLists.txt +++ b/filters/karbon/svg/CMakeLists.txt @@ -1,35 +1,35 @@ include_directories( ${CMAKE_SOURCE_DIR}/karbon ) if(SHOULD_BUILD_FILTER_KARBON_TO_SVG) set(karbon2svg_PART_SRCS SvgExport.cpp ) add_library(calligra_filter_karbon2svg MODULE ${karbon2svg_PART_SRCS}) calligra_filter_desktop_to_json(calligra_filter_karbon2svg calligra_filter_karbon2svg.desktop) -target_link_libraries(calligra_filter_karbon2svg karbonui) +target_link_libraries(calligra_filter_karbon2svg karbonui kopageapp) install(TARGETS calligra_filter_karbon2svg DESTINATION ${PLUGIN_INSTALL_DIR}/calligra/formatfilters) endif() if(SHOULD_BUILD_FILTER_SVG_TO_KARBON) set(svg2karbon_PART_SRCS SvgImport.cpp ) add_library(calligra_filter_svg2karbon MODULE ${svg2karbon_PART_SRCS}) calligra_filter_desktop_to_json(calligra_filter_svg2karbon calligra_filter_svg2karbon.desktop) -target_link_libraries(calligra_filter_svg2karbon karbonui KF5::Archive) +target_link_libraries(calligra_filter_svg2karbon karbonui kopageapp KF5::Archive) install(TARGETS calligra_filter_svg2karbon DESTINATION ${PLUGIN_INSTALL_DIR}/calligra/formatfilters) endif() diff --git a/filters/karbon/svg/SvgExport.cpp b/filters/karbon/svg/SvgExport.cpp index 5face41749b..8c048e502b4 100644 --- a/filters/karbon/svg/SvgExport.cpp +++ b/filters/karbon/svg/SvgExport.cpp @@ -1,77 +1,85 @@ /* This file is part of the KDE project Copyright (C) 2002 Lars Siebold Copyright (C) 2002-2003,2005 Rob Buis Copyright (C) 2002,2005-2006 David Faure Copyright (C) 2002 Werner Trobin Copyright (C) 2002 Lennart Kudling Copyright (C) 2004 Nicolas Goutte Copyright (C) 2005 Boudewijn Rempt Copyright (C) 2005 Raphael Langerhorst Copyright (C) 2005 Thomas Zander Copyright (C) 2005,2007-2008 Jan Hambrecht Copyright (C) 2006 Inge Wallin Copyright (C) 2006 Martin Pfeiffer Copyright (C) 2006 Gábor Lehel Copyright (C) 2006 Laurent Montel Copyright (C) 2006 Christian Mueller Copyright (C) 2006 Ariya Hidayat Copyright (C) 2010 Thorsten Zachmann This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SvgExport.h" #include #include #include #include #include +#include +#include #include #include K_PLUGIN_FACTORY_WITH_JSON(SvgExportFactory, "calligra_filter_karbon2svg.json", registerPlugin();) SvgExport::SvgExport(QObject*parent, const QVariantList&) : KoFilter(parent) { } KoFilter::ConversionStatus SvgExport::convert(const QByteArray& from, const QByteArray& to) { if (to != "image/svg+xml" || from != "application/vnd.oasis.opendocument.graphics") return KoFilter::NotImplemented; KoDocument * document = m_chain->inputDocument(); if (!document) return KoFilter::ParsingError; KarbonDocument * karbonPart = dynamic_cast(document); if (!karbonPart) return KoFilter::WrongFormat; - SvgWriter writer(karbonPart->layers(), karbonPart->pageSize()); + KoPAPageBase *page = karbonPart->pages().value(0); + if (!page) { + return KoFilter::WrongFormat; + } + const KoPageLayout &layout = page->pageLayout(); + const QSizeF size(layout.width, layout.height); + SvgWriter writer(page->shapes(), size); if (!writer.save(m_chain->outputFile(), true)) return KoFilter::CreationError; return KoFilter::OK; } #include "SvgExport.moc" diff --git a/filters/karbon/svg/SvgImport.cpp b/filters/karbon/svg/SvgImport.cpp index 6aa3d0544a7..c3f750f9d70 100644 --- a/filters/karbon/svg/SvgImport.cpp +++ b/filters/karbon/svg/SvgImport.cpp @@ -1,204 +1,211 @@ /* This file is part of the KDE project * Copyright (C) 2002-2005,2007 Rob Buis * Copyright (C) 2002-2004 Nicolas Goutte * Copyright (C) 2005-2006 Tim Beaulen * Copyright (C) 2005-2009 Jan Hambrecht * Copyright (C) 2005,2007 Thomas Zander * Copyright (C) 2006-2007 Inge Wallin * Copyright (C) 2007-2008 Thorsten Zachmann * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SvgImport.h" #include "SvgParser.h" #include #include #include #include #include #include #include #include +#include +#include +#include #include #include #include #include #include K_PLUGIN_FACTORY_WITH_JSON(SvgImportFactory, "calligra_filter_svg2karbon.json", registerPlugin();) const QLoggingCategory &SVG_LOG() { static const QLoggingCategory category("calligra.filter.svg2karbon"); return category; } #define debugSvg qCDebug(SVG_LOG) #define warnSvg qCWarning(SVG_LOG) #define errorSvg qCCritical(SVG_LOG) SvgImport::SvgImport(QObject*parent, const QVariantList&) : KoFilter(parent), m_document(0) { } SvgImport::~SvgImport() { } KoFilter::ConversionStatus SvgImport::convert(const QByteArray& from, const QByteArray& to) { // check for proper conversion if (to != "application/vnd.oasis.opendocument.graphics") return KoFilter::NotImplemented; if (from != "image/svg+xml" && from != "image/svg+xml-compressed") return KoFilter::NotImplemented; //Find the last extension QString strExt; QString fileIn(m_chain->inputFile()); const int result = fileIn.lastIndexOf('.'); if (result >= 0) strExt = fileIn.mid(result).toLower(); const KCompressionDevice::CompressionType compressionType = (strExt == QLatin1String(".gz")) //in case of .svg.gz (logical extension) || (strExt == QLatin1String(".svgz")) ? //in case of .svgz (extension used prioritary) KCompressionDevice::GZip : (strExt == QLatin1String(".bz2")) ? //in case of .svg.bz2 (logical extension) KCompressionDevice::BZip2 : KCompressionDevice::None; /*debugSvg <<"File extension: -" << strExt <<"- Compression:" << strMime;*/ QIODevice* in = new KCompressionDevice(fileIn, compressionType); if (!in->open(QIODevice::ReadOnly)) { errorSvg << "Cannot open file! Aborting!" << endl; delete in; return KoFilter::FileNotFound; } int line, col; QString errormessage; KoXmlDocument inputDoc; const bool parsed = inputDoc.setContent(in, &errormessage, &line, &col); in->close(); delete in; if (! parsed) { errorSvg << "Error while parsing file: " << "at line " << line << " column: " << col << " message: " << errormessage << endl; // ### TODO: feedback to the user return KoFilter::ParsingError; } m_document = dynamic_cast(m_chain->outputDocument()); - if (! m_document) + if (!m_document) { return KoFilter::CreationError; - + } + if (m_document->pages().isEmpty()) { + KoPAMasterPage *mp = dynamic_cast(m_document->pages(true).value(0)); + if (!mp) { + mp = new KoPAMasterPage(); + m_document->insertPage(mp, 0); + } + m_document->insertPage(new KoPAPage(mp), 0); + } // Do the conversion! convert(inputDoc.documentElement()); return KoFilter::OK; } void SvgImport::convert(const KoXmlElement &rootElement) { if (! m_document) return; // set default page size to A4 QSizeF pageSize(550.0, 841.0); SvgParser parser(m_document->resourceManager()); parser.setXmlBaseDir(QFileInfo(m_chain->inputFile()).filePath()); QList toplevelShapes = parser.parseSvg(rootElement, &pageSize); // parse the root svg element buildDocument(toplevelShapes, parser.shapes()); // set the page size - m_document->setPageSize(pageSize); + KoPageLayout & layout = m_document->pages().at(0)->pageLayout(); + layout.width = pageSize.width(); + layout.height = pageSize.height(); } void SvgImport::buildDocument(const QList &toplevelShapes, const QList &shapes) { + Q_UNUSED(shapes); + KoPAPageBase *page = m_document->pages().first(); // if we have only top level groups, make them layers bool onlyTopLevelGroups = true; foreach(KoShape * shape, toplevelShapes) { if (! dynamic_cast(shape) || shape->filterEffectStack()) { onlyTopLevelGroups = false; break; } } - - // add all shapes to the document - foreach(KoShape * shape, shapes) { - m_document->add(shape); + KoShapeLayer *oldLayer = 0; + if (page->shapeCount()) { + oldLayer = dynamic_cast(page->shapes().first()); } - - KoShapeLayer * oldLayer = 0; - if (m_document->layers().count()) - oldLayer = m_document->layers().first(); - if (onlyTopLevelGroups) { foreach(KoShape * shape, toplevelShapes) { // ungroup toplevel groups - KoShapeGroup * group = dynamic_cast(shape); + KoShapeGroup *group = dynamic_cast(shape); QList children = group->shapes(); KoShapeUngroupCommand cmd(group, children, QList() << group); cmd.redo(); - KoShapeLayer * layer = new KoShapeLayer(); + KoShapeLayer *layer = new KoShapeLayer(); foreach(KoShape * child, children) { - m_document->add(child); layer->addShape(child); } - if (! group->name().isEmpty()) + if (!group->name().isEmpty()) { layer->setName(group->name()); + } layer->setVisible(group->isVisible()); layer->setZIndex(group->zIndex()); - m_document->insertLayer(layer); + page->addShape(layer); delete group; } } else { - KoShapeLayer * layer = new KoShapeLayer(); + KoShapeLayer *layer = new KoShapeLayer(); foreach(KoShape * shape, toplevelShapes) { - m_document->add(shape); layer->addShape(shape); } - m_document->insertLayer(layer); + page->addShape(layer); } - if (oldLayer) { - m_document->removeLayer(oldLayer); + page->removeShape(oldLayer); delete oldLayer; } } #include "SvgImport.moc" diff --git a/filters/karbon/wmf/CMakeLists.txt b/filters/karbon/wmf/CMakeLists.txt index f00dff6279b..ca6f40305f7 100644 --- a/filters/karbon/wmf/CMakeLists.txt +++ b/filters/karbon/wmf/CMakeLists.txt @@ -1,36 +1,36 @@ include_directories( ${VECTORIMAGE_INCLUDES} ) if(SHOULD_BUILD_FILTER_WMF_TO_SVG) set(wmf2svg_PART_SRCS WmfImportDebug.cpp WmfImport.cpp WmfImportParser.cpp ) add_library(calligra_filter_wmf2svg MODULE ${wmf2svg_PART_SRCS}) target_link_libraries(calligra_filter_wmf2svg kovectorimage komain koodf) install(TARGETS calligra_filter_wmf2svg DESTINATION ${PLUGIN_INSTALL_DIR}/calligra/formatfilters) calligra_filter_desktop_to_json(calligra_filter_wmf2svg calligra_filter_wmf2svg.desktop) if(SHOULD_BUILD_FILEMANAGER_THUMBNAIL) install(FILES karbon_wmf_thumbnail.desktop DESTINATION ${SERVICES_INSTALL_DIR}) endif() endif() if(SHOULD_BUILD_FILTER_KARBON_TO_WMF) set(karbon2wmf_PART_SRCS WmfExport.cpp) add_library(calligra_filter_karbon2wmf MODULE ${karbon2wmf_PART_SRCS}) -target_link_libraries(calligra_filter_karbon2wmf kovectorimage karboncommon karbonui) +target_link_libraries(calligra_filter_karbon2wmf kovectorimage karboncommon karbonui kopageapp) install(TARGETS calligra_filter_karbon2wmf DESTINATION ${PLUGIN_INSTALL_DIR}/calligra/formatfilters) calligra_filter_desktop_to_json(calligra_filter_karbon2wmf calligra_filter_karbon2wmf.desktop) endif() diff --git a/filters/karbon/wmf/WmfExport.cpp b/filters/karbon/wmf/WmfExport.cpp index af96bbcbf0c..2247bd04026 100644 --- a/filters/karbon/wmf/WmfExport.cpp +++ b/filters/karbon/wmf/WmfExport.cpp @@ -1,186 +1,192 @@ /* This file is part of the KDE project * Copyright (c) 2003 thierry lorthiois (lorthioist@wanadoo.fr) * Copyright (c) 2007 Jan Hambrecht * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License version 2 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WmfExport.h" #include #include #include #include #include #include #include #include #include #include #include #include +#include +#include /* TODO: bs.wmf stroke in red with MSword and in brown with Words ?? */ K_PLUGIN_FACTORY_WITH_JSON(WmfExportFactory, "calligra_filter_karbon2wmf.json", registerPlugin();) WmfExport::WmfExport(QObject*parent, const QVariantList&) : KoFilter(parent) { } WmfExport::~WmfExport() { } KoFilter::ConversionStatus WmfExport::convert(const QByteArray& from, const QByteArray& to) { if (to != "image/x-wmf" || from != "application/vnd.oasis.opendocument.graphics") return KoFilter::NotImplemented; KoDocument * doc = m_chain->inputDocument(); if (! doc) return KoFilter::ParsingError; KarbonDocument * karbonPart = dynamic_cast(doc); if (! karbonPart) return KoFilter::WrongFormat; // open Placeable Wmf file mWmf = new Libwmf::WmfWriter(m_chain->outputFile()); if (!mWmf->begin()) { delete mWmf; return KoFilter::WrongFormat; } paintDocument(karbonPart); mWmf->end(); delete mWmf; return KoFilter::OK; } void WmfExport::paintDocument(KarbonDocument* document) { - + KoPAPageBase *page = document->pages().value(0); + if (!page) { + return; + } // resolution mDpi = 1000; - QSizeF pageSize = document->pageSize(); + const KoPageLayout &layout = page->pageLayout(); + QSizeF pageSize(layout.width, layout.height); int width = static_cast(POINT_TO_INCH(pageSize.width()) * mDpi); int height = static_cast(POINT_TO_INCH(pageSize.height()) * mDpi); mWmf->setDefaultDpi(mDpi); mWmf->setWindow(0, 0, width, height); if ((pageSize.width() != 0) && (pageSize.height() != 0)) { mScaleX = static_cast(width) / pageSize.width(); mScaleY = static_cast(height) / pageSize.height(); } - QList shapes = document->shapes(); + QList shapes = page->shapes(); qSort(shapes.begin(), shapes.end(), KoShape::compareShapeZIndex); // Export layers. foreach(KoShape * shape, shapes) { if (dynamic_cast(shape)) continue; paintShape(shape); } } void WmfExport::paintShape(KoShape * shape) { QList subpaths = shape->outline().toFillPolygons(shape->absoluteTransformation(0)); if (! subpaths.count()) return; QList polygons; foreach(const QPolygonF & subpath, subpaths) { QPolygon p; uint pointCount = subpath.count(); for (uint i = 0; i < pointCount; ++i) p.append(QPoint(coordX(subpath[i].x()), coordY(subpath[i].y()))); polygons.append(p); } mWmf->setPen(getPen(shape->stroke())); if (polygons.count() == 1 && ! shape->background()) mWmf->drawPolyline(polygons.first()); else { QBrush fill(Qt::NoBrush); QSharedPointer cbg = qSharedPointerDynamicCast(shape->background()); if (cbg) fill = QBrush(cbg->color(), cbg->style()); QSharedPointer gbg = qSharedPointerDynamicCast(shape->background()); if (gbg) { fill = QBrush(*gbg->gradient()); fill.setTransform(gbg->transform()); } QSharedPointer pbg = qSharedPointerDynamicCast(shape->background()); if (pbg) { fill.setTextureImage(pbg->pattern()); fill.setTransform(pbg->transform()); } mWmf->setBrush(fill); if (polygons.count() == 1) mWmf->drawPolygon(polygons.first()); else mWmf->drawPolyPolygon(polygons); } } QPen WmfExport::getPen(const KoShapeStrokeModel * stroke) { const KoShapeStroke * lineStroke = dynamic_cast(stroke); if (! lineStroke) return QPen(Qt::NoPen); QPen pen(lineStroke->lineStyle()); if (pen.style() > Qt::SolidLine) pen.setDashPattern(lineStroke->lineDashes()); pen.setColor(lineStroke->color()); pen.setCapStyle(lineStroke->capStyle()); pen.setJoinStyle(lineStroke->joinStyle()); pen.setWidthF(coordX(lineStroke->lineWidth())); pen.setMiterLimit(lineStroke->miterLimit()); return pen; } int WmfExport::coordX(double left) { return (int)(left * mScaleX); } int WmfExport::coordY(double top) { return (int)(top * mScaleY); } #include diff --git a/karbon/CMakeLists.txt b/karbon/CMakeLists.txt index 98eae2b828d..10b9498c658 100644 --- a/karbon/CMakeLists.txt +++ b/karbon/CMakeLists.txt @@ -1,78 +1,79 @@ project(karbon) #Set the correct compiler options if(CMAKE_SIZEOF_VOID_P EQUAL 4) # 32 bit message(STATUS "Karbon detected that you use a 32 bit processor.") else() # 64 bit (well, anything else than 32 bit, but someone use something else than 32 or 64 bit ?) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") message(STATUS "Karbon detected that you use a 64 bit processor. Added -fPIC to the CXX_FLAGS.") endif() add_definitions(-DTRANSLATION_DOMAIN=\"karbon\") include_directories( + ${KOPAGEAPP_INCLUDES} ${FLAKE_INCLUDES} ${KOTEXT_INCLUDES} ${KOMAIN_INCLUDES} ${CMAKE_SOURCE_DIR}/karbon/ui ${CMAKE_SOURCE_DIR}/karbon/common ${CMAKE_SOURCE_DIR}/karbon/common/commands ) add_subdirectory( common ) add_subdirectory( ui ) add_subdirectory( plugins ) add_subdirectory( data ) add_subdirectory( templates ) ########### next target ############### set(karbonpart_PART_SRCS KarbonFactoryInit.cpp ) add_library(karbonpart MODULE ${karbonpart_PART_SRCS}) calligra_part_desktop_to_json(karbonpart "${CMAKE_CURRENT_SOURCE_DIR}/data/karbonpart.desktop") target_link_libraries(karbonpart karbonui) install(TARGETS karbonpart DESTINATION ${PLUGIN_INSTALL_DIR}/calligra/parts) ########### next target ############### if(NOT RELEASE_BUILD) add_definitions(-DMAINTANER_WANTED_SPLASH) endif() set(karbon_KDEINIT_SRCS main.cpp ) file(GLOB karbon_icons "${CMAKE_CURRENT_SOURCE_DIR}/pics/action/*-actions-*.png") ecm_install_icons(ICONS ${karbon_icons} DESTINATION ${DATA_INSTALL_DIR}/karbon/icons) file(GLOB karbon_app_icons "${CMAKE_CURRENT_SOURCE_DIR}/pics/app/*-apps-calligrakarbon.png") ecm_add_app_icon(kdeinit_app_ICONS_SRCS ICONS ${karbon_app_icons}) if(WIN32) set(_resourcefile "${CMAKE_CURRENT_BINARY_DIR}/kdeinit_app_ICONS_SRCS.rc") endif() ecm_install_icons(ICONS ${karbon_app_icons} "${CMAKE_CURRENT_SOURCE_DIR}/pics/app/sc-apps-calligrakarbon.svgz" DESTINATION ${ICON_INSTALL_DIR} ) kf5_add_kdeinit_executable( karbon ${karbon_KDEINIT_SRCS}) if (APPLE) set_target_properties(karbon PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.template) set_target_properties(karbon PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.calligra.karbon") set_target_properties(karbon PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Karbon") install( FILES ${CMAKE_CURRENT_BINARY_DIR}/karbon_KDEINIT_SRCS.icns DESTINATION ${BUNDLE_INSTALL_DIR}/karbon.app/Contents/Resources) endif() target_link_libraries(kdeinit_karbon karbonui) install(TARGETS kdeinit_karbon ${INSTALL_TARGETS_DEFAULT_ARGS}) target_link_libraries(karbon kdeinit_karbon) install(TARGETS karbon ${INSTALL_TARGETS_DEFAULT_ARGS}) diff --git a/karbon/data/karbon.rc b/karbon/data/karbon.rc index 7cc5690f2d6..300fe0e7a0d 100644 --- a/karbon/data/karbon.rc +++ b/karbon/data/karbon.rc @@ -1,168 +1,180 @@ &Order &Align &File &Edit &View - - + + &Object &Order &Align &Distribute &Path Effe&cts &Settings - + + + &Page + + + + + + + + + + Edit diff --git a/karbon/ui/CMakeLists.txt b/karbon/ui/CMakeLists.txt index fa3e95cc4d8..e6975bf17b5 100644 --- a/karbon/ui/CMakeLists.txt +++ b/karbon/ui/CMakeLists.txt @@ -1,55 +1,50 @@ include_directories( + ${KOPAGEAPP_INCLUDES} ${KOODF_INCLUDES} ${KOMAIN_INCLUDES} ${CMAKE_SOURCE_DIR}/karbon/ ${CMAKE_SOURCE_DIR}/karbon/ui ${CMAKE_SOURCE_DIR}/karbon/ui/dialogs ${CMAKE_SOURCE_DIR}/karbon/ui/dockers ${CMAKE_SOURCE_DIR}/karbon/ui/widgets ${CMAKE_SOURCE_DIR}/karbon/ui/commands ) set(karbonui_SRCS KarbonUiDebug.cpp KarbonFactory.cpp KarbonDocument.cpp KarbonPart.cpp KarbonView.cpp - KarbonPrintJob.cpp - KarbonZoomController.cpp + ProxyView.cpp + KarbonDocumentMergeCommand.cpp - commands/KarbonLayerReorderCommand.cpp - dialogs/KarbonConfigureDialog.cpp - dockers/KarbonLayerDocker.cpp - dockers/KarbonLayerModel.cpp - dockers/KarbonLayerSortingModel.cpp - - widgets/KarbonCanvas.cpp widgets/KarbonSmallStylePreview.cpp widgets/KarbonPaletteBarWidget.cpp widgets/KarbonPaletteWidget.cpp widgets/KarbonConfigInterfacePage.cpp ) add_library( karbonui SHARED ${karbonui_SRCS} ) generate_export_header(karbonui BASE_NAME karbonui) target_link_libraries(karbonui PUBLIC karboncommon flake PRIVATE + kopageapp kowidgets koodf koplugin KF5::IconThemes KF5::GuiAddons ) set_target_properties(karbonui PROPERTIES VERSION ${GENERIC_CALLIGRA_LIB_VERSION} SOVERSION ${GENERIC_CALLIGRA_LIB_SOVERSION} ) install(TARGETS karbonui ${INSTALL_TARGETS_DEFAULT_ARGS}) diff --git a/karbon/ui/KarbonDocument.cpp b/karbon/ui/KarbonDocument.cpp index a7f9ab8f591..4b014acf548 100644 --- a/karbon/ui/KarbonDocument.cpp +++ b/karbon/ui/KarbonDocument.cpp @@ -1,779 +1,213 @@ /* This file is part of the KDE project * Copyright (C) 2001-2002 Lennart Kudling * Copyright (C) 2001-2007 Rob Buis * Copyright (C) 2002-2006 Laurent Montel * Copyright (C) 2002 Werner Trobin * Copyright (C) 2002-2006 David Faure * Copyright (C) 2002 Stephan Kulow * Copyright (C) 2002 Benoit Vautrin * Copyright (C) 2003 Thomas Nagy * Copyright (C) 2003,2006 Dirk Mueller * Copyright (C) 2004 Brad Hards * Copyright (C) 2004-2006 Peter Simonsson * Copyright (C) 2004-2005 Fredrik Edemar * Copyright (C) 2005-2006 Tim Beaulen * Copyright (C) 2005 Sven Langkamp * Copyright (C) 2005-2007 Jan Hambrecht * Copyright (C) 2005-2007 Thomas Zander * Copyright (C) 2005-2013 Inge Wallin * Copyright (C) 2005 Johannes Schaub * Copyright (C) 2006 Gabor Lehel * Copyright (C) 2006 Stefan Nikolaus * Copyright (C) 2006 Jaison Lee * Copyright (C) 2006 Casper Boemann * Copyright (C) 2006-2007 Thorsten Zachmann * Copyright (C) 2007 Matthias Kretz * Copyright (C) 2012 Yue Liu * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KarbonDocument.h" #include "KarbonPart.h" #include "KarbonFactory.h" #include "KarbonView.h" -#include #include "KarbonUiDebug.h" #include -#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Make sure an appropriate DTD is available in www/calligra/DTD if changing this value // static const char * CURRENT_DTD_VERSION = "1.2"; class Q_DECL_HIDDEN KarbonDocument::Private { public: Private() - : pageSize(0.0, 0.0), - hasExternalDataCenterMap(false), - showStatusBar(true), + : showStatusBar(true), merge(false), maxRecentFiles(10) {} - ~Private() - { - layers.clear(); - objects.clear(); - if (!hasExternalDataCenterMap) - qDeleteAll(dataCenterMap); - } - - qreal getAttribute(KoXmlElement &element, const char *attributeName, qreal defaultValue) - { - QString value = element.attribute(attributeName); - if (! value.isEmpty()) - return value.toDouble(); - else - return defaultValue; - } - - int getAttribute(KoXmlElement &element, const char *attributeName, int defaultValue) - { - QString value = element.attribute(attributeName); - if (! value.isEmpty()) - return value.toInt(); - else - return defaultValue; - } - // KarbonDocument document; ///< store non-visual doc info - QSizeF pageSize; ///< the documents page size - - QList objects; ///< The list of all object of the document. - QList layers; ///< The layers in this document. - QMap dataCenterMap; - bool hasExternalDataCenterMap; bool showStatusBar; ///< enable/disable status bar in attached view(s) bool merge; uint maxRecentFiles; ///< max. number of files shown in open recent menu item }; KarbonDocument::KarbonDocument(KarbonPart* part) - : KoDocument(part) - , d(new Private()) + : KoPADocument(part) + , d(new Private()) { Q_ASSERT(part); - resourceManager()->setUndoStack(undoStack()); initConfig(); SvgShapeFactory::addToRegistry(); // set as default paper KoPageLayout pl = pageLayout(); pl.format = KoPageFormat::defaultFormat(); pl.orientation = KoPageFormat::Portrait; pl.width = MM_TO_POINT(KoPageFormat::width(pl.format, pl.orientation)); pl.height = MM_TO_POINT(KoPageFormat::height(pl.format, pl.orientation)); setPageLayout(pl); } KarbonDocument::~KarbonDocument() { delete d; } -void KarbonDocument::setPageLayout(const KoPageLayout& layout) -{ - KoDocument::setPageLayout(layout); - setPageSize(QSizeF(layout.width, layout.height)); -} - -bool KarbonDocument::loadXML(const KoXmlDocument&, KoStore*) -{ - return false; -} - -bool KarbonDocument::loadOdf(KoOdfReadStore & odfStore) -{ - debugKarbonUi << "Start loading OASIS document..." /*<< doc.toString()*/; - - KoXmlElement contents = odfStore.contentDoc().documentElement(); - debugKarbonUi << "Start loading OASIS document..." << contents.text(); - debugKarbonUi << "Start loading OASIS contents..." << contents.lastChild().localName(); - debugKarbonUi << "Start loading OASIS contents..." << contents.lastChild().namespaceURI(); - debugKarbonUi << "Start loading OASIS contents..." << contents.lastChild().isElement(); - KoXmlElement body(KoXml::namedItemNS(contents, KoXmlNS::office, "body")); - if (body.isNull()) { - debugKarbonUi << "No office:body found!"; - setErrorMessage(i18n("Invalid OASIS document. No office:body tag found.")); - return false; - } - - body = KoXml::namedItemNS(body, KoXmlNS::office, "drawing"); - if (body.isNull()) { - debugKarbonUi << "No office:drawing found!"; - setErrorMessage(i18n("Invalid OASIS document. No office:drawing tag found.")); - return false; - } - - KoXmlElement page(KoXml::namedItemNS(body, KoXmlNS::draw, "page")); - if (page.isNull()) { - debugKarbonUi << "No office:drawing found!"; - setErrorMessage(i18n("Invalid OASIS document. No draw:page tag found.")); - return false; - } - - KoXmlElement * master = 0; - if (odfStore.styles().masterPages().contains("Standard")) - master = odfStore.styles().masterPages().value("Standard"); - else if (odfStore.styles().masterPages().contains("Default")) - master = odfStore.styles().masterPages().value("Default"); - else if (! odfStore.styles().masterPages().empty()) - master = odfStore.styles().masterPages().begin().value(); - - if (master) { - const QString pageStyleName = master->attributeNS(KoXmlNS::style, "page-layout-name", QString()); - const KoXmlElement *style = odfStore.styles().findStyle(pageStyleName); - if (style) { - KoPageLayout layout; - layout.loadOdf(*style); - setPageLayout(layout); - } - } else { - warnKarbonUi << "No master page found!"; - return false; - } - - KoOdfLoadingContext context(odfStore.styles(), odfStore.store()); - KoShapeLoadingContext shapeContext(context, resourceManager()); - - loadOasis(page, shapeContext); - - if (pageSize().isEmpty()) { - QSizeF pageSize = contentRect().united(QRectF(0, 0, 1, 1)).size(); - setPageSize(pageSize); - } - - loadOasisSettings(odfStore.settingsDoc()); - - return true; -} - -bool KarbonDocument::completeLoading(KoStore* store) -{ - bool ok = true; - foreach(KoDataCenterBase *dataCenter, dataCenterMap()) { - ok = ok && dataCenter->completeLoading(store); - } - return ok; -} - -void KarbonDocument::loadOasisSettings(const KoXmlDocument & settingsDoc) -{ - if (settingsDoc.isNull()) - return ; // not an error if some file doesn't have settings.xml - KoOasisSettings settings(settingsDoc); - KoOasisSettings::Items viewSettings = settings.itemSet("view-settings"); - if (!viewSettings.isNull()) { - setUnit(KoUnit::fromSymbol(viewSettings.parseConfigItemString("unit"))); - // FIXME: add other config here. - } - guidesData().loadOdfSettings(settingsDoc); - gridData().loadOdfSettings(settingsDoc); -} - -void KarbonDocument::saveOasisSettings(KoStore * store) -{ - KoStoreDevice settingsDev(store); - KoXmlWriter * settingsWriter = KoOdfWriteStore::createOasisXmlWriter(&settingsDev, "office:document-settings"); - - settingsWriter->startElement("office:settings"); - settingsWriter->startElement("config:config-item-set"); - settingsWriter->addAttribute("config:name", "view-settings"); - - saveUnitOdf(settingsWriter); - - settingsWriter->endElement(); // config:config-item-set - - settingsWriter->startElement("config:config-item-set"); - settingsWriter->addAttribute("config:name", "ooo:view-settings"); - settingsWriter->startElement("config:config-item-map-indexed"); - settingsWriter->addAttribute("config:name", "Views"); - settingsWriter->startElement("config:config-item-map-entry"); - - guidesData().saveOdfSettings(*settingsWriter); - gridData().saveOdfSettings(*settingsWriter); - - settingsWriter->endElement(); // config:config-item-map-entry - settingsWriter->endElement(); // config:config-item-map-indexed - settingsWriter->endElement(); // config:config-item-set - - settingsWriter->endElement(); // office:settings - settingsWriter->endElement(); // office:document-settings - - settingsWriter->endDocument(); - - delete settingsWriter; -} - -bool KarbonDocument::saveOdf(SavingContext &documentContext) -{ - KoStore * store = documentContext.odfStore.store(); - KoXmlWriter* contentWriter = documentContext.odfStore.contentWriter(); - if (!contentWriter) - return false; - - KoGenStyles mainStyles; - KoXmlWriter * bodyWriter = documentContext.odfStore.bodyWriter(); - - KoShapeSavingContext shapeContext(*bodyWriter, mainStyles, documentContext.embeddedSaver); - - // save text styles - saveOdfStyles(shapeContext); - - // save page - QString layoutName = mainStyles.insert(pageLayout().saveOdf(), "PL"); - KoGenStyle masterPage(KoGenStyle::MasterPageStyle); - masterPage.addAttribute("style:page-layout-name", layoutName); - mainStyles.insert(masterPage, "Default", KoGenStyles::DontAddNumberToName); - - bodyWriter->startElement("office:body"); - bodyWriter->startElement("office:drawing"); - - saveOasis(shapeContext); // Save contents - - bodyWriter->endElement(); // office:drawing - bodyWriter->endElement(); // office:body - - mainStyles.saveOdfStyles(KoGenStyles::DocumentAutomaticStyles, contentWriter); - - documentContext.odfStore.closeContentWriter(); - - //add manifest line for content.xml - documentContext.odfStore.manifestWriter()->addManifestEntry("content.xml", "text/xml"); - - if (!shapeContext.saveDataCenter(store, documentContext.odfStore.manifestWriter())) { - return false; - } - - if (! mainStyles.saveOdfStylesDotXml(store, documentContext.odfStore.manifestWriter())) - return false; - - if (! store->open("settings.xml")) - return false; - - saveOasisSettings(store); - - if (! store->close()) - return false; - - documentContext.odfStore.manifestWriter()->addManifestEntry("settings.xml", "text/xml"); - - setModified(false); - - return true; -} - void KarbonDocument::slotDocumentRestored() { setModified(false); } -void KarbonDocument::paintContent(QPainter &painter, const QRect& rect) -{ - KoShapePainter shapePainter; - shapePainter.setShapes(shapes()); - shapePainter.paint(painter, rect, QRectF(QPointF(), pageSize())); -} - bool KarbonDocument::showStatusBar() const { return d->showStatusBar; } void KarbonDocument::setShowStatusBar(bool b) { d->showStatusBar = b; } uint KarbonDocument::maxRecentFiles() const { return d->maxRecentFiles; } void KarbonDocument::reorganizeGUI() { foreach(KoView* view, documentPart()->views()) { KarbonView * kv = qobject_cast(view); if (kv) { kv->reorganizeGUI(); - emit applyCanvasConfiguration(kv->canvasWidget()); } } } void KarbonDocument::initConfig() { KSharedConfigPtr config = KarbonFactory::karbonConfig(); // disable grid by default gridData().setShowGrid(false); if (config->hasGroup("Interface")) { KConfigGroup interfaceGroup = config->group("Interface"); setAutoSave(interfaceGroup.readEntry("AutoSave", defaultAutoSave() / 60) * 60); d->maxRecentFiles = interfaceGroup.readEntry("NbRecentFile", 10); setShowStatusBar(interfaceGroup.readEntry("ShowStatusBar" , true)); setBackupFile(interfaceGroup.readEntry("BackupFile", true)); } int undos = 30; QString defaultUnitSymbol = QLatin1String((QLocale().measurementSystem() == QLocale::ImperialSystem)?"in":"cm"); if (config->hasGroup("Misc")) { KConfigGroup miscGroup = config->group("Misc"); undos = miscGroup.readEntry("UndoRedo", -1); defaultUnitSymbol = miscGroup.readEntry("Units", defaultUnitSymbol); } undoStack()->setUndoLimit(undos); setUnit(KoUnit::fromSymbol(defaultUnitSymbol)); - if (config->hasGroup("Grid")) { - KoGridData defGrid; - KConfigGroup gridGroup = config->group("Grid"); - qreal spacingX = gridGroup.readEntry("SpacingX", defGrid.gridX()); - qreal spacingY = gridGroup.readEntry("SpacingY", defGrid.gridY()); - gridData().setGrid(spacingX, spacingY); - QColor color = gridGroup.readEntry("Color", defGrid.gridColor()); - gridData().setGridColor(color); - } } bool KarbonDocument::mergeNativeFormat(const QString &file) { d->merge = true; bool result = loadNativeFormat(file); if (!result) showLoadingErrorDialog(); d->merge = false; return result; } -void KarbonDocument::addShape(KoShape* shape) -{ - KoCanvasController* canvasController = KoToolManager::instance()->activeCanvasController(); - - KoShapeLayer *layer = dynamic_cast(shape); - if (layer) { - insertLayer(layer); - if (canvasController) { - KoSelection *selection = canvasController->canvas()->shapeManager()->selection(); - selection->setActiveLayer(layer); - } - } else { - // only add shape to active layer if it has no parent yet - if (! shape->parent()) { - debugKarbonUi << "shape has no parent, adding to the active layer!"; - KoShapeLayer *activeLayer = 0; - if (canvasController) - activeLayer = canvasController->canvas()->shapeManager()->selection()->activeLayer(); - else if (layers().count()) - activeLayer = layers().first(); - - if (activeLayer) - activeLayer->addShape(shape); - } - - add(shape); - - foreach(KoView *view, documentPart()->views()) { - KarbonCanvas *canvas = ((KarbonView*)view)->canvasWidget(); - canvas->shapeManager()->addShape(shape); - } - } - - setModified(true); - emit shapeCountChanged(); -} - -void KarbonDocument::removeShape(KoShape* shape) -{ - KoShapeLayer *layer = dynamic_cast(shape); - if (layer) { - removeLayer(layer); - } else { - remove(shape); - foreach(KoView *view, documentPart()->views()) { - KarbonCanvas *canvas = ((KarbonView*)view)->canvasWidget(); - canvas->shapeManager()->remove(shape); - } - } - setModified(true); - emit shapeCountChanged(); -} - -void KarbonDocument::setPageSize(const QSizeF &pageSize) -{ - d->pageSize = pageSize; - foreach(KoView *view, documentPart()->views()) { - KarbonCanvas *canvas = ((KarbonView*)view)->canvasWidget(); - canvas->resourceManager()->setResource(KoCanvasResourceManager::PageSize, pageSize); - } -} - -QSizeF KarbonDocument::pageSize() const -{ - return d->pageSize; -} - -void KarbonDocument::insertLayer(KoShapeLayer* layer) -{ - if (!d->layers.contains(layer)) { - if (d->layers.count()) { - layer->setZIndex(d->layers.last()->zIndex() + 1); - } else { - layer->setZIndex(d->layers.count()); - } - d->layers.append(layer); - } -} - -void KarbonDocument::removeLayer(KoShapeLayer* layer) -{ - d->layers.removeAt(d->layers.indexOf(layer)); - if (d->layers.count() == 0) - d->layers.append(new KoShapeLayer()); -} - -bool KarbonDocument::canRaiseLayer(KoShapeLayer* layer) -{ - int pos = d->layers.indexOf(layer); - return (pos != int(d->layers.count()) - 1 && pos >= 0); -} - -bool KarbonDocument::canLowerLayer(KoShapeLayer* layer) +KoOdf::DocumentType KarbonDocument::documentType() const { - int pos = d->layers.indexOf(layer); - return (pos > 0); + return KoOdf::Graphics; } -void KarbonDocument::raiseLayer(KoShapeLayer* layer) +const char * KarbonDocument::odfTagName(bool withNamespace) { - int pos = d->layers.indexOf(layer); - if (pos != int(d->layers.count()) - 1 && pos >= 0) { - KoShapeLayer * layerAbove = d->layers.at(pos + 1); - int lowerZIndex = layer->zIndex(); - int upperZIndex = layerAbove->zIndex(); - layer->setZIndex(upperZIndex); - layerAbove->setZIndex(lowerZIndex); - d->layers.move(pos, pos + 1); - } + return withNamespace ? "office:drawing": "drawing"; } - -void KarbonDocument::lowerLayer(KoShapeLayer* layer) -{ - int pos = d->layers.indexOf(layer); - if (pos > 0) { - KoShapeLayer * layerBelow = d->layers.at(pos - 1); - int upperZIndex = layer->zIndex(); - int lowerZIndex = layerBelow->zIndex(); - layer->setZIndex(lowerZIndex); - layerBelow->setZIndex(upperZIndex); - d->layers.move(pos, pos - 1); - } -} - -int KarbonDocument::layerPos(KoShapeLayer* layer) -{ - return d->layers.indexOf(layer); -} - -void KarbonDocument::add(KoShape* shape) -{ - if (! d->objects.contains(shape)) - d->objects.append(shape); -} - -void KarbonDocument::remove(KoShape* shape) -{ - d->objects.removeAt(d->objects.indexOf(shape)); -} - -void KarbonDocument::saveOasis(KoShapeSavingContext & context) const -{ - context.xmlWriter().startElement("draw:page"); - context.xmlWriter().addAttribute("draw:name", ""); - context.xmlWriter().addAttribute("draw:id", "page1"); - context.xmlWriter().addAttribute("xml:id", "page1"); - context.xmlWriter().addAttribute("draw:master-page-name", "Default"); - - foreach(KoShapeLayer * layer, d->layers) { - context.addLayerForSaving(layer); - } - context.saveLayerSet(context.xmlWriter()); - - foreach(KoShapeLayer * layer, d->layers) { - layer->saveOdf(context); - } - - context.xmlWriter().endElement(); // draw:page -} - -bool KarbonDocument::loadOasis(const KoXmlElement &element, KoShapeLoadingContext &context) -{ - // load text styles used by text shapes - loadOdfStyles(context); - - qDeleteAll(d->layers); - d->layers.clear(); - qDeleteAll(d->objects); - d->objects.clear(); - - const KoXmlElement & pageLayerSet = KoXml::namedItemNS(element, KoXmlNS::draw, "layer-set"); - const KoXmlElement & usedPageLayerSet = pageLayerSet.isNull() ? context.odfLoadingContext().stylesReader().layerSet() : pageLayerSet; - - KoXmlElement layerElement; - forEachElement(layerElement, usedPageLayerSet) { - KoShapeLayer * l = new KoShapeLayer(); - if (l->loadOdf(layerElement, context)) - insertLayer(l); - } - - KoShapeLayer * defaultLayer = 0; - - // check if we have to insert a default layer - if (d->layers.count() == 0) - defaultLayer = new KoShapeLayer(); - - KoXmlElement child; - forEachElement(child, element) { - debugKarbonUi << "loading shape" << child.localName(); - - KoShape * shape = KoShapeRegistry::instance()->createShapeFromOdf(child, context); - if (shape) - d->objects.append(shape); - } - - // add all toplevel shapes to the default layer - foreach(KoShape * shape, d->objects) { - if (! shape->parent()) { - if (! defaultLayer) - defaultLayer = new KoShapeLayer(); - - defaultLayer->addShape(shape); - } - } - - if (defaultLayer) - insertLayer(defaultLayer); - - KoOdfStylesReader & styleReader = context.odfLoadingContext().stylesReader(); - QHash masterPages = styleReader.masterPages(); - - KoXmlElement * master = 0; - if( masterPages.contains( "Standard" ) ) - master = masterPages.value( "Standard" ); - else if( masterPages.contains( "Default" ) ) - master = masterPages.value( "Default" ); - else if( ! masterPages.empty() ) - master = masterPages.begin().value(); - - if (master) { - context.odfLoadingContext().setUseStylesAutoStyles( true ); - - QList masterPageShapes; - KoXmlElement child; - forEachElement(child, (*master)) { - debugKarbonUi <<"loading master page shape" << child.localName(); - KoShape * shape = KoShapeRegistry::instance()->createShapeFromOdf( child, context ); - if( shape ) - masterPageShapes.append( shape ); - } - - KoShapeLayer * masterPageLayer = 0; - // add all toplevel shapes to the master page layer - foreach(KoShape * shape, masterPageShapes) { - d->objects.append( shape ); - if(!shape->parent()) { - if( ! masterPageLayer ) { - masterPageLayer = new KoShapeLayer(); - masterPageLayer->setName(i18n("Master Page")); - } - - masterPageLayer->addShape(shape); - } - } - - if( masterPageLayer ) - insertLayer( masterPageLayer ); - - context.odfLoadingContext().setUseStylesAutoStyles( false ); - } - - return true; -} - -QRectF KarbonDocument::boundingRect() const -{ - return contentRect().united(QRectF(QPointF(0, 0), d->pageSize)); -} - -QRectF KarbonDocument::contentRect() const -{ - QRectF bb; - foreach(KoShape* layer, d->layers) { - if (bb.isNull()) - bb = layer->boundingRect(); - else - bb = bb.united(layer->boundingRect()); - } - - return bb; -} - -const QList KarbonDocument::shapes() const -{ - return d->objects; -} - -const QList KarbonDocument::layers() const -{ - return d->layers; -} - -KoImageCollection * KarbonDocument::imageCollection() -{ - return resourceManager()->imageCollection(); -} - -QMap KarbonDocument::dataCenterMap() const -{ - return d->dataCenterMap; -} - -void KarbonDocument::useExternalDataCenterMap(const QMap &dataCenters) -{ - qDeleteAll(d->dataCenterMap); - d->dataCenterMap = dataCenters; - d->hasExternalDataCenterMap = true; -} - -void KarbonDocument::loadOdfStyles(KoShapeLoadingContext & context) -{ - // Only text styles (old style system). - KoStyleManager *styleManager = resourceManager()->resource(KoText::StyleManager).value(); - - if (! styleManager) - return; - - KoTextSharedLoadingData * sharedData = new KoTextSharedLoadingData(); - if (! sharedData) - return; - - sharedData->loadOdfStyles(context, styleManager); - context.addSharedData(KOTEXT_SHARED_LOADING_ID, sharedData); -} - -void KarbonDocument::saveOdfStyles(KoShapeSavingContext & context) -{ - KoStyleManager * styleManager = dynamic_cast(dataCenterMap()["StyleManager"]); - if (! styleManager) - return; - - styleManager->saveOdf(context); -} - -void KarbonDocument::addToDataCenterMap(const QString &key, KoDataCenterBase* dataCenter) -{ - d->dataCenterMap.insert(key, dataCenter); -} - diff --git a/karbon/ui/KarbonDocument.h b/karbon/ui/KarbonDocument.h index 92ec7240942..8cf21d478a1 100644 --- a/karbon/ui/KarbonDocument.h +++ b/karbon/ui/KarbonDocument.h @@ -1,264 +1,114 @@ /* This file is part of the KDE project * Copyright (C) 2001-2002 Lennart Kudling * Copyright (C) 2001-2005,2007 Rob Buis * Copyright (C) 2002,2004-2005 Laurent Montel * Copyright (C) 2002 Benoit Vautrin * Copyright (C) 2004-2005,2007 David Faure * Copyright (C) 2004,2006 Peter Simonsson * Copyright (C) 2004-2005 Fredrik Edemar * Copyright (C) 2005-2007 Jan Hambrecht * Copyright (C) 2005-2007 Thomas Zander * Copyright (C) 2006 Inge Wallin * Copyright (C) 2006 Tim Beaulen * Copyright (C) 2006 Casper Boemann * Copyright (C) 2006-2007 Thorsten Zachmann * Copyright (C) 2012 Yue Liu * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KARBON_DOCUMENT_H #define KARBON_DOCUMENT_H #include #include #include #include -#include +#include #include #include #include class QRect; class KarbonPart; class KarbonCanvas; class KoDataCenterBase; class KoShape; class KoShapeSavingContext; class KoShapeLayer; class KoImageCollection; class KoStore; #define KARBON_MIME_TYPE "application/vnd.oasis.opendocument.graphics" /** * Keeps track of visual per document properties. * It loads initial settings and applies them to the document and its views. */ -class KARBONUI_EXPORT KarbonDocument : public KoDocument, public KoShapeBasedDocumentBase +class KARBONUI_EXPORT KarbonDocument : public KoPADocument { Q_OBJECT public: explicit KarbonDocument(KarbonPart *part); virtual ~KarbonDocument(); - /// reimplemented form KoDocument - virtual void paintContent(QPainter& painter, const QRect& rect); - /// reimplemented form KoDocument - virtual bool loadXML(const KoXmlDocument& document, KoStore *store); - /// reimplemented form KoDocument - virtual bool loadOdf(KoOdfReadStore & odfStore); - /// reimplemented form KoDocument - virtual bool completeLoading(KoStore* store); - /// reimplemented form KoDocument - virtual bool saveOdf(SavingContext &documentContext); + KoOdf::DocumentType documentType() const; /// reimplemented from KoDocument virtual QByteArray nativeFormatMimeType() const { return KARBON_MIME_TYPE; } /// reimplemented from KoDocument virtual QByteArray nativeOasisMimeType() const { return KARBON_MIME_TYPE; } /// reimplemented from KoDocument virtual QStringList extraNativeMimeTypes() const { - return QStringList() << "application/vnd.oasis.opendocument.graphics" - << "application/vnd.oasis.opendocument.graphics-template"; + return QStringList() << "application/vnd.oasis.opendocument.graphics-template"; } - /// implemented from KoShapeController - virtual void addShape(KoShape* shape); - /// implemented from KoShapeController - virtual void removeShape(KoShape* shape); - /// Returns if status bar is shown bool showStatusBar() const; /// Shows/hides status bar void setShowStatusBar(bool b); /// update attached view(s) on the current doc settings /// at this time only the status bar is handled void reorganizeGUI(); /// Returns maximum number of recent files uint maxRecentFiles() const; - /// Sets page layout of the document - virtual void setPageLayout(const KoPageLayout& layout); - bool mergeNativeFormat(const QString & file); - // merged from original KarbonDocument - - /** - * Checks if specified layer can be raised. - * - * A layer can be raised if there is more than one layer and the specified layer - * is not already at the top. - * - * @param layer the layer to check - * @return true if layer can be raised, else false - */ - bool canRaiseLayer(KoShapeLayer* layer); - - /** - * Checks if specified layer can be lowered. - * - * A layer can be lowered if there is more than one layer and the specified layer - * is not already at the bottom. - * - * @param layer the layer to check - * @return true if layer can be lowered, else false - */ - bool canLowerLayer(KoShapeLayer* layer); - - /** - * Raises the layer. - * - * @param layer the layer to raise - */ - void raiseLayer(KoShapeLayer* layer); - - /** - * Lowers the layer. - * - * @param layer the layer to lower - */ - void lowerLayer(KoShapeLayer* layer); - - /** - * Returns the position of the specified layer. - * - * @param layer the layer to retrieve the position for - * @return the layer position - */ - int layerPos(KoShapeLayer* layer); - - /** - * Inserts a new layer. - * - * The layer is appended at the end, on top of all other layers, and is activated. - * - * @param layer the layer to insert - */ - void insertLayer(KoShapeLayer* layer); - - /** - * Removes the layer. - * - * If there is no layer left, a new layer is created, inserted and activated. - * - * @param layer the layer to remove - */ - void removeLayer(KoShapeLayer* layer); - - /** - * Returns the list of layers. - * The layer list provides a hierarchical view/access of the document data. - * All the documents shapes are children of a shape container, where a layer - * resembles a root container which can contain other containers in an - * arbitrary nesting depth. - */ - const QList layers() const; - - /** - * Returns the list of all shapes of the document. - * This list provides a flat view/access to all the documents shapes. - * For an hierarchical view/access one should retrieve the documents - * layers with layers(). - */ - const QList shapes() const; - - void saveOasis(KoShapeSavingContext & context) const; - bool loadOasis(const KoXmlElement &element, KoShapeLoadingContext &context); - void loadOdfStyles(KoShapeLoadingContext & context); - void saveOdfStyles(KoShapeSavingContext & context); - - /** - * Adds an object to the document. - * - * @param shape the object to append - */ - void add(KoShape* shape); - - /** - * Removes an object from the document. - * - * @param shape the object to append - */ - void remove(KoShape* shape); - - /// Returns the united bounding rectangle of the documents content and the document page - QRectF boundingRect() const; - - /// Returns the bounding rectangle of the documents content - QRectF contentRect() const; - - /// Returns the documents page size - QSizeF pageSize() const; - - /// Sets given page size to all attached views/canvases - void setPageSize(const QSizeF &pageSize); - - /// Sets the documents page size - //void setDocumentPageSize(QSizeF pageSize); - - /// Returns the documents image collection - KoImageCollection * imageCollection(); - - /// Returns the documents data centers - QMap dataCenterMap() const; - - /// Sets the data centers to be used by this document - void useExternalDataCenterMap(const QMap &dataCenters); - - void addToDataCenterMap(const QString &key, KoDataCenterBase* dataCenter); - public Q_SLOTS: void slotDocumentRestored(); Q_SIGNALS: - void shapeCountChanged(); void applyCanvasConfiguration(KarbonCanvas *canvas); protected: - - /// Loads settings like grid and guide lines from given xml document - void loadOasisSettings(const KoXmlDocument & settingsDoc); - /// Saves settings like grid and guide lines to store - void saveOasisSettings(KoStore * store); - + virtual const char *odfTagName(bool withNamespace); /// Reads settings from config file void initConfig(); private: class Private; Private * const d; }; #endif // KARBON_DOCUMENT_H diff --git a/karbon/ui/KarbonDocumentMergeCommand.cpp b/karbon/ui/KarbonDocumentMergeCommand.cpp index a7c9d9d82d2..a756946f6f9 100644 --- a/karbon/ui/KarbonDocumentMergeCommand.cpp +++ b/karbon/ui/KarbonDocumentMergeCommand.cpp @@ -1,95 +1,131 @@ /* This file is part of the KDE project * Copyright (C) 2009 Jan Hambrecht * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KarbonDocumentMergeCommand.h" #include "KarbonPart.h" #include "KarbonDocument.h" + +#include #include "KoShapeLayer.h" +#include +#include +#include + #include -class KarbonDocumentMergeCommand::Private +class MergePageCommand : public KUndo2Command { public: - Private() : hasMerged(false) + MergePageCommand(KoPADocument *doc, KoPAPageBase *targetPage, KoPAPageBase *sourcePage, KUndo2Command *parent) + : KUndo2Command(parent) + , mine(true) + , doc(doc) + , targetPage(targetPage) { + layers = sourcePage->shapes(); + sourcePage->removeAllShapes(); } - - ~Private() - { - if (!hasMerged) { + ~MergePageCommand() { + if (mine) { qDeleteAll(layers); - qDeleteAll(shapes); } } + void redo() { + for (int i = 0; i < layers.count(); ++i) { + targetPage->addShape(layers.at(i)); + } + mine = false; + doc->emitUpdate(targetPage); + } + void undo() { + for (int i = 0; i < layers.count(); ++i) { + targetPage->removeShape(layers.at(i)); + } + mine = true; + doc->emitUpdate(targetPage); + } - KarbonDocument * targetPart; - QList layers; - QList shapes; - bool hasMerged; +private: + bool mine; + KoPADocument *doc; + KoPAPageBase *targetPage; + QList layers; }; -KarbonDocumentMergeCommand::KarbonDocumentMergeCommand(KarbonDocument *targetPart, KarbonDocument *sourcePart) - : KUndo2Command(0), d(new Private()) +class AddPageCommand : public KUndo2Command { - d->targetPart = targetPart; - d->layers = sourcePart->layers(); - d->shapes = sourcePart->shapes(); - foreach(KoShapeLayer * layer, d->layers) { - sourcePart->removeShape(layer); +public: + AddPageCommand(KarbonDocument *doc, KoPAPageBase *sourcePage, KUndo2Command *parent) + : KUndo2Command(parent) + , mine(true) + , doc(doc) + { + newPage = doc->newPage(dynamic_cast(doc->pages(true).value(0))); + QList layers = sourcePage->shapes(); + sourcePage->removeAllShapes(); + for (int i = 0; i < layers.count(); ++i) { + newPage->addShape(layers.at(i)); + } } - foreach(KoShape * shape, d->shapes) { - sourcePart->removeShape(shape); + ~AddPageCommand() { + if (mine) { + delete newPage; + } + } + void redo() { + doc->insertPage(newPage, doc->pages().count()); + mine = false; + } + void undo() { + doc->takePage(newPage); + mine = true; } - setText(kundo2_i18n("Insert graphics")); -} -KarbonDocumentMergeCommand::~KarbonDocumentMergeCommand() -{ - delete d; -} +private: + bool mine; + KarbonDocument *doc; + KoPAPageBase *newPage; +}; -void KarbonDocumentMergeCommand::redo() +KarbonDocumentMergeCommand::KarbonDocumentMergeCommand(KarbonDocument *targetPart, KarbonDocument &sourcePart, KUndo2Command *parent) + : KUndo2Command(parent) { - if (!d->hasMerged) { - foreach(KoShapeLayer * layer, d->layers) { - d->targetPart->addShape(layer); - } - foreach(KoShape * shape, d->shapes) { - d->targetPart->addShape(shape); + QList pages; + for(int i = 0; i < sourcePart.pages().count(); ++i) { + KoPAPageBase *sourcePage = sourcePart.pages().at(i); + pages << sourcePage; + if (i < targetPart->pages().count()) { + KoPAPageBase *targetPage = targetPart->pages().at(i); + new MergePageCommand(targetPart, targetPage, sourcePage, this); + } else { + new AddPageCommand(targetPart, sourcePage, this); } - d->hasMerged = true; } + setText(kundo2_i18n("Insert graphics")); +} +void KarbonDocumentMergeCommand::redo() +{ KUndo2Command::redo(); } void KarbonDocumentMergeCommand::undo() { KUndo2Command::undo(); - - if (d->hasMerged) { - foreach(KoShapeLayer * layer, d->layers) { - d->targetPart->removeShape(layer); - } - foreach(KoShape * shape, d->shapes) { - d->targetPart->removeShape(shape); - } - d->hasMerged = false; - } } diff --git a/karbon/ui/KarbonDocumentMergeCommand.h b/karbon/ui/KarbonDocumentMergeCommand.h index 561af0a3507..af0f0d695a3 100644 --- a/karbon/ui/KarbonDocumentMergeCommand.h +++ b/karbon/ui/KarbonDocumentMergeCommand.h @@ -1,40 +1,36 @@ /* This file is part of the KDE project * Copyright (C) 2009 Jan Hambrecht * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef _KARBONDOCUMENTMERGECOMMAND_H_ #define _KARBONDOCUMENTMERGECOMMAND_H_ #include class KarbonDocument; class KarbonDocumentMergeCommand : public KUndo2Command { public: - KarbonDocumentMergeCommand(KarbonDocument * targetPart, KarbonDocument * sourcePart); - virtual ~KarbonDocumentMergeCommand(); - virtual void redo(); - virtual void undo(); - -private: - class Private; - Private * const d; + KarbonDocumentMergeCommand(KarbonDocument * targetPart, KarbonDocument &sourcePart, KUndo2Command *parent = 0); + virtual ~KarbonDocumentMergeCommand() Q_DECL_OVERRIDE = default; + virtual void redo() Q_DECL_OVERRIDE; + virtual void undo() Q_DECL_OVERRIDE; }; #endif // _KARBONDOCUMENTMERGECOMMAND_H_ diff --git a/karbon/ui/KarbonFactory.cpp b/karbon/ui/KarbonFactory.cpp index 4bd641241f9..4d4254d567e 100644 --- a/karbon/ui/KarbonFactory.cpp +++ b/karbon/ui/KarbonFactory.cpp @@ -1,88 +1,89 @@ /* This file is part of the KDE project * Copyright (C) 2001-2003 Lennart Kudling * Copyright (C) 2002-2003 Rob Buis * Copyright (C) 2002 Tomislav Lukman * Copyright (C) 2002,2004-2005,2007 David Faure * Copyright (C) 2002 BenoĂ®t Vautrin * Copyright (C) 2003 Lukáš Tinkl * Copyright (C) 2004,2006 Laurent Montel * Copyright (C) 2005-2006 Tim Beaulen * Copyright (C) 2005,2007 Thomas Zander * Copyright (C) 2006-2007 Jan Hambrecht * Copyright (C) 2007 Boudewijn Rempt * Copyright (C) 2007 Matthias Kretz * Copyright (C) 2007 Stephan Kulow * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KarbonFactory.h" #include "KarbonPart.h" #include "KarbonDocument.h" #include "KarbonAboutData.h" #include #include #include KoComponentData* KarbonFactory::s_global = 0; KarbonFactory::KarbonFactory() : KPluginFactory() { (void)global(); } KarbonFactory::~KarbonFactory() { } QObject* KarbonFactory::create(const char* /*iface*/, QWidget* /*parentWidget*/, QObject *parent, const QVariantList& args, const QString& keyword) { Q_UNUSED(args); Q_UNUSED(keyword); KarbonPart *part = new KarbonPart(parent); KarbonDocument* doc = new KarbonDocument(part); part->setDocument(doc); return part; } const KSharedConfig::Ptr& KarbonFactory::karbonConfig() { return global().config(); } const KoComponentData &KarbonFactory::global() { if (!s_global) { KAboutData *aboutData = newKarbonAboutData(); s_global = new KoComponentData(*aboutData); delete aboutData; // Add any application-specific resource directories here // Tell the iconloader about share/apps/calligra/icons KIconLoader::global()->addAppDir("calligra"); // Load Karbon specific dockers. KoPluginLoader::load(QStringLiteral("karbon/dockers")); + KoPluginLoader::load(QStringLiteral("calligra/pageapptools")); } return *s_global; } diff --git a/karbon/ui/KarbonPart.cpp b/karbon/ui/KarbonPart.cpp index 1ca28c7692b..ecd1055fd46 100644 --- a/karbon/ui/KarbonPart.cpp +++ b/karbon/ui/KarbonPart.cpp @@ -1,115 +1,103 @@ /* This file is part of the KDE project * Copyright (C) 2001-2002 Lennart Kudling * Copyright (C) 2001-2007 Rob Buis * Copyright (C) 2002-2006 Laurent Montel * Copyright (C) 2002 Werner Trobin * Copyright (C) 2002-2006 David Faure * Copyright (C) 2002 Stephan Kulow * Copyright (C) 2002 Benoit Vautrin * Copyright (C) 2003 Thomas Nagy * Copyright (C) 2003,2006 Dirk Mueller * Copyright (C) 2004 Brad Hards * Copyright (C) 2004-2006 Peter Simonsson * Copyright (C) 2004-2005 Fredrik Edemar * Copyright (C) 2005-2006 Tim Beaulen * Copyright (C) 2005 Sven Langkamp * Copyright (C) 2005-2007 Jan Hambrecht * Copyright (C) 2005-2007 Thomas Zander * Copyright (C) 2005-2006 Inge Wallin * Copyright (C) 2005 Johannes Schaub * Copyright (C) 2006 Gabor Lehel * Copyright (C) 2006 Stefan Nikolaus * Copyright (C) 2006 Jaison Lee * Copyright (C) 2006,2012 C. Boemann * Copyright (C) 2006-2007 Thorsten Zachmann * Copyright (C) 2007 Matthias Kretz * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KarbonPart.h" #include "KarbonView.h" +#include "ProxyView.h" #include "KarbonDocument.h" #include "KarbonFactory.h" -#include "KarbonCanvas.h" +#include "KarbonPaletteBarWidget.h" #include #include #include #include +#include + KarbonPart::KarbonPart(QObject *parent) : KoPart(KarbonFactory::global(), parent) { setTemplatesResourcePath(QLatin1String("karbon/templates/")); } KarbonPart::~KarbonPart() { } -void KarbonPart::setDocument(KoDocument *document) -{ - KoPart::setDocument(document); - KarbonDocument *doc = qobject_cast(document); - connect(doc, SIGNAL(applyCanvasConfiguration(KarbonCanvas*)), SLOT(applyCanvasConfiguration(KarbonCanvas*))); -} - KoView * KarbonPart::createViewInstance(KoDocument *_document, QWidget *parent) { KarbonDocument *doc = qobject_cast(_document); + ProxyView *view = new ProxyView(this, doc, parent); - KarbonView *result = new KarbonView(this, doc, parent); + KarbonView *result = new KarbonView(this, doc, view); + view->view = result; - KoCanvasResourceManager * provider = result->canvasWidget()->resourceManager(); - provider->setResource(KoCanvasResourceManager::PageSize, doc->pageSize()); + // Add the color bar below the karbon view (the reason for the ProxyView) + QVBoxLayout *layout = new QVBoxLayout(view); + layout->setMargin(0); + layout->setSpacing(0); + layout->addWidget(result); + layout->addWidget(result->colorBar()); - applyCanvasConfiguration(result->canvasWidget()); + connect(doc, SIGNAL(replaceActivePage(KoPAPageBase*,KoPAPageBase*)), result, SLOT(replaceActivePage(KoPAPageBase*,KoPAPageBase*))); - return result; + return view; } KoMainWindow *KarbonPart::createMainWindow() { return new KoMainWindow(KARBON_MIME_TYPE, componentData()); } void KarbonPart::openTemplate(const QUrl& url) { KoPart::openTemplate(url); // explicitly set the output mimetype to our native mimetype // so that autosaving works for not yet saved templates as well if (document()->outputMimeType().isEmpty()) { document()->setOutputMimeType("application/vnd.oasis.opendocument.graphics"); } } - - -void KarbonPart::applyCanvasConfiguration(KarbonCanvas *canvas) -{ - KSharedConfigPtr config = componentData().config(); - - QColor color(Qt::white); - if (config->hasGroup("Interface")) { - color = config->group("Interface").readEntry("CanvasColor", color); - } - canvas->setBackgroundColor(color); -} - - diff --git a/karbon/ui/KarbonPart.h b/karbon/ui/KarbonPart.h index 47fb6f28ad5..08104828b41 100644 --- a/karbon/ui/KarbonPart.h +++ b/karbon/ui/KarbonPart.h @@ -1,70 +1,61 @@ /* This file is part of the KDE project * Copyright (C) 2001-2002 Lennart Kudling * Copyright (C) 2001-2005,2007 Rob Buis * Copyright (C) 2002,2004-2005 Laurent Montel * Copyright (C) 2002 Benoit Vautrin * Copyright (C) 2004-2005,2007 David Faure * Copyright (C) 2004,2006 Peter Simonsson * Copyright (C) 2004-2005 Fredrik Edemar * Copyright (C) 2005-2007 Jan Hambrecht * Copyright (C) 2005-2007 Thomas Zander * Copyright (C) 2006 Inge Wallin * Copyright (C) 2006 Tim Beaulen * Copyright (C) 2006,2012 C. Boemann * Copyright (C) 2006-2007 Thorsten Zachmann * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KARBON_PART_H #define KARBON_PART_H #include #include "karbonui_export.h" class KoView; class KoDocument; -class KarbonCanvas; - class KARBONUI_EXPORT KarbonPart : public KoPart { Q_OBJECT public: explicit KarbonPart(QObject *parent); virtual ~KarbonPart(); - void setDocument(KoDocument *document); - /// reimplemented virtual KoView *createViewInstance(KoDocument *document, QWidget *parent); /// reimplemented virtual KoMainWindow *createMainWindow(); protected Q_SLOTS: - /// reimplemented virtual void openTemplate(const QUrl& url); - -private Q_SLOTS: - - void applyCanvasConfiguration(KarbonCanvas *canvas); }; #endif diff --git a/karbon/ui/KarbonPrintJob.cpp b/karbon/ui/KarbonPrintJob.cpp deleted file mode 100644 index 9dea106f2d3..00000000000 --- a/karbon/ui/KarbonPrintJob.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* This file is part of the KDE project - * Copyright (C) 2007 Thomas Zander - * Copyright (C) 2009,2012 Jan Hambrecht - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "KarbonPrintJob.h" -#include "KarbonView.h" -#include "KarbonCanvas.h" -#include "KarbonPart.h" -#include "KarbonDocument.h" - -#include -#include - -#include - -KarbonPrintJob::KarbonPrintJob(KarbonView *view, PrintMode printMode) - : KoPrintingDialog(view), - m_view(view) -{ - setShapeManager(m_view->canvasWidget()->shapeManager()); - printer().setFromTo(1, 1); - - QSizeF pageSize = m_view->part()->pageSize(); - if (pageSize.width() > pageSize.height()) - printer().setOrientation(QPrinter::Landscape); - else - printer().setOrientation(QPrinter::Portrait); - - if (printMode == PrintToPdf) { - printer().setPaperSize(pageSize, QPrinter::Point); - printer().setFullPage(true); - } -} - -QRectF KarbonPrintJob::preparePage(int) -{ - // if we have any custom tabs, here is where can can read them out and do our thing. - - const QSizeF contentSize = m_view->part()->pageSize(); - const QRectF pageRectPt = printer().pageRect(QPrinter::Point); - const double scale = POINT_TO_INCH(printer().resolution()); - - qreal zoom = 1.0; - // fit document page to printer page if it is bigger than the printing page rect - if (contentSize.width() > pageRectPt.width() || contentSize.height() > pageRectPt.height()) { - qreal zoomX = pageRectPt.width() / contentSize.width(); - qreal zoomY = pageRectPt.height() / contentSize.height(); - zoom = qMin(zoomX, zoomY); - } - - painter().scale(zoom, zoom); - painter().setRenderHint(QPainter::Antialiasing); - - return QRectF(QPointF(), scale * contentSize); -} - -QList KarbonPrintJob::shapesOnPage(int) -{ - return shapeManager()->shapes(); -} - -QList KarbonPrintJob::createOptionWidgets() const -{ - return QList(); -} diff --git a/karbon/ui/KarbonPrintJob.h b/karbon/ui/KarbonPrintJob.h deleted file mode 100644 index bb745fcdd3f..00000000000 --- a/karbon/ui/KarbonPrintJob.h +++ /dev/null @@ -1,48 +0,0 @@ -/* This file is part of the KDE project - * Copyright (C) 2007 Thomas Zander - * Copyright (C) 2012 Jan Hambrecht - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef KARBONPRINTJOB_H -#define KARBONPRINTJOB_H - -#include - -class KarbonView; - -class KarbonPrintJob : public KoPrintingDialog -{ -public: - // the available print modes - enum PrintMode { - PrintToPaper, ///< printing to to printer device - PrintToPdf ///< printing to pdf file - }; - - KarbonPrintJob(KarbonView *view, PrintMode printMode); - -protected: - virtual QRectF preparePage(int pageNumber); - virtual QList shapesOnPage(int pageNumber); - virtual QList createOptionWidgets() const; - -private: - KarbonView *m_view; -}; - -#endif // KARBONPRINTJOB_H diff --git a/karbon/ui/KarbonView.cpp b/karbon/ui/KarbonView.cpp index bc052d61215..c6946734755 100644 --- a/karbon/ui/KarbonView.cpp +++ b/karbon/ui/KarbonView.cpp @@ -1,1538 +1,1291 @@ /* This file is part of the KDE project * Copyright (C) 2001-2002 Lennart Kudling * Copyright (C) 2001-2005,2007 Rob Buis * Copyright (C) 2002-2003,2005 Tomislav Lukman * Copyright (C) 2002-2003,2006 Laurent Montel * Copyright (C) 2002-2006 Stephan Binner * Copyright (C) 2002,2005 David Faure * Copyright (C) 2002 Benoit Vautrin * Copyright (C) 2002,2005-2007 Thomas Zander * Copyright (C) 2003 Dirk Mueller * Copyright (C) 2003,2006 Stephan Kulow * Copyright (C) 2004 Brad Hards * Copyright (C) 2005-2006 Tim Beaulen * Copyright (C) 2005 Yann Bodson * Copyright (C) 2005-2010 Boudewijn Rempt * Copyright (C) 2005-2009,2011 Jan Hambrecht * Copyright (C) 2005-2006 Peter Simonsson * Copyright (C) 2005-2006 Sven Langkamp * Copyright (C) 2005-2006 Inge Wallin * Copyright (C) 2005-2006 C. Boemann * Copyright (C) 2006 Martin Ellis * Copyright (C) 2006 Adriaan de Groot * Copyright (C) 2006 Sebastian Sauer * Copyright (C) 2006-2007 Thorsten Zachmann * Copyright (C) 2006 Andreas Hartmetz * Copyright (C) 2006 Stefan Nikolaus * Copyright (C) 2006-2007 Aaron J. Seigo * Copyright (C) 2007 Matthias Kretz * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KarbonView.h" // Dialogs. #include "KarbonConfigureDialog.h" -// Dockers. -#include "KarbonLayerDocker.h" - // The rest. #include "Karbon.h" #include "KarbonFactory.h" #include "KarbonPart.h" -#include "KarbonCanvas.h" #include "KarbonDocument.h" -#include "KarbonPrintJob.h" -#include "KarbonZoomController.h" #include "KarbonSmallStylePreview.h" #include "KarbonDocumentMergeCommand.h" #include "KarbonPaletteBarWidget.h" #include "KarbonUiDebug.h" +#include "KarbonOutlinePaintingStrategy.h" + +#include +#include +#include #include #include #include #include #include #include -#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // KF5 header #include #include #include #include #include #include #include +#include // qt header #include #include #include #include #include #include #include #include #include #include #include #include class Q_DECL_HIDDEN KarbonView::Private { public: Private(KarbonPart *part, KarbonDocument * doc) - : karbonPart(part), part(doc), canvas(0), canvasController(0), horizRuler(0), vertRuler(0) + : karbonPart(part), part(doc) , colorBar(0), closePath(0), combinePath(0) , separatePath(0), reversePath(0), intersectPath(0), subtractPath(0) , unitePath(0), excludePath(0), pathSnapToGrid(0), configureAction(0) , deleteSelectionAction(0), clipObjects(0), unclipObjects(0) - , flipVertical(0), flipHorizontal(0), viewAction(0), showRulerAction(0) + , flipVertical(0), flipHorizontal(0), viewAction(0) , snapGridAction(0), showPageMargins(0), showGuidesAction(0) , showPaletteAction(0) - , status(0), cursorCoords(0), smallPreview(0), zoomActionWidget(0) + , status(0), cursorCoords(0), smallPreview(0) {} KarbonPart * karbonPart; KarbonDocument * part; - KarbonCanvas * canvas; - KoCanvasController * canvasController; - KoRuler * horizRuler; - KoRuler * vertRuler; KarbonPaletteBarWidget *colorBar; // actions: QAction * closePath; QAction * combinePath; QAction * separatePath; QAction * reversePath; QAction * intersectPath; QAction * subtractPath; QAction * unitePath; QAction * excludePath; QAction * pathSnapToGrid; QAction * configureAction; QAction * deleteSelectionAction; QAction * clipObjects; QAction * unclipObjects; QAction * flipVertical; QAction * flipHorizontal; KToggleAction * viewAction; - KToggleAction * showRulerAction; + KToggleAction * snapGridAction; KToggleAction * showPageMargins; KToggleAction * showGuidesAction; + KToggleAction * showPaletteAction; //Status Bar QLabel * status; ///< ordinary status QLabel * cursorCoords; ///< cursor coordinates KarbonSmallStylePreview * smallPreview; ///< small style preview - QWidget * zoomActionWidget; ///< zoom action widget }; KarbonView::KarbonView(KarbonPart *karbonPart, KarbonDocument* doc, QWidget* parent) - : KoView(karbonPart, doc, parent), d(new Private(karbonPart, doc)) + : KoPAView(karbonPart, doc, KoPAView::NormalMode, parent) + , d(new Private(karbonPart, doc)) { setAcceptDrops(true); setXMLFile(QString::fromLatin1("karbon.rc")); - const int viewMargin = 250; - d->canvas = new KarbonCanvas(doc); - d->canvas->setParent(this); - d->canvas->setDocumentViewMargin(viewMargin); - connect(d->canvas->shapeManager()->selection(), SIGNAL(selectionChanged()), - this, SLOT(selectionChanged())); - - KoCanvasControllerWidget *canvasController = new KoCanvasControllerWidget(actionCollection(), this); - d->canvasController = canvasController; - canvasController->setMinimumSize(QSize(viewMargin + 50, viewMargin + 50)); - d->canvasController->setCanvas(d->canvas); - d->canvasController->setCanvasMode(KoCanvasController::Infinite); - // always show srollbars which fixes some nasty infinite - // recursion when scrollbars are disabled during resizing - canvasController->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - canvasController->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - canvasController->show(); - - // set up status bar message - d->status = new QLabel(QString(), this); - d->status->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); - d->status->setMinimumWidth(300); - addStatusBarItem(d->status, 1); - connect(KoToolManager::instance(), SIGNAL(changedStatusText(QString)), - d->status, SLOT(setText(QString))); d->cursorCoords = new QLabel(QString(), this); d->cursorCoords->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); d->cursorCoords->setMinimumWidth(50); addStatusBarItem(d->cursorCoords, 0); - - // TODO maybe the zoomHandler should be a member of the view and not the canvas. - // set up the zoom controller - KarbonZoomController * zoomController = new KarbonZoomController(d->canvasController, actionCollection(), this); - zoomController->setPageSize(d->part->pageSize()); - d->zoomActionWidget = zoomController->zoomAction()->createWidget(statusBar()); - addStatusBarItem(d->zoomActionWidget, 0); - zoomController->setZoomMode(KoZoomMode::ZOOM_PAGE); - connect(zoomController, SIGNAL(zoomedToSelection()), this, SLOT(zoomSelection())); - connect(zoomController, SIGNAL(zoomedToAll()), this, SLOT(zoomDrawing())); + connect(canvasController()->proxyObject, SIGNAL(canvasMousePositionChanged(QPoint)), this, SLOT(mousePositionChanged(QPoint))); d->smallPreview = new KarbonSmallStylePreview(this); connect(d->smallPreview, SIGNAL(fillApplied()), this, SLOT(applyFillToSelection())); connect(d->smallPreview, SIGNAL(strokeApplied()), this, SLOT(applyStrokeToSelection())); addStatusBarItem(d->smallPreview, 0); - - KoToolManager::instance()->addController(d->canvasController); - KoToolManager::instance()->registerTools(actionCollection(), d->canvasController); + // FIXME: This was not neccessary before refactoring to pageapp, why now? + // Also, changing colors of a shape does not update preview + connect(shapeManager(), SIGNAL(selectionChanged()), d->smallPreview, SLOT(selectionChanged())); initActions(); // Load all plugins const QList pluginFactories = KoPluginLoader::instantiatePluginFactories(QStringLiteral("karbon/extensions")); foreach (KPluginFactory* factory, pluginFactories) { QObject *object = factory->create(this, QVariantList()); KXMLGUIClient *clientPlugin = dynamic_cast(object); if (clientPlugin) { insertChildClient(clientPlugin); } else { // not our/valid plugin, so delete the created object object->deleteLater(); } } - unsigned int max = part()->maxRecentFiles(); + unsigned int max = static_cast(kopaDocument())->maxRecentFiles(); setNumberOfRecentFiles(max); - // widgets: - d->horizRuler = new KoRuler(this, Qt::Horizontal, d->canvas->viewConverter()); - d->horizRuler->setShowMousePosition(true); - d->horizRuler->setUnit(doc->unit()); - d->horizRuler->setRightToLeft(false); - d->horizRuler->setVisible(false); - new KoRulerController(d->horizRuler, d->canvas->resourceManager()); - - connect(doc, SIGNAL(unitChanged(KoUnit)), this, SLOT(updateUnit(KoUnit))); - - d->vertRuler = new KoRuler(this, Qt::Vertical, d->canvas->viewConverter()); - d->vertRuler->setShowMousePosition(true); - d->vertRuler->setUnit(doc->unit()); - d->vertRuler->setVisible(false); - - connect(d->canvas, SIGNAL(documentOriginChanged(QPoint)), this, SLOT(pageOffsetChanged())); - connect(d->canvasController->proxyObject, SIGNAL(canvasOffsetXChanged(int)), this, SLOT(pageOffsetChanged())); - connect(d->canvasController->proxyObject, SIGNAL(canvasOffsetYChanged(int)), this, SLOT(pageOffsetChanged())); - connect(d->canvasController->proxyObject, SIGNAL(canvasMousePositionChanged(QPoint)), - this, SLOT(mousePositionChanged(QPoint))); - d->vertRuler->createGuideToolConnection(d->canvas); - d->horizRuler->createGuideToolConnection(d->canvas); - - updateRuler(); - d->colorBar = new KarbonPaletteBarWidget(Qt::Horizontal, this); connect(d->colorBar, SIGNAL(colorSelected(KoColor)), this, SLOT(applyPaletteColor(KoColor))); - connect(d->canvas->shapeManager(), SIGNAL(selectionContentChanged()), d->colorBar, SLOT(updateDocumentColors())); - connect(part(), SIGNAL(shapeCountChanged()), d->colorBar, SLOT(updateDocumentColors())); + connect(shapeManager(), SIGNAL(selectionContentChanged()), d->colorBar, SLOT(updateDocumentColors())); + connect(kopaDocument(), SIGNAL(shapeAdded(KoShape*)), d->colorBar, SLOT(updateDocumentColors())); + connect(kopaDocument(), SIGNAL(shapeRemoved(KoShape*)), d->colorBar, SLOT(updateDocumentColors())); if (mainWindow()) { - // set the first layer active - d->canvasController->canvas()->shapeManager()->selection()->setActiveLayer(part()->layers().first()); - - //Create Dockers - createLayersTabDock(); - - // set one whitespace as title to allow a one column toolbox - KoToolBoxFactory toolBoxFactory; - mainWindow()->createDockWidget(&toolBoxFactory); - - connect(canvasController, SIGNAL(toolOptionWidgetsChanged(QList >)), - mainWindow()->dockerManager(), SLOT(newOptionWidgets(QList >))); - - KoToolManager::instance()->requestToolActivation(d->canvasController); - - KConfigGroup interfaceGroup = KarbonFactory::global().config()->group("Interface"); - if(interfaceGroup.readEntry("ShowRulers", false)) { - d->horizRuler->setVisible(true); - d->vertRuler->setVisible(true); - d->showRulerAction->setChecked(true); - } - if (!interfaceGroup.readEntry("ShowPalette", true)) { - d->colorBar->setVisible(false); - d->showPaletteAction->setChecked(false); + KSharedConfigPtr config = KSharedConfig::openConfig(); + if (config->hasGroup("Interface")) { + KConfigGroup interfaceGroup = config->group( "Interface" ); + if (!interfaceGroup.readEntry("ShowPalette", true)) { + d->colorBar->setVisible(false); + d->showPaletteAction->setChecked(false); + } } } - // layout: - QGridLayout *layout = new QGridLayout(); - layout->setMargin(0); - layout->setSpacing(0); - layout->addWidget(d->horizRuler->tabChooser(), 0, 0); - layout->addWidget(d->horizRuler, 0, 1); - layout->addWidget(d->vertRuler, 1, 0); - layout->addWidget(canvasController, 1, 1); - layout->addWidget(d->colorBar, 2, 1); - setLayout(layout); - reorganizeGUI(); setFocusPolicy(Qt::NoFocus); } KarbonView::~KarbonView() { - KoToolManager::instance()->removeCanvasController(d->canvasController); - - removeStatusBarItem(d->status); removeStatusBarItem(d->cursorCoords); removeStatusBarItem(d->smallPreview); - removeStatusBarItem(d->zoomActionWidget); + if (factory()) { + factory()->removeClient(this); + } delete d; } +KarbonPaletteBarWidget *KarbonView::colorBar() const +{ + return d->colorBar; +} + KarbonDocument * KarbonView::part() const { - return d->part; + return static_cast(kopaDocument()); } -KarbonCanvas * KarbonView::canvasWidget() const +KoCanvasResourceManager *KarbonView::resourceManager() const { - return d->canvas; + return kopaCanvas()->resourceManager(); } -KoZoomController * KarbonView::zoomController() const +KoPACanvas *KarbonView::canvasWidget() const { - return 0; + return dynamic_cast(kopaCanvas()); } void KarbonView::resizeEvent(QResizeEvent* /*event*/) { - if (!d->showRulerAction) - return; - - if (!d->canvas) + if (!kopaCanvas()) return; reorganizeGUI(); } void KarbonView::dragEnterEvent(QDragEnterEvent * event) { QColor color = KColorMimeData::fromMimeData(event->mimeData()); if (color.isValid()) { event->accept(); } KoView::dragEnterEvent(event); } void KarbonView::dropEvent(QDropEvent *e) { //Accepts QColor - from Color Manager's KColorPatch QColor color = KColorMimeData::fromMimeData(e->mimeData()); if (color.isValid()) { - KoSelection * selection = d->canvas->shapeManager()->selection(); + KoSelection * selection = shapeManager()->selection(); if (! selection) return; - if (! part()) + if (! kopaDocument()) return; - if (d->canvas->resourceManager()->intResource(KoCanvasResourceManager::ActiveStyleType) == KoFlake::Foreground) { + if (resourceManager()->intResource(KoCanvasResourceManager::ActiveStyleType) == KoFlake::Foreground) { QList strokes; QList selectedShapes = selection->selectedShapes(); foreach(KoShape * shape, selectedShapes) { KoShapeStroke * stroke = dynamic_cast(shape->stroke()); KoShapeStroke * newStroke = 0; if (stroke) { newStroke = new KoShapeStroke(*stroke); newStroke->setColor(color); } else { newStroke = new KoShapeStroke(1.0, color); } strokes.append(newStroke); } - d->canvas->addCommand(new KoShapeStrokeCommand(selectedShapes, strokes, 0)); + kopaCanvas()->addCommand(new KoShapeStrokeCommand(selectedShapes, strokes, 0)); } else { QSharedPointer fill(new KoColorBackground(color)); - d->canvas->addCommand(new KoShapeBackgroundCommand(selection->selectedShapes(), fill, 0)); + kopaCanvas()->addCommand(new KoShapeBackgroundCommand(selection->selectedShapes(), fill, 0)); } } - KoView::dropEvent(e); + KoPAView::dropEvent(e); } -void KarbonView::addImages(const QVector &imageList, const QPoint &insertAt) -{ - // get position from event and convert to document coordinates - QPointF pos = canvasWidget()->viewConverter()->viewToDocument(insertAt) - + canvasWidget()->documentOffset() - canvasWidget()->documentOrigin(); - - // create a factory - KoShapeFactoryBase *factory = KoShapeRegistry::instance()->value("PictureShape"); - if (!factory) { - warnKarbonUi << "No picture shape found, cannot drop images."; - return; - } - - foreach(const QImage &image, imageList) { - - KoProperties params; - QVariant v; - v.setValue(image); - params.setProperty("qimage", v); - - KoShape *shape = factory->createShape(¶ms, part()->resourceManager()); - - if (!shape) { - warnKarbonUi << "Could not create a shape from the image"; - return; - } - shape->setPosition(pos); - pos += QPointF(25,25); // increase the position for each shape we insert so the - // user can see them all. - KUndo2Command *cmd = canvasWidget()->shapeController()->addShapeDirect(shape); - if (cmd) { - KoSelection *selection = canvasWidget()->shapeManager()->selection(); - selection->deselectAll(); - selection->select(shape); - } - canvasWidget()->addCommand(cmd); - } -} - - - void KarbonView::fileImportGraphic() { - QByteArray nativeMimeType = part()->nativeFormatMimeType(); + QByteArray nativeMimeType = kopaDocument()->nativeFormatMimeType(); QStringList filter = KoFilterManager::mimeFilter(nativeMimeType, KoFilterManager::Import); QStringList imageFilter; // add filters for all formats supported by QImage foreach(const QByteArray &mimeType, QImageReader::supportedMimeTypes()) { imageFilter << QLatin1String(mimeType); } filter.append(imageFilter); KoFileDialog dialog(0, KoFileDialog::OpenFile, "OpenDocument"); dialog.setCaption(i18n("Choose Graphic to Add")); dialog.setMimeTypeFilters(imageFilter); QString fname = dialog.filename(); if (fname.isEmpty()) return; - QMap dataCenters = part()->dataCenterMap(); - KarbonPart importPart(0); KarbonDocument importDocument(&importPart); importPart.setDocument(&importDocument); - // use data centers of this document for importing - importDocument.useExternalDataCenterMap(dataCenters); - bool success = true; // check if we have an empty mime type (probably because the "All supported files" // filter was active) QString currentMimeFilter; // get mime type from file QMimeType mimeType = QMimeDatabase().mimeTypeForFile(fname); if (mimeType.isValid()) { const QString mime = mimeType.name(); if (mime == nativeMimeType) { currentMimeFilter = nativeMimeType; } else { foreach(const QString &filter, imageFilter) { if (mime == filter) { currentMimeFilter = filter; break; } } } } // check if we are loading an image format if (imageFilter.contains(currentMimeFilter)) { QImage image; if (!image.load(fname)) { KMessageBox::error(0, i18n("Could not load image."), i18n("Import graphic"), 0); return; } KoShapeFactoryBase * factory = KoShapeRegistry::instance()->get("PictureShape"); if (!factory) { KMessageBox::error(0, i18n("Could not create image shape."), i18n("Import graphic"), 0); return; } - KoShape *picture = factory->createDefaultShape(part()->resourceManager()); - KoImageCollection *imageCollection = part()->resourceManager()->imageCollection(); + KoShape *picture = factory->createDefaultShape(kopaDocument()->resourceManager()); + KoImageCollection *imageCollection = kopaDocument()->resourceManager()->imageCollection(); if (!picture || !imageCollection) { KMessageBox::error(0, i18n("Could not create image shape."), i18n("Import graphic"), 0); return; } // calculate shape size in point from image resolution qreal pxWidth = static_cast(image.width()); qreal pxHeight = static_cast(image.height()); qreal width = DM_TO_POINT(pxWidth / static_cast(image.dotsPerMeterX()) * 10.0); qreal height = DM_TO_POINT(pxHeight / static_cast(image.dotsPerMeterY()) * 10.0); // set shape data picture->setUserData(imageCollection->createImageData(image)); picture->setSize(QSizeF(width, height)); picture->setPosition(QPointF()); picture->setKeepAspectRatio(true); - KUndo2Command * cmd = d->canvas->shapeController()->addShapeDirect(picture); + KUndo2Command * cmd = kopaCanvas()->shapeController()->addShapeDirect(picture); cmd->setText(kundo2_i18n("Insert graphics")); - d->canvas->addCommand(cmd); - d->canvas->shapeManager()->selection()->select(picture); + kopaCanvas()->addCommand(cmd); + shapeManager()->selection()->select(picture); return; } - + // TODO: It is not obvious how this is best implemented when importing multipage docs + // Append pages? + // Append layers to existing pages? + // Add shapes to active page? + // etc? // check if we are loading our native format if (nativeMimeType == currentMimeFilter) { // directly load the native format success = importDocument.loadNativeFormat(fname); if (!success) { importDocument.showLoadingErrorDialog(); } } else { // use import filters to load the file KoFilterManager man(&importDocument); KoFilter::ConversionStatus status = KoFilter::OK; QString importedFile = man.importDocument(fname, QString(), status); if (status != KoFilter::OK) { importDocument.showLoadingErrorDialog(); success = false; } else if (!importedFile.isEmpty()) { success = importDocument.loadNativeFormat(importedFile); if (!success) { importDocument.showLoadingErrorDialog(); } // remove the temporary file created during format conversion unlink(QFile::encodeName(importedFile)); } } if (success) { - QList importedShapes = importDocument.shapes(); - - KarbonDocumentMergeCommand * cmd = new KarbonDocumentMergeCommand(part(), &importDocument); - d->canvas->addCommand(cmd); - + KarbonDocumentMergeCommand * cmd = new KarbonDocumentMergeCommand(dynamic_cast(kopaDocument()), importDocument); + kopaCanvas()->addCommand(cmd); +/* foreach(KoShape * shape, importedShapes) { d->canvas->shapeManager()->selection()->select(shape, false); - } + }*/ } } void KarbonView::selectionDuplicate() { - d->canvas->toolProxy()->copy(); - d->canvas->toolProxy()->paste(); + kopaCanvas()->toolProxy()->copy(); + kopaCanvas()->toolProxy()->paste(); } void KarbonView::editSelectAll() { - KoSelection* selection = d->canvas->shapeManager()->selection(); - if (! selection) + KoSelection* selection = shapeManager()->selection(); + if (! selection) { return; - - QList shapes = part()->shapes(); + } + QList shapes; + for (int i = 0; i < kopaDocument()->pages().count(); ++i) { + KoShapeLayer *l = dynamic_cast(kopaDocument()->pages().at(i)); + shapes += l->shapes(); + } debugKarbonUi << "shapes.size() =" << shapes.size(); foreach(KoShape* shape, shapes) { selection->select(shape); shape->update(); } selectionChanged(); } void KarbonView::editDeselectAll() { - KoSelection* selection = d->canvas->shapeManager()->selection(); + KoSelection* selection = shapeManager()->selection(); if (selection) selection->deselectAll(); selectionChanged(); } void KarbonView::editDeleteSelection() { - d->canvas->toolProxy()->deleteSelection(); + kopaCanvas()->toolProxy()->deleteSelection(); } void KarbonView::selectionDistributeHorizontalCenter() { selectionDistribute(KoShapeDistributeCommand::HorizontalCenterDistribution); } void KarbonView::selectionDistributeHorizontalGap() { selectionDistribute(KoShapeDistributeCommand::HorizontalGapsDistribution); } void KarbonView::selectionDistributeHorizontalLeft() { selectionDistribute(KoShapeDistributeCommand::HorizontalLeftDistribution); } void KarbonView::selectionDistributeHorizontalRight() { selectionDistribute(KoShapeDistributeCommand::HorizontalRightDistribution); } void KarbonView::selectionDistributeVerticalCenter() { selectionDistribute(KoShapeDistributeCommand::VerticalCenterDistribution); } void KarbonView::selectionDistributeVerticalGap() { selectionDistribute(KoShapeDistributeCommand::VerticalGapsDistribution); } void KarbonView::selectionDistributeVerticalBottom() { selectionDistribute(KoShapeDistributeCommand::VerticalBottomDistribution); } void KarbonView::selectionDistributeVerticalTop() { selectionDistribute(KoShapeDistributeCommand::VerticalTopDistribution); } void KarbonView::selectionDistribute(KoShapeDistributeCommand::Distribute distribute) { - KoSelection* selection = d->canvas->shapeManager()->selection(); + KoSelection* selection = shapeManager()->selection(); if (! selection) return; QList selectedShapes = selection->selectedShapes(KoFlake::TopLevelSelection); if (selectedShapes.count() < 2) return; KoShapeDistributeCommand *cmd = new KoShapeDistributeCommand(selectedShapes, distribute, selection->boundingRect()); - d->canvas->addCommand(cmd); + kopaCanvas()->addCommand(cmd); } void KarbonView::clipObjects() { - KoSelection* selection = d->canvas->shapeManager()->selection(); + KoSelection* selection = shapeManager()->selection(); if( ! selection ) return; QList selectedShapes = selection->selectedShapes( KoFlake::TopLevelSelection ); if( ! selectedShapes.count() ) return; KoShape * shapeToClip = selectedShapes.first(); selectedShapes.removeOne( shapeToClip ); QList clipPaths; foreach( KoShape * shape, selectedShapes ) { KoPathShape * path = dynamic_cast( shape ); if( path ) clipPaths.append( path ); } if( ! clipPaths.count() ) return; - KUndo2Command * cmd = new KoShapeClipCommand( d->part, shapeToClip, clipPaths ); - d->canvas->addCommand( cmd ); + KUndo2Command * cmd = new KoShapeClipCommand( kopaDocument(), shapeToClip, clipPaths ); + kopaCanvas()->addCommand( cmd ); } void KarbonView::unclipObjects() { - KoSelection* selection = d->canvas->shapeManager()->selection(); + KoSelection* selection = shapeManager()->selection(); if( ! selection ) return; QList selectedShapes = selection->selectedShapes( KoFlake::TopLevelSelection ); if( ! selectedShapes.count() ) return; QList shapesToUnclip; foreach(KoShape *shape, selectedShapes) { if (shape->clipPath()) shapesToUnclip.append(shape); } if (!shapesToUnclip.count()) return; - d->canvas->addCommand(new KoShapeUnclipCommand(d->part, shapesToUnclip)); + kopaCanvas()->addCommand(new KoShapeUnclipCommand(kopaDocument(), shapesToUnclip)); } void KarbonView::flipVertical() { selectionFlip(false, true); } void KarbonView::flipHorizontal() { selectionFlip(true, false); } void KarbonView::selectionFlip(bool horizontally, bool vertically) { if (!horizontally && !vertically) return; - KoSelection* selection = d->canvas->shapeManager()->selection(); + KoSelection* selection = shapeManager()->selection(); if( ! selection ) return; QList selectedShapes = selection->selectedShapes( KoFlake::StrippedSelection ); const int selectedShapesCount = selectedShapes.count(); if( selectedShapesCount < 1 ) return; // mirror about center point QPointF mirrorCenter = selection->absolutePosition(KoFlake::CenteredPosition); QTransform mirrorMatrix; mirrorMatrix.translate(mirrorCenter.x(), mirrorCenter.y()); mirrorMatrix.scale( horizontally ? -1.0 : 1.0, vertically ? -1.0 : 1.0); mirrorMatrix.translate(-mirrorCenter.x(), -mirrorCenter.y()); QVector oldState; QVector newState; oldState.reserve(selectedShapesCount); newState.reserve(selectedShapesCount); foreach( KoShape* shape, selectedShapes ) { shape->update(); oldState << shape->transformation(); // apply the mirror transformation shape->applyAbsoluteTransformation(mirrorMatrix); newState << shape->transformation(); } selection->applyAbsoluteTransformation(mirrorMatrix); KUndo2Command *cmd = new KoShapeTransformCommand(selectedShapes, oldState, newState); if (horizontally && !vertically) cmd->setText(kundo2_i18n("Mirror Horizontally")); else if (!horizontally && vertically) cmd->setText(kundo2_i18n("Mirror Vertically")); else cmd->setText(kundo2_i18n("Mirror Horizontally and Vertically")); - d->canvas->addCommand(cmd); + kopaCanvas()->addCommand(cmd); } void KarbonView::closePath() { // TODO add the new close path command here } void KarbonView::combinePath() { - KoSelection* selection = d->canvas->shapeManager()->selection(); + KoSelection* selection = shapeManager()->selection(); if (! selection) return; QList selectedShapes = selection->selectedShapes(); QList paths; foreach(KoShape* shape, selectedShapes) { KoPathShape *path = dynamic_cast(shape); if (path) { KoParameterShape * paramShape = dynamic_cast(path); if (paramShape && paramShape->isParametricShape()) continue; paths << path; selection->deselect(shape); } } if (paths.size()) - d->canvas->addCommand(new KoPathCombineCommand(part(), paths)); + kopaCanvas()->addCommand(new KoPathCombineCommand(kopaDocument(), paths)); } void KarbonView::separatePath() { - KoSelection* selection = d->canvas->shapeManager()->selection(); + KoSelection* selection = shapeManager()->selection(); if (! selection) return; QList selectedShapes = selection->selectedShapes(); QList paths; foreach(KoShape* shape, selectedShapes) { KoPathShape *path = dynamic_cast(shape); if (path) { paths << path; selection->deselect(shape); } } if (!paths.size()) { return; } KUndo2Command *cmd = new KUndo2Command; cmd->setText(kundo2_i18n("Separate paths")); foreach(KoPathShape* p, paths) { QList separatedPaths; QList newShapes; if (p->separate(separatedPaths)) { foreach(KoPathShape *subPath, separatedPaths) { - new KoShapeCreateCommand(part(), subPath, cmd); + new KoShapeCreateCommand(kopaDocument(), subPath, cmd); newShapes << subPath; } // make sure we put the new subpaths into the parent // of the original path KoShapeGroup *parentGroup = dynamic_cast(p->parent()); if (parentGroup) { new KoShapeGroupCommand(parentGroup, newShapes, cmd); } - new KoShapeDeleteCommand(part(), p, cmd); + new KoShapeDeleteCommand(kopaDocument(), p, cmd); } } - d->canvas->addCommand(cmd); + kopaCanvas()->addCommand(cmd); } void KarbonView::reversePath() { QList paths = selectedPathShapes(); if (paths.size()) - d->canvas->addCommand(new KoPathReverseCommand(paths)); + kopaCanvas()->addCommand(new KoPathReverseCommand(paths)); } void KarbonView::intersectPaths() { booleanOperation(KarbonBooleanCommand::Intersection); } void KarbonView::subtractPaths() { booleanOperation(KarbonBooleanCommand::Subtraction); } void KarbonView::unitePaths() { booleanOperation(KarbonBooleanCommand::Union); } void KarbonView::excludePaths() { booleanOperation(KarbonBooleanCommand::Exclusion); } void KarbonView::booleanOperation(KarbonBooleanCommand::BooleanOperation operation) { - KoSelection* selection = d->canvas->shapeManager()->selection(); + KoSelection* selection = shapeManager()->selection(); if (! selection) return; QList selectedShapes = selection->selectedShapes(); QList paths; foreach(KoShape* shape, selectedShapes) { KoPathShape *path = dynamic_cast(shape); if (path) { paths << path; selection->deselect(shape); } } if (paths.size() == 2) { KUndo2Command * macro = new KUndo2Command(kundo2_i18n("Boolean Operation")); KoParameterShape * paramShape = dynamic_cast(paths[0]); if (paramShape && paramShape->isParametricShape()) new KoParameterToPathCommand(paramShape, macro); paramShape = dynamic_cast(paths[1]); if (paramShape && paramShape->isParametricShape()) new KoParameterToPathCommand(paramShape, macro); - new KarbonBooleanCommand(part(), paths[0], paths[1], operation, macro); - new KoShapeDeleteCommand(part(), paths[0], macro); - new KoShapeDeleteCommand(part(), paths[1], macro); - d->canvas->addCommand(macro); + new KarbonBooleanCommand(kopaDocument(), paths[0], paths[1], operation, macro); + new KoShapeDeleteCommand(kopaDocument(), paths[0], macro); + new KoShapeDeleteCommand(kopaDocument(), paths[1], macro); + kopaCanvas()->addCommand(macro); } } void KarbonView::pathSnapToGrid() { - KoSelection* selection = d->canvas->shapeManager()->selection(); + KoSelection* selection = shapeManager()->selection(); if (! selection) return; QList selectedShapes = selection->selectedShapes(); QList points; QVector offsets; // store current grid snap state - bool oldSnapToGrid = part()->gridData().snapToGrid(); + bool oldSnapToGrid = kopaDocument()->gridData().snapToGrid(); // enable grid snapping - part()->gridData().setSnapToGrid(true); + kopaDocument()->gridData().setSnapToGrid(true); - KoSnapGuide snapGuide(d->canvas); + KoSnapGuide snapGuide(kopaCanvas()); snapGuide.enableSnapStrategies(KoSnapGuide::GridSnapping); snapGuide.setSnapDistance(INT_MAX); foreach(KoShape* shape, selectedShapes) { KoParameterShape * paramShape = dynamic_cast(shape); if (paramShape && paramShape->isParametricShape()) continue; KoPathShape *path = dynamic_cast(shape); if (! path) continue; uint subpathCount = path->subpathCount(); for (uint i = 0; i < subpathCount; ++i) { uint pointCount = path->subpathPointCount(i); for (uint j = 0; j < pointCount; ++j) { KoPathPointIndex index(i, j); KoPathPoint * p = path->pointByIndex(index); if (!p) continue; QPointF docPoint = path->shapeToDocument(p->point()); QPointF offset = snapGuide.snap(docPoint, 0) - docPoint; points.append(KoPathPointData(path, index)); offsets.append(offset); } } } // reset grid snapping state to old value - part()->gridData().setSnapToGrid(oldSnapToGrid); + kopaDocument()->gridData().setSnapToGrid(oldSnapToGrid); - d->canvas->addCommand(new KoPathPointMoveCommand(points, offsets)); + kopaCanvas()->addCommand(new KoPathPointMoveCommand(points, offsets)); } void KarbonView::viewModeChanged(bool outlineMode) { - d->canvas->enableOutlineMode(outlineMode); - d->canvas->updateCanvas(d->canvas->canvasWidget()->rect()); + if (outlineMode) { + new KarbonOutlinePaintingStrategy(shapeManager()); + } else { + shapeManager()->setPaintingStrategy(new KoShapeManagerPaintingStrategy(shapeManager())); + } } void KarbonView::zoomSelection() { - KoSelection* selection = d->canvas->shapeManager()->selection(); + KoSelection* selection = shapeManager()->selection(); if (! selection) return; if (! selection->count()) return; - const KoZoomHandler * zoomHandler = dynamic_cast(d->canvas->viewConverter()); + const KoZoomHandler * zoomHandler = dynamic_cast(viewConverter()); if (! zoomHandler) return; QRectF bbox = selection->boundingRect(); QRect viewRect = zoomHandler->documentToView(bbox).toRect(); - d->canvasController->zoomTo(viewRect.translated(d->canvas->documentOrigin())); - QPointF newCenter = d->canvas->documentOrigin() + zoomHandler->documentToView(bbox.center()); - d->canvasController->setPreferredCenter(newCenter.toPoint()); + kopaCanvas()->canvasController()->zoomTo(viewRect.translated(kopaCanvas()->documentOrigin())); +// QPointF newCenter = kopaCanvas()->documentOrigin() + zoomHandler->documentToView(bbox.center()); +// kopaCanvas()->setPreferredCenter(newCenter.toPoint()); } void KarbonView::zoomDrawing() { - const KoZoomHandler * zoomHandler = dynamic_cast(d->canvas->viewConverter()); + const KoZoomHandler * zoomHandler = dynamic_cast(kopaCanvas()->viewConverter()); if (! zoomHandler) return; - QRectF bbox = d->part->contentRect(); + QRectF bbox = activePage()->contentRect(); if (bbox.isNull()) return; QRect viewRect = zoomHandler->documentToView(bbox).toRect(); - d->canvasController->zoomTo(viewRect.translated(d->canvas->documentOrigin())); - QPointF newCenter = d->canvas->documentOrigin() + zoomHandler->documentToView(bbox.center()); - d->canvasController->setPreferredCenter(newCenter.toPoint()); + kopaCanvas()->canvasController()->zoomTo(viewRect.translated(kopaCanvas()->documentOrigin())); +// QPointF newCenter = kopaCanvas()->documentOrigin() + zoomHandler->documentToView(bbox.center()); +// kopaCanvas()->setPreferredCenter(newCenter.toPoint()); } void KarbonView::initActions() { // view -----> d->viewAction = new KToggleAction(i18n("Outline &Mode"), this); actionCollection()->addAction("view_mode", d->viewAction); connect(d->viewAction, SIGNAL(toggled(bool)), this, SLOT(viewModeChanged(bool))); - d->showPageMargins = new KToggleAction(i18n("Show Page Margins"), this); - actionCollection()->addAction("view_show_margins", d->showPageMargins); - connect(d->showPageMargins, SIGNAL(toggled(bool)), SLOT(togglePageMargins(bool))); - // No need for the other actions in read-only (embedded) mode if (!mainWindow()) return; // edit -----> QAction *action = actionCollection()->addAction(KStandardAction::Cut, "edit_cut", 0, 0); - new KoCutController(d->canvas, action); + new KoCutController(kopaCanvas(), action); action = actionCollection()->addAction(KStandardAction::Copy, "edit_copy", 0, 0); - new KoCopyController(d->canvas, action); + new KoCopyController(kopaCanvas(), action); action = actionCollection()->addAction(KStandardAction::Paste, "edit_paste", 0, 0); - new KoPasteController(d->canvas, action); + new KoPasteController(kopaCanvas(), action); actionCollection()->addAction(KStandardAction::SelectAll, "edit_select_all", this, SLOT(editSelectAll())); actionCollection()->addAction(KStandardAction::Deselect, "edit_deselect_all", this, SLOT(editDeselectAll())); QAction *actionImportGraphic = new QAction(i18n("&Import Graphic..."), this); actionCollection()->addAction("file_import", actionImportGraphic); connect(actionImportGraphic, SIGNAL(triggered()), this, SLOT(fileImportGraphic())); d->deleteSelectionAction = new QAction(koIcon("edit-delete"), i18n("D&elete"), this); actionCollection()->addAction("edit_delete", d->deleteSelectionAction); d->deleteSelectionAction->setShortcut(QKeySequence("Del")); connect(d->deleteSelectionAction, SIGNAL(triggered()), this, SLOT(editDeleteSelection())); - connect(d->canvas->toolProxy(), SIGNAL(selectionChanged(bool)), d->deleteSelectionAction, SLOT(setEnabled(bool))); + connect(kopaCanvas()->toolProxy(), SIGNAL(selectionChanged(bool)), d->deleteSelectionAction, SLOT(setEnabled(bool))); QAction *actionEditGuides = new QAction(koIcon("edit-guides"), i18n("Edit Guides"), this); actionCollection()->addAction("edit_guides", actionEditGuides); connect(actionEditGuides, SIGNAL(triggered()), this, SLOT(editGuides())); // edit <----- // object -----> QAction *actionDuplicate = new QAction(i18nc("Duplicate selection", "&Duplicate"), this); actionCollection()->addAction("object_duplicate", actionDuplicate); actionDuplicate->setShortcut(QKeySequence("Ctrl+D")); connect(actionDuplicate, SIGNAL(triggered()), this, SLOT(selectionDuplicate())); QAction *actionDistributeHorizontalCenter = new QAction(koIcon("distribute-horizontal-center"), i18n("Distribute Center (Horizontal)"), this); actionCollection()->addAction("object_distribute_horizontal_center", actionDistributeHorizontalCenter); connect(actionDistributeHorizontalCenter, SIGNAL(triggered()), this, SLOT(selectionDistributeHorizontalCenter())); QAction *actionDistributeHorizontalGap = new QAction(koIcon("distribute-horizontal-equal"), i18n("Distribute Gaps (Horizontal)"), this); actionCollection()->addAction("object_distribute_horizontal_gap", actionDistributeHorizontalGap); connect(actionDistributeHorizontalGap, SIGNAL(triggered()), this, SLOT(selectionDistributeHorizontalGap())); QAction *actionDistributeLeft = new QAction(koIcon("distribute-horizontal-left"), i18n("Distribute Left Borders"), this); actionCollection()->addAction("object_distribute_horizontal_left", actionDistributeLeft); connect(actionDistributeLeft, SIGNAL(triggered()), this, SLOT(selectionDistributeHorizontalLeft())); QAction *actionDistributeRight = new QAction(koIcon("distribute-horizontal-right"), i18n("Distribute Right Borders"), this); actionCollection()->addAction("object_distribute_horizontal_right", actionDistributeRight); connect(actionDistributeRight, SIGNAL(triggered()), this, SLOT(selectionDistributeHorizontalRight())); QAction *actionDistributeVerticalCenter = new QAction(koIcon("distribute-vertical-center"), i18n("Distribute Center (Vertical)"), this); actionCollection()->addAction("object_distribute_vertical_center", actionDistributeVerticalCenter); connect(actionDistributeVerticalCenter, SIGNAL(triggered()), this, SLOT(selectionDistributeVerticalCenter())); QAction *actionDistributeVerticalGap = new QAction(koIcon("distribute-vertical-equal"), i18n("Distribute Gaps (Vertical)"), this); actionCollection()->addAction("object_distribute_vertical_gap", actionDistributeVerticalGap); connect(actionDistributeVerticalGap, SIGNAL(triggered()), this, SLOT(selectionDistributeVerticalGap())); QAction *actionDistributeBottom = new QAction(koIcon("distribute-vertical-bottom"), i18n("Distribute Bottom Borders"), this); actionCollection()->addAction("object_distribute_vertical_bottom", actionDistributeBottom); connect(actionDistributeBottom, SIGNAL(triggered()), this, SLOT(selectionDistributeVerticalBottom())); QAction *actionDistributeTop = new QAction(koIcon("distribute-vertical-top"), i18n("Distribute Top Borders"), this); actionCollection()->addAction("object_distribute_vertical_top", actionDistributeTop); connect(actionDistributeTop, SIGNAL(triggered()), this, SLOT(selectionDistributeVerticalTop())); - d->showRulerAction = new KToggleAction(i18n("Show Rulers"), this); - actionCollection()->addAction("view_show_ruler", d->showRulerAction); - d->showRulerAction->setToolTip(i18n("Shows or hides rulers")); - d->showRulerAction->setChecked(false); - connect(d->showRulerAction, SIGNAL(triggered()), this, SLOT(showRuler())); - - KToggleAction *gridAction = d->part->gridData().gridToggleAction(d->canvas); - actionCollection()->addAction("view_grid", gridAction); - - d->showGuidesAction = KoStandardAction::showGuides(this, SLOT(showGuides()), this); - actionCollection()->addAction(KoStandardAction::name(KoStandardAction::ShowGuides), d->showGuidesAction); - d->showGuidesAction->setChecked(d->part->guidesData().showGuideLines()); - d->showPaletteAction = new KToggleAction(i18n("Show Color Palette"), this); actionCollection()->addAction("view_show_palette", d->showPaletteAction); d->showPaletteAction->setToolTip(i18n("Show or hide color palette")); d->showPaletteAction->setChecked(true); connect(d->showPaletteAction, SIGNAL(triggered()), this, SLOT(showPalette())); - d->snapGridAction = new KToggleAction(i18n("Snap to Grid"), this); - actionCollection()->addAction("view_snap_to_grid", d->snapGridAction); - d->snapGridAction->setToolTip(i18n("Snaps to grid")); - connect(d->snapGridAction, SIGNAL(triggered()), this, SLOT(snapToGrid())); - action = actionCollection()->action("object_group"); if (action) { action->setShortcut(QKeySequence("Ctrl+G")); } action = actionCollection()->action("object_ungroup"); if (action) { action->setShortcut(QKeySequence("Ctrl+Shift+G")); } d->clipObjects = new QAction(i18n("&Clip Object"), this); actionCollection()->addAction("object_clip", d->clipObjects ); connect(d->clipObjects, SIGNAL(triggered()), this, SLOT(clipObjects())); d->unclipObjects = new QAction(i18n("&Unclip Objects"), this); actionCollection()->addAction("object_unclip", d->unclipObjects ); connect(d->unclipObjects, SIGNAL(triggered()), this, SLOT(unclipObjects())); d->flipVertical = new QAction(koIcon("object-flip-vertical"), i18n("Mirror Vertically"), this); actionCollection()->addAction("object_flip_vertical", d->flipVertical); connect(d->flipVertical, SIGNAL(triggered()), this, SLOT(flipVertical())); d->flipHorizontal = new QAction(koIcon("object-flip-horizontal"), i18n("Mirror Horizontally"), this); actionCollection()->addAction("object_flip_horizontal", d->flipHorizontal); connect(d->flipHorizontal, SIGNAL(triggered()), this, SLOT(flipHorizontal())); // object <----- // path -------> d->closePath = new QAction(i18n("&Close Path"), this); actionCollection()->addAction("close_path", d->closePath); d->closePath->setShortcut(QKeySequence("Ctrl+U")); d->closePath->setEnabled(false); connect(d->closePath, SIGNAL(triggered()), this, SLOT(closePath())); d->combinePath = new QAction(i18n("Com&bine Path"), this); actionCollection()->addAction("combine_path", d->combinePath); d->combinePath->setShortcut(QKeySequence("Ctrl+K")); d->combinePath->setEnabled(false); connect(d->combinePath, SIGNAL(triggered()), this, SLOT(combinePath())); d->separatePath = new QAction(i18n("Se¶te Path"), this); actionCollection()->addAction("separate_path", d->separatePath); d->separatePath->setShortcut(QKeySequence("Shift+Ctrl+K")); d->separatePath->setEnabled(false); connect(d->separatePath, SIGNAL(triggered()), this, SLOT(separatePath())); d->reversePath = new QAction(i18n("Re&verse Path"), this); actionCollection()->addAction("reverse_path", d->reversePath); d->reversePath->setShortcut(QKeySequence("Ctrl+R")); d->reversePath->setEnabled(false); connect(d->reversePath, SIGNAL(triggered()), this, SLOT(reversePath())); d->intersectPath = new QAction(i18n("Intersect Paths"), this); actionCollection()->addAction("intersect_path", d->intersectPath); //d->intersectPath->setShortcut(QKeySequence("Shift+Ctrl+K")); d->intersectPath->setEnabled(false); connect(d->intersectPath, SIGNAL(triggered()), this, SLOT(intersectPaths())); d->subtractPath = new QAction(i18n("Subtract Paths"), this); actionCollection()->addAction("subtract_path", d->subtractPath); //d->subtractPath->setShortcut(QKeySequence("Shift+Ctrl+K")); d->subtractPath->setEnabled(false); connect(d->subtractPath, SIGNAL(triggered()), this, SLOT(subtractPaths())); d->unitePath = new QAction(i18n("Unite Paths"), this); actionCollection()->addAction("unite_path", d->unitePath); //d->unitePath->setShortcut(QKeySequence("Shift+Ctrl+K")); d->unitePath->setEnabled(false); connect(d->unitePath, SIGNAL(triggered()), this, SLOT(unitePaths())); d->excludePath = new QAction(i18n("Exclude Paths"), this); actionCollection()->addAction("exclude_path", d->excludePath); //d->excludePath->setShortcut(QKeySequence("Shift+Ctrl+K")); d->excludePath->setEnabled(false); connect(d->excludePath, SIGNAL(triggered()), this, SLOT(excludePaths())); d->pathSnapToGrid = new QAction(i18n("Snap Path to Grid"), this); actionCollection()->addAction("path_snap_to_grid", d->pathSnapToGrid); d->pathSnapToGrid->setEnabled(false); connect(d->pathSnapToGrid, SIGNAL(triggered()), this, SLOT(pathSnapToGrid())); // path <----- - d->configureAction = new QAction(koIcon("configure"), i18n("Configure Karbon..."), this); - actionCollection()->addAction("configure", d->configureAction); - connect(d->configureAction, SIGNAL(triggered()), this, SLOT(configure())); - // not sure why this isn't done through KStandardAction, but since it isn't - // we ought to set the MenuRole manually so the item ends up in the appropriate - // menu on OS X: - d->configureAction->setMenuRole(QAction::PreferencesRole); - - QAction *actionPageLayout = new QAction(i18n("Page &Layout..."), this); - actionCollection()->addAction("page_layout", actionPageLayout); - connect(actionPageLayout, SIGNAL(triggered()), this, SLOT(configurePageLayout())); - // view ----> QAction * zoomSelection = new QAction(koIcon("zoom-select"), i18n("Zoom to Selection"), this); actionCollection()->addAction("view_zoom_selection", zoomSelection); connect(zoomSelection, SIGNAL(triggered()), this, SLOT(zoomSelection())); QAction * zoomDrawing = new QAction(koIcon("zoom-draw"), i18n("Zoom to Drawing"), this); actionCollection()->addAction("view_zoom_drawing", zoomDrawing); connect(zoomDrawing, SIGNAL(triggered()), this, SLOT(zoomDrawing())); // view <----- } void KarbonView::mousePositionChanged(const QPoint &position) { - QPoint canvasOffset(d->canvasController->canvasOffsetX(), d->canvasController->canvasOffsetY()); - QPoint viewPos = position - d->canvas->documentOrigin() - canvasOffset; - if (d->horizRuler->isVisible()) - d->horizRuler->updateMouseCoordinate(viewPos.x()); - if (d->vertRuler->isVisible()) - d->vertRuler->updateMouseCoordinate(viewPos.y()); + const QPoint canvasOffset(canvasController()->canvasOffsetX(), canvasController()->canvasOffsetY() ); + const QPoint viewPos = position - kopaCanvas()->documentOrigin() - canvasOffset; - QPointF documentPos = d->canvas->viewConverter()->viewToDocument(viewPos); - qreal x = part()->unit().toUserValue(documentPos.x()); - qreal y = part()->unit().toUserValue(documentPos.y()); + QPointF documentPos = kopaCanvas()->viewConverter()->viewToDocument(viewPos); + qreal x = kopaDocument()->unit().toUserValue(documentPos.x()); + qreal y = kopaDocument()->unit().toUserValue(documentPos.y()); if (statusBar() && statusBar()->isVisible()) { QLocale locale; d->cursorCoords->setText(QString::fromLatin1("%1, %2").arg(locale.toString(x, 'f', 2), locale.toString(y, 'f', 2))); } } void KarbonView::reorganizeGUI() { - if (d->snapGridAction) - d->snapGridAction->setChecked(part()->gridData().snapToGrid()); - if (statusBar()) - statusBar()->setVisible(part()->showStatusBar()); + // TODO: Find a better solution, maybe move to KoPAView? + if (statusBar()) { + bool show = true; + if (mainWindow()) { + KSharedConfigPtr config = KSharedConfig::openConfig(); + if (config->hasGroup("Interface")) { + KConfigGroup interfaceGroup = config->group( "Interface" ); + if (!interfaceGroup.readEntry("ShowStatusBar", true)) { + show = false; + } + } + } + statusBar()->setVisible(show); + } } void KarbonView::setNumberOfRecentFiles(unsigned int number) { - if (mainWindow()) // 0L when embedded into konq ! + if (mainWindow()) { // 0L when embedded into konq ! mainWindow()->setMaxRecentItems(number); -} - -void KarbonView::showRuler() -{ - if(!mainWindow()) - return; - - const bool showRuler = d->showRulerAction->isChecked(); - d->horizRuler->setVisible(showRuler); - d->vertRuler->setVisible(showRuler); - if (showRuler) - updateRuler(); - - // this will make the last setting of the ruler visibility persistent - KConfigGroup interfaceGroup = KarbonFactory::global().config()->group("Interface"); - if (!showRuler && !interfaceGroup.hasDefault("ShowRulers")) - interfaceGroup.revertToDefault("ShowRulers"); - else - interfaceGroup.writeEntry("ShowRulers", showRuler); -} - -void KarbonView::togglePageMargins(bool b) -{ - ((KToggleAction*)actionCollection()->action("view_show_margins"))->setChecked(b); - d->canvas->setShowPageMargins(b); - d->canvas->update(); -} - -void KarbonView::pageOffsetChanged() -{ - d->horizRuler->setOffset(d->canvasController->canvasOffsetX() + d->canvas->documentOrigin().x()); - d->vertRuler->setOffset(d->canvasController->canvasOffsetY() + d->canvas->documentOrigin().y()); -} - -void KarbonView::updateRuler() -{ - d->horizRuler->setRulerLength(part()->pageSize().width()); - d->vertRuler->setRulerLength(part()->pageSize().height()); -} - -void KarbonView::showGuides() -{ - d->part->guidesData().setShowGuideLines(d->showGuidesAction->isChecked()); - d->canvas->update(); + } } void KarbonView::editGuides() { KoToolManager::instance()->switchToolRequested("GuidesTool_ID"); } -void KarbonView::snapToGrid() -{ - d->part->gridData().setSnapToGrid(d->snapGridAction->isChecked()); - d->canvas->update(); -} - void KarbonView::showPalette() { if(!mainWindow()) return; const bool showPalette = d->showPaletteAction->isChecked(); d->colorBar->setVisible(showPalette); // this will make the last setting of the ruler visibility persistent KConfigGroup interfaceGroup = KarbonFactory::global().config()->group("Interface"); if (showPalette && !interfaceGroup.hasDefault("ShowPalette")) interfaceGroup.revertToDefault("ShowPalette"); else interfaceGroup.writeEntry("ShowPalette", showPalette); } -void KarbonView::configure() +void KarbonView::openConfiguration() { QPointer dialog = new KarbonConfigureDialog(this); dialog->exec(); delete dialog; - d->part->reorganizeGUI(); - d->canvas->update(); -} - -void KarbonView::configurePageLayout() -{ - QPointer dlg = new KoPageLayoutDialog(this, part()->pageLayout()); - dlg->showPageSpread(false); - dlg->showTextDirection(false); - dlg->setPageSpread(false); - dlg->setUnit(d->part->unit()); - - if (dlg->exec() == QDialog::Accepted) { - if (dlg) { - part()->setPageLayout(dlg->pageLayout()); - } - } - delete dlg; + reorganizeGUI(); } void KarbonView::selectionChanged() { if (!mainWindow()) return; - KoSelection *selection = d->canvas->shapeManager()->selection(); + KoSelection *selection = kopaCanvas()->shapeManager()->selection(); QList selectedShapes = selection->selectedShapes(KoFlake::FullSelection); const int count = selectedShapes.count(); d->closePath->setEnabled(false); d->combinePath->setEnabled(false); d->excludePath->setEnabled(false); d->intersectPath->setEnabled(false); d->subtractPath->setEnabled(false); d->unitePath->setEnabled(false); d->pathSnapToGrid->setEnabled(false); d->clipObjects->setEnabled(false); d->unclipObjects->setEnabled(false); d->flipHorizontal->setEnabled(count > 0); d->flipVertical->setEnabled(count > 0); debugKarbonUi << count << " shapes selected"; if (count > 0) { uint selectedPaths = 0; uint selectedParametrics = 0; // check for different shape types for enabling specific actions foreach(KoShape* shape, selectedShapes) { if (dynamic_cast(shape)) { KoParameterShape * ps = dynamic_cast(shape); if (ps && ps->isParametricShape()) selectedParametrics++; else selectedPaths++; } } debugKarbonUi << selectedPaths << " path shapes selected"; debugKarbonUi << selectedParametrics << " parameter shapes selected"; //TODO enable action when the ClosePath command is ported //d->closePath->setEnabled( selectedPaths > 0 ); d->combinePath->setEnabled(selectedPaths > 1); d->separatePath->setEnabled(selectedPaths > 0); d->reversePath->setEnabled(selectedPaths > 0); d->excludePath->setEnabled(selectedPaths + selectedParametrics == 2); d->intersectPath->setEnabled(selectedPaths + selectedParametrics == 2); d->subtractPath->setEnabled(selectedPaths + selectedParametrics == 2); d->unitePath->setEnabled(selectedPaths + selectedParametrics == 2); d->pathSnapToGrid->setEnabled(selectedPaths > 0); d->clipObjects->setEnabled(selectedPaths > 0 && count > 1); d->unclipObjects->setEnabled(selectedShapes.first()->clipPath() != 0); // if only one shape selected, set its parent layer as the active layer if (count == 1) { KoShapeContainer * parent = selection->selectedShapes().first()->parent(); while (parent) { if (parent->parent()) parent = parent->parent(); else break; } KoShapeLayer * layer = dynamic_cast(parent); if (layer) selection->setActiveLayer(layer); } } } void KarbonView::setCursor(const QCursor &c) { - d->canvas->setCursor(c); -} - -void KarbonView::createLayersTabDock() -{ - if (mainWindow()) - { - KarbonLayerDockerFactory layerFactory; - KarbonLayerDocker * layerDocker = qobject_cast(mainWindow()->createDockWidget(&layerFactory)); - layerDocker->setCanvas(d->canvas); - connect(d->canvas->shapeManager(), SIGNAL(selectionChanged()), - layerDocker, SLOT(updateView())); - connect(d->canvas->shapeManager(), SIGNAL(selectionContentChanged()), - layerDocker, SLOT(updateView())); - connect(d->part, SIGNAL(shapeCountChanged()), layerDocker, SLOT(updateView())); - } + kopaCanvas()->setCursor(c); } void KarbonView::updateReadWrite(bool readwrite) { Q_UNUSED(readwrite); } -void KarbonView::updateUnit(const KoUnit &unit) -{ - d->horizRuler->setUnit(unit); - d->vertRuler->setUnit(unit); - d->canvas->resourceManager()->setResource(KoCanvasResourceManager::Unit, unit); -} - QList KarbonView::selectedPathShapes() { - KoSelection* selection = d->canvas->shapeManager()->selection(); + KoSelection* selection = shapeManager()->selection(); if (! selection) return QList(); QList selectedShapes = selection->selectedShapes(); QList paths; foreach(KoShape* shape, selectedShapes) { KoPathShape *path = dynamic_cast(shape); if (path) { paths << path; selection->deselect(shape); } } return paths; } -KoPrintJob * KarbonView::createPrintJob() -{ - return new KarbonPrintJob(this, KarbonPrintJob::PrintToPaper); -} - -KoPrintJob * KarbonView::createPdfPrintJob() -{ - return new KarbonPrintJob(this, KarbonPrintJob::PrintToPdf); -} - void KarbonView::applyFillToSelection() { - KoSelection *selection = d->canvas->shapeManager()->selection(); + KoSelection *selection = shapeManager()->selection(); if (! selection->count()) return; KoShape * shape = selection->firstSelectedShape(); - d->canvas->addCommand(new KoShapeBackgroundCommand(selection->selectedShapes(), shape->background())); + kopaCanvas()->addCommand(new KoShapeBackgroundCommand(selection->selectedShapes(), shape->background())); } void KarbonView::applyStrokeToSelection() { - KoSelection *selection = d->canvas->shapeManager()->selection(); + KoSelection *selection = shapeManager()->selection(); if (! selection->count()) return; KoShape * shape = selection->firstSelectedShape(); - d->canvas->addCommand(new KoShapeStrokeCommand(selection->selectedShapes(), shape->stroke())); + kopaCanvas()->addCommand(new KoShapeStrokeCommand(selection->selectedShapes(), shape->stroke())); } void KarbonView::applyPaletteColor(const KoColor &color) { - KoSelection *selection = d->canvas->shapeManager()->selection(); + KoSelection *selection = shapeManager()->selection(); if (! selection->count()) return; - int style = d->canvas->resourceManager()->intResource(KoCanvasResourceManager::ActiveStyleType); + int style = resourceManager()->intResource(KoCanvasResourceManager::ActiveStyleType); if (style == KoFlake::Foreground) { QList newStrokes; foreach(KoShape *shape, selection->selectedShapes()) { KoShapeStroke *stroke = dynamic_cast(shape->stroke()); if (stroke) { // preserve stroke properties KoShapeStroke *newStroke = new KoShapeStroke(*stroke); newStroke->setColor(color.toQColor()); newStrokes << newStroke; } else { newStrokes << new KoShapeStroke(1.0, color.toQColor()); } } - d->canvas->addCommand(new KoShapeStrokeCommand(selection->selectedShapes(), newStrokes)); - d->canvas->resourceManager()->setForegroundColor(color); + kopaCanvas()->addCommand(new KoShapeStrokeCommand(selection->selectedShapes(), newStrokes)); + resourceManager()->setForegroundColor(color); } else { QSharedPointer fill(new KoColorBackground(color.toQColor())); - d->canvas->addCommand(new KoShapeBackgroundCommand(selection->selectedShapes(), fill)); - d->canvas->resourceManager()->setBackgroundColor(color); + kopaCanvas()->addCommand(new KoShapeBackgroundCommand(selection->selectedShapes(), fill)); + resourceManager()->setBackgroundColor(color); } } +void KarbonView::replaceActivePage(KoPAPageBase *page, KoPAPageBase *newActivePage) +{ + if (page == activePage() ) { + viewMode()->updateActivePage(newActivePage); + } +} diff --git a/karbon/ui/KarbonView.h b/karbon/ui/KarbonView.h index cc609523590..993e2dda03d 100644 --- a/karbon/ui/KarbonView.h +++ b/karbon/ui/KarbonView.h @@ -1,175 +1,170 @@ /* This file is part of the KDE project * Copyright (C) 2001-2002 Lennart Kudling * Copyright (C) 2001-2005,2007 Rob Buis * Copyright (C) 2002-2003,2005 Tomislav Lukman * Copyright (C) 2002,2005 Laurent Montel * Copyright (C) 2002,2005,2007 David Faure * Copyright (C) 2002 Benoit Vautrin * Copyright (C) 2005-2006 Peter Simonsson * Copyright (C) 2005-2006 Tim Beaulen * Copyright (C) 2005-2006 Thomas Zander * Copyright (C) 2005-2007 Jan Hambrecht * Copyright (C) 2005-2006 Inge Wallin * Copyright (C) 2005-2006 C. Boemann * Copyright (C) 2005-2006 Sven Langkamp * Copyright (C) 2006 Martin Ellis * Copyright (C) 2006 Boudewijn Rempt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef __KARBON_VIEW__ #define __KARBON_VIEW__ -#include +#include #include #include #include #include "KarbonBooleanCommand.h" class QDropEvent; class QResizeEvent; +class QLayout; class KarbonDocument; class KoColor; class KoUnit; +class KarbonPaletteBarWidget; class KarbonPart; -class KarbonCanvas; -class KARBONUI_EXPORT KarbonView : public KoView +class KoPACanvas; +class KoCanvasResourceManager; + +class KARBONUI_EXPORT KarbonView : public KoPAView { Q_OBJECT public: KarbonView(KarbonPart *part, KarbonDocument* doc, QWidget* parent = 0); virtual ~KarbonView(); /// Returns the view is attached to - KarbonDocument * part() const; + KarbonDocument * part() const; /// Returns the canvas widget of this view - KarbonCanvas * canvasWidget() const; + KoPACanvas *canvasWidget() const; void reorganizeGUI(); void setNumberOfRecentFiles(uint number); /// Reimplemented from QWidget virtual void setCursor(const QCursor &); /// Reimplemented from QWidget virtual void dropEvent(QDropEvent *e); - /// Reimplemented from KoView - virtual KoZoomController *zoomController() const; + KoCanvasResourceManager *resourceManager() const; + + KarbonPaletteBarWidget *colorBar() const; + public Q_SLOTS: // editing: void editSelectAll(); void editDeselectAll(); void editDeleteSelection(); void selectionDuplicate(); void selectionDistributeHorizontalCenter(); void selectionDistributeHorizontalGap(); void selectionDistributeHorizontalLeft(); void selectionDistributeHorizontalRight(); void selectionDistributeVerticalCenter(); void selectionDistributeVerticalGap(); void selectionDistributeVerticalBottom(); void selectionDistributeVerticalTop(); void fileImportGraphic(); void clipObjects(); void unclipObjects(); void flipVertical(); void flipHorizontal(); void closePath(); void combinePath(); void separatePath(); void reversePath(); void intersectPaths(); void subtractPaths(); void unitePaths(); void excludePaths(); void pathSnapToGrid(); - void configure(); - - void configurePageLayout(); - void selectionChanged(); - void togglePageMargins(bool); - void showRuler(); - void showGuides(); void editGuides(); - void snapToGrid(); void showPalette(); + void replaceActivePage(KoPAPageBase *page, KoPAPageBase *newActivePage); + protected Q_SLOTS: // Object related operations. // View void viewModeChanged(bool); void zoomSelection(); void zoomDrawing(); void mousePositionChanged(const QPoint &position); - void pageOffsetChanged(); - - void updateUnit(const KoUnit &unit); void applyFillToSelection(); void applyStrokeToSelection(); void applyPaletteColor(const KoColor &color); protected: + /// Use own configuaration dialog + virtual void openConfiguration(); + virtual void updateReadWrite(bool readwrite); virtual void resizeEvent(QResizeEvent* event); virtual void dragEnterEvent(QDragEnterEvent * event); - virtual void addImages(const QVector &imageList, const QPoint &insertAt); - void createLayersTabDock(); void createStrokeDock(); void createColorDock(); - virtual KoPrintJob * createPrintJob(); - virtual KoPrintJob * createPdfPrintJob(); - private: void initActions(); void updateRuler(); void selectionDistribute(KoShapeDistributeCommand::Distribute distribute); void booleanOperation(KarbonBooleanCommand::BooleanOperation operation); void selectionFlip(bool horizontally, bool vertically); /// Returns a list of all selected path shapes QList selectedPathShapes(); class Private; Private * const d; }; #endif // __KARBON_VIEW__ diff --git a/karbon/ui/ProxyView.cpp b/karbon/ui/ProxyView.cpp new file mode 100644 index 00000000000..b0819d53806 --- /dev/null +++ b/karbon/ui/ProxyView.cpp @@ -0,0 +1,76 @@ +/* This file is part of the KDE project + * Copyright (C) 2019 Dag Andersen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "ProxyView.h" + +#include + +#include + +ProxyView::ProxyView(KoPart *karbonPart, KoDocument* doc, QWidget* parent) + : KoView(karbonPart, doc, parent) +{ + setObjectName("Karbon view helper"); +} + +ProxyView::~ProxyView() +{ + if (factory()) { + factory()->removeClient(this); + } +} + +void ProxyView::updateReadWrite(bool readwrite) +{ + view->updateReadWrite(readwrite); +} + +KoZoomController *ProxyView::zoomController() const +{ + return view->zoomController(); +} + +KoPageLayout ProxyView::pageLayout() const +{ + return view->pageLayout(); +} + +void ProxyView::guiActivateEvent(bool activated) +{ + if (activated) { + factory()->addClient(view); + } else { + factory()->removeClient(view); + } +} + +QPrintDialog *ProxyView::createPrintDialog(KoPrintJob *printJob, QWidget *parent) +{ + return view->createPrintDialog(printJob, parent); +} + +KoPrintJob *ProxyView::createPrintJob() +{ + return view->createPrintJob(); +} + +KoPrintJob *ProxyView::createPdfPrintJob() +{ + return view->createPdfPrintJob(); +} diff --git a/karbon/ui/dockers/KarbonLayerSortingModel.h b/karbon/ui/ProxyView.h similarity index 51% rename from karbon/ui/dockers/KarbonLayerSortingModel.h rename to karbon/ui/ProxyView.h index 1ad9d65cde4..b855a3cafe2 100644 --- a/karbon/ui/dockers/KarbonLayerSortingModel.h +++ b/karbon/ui/ProxyView.h @@ -1,40 +1,48 @@ /* This file is part of the KDE project - * Copyright (C) 2008-2009 Jan Hambrecht + * Copyright (C) 2019 Dag Andersen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ -#ifndef KARBON_LAYER_SORTING_MODEL_H -#define KARBON_LAYER_SORTING_MODEL_H +#ifndef __PROXYVIEW_H__ +#define __PROXYVIEW_H__ -#include +#include +#include -class KarbonDocument; - -class KarbonLayerSortingModel : public QSortFilterProxyModel +class ProxyView : public KoView { Q_OBJECT public: - explicit KarbonLayerSortingModel(QObject *parent); - /// Sets a new document to use for sorting - void setDocument(KarbonDocument * newDocument); -protected: - virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const; + ProxyView(KoPart *part, KoDocument* doc, QWidget* parent = 0); + ~ProxyView() Q_DECL_OVERRIDE; + + virtual void updateReadWrite(bool readwrite) Q_DECL_OVERRIDE; + virtual KoZoomController *zoomController() const Q_DECL_OVERRIDE; + virtual KoPageLayout pageLayout() const Q_DECL_OVERRIDE; + virtual void guiActivateEvent(bool activated) Q_DECL_OVERRIDE; + + virtual QPrintDialog *createPrintDialog(KoPrintJob *printJob, QWidget *parent) Q_DECL_OVERRIDE; + virtual KoPrintJob *createPrintJob() Q_DECL_OVERRIDE; + virtual KoPrintJob *createPdfPrintJob() Q_DECL_OVERRIDE; + private: - KarbonDocument *m_document; ///< the underlying data structure + friend class KarbonPart; + KoView *view; }; -#endif // KARBON_LAYER_SORTING_MODEL_H +#endif + diff --git a/karbon/ui/dockers/KarbonLayerDocker.cpp b/karbon/ui/dockers/KarbonLayerDocker.cpp deleted file mode 100644 index 5c63bf16bdd..00000000000 --- a/karbon/ui/dockers/KarbonLayerDocker.cpp +++ /dev/null @@ -1,492 +0,0 @@ -/* This file is part of the KDE project - * Copyright (C) 2006-2009 Jan Hambrecht - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "KarbonLayerDocker.h" -#include "KarbonLayerModel.h" -#include "KarbonLayerSortingModel.h" -#include "KarbonFactory.h" - -#include -#include -#include -#include - -#include -//#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -enum ButtonIds { - Button_New, - Button_Raise, - Button_Lower, - Button_Delete -}; - -KarbonLayerDockerFactory::KarbonLayerDockerFactory() -{ -} - -QString KarbonLayerDockerFactory::id() const -{ - return QString("Layer view"); -} - -QDockWidget* KarbonLayerDockerFactory::createDockWidget() -{ - KarbonLayerDocker* widget = new KarbonLayerDocker(); - widget->setObjectName(id()); - - return widget; -} - -KarbonLayerDocker::KarbonLayerDocker() - : m_doc(0), m_model(0), m_updateTimer(this) -{ - setWindowTitle(i18n("Layer view")); - - QWidget *mainWidget = new QWidget(this); - QGridLayout* layout = new QGridLayout(mainWidget); - layout->addWidget(m_layerView = new KoDocumentSectionView(mainWidget), 0, 0, 1, 6); - - QButtonGroup *buttonGroup = new QButtonGroup(mainWidget); - buttonGroup->setExclusive(false); - - QPushButton *button = new QPushButton(mainWidget); - button->setIcon(koIcon("list-add")); - button->setToolTip(i18n("Add a new layer")); - buttonGroup->addButton(button, Button_New); - layout->addWidget(button, 1, 0); - - button = new QPushButton(mainWidget); - button->setIcon(koIcon("list-remove")); - button->setToolTip(i18n("Delete selected objects")); - buttonGroup->addButton(button, Button_Delete); - layout->addWidget(button, 1, 1); - - button = new QPushButton(mainWidget); - button->setIcon(koIcon("go-up")); - button->setToolTip(i18n("Raise selected objects")); - buttonGroup->addButton(button, Button_Raise); - layout->addWidget(button, 1, 2); - - button = new QPushButton(mainWidget); - button->setIcon(koIcon("go-down")); - button->setToolTip(i18n("Lower selected objects")); - buttonGroup->addButton(button, Button_Lower); - layout->addWidget(button, 1, 3); - - QToolButton * toolButton = new QToolButton(mainWidget); - QMenu * menu = new QMenu(this); - QActionGroup *group = new QActionGroup(this); - - m_viewModeActions.insert(KoDocumentSectionView::MinimalMode, - menu->addAction(koIcon("view-list-text"), i18n("Minimal View"), this, SLOT(minimalView()))); - m_viewModeActions.insert(KoDocumentSectionView::DetailedMode, - menu->addAction(koIcon("view-list-details"), i18n("Detailed View"), this, SLOT(detailedView()))); - m_viewModeActions.insert(KoDocumentSectionView::ThumbnailMode, - menu->addAction(koIcon("view-preview"), i18n("Thumbnail View"), this, SLOT(thumbnailView()))); - - foreach(QAction* action, m_viewModeActions) { - action->setCheckable(true); - action->setActionGroup(group); - } - - toolButton->setMenu(menu); - toolButton->setPopupMode(QToolButton::InstantPopup); - toolButton->setIcon(koIcon("view-choose")); - toolButton->setText(i18n("View mode")); - layout->addWidget(toolButton, 1, 5); - layout->setSpacing(0); - layout->setMargin(3); - - setWidget(mainWidget); - - connect(buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotButtonClicked(int))); - - m_model = new KarbonLayerModel(this); - m_model->setDocument(m_doc ? m_doc : 0); - m_sortModel = new KarbonLayerSortingModel(this); - m_sortModel->setDocument(m_doc ? m_doc : 0); - m_sortModel->setSourceModel(m_model); - - m_layerView->setItemsExpandable(true); - m_layerView->setModel(m_sortModel); - m_layerView->setDisplayMode(KoDocumentSectionView::MinimalMode); - m_layerView->setSelectionMode(QAbstractItemView::ExtendedSelection); - m_layerView->setSelectionBehavior(QAbstractItemView::SelectRows); - m_layerView->setDragDropMode(QAbstractItemView::InternalMove); - m_layerView->setSortingEnabled(true); - - KoDocumentSectionView::DisplayMode mode = KoDocumentSectionView::MinimalMode; - KSharedConfigPtr config = KarbonFactory::karbonConfig(); - if (config->hasGroup("Interface")) { - QString modeStr = config->group("Interface").readEntry("LayerDockerMode", "minimal"); - if (modeStr == "detailed") - mode = KoDocumentSectionView::DetailedMode; - else if (modeStr == "thumbnail") - mode = KoDocumentSectionView::ThumbnailMode; - } - setViewMode(mode); - - connect(m_layerView, SIGNAL(clicked(QModelIndex)), this, SLOT(itemClicked(QModelIndex))); - - m_updateTimer.setSingleShot(true); - m_updateTimer.setInterval(250); - connect(&m_updateTimer, SIGNAL(timeout()), m_model, SLOT(update())); -} - -KarbonLayerDocker::~KarbonLayerDocker() -{ - KSharedConfigPtr config = KarbonFactory::karbonConfig(); - QString modeStr; - switch (m_layerView->displayMode()) { - case KoDocumentSectionView::MinimalMode: - modeStr = "minimal"; - break; - case KoDocumentSectionView::DetailedMode: - modeStr = "detailed"; - break; - case KoDocumentSectionView::ThumbnailMode: - modeStr = "thumbnail"; - break; - } - config->group("Interface").writeEntry("LayerDockerMode", modeStr); -} - -void KarbonLayerDocker::updateView() -{ - if (m_updateTimer.isActive()) - return; - - m_updateTimer.start(); -} - -void KarbonLayerDocker::setCanvas(KoCanvasBase* canvas) -{ - KarbonCanvas *c = dynamic_cast(canvas); - if (c) { - m_doc = c->document(); - m_sortModel->setDocument(m_doc ? m_doc : 0); - m_model->setDocument(m_doc ? m_doc : 0); - m_model->update(); - } -} - -void KarbonLayerDocker::unsetCanvas() -{ - m_doc = 0; - m_sortModel->setDocument(0); - m_model->setDocument(0); - m_model->update(); -} - -//Adapt code and connect okbutton or other to new slot. It doesn't exist in qdialog -void KarbonLayerDocker::slotButtonClicked(int buttonId) -{ - switch (buttonId) { - case Button_New: - addLayer(); - break; - case Button_Raise: - raiseItem(); - break; - case Button_Lower: - lowerItem(); - break; - case Button_Delete: - deleteItem(); - break; - } -} - -void KarbonLayerDocker::itemClicked(const QModelIndex &index) -{ - KoShape *shape = shapeFromIndex(index); - if (! shape) - return; - - KoCanvasController * canvasController = KoToolManager::instance()->activeCanvasController(); - if (! canvasController) - return; - - KoSelection *selection = canvasController->canvas()->shapeManager()->selection(); - if (! selection) - return; - - KoShapeLayer * layer = dynamic_cast(shape); - if (layer) { - selection->setActiveLayer(layer); - return; - } - - QList selectedLayers; - QList selectedShapes; - - // separate selected layers and selected shapes - extractSelectedLayersAndShapes(selectedLayers, selectedShapes); - - foreach(KoShape* shape, selection->selectedShapes()) - shape->update(); - - selection->deselectAll(); - - foreach(KoShape* shape, selectedShapes) { - if (shape) { - selection->select(shape, false); - shape->update(); - } - } -} - -void KarbonLayerDocker::addLayer() -{ - bool ok = true; - QString name = QInputDialog::getText(this, - i18n("New Layer"), - i18n("Enter the name of the new layer:"), - QLineEdit::Normal, - i18n("New layer"), &ok); - if (ok) { - KoShapeLayer* layer = new KoShapeLayer(); - layer->setName(name); - KoCanvasController* canvasController = KoToolManager::instance()->activeCanvasController(); - KUndo2Command *cmd = new KoShapeCreateCommand(m_doc, layer, 0); - cmd->setText(kundo2_i18n("Create Layer")); - canvasController->canvas()->addCommand(cmd); - m_model->update(); - } -} - -void KarbonLayerDocker::deleteItem() -{ - QList selectedLayers; - QList selectedShapes; - - // separate selected layers and selected shapes - extractSelectedLayersAndShapes(selectedLayers, selectedShapes); - - KUndo2Command *cmd = 0; - - if (selectedLayers.count()) { - if (m_doc->layers().count() > selectedLayers.count()) { - QList deleteShapes; - foreach(KoShapeLayer* layer, selectedLayers) { - deleteShapes += layer->shapes(); - deleteShapes.append(layer); - } - cmd = new KoShapeDeleteCommand(m_doc, deleteShapes); - cmd->setText(kundo2_i18n("Delete Layer")); - } else { - KMessageBox::error(0L, i18n("Could not delete all layers. At least one layer is required."), i18n("Error deleting layers")); - } - } else if (selectedShapes.count()) { - cmd = new KoShapeDeleteCommand(m_doc, selectedShapes); - } - - if (cmd) { - KoCanvasController* canvasController = KoToolManager::instance()->activeCanvasController(); - canvasController->canvas()->addCommand(cmd); - m_model->update(); - } -} - -void KarbonLayerDocker::raiseItem() -{ - QList selectedLayers; - QList selectedShapes; - - // separate selected layers and selected shapes - extractSelectedLayersAndShapes(selectedLayers, selectedShapes, true); - - KoCanvasBase* canvas = KoToolManager::instance()->activeCanvasController()->canvas(); - - KUndo2Command *cmd = 0; - - if (selectedLayers.count()) { - // check if all layers could be raised - foreach(KoShapeLayer* layer, selectedLayers) - if (! m_doc->canRaiseLayer(layer)) - return; - - cmd = new KarbonLayerReorderCommand(m_doc, selectedLayers, KarbonLayerReorderCommand::RaiseLayer); - } else if (selectedShapes.count()) { - cmd = KoShapeReorderCommand::createCommand(selectedShapes, canvas->shapeManager(), KoShapeReorderCommand::RaiseShape); - } - - if (cmd) { - canvas->addCommand(cmd); - m_model->update(); - - // adjust layer selection - if (selectedLayers.count()) { - selectLayers(selectedLayers); - } - } -} - -void KarbonLayerDocker::lowerItem() -{ - QList selectedLayers; - QList selectedShapes; - - // separate selected layers and selected shapes - extractSelectedLayersAndShapes(selectedLayers, selectedShapes, true); - - KoCanvasBase* canvas = KoToolManager::instance()->activeCanvasController()->canvas(); - - KUndo2Command *cmd = 0; - - if (selectedLayers.count()) { - // check if all layers could be raised - foreach(KoShapeLayer* layer, selectedLayers) - if (! m_doc->canLowerLayer(layer)) - return; - - cmd = new KarbonLayerReorderCommand(m_doc, selectedLayers, KarbonLayerReorderCommand::LowerLayer); - } else if (selectedShapes.count()) { - cmd = KoShapeReorderCommand::createCommand(selectedShapes, canvas->shapeManager(), KoShapeReorderCommand::LowerShape); - } - - if (cmd) { - canvas->addCommand(cmd); - m_model->update(); - - // adjust layer selection - if (selectedLayers.count()) { - selectLayers(selectedLayers); - } - } -} - -void KarbonLayerDocker::selectLayers(const QList &layers) -{ - QItemSelectionModel * selModel = m_layerView->selectionModel(); - selModel->clearSelection(); - foreach(KoShapeLayer * layer, layers) { - int layerPos = m_doc->layerPos(layer); - QModelIndex child = m_model->index(layerPos, 0); - selModel->select(m_sortModel->mapFromSource(child), QItemSelectionModel::Select); - } -} - -void KarbonLayerDocker::extractSelectedLayersAndShapes( - QList &layers, QList &shapes, bool addChilds) -{ - layers.clear(); - shapes.clear(); - - QModelIndexList selectedItems = m_layerView->selectionModel()->selectedIndexes(); - if (selectedItems.count() == 0) - return; - - // separate selected layers and selected shapes - foreach(const QModelIndex & index, selectedItems) { - KoShape *shape = shapeFromIndex(index); - KoShapeLayer *layer = dynamic_cast(shape); - if (layer) { - layers.append(layer); - } else if (! selectedItems.contains(index.parent())) { - shapes.append(shape); - KoShapeGroup * group = dynamic_cast(shape); - if (group && addChilds) - addChildsRecursive(group, shapes); - } - } -} - -void KarbonLayerDocker::addChildsRecursive(KoShapeGroup * parent, QList &shapes) -{ - foreach(KoShape * child, parent->shapes()) { - if (! shapes.contains(child)) - shapes.append(child); - KoShapeGroup * group = dynamic_cast(child); - if (group) - addChildsRecursive(group, shapes); - } -} - -KoShape * KarbonLayerDocker::shapeFromIndex(const QModelIndex &index) -{ - Q_ASSERT(index.internalPointer()); - - QModelIndex sourceIndex = index; - if (index.model() != m_model) - sourceIndex = m_sortModel->mapToSource(index); - - if (! sourceIndex.isValid()) - return 0; - - return static_cast(sourceIndex.internalPointer()); -} - -void KarbonLayerDocker::minimalView() -{ - setViewMode(KoDocumentSectionView::MinimalMode); -} - -void KarbonLayerDocker::detailedView() -{ - setViewMode(KoDocumentSectionView::DetailedMode); -} - -void KarbonLayerDocker::thumbnailView() -{ - setViewMode(KoDocumentSectionView::ThumbnailMode); -} - -void KarbonLayerDocker::setViewMode(KoDocumentSectionView::DisplayMode mode) -{ - const bool expandable = (mode != KoDocumentSectionView::ThumbnailMode); - - // collapse all layers if in thumbnail mode - if (!expandable) - m_layerView->collapseAll(); - - m_layerView->setDisplayMode(mode); - m_layerView->setItemsExpandable(expandable); - m_layerView->setRootIsDecorated(expandable); - m_layerView->setSortingEnabled(true); - m_viewModeActions[mode]->setChecked(true); -} - - -// kate: replace-tabs on; space-indent on; indent-width 4; mixedindent off; indent-mode cstyle; diff --git a/karbon/ui/dockers/KarbonLayerDocker.h b/karbon/ui/dockers/KarbonLayerDocker.h deleted file mode 100644 index a830d2b936e..00000000000 --- a/karbon/ui/dockers/KarbonLayerDocker.h +++ /dev/null @@ -1,91 +0,0 @@ -/* This file is part of the KDE project - * Copyright (C) 2006-2007 Jan Hambrecht - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ -#ifndef KARBONLAYERDOCKER_H -#define KARBONLAYERDOCKER_H - -#include -#include -#include -#include -#include - -class KoShape; -class KoShapeLayer; -class KoShapeGroup; -class KarbonLayerModel; -class KarbonLayerSortingModel; -class KarbonDocument; -class QModelIndex; - -class KarbonLayerDockerFactory : public KoDockFactoryBase -{ -public: - KarbonLayerDockerFactory(); - - virtual QString id() const; - virtual QDockWidget* createDockWidget(); - DockPosition defaultDockPosition() const { - return DockRight; - } -}; - -class KarbonLayerDocker : public QDockWidget, public KoCanvasObserverBase -{ - Q_OBJECT - -public: - KarbonLayerDocker(); - virtual ~KarbonLayerDocker(); - - virtual QString observerName() const { return QStringLiteral("KarbonLayerDocker"); } - -public Q_SLOTS: - void updateView(); - virtual void setCanvas(KoCanvasBase* canvas); - virtual void unsetCanvas(); -private Q_SLOTS: - void slotButtonClicked(int buttonId); - void addLayer(); - void deleteItem(); - void raiseItem(); - void lowerItem(); - void itemClicked(const QModelIndex &index); - void minimalView(); - void detailedView(); - void thumbnailView(); -private: - void extractSelectedLayersAndShapes(QList &layers, QList &shapes, bool addChilds = false); - void addChildsRecursive(KoShapeGroup * parent, QList &shapes); - - KoShape * shapeFromIndex(const QModelIndex &index); - - void setViewMode(KoDocumentSectionView::DisplayMode mode); - void selectLayers(const QList &layers); - - KarbonDocument * m_doc; - KarbonLayerModel * m_model; - KarbonLayerSortingModel * m_sortModel; - KoDocumentSectionView * m_layerView; - QTimer m_updateTimer; - QHash m_viewModeActions; -}; - -#endif // KARBONLAYERDOCKER_H - -// kate: replace-tabs on; space-indent on; indent-width 4; mixedindent off; indent-mode cstyle; diff --git a/karbon/ui/dockers/KarbonLayerModel.cpp b/karbon/ui/dockers/KarbonLayerModel.cpp deleted file mode 100644 index 8d24856d93e..00000000000 --- a/karbon/ui/dockers/KarbonLayerModel.cpp +++ /dev/null @@ -1,535 +0,0 @@ -/* This file is part of the KDE project - * Copyright (C) 2007-2008,2011 Jan Hambrecht - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "KarbonLayerModel.h" - -#include "KarbonUiDebug.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -KoShapeContainer *shapeToContainer(KoShape *shape) -{ - KoShapeGroup *group = dynamic_cast(shape); - if (group) - return group; - KoShapeLayer *layer = dynamic_cast(shape); - if (layer) - return layer; - - return 0; -} - -KarbonLayerModel::KarbonLayerModel(QObject * parent) - : KoDocumentSectionModel(parent), m_document(0) -{ -} - -Qt::DropActions KarbonLayerModel::supportedDragActions() const -{ - return Qt::MoveAction; -} - -void KarbonLayerModel::update() -{ - emit layoutAboutToBeChanged(); - emit layoutChanged(); -} - -void KarbonLayerModel::setDocument(KarbonDocument * newDocument) -{ - beginResetModel(); - m_document = newDocument; - endResetModel(); -} - -int KarbonLayerModel::rowCount(const QModelIndex &parent) const -{ - if (! m_document) - return 0; - - // check if parent is root node - if (! parent.isValid()) - return m_document->layers().count(); - - Q_ASSERT(parent.model() == this); - Q_ASSERT(parent.internalPointer()); - - KoShapeContainer *parentShape = shapeToContainer((KoShape*)parent.internalPointer()); - if (! parentShape) - return 0; - - return parentShape->shapeCount(); -} - -int KarbonLayerModel::columnCount(const QModelIndex &) const -{ - if (! m_document) - return 0; - else - return 1; -} - -QModelIndex KarbonLayerModel::index(int row, int column, const QModelIndex &parent) const -{ - if (! m_document) - return QModelIndex(); - - // check if parent is root node - if (! parent.isValid()) { - if (row >= 0 && row < m_document->layers().count()) - return createIndex(row, column, m_document->layers().at(row)); - else - return QModelIndex(); - } - - Q_ASSERT(parent.model() == this); - Q_ASSERT(parent.internalPointer()); - - KoShapeContainer *parentShape = shapeToContainer((KoShape*)parent.internalPointer()); - if (! parentShape) - return QModelIndex(); - - if (row < parentShape->shapeCount()) - return createIndex(row, column, childFromIndex(parentShape, row)); - else - return QModelIndex(); -} - -QModelIndex KarbonLayerModel::parent(const QModelIndex &child) const -{ - // check if child is root node - if (! m_document || ! child.isValid()) - return QModelIndex(); - - Q_ASSERT(child.model() == this); - Q_ASSERT(child.internalPointer()); - - KoShape *childShape = static_cast(child.internalPointer()); - if (! childShape) - return QModelIndex(); - - return parentIndexFromShape(childShape); -} - -QVariant KarbonLayerModel::data(const QModelIndex &index, int role) const -{ - if (! index.isValid()) - return QVariant(); - - Q_ASSERT(index.model() == this); - Q_ASSERT(index.internalPointer()); - - KoShape *shape = static_cast(index.internalPointer()); - - switch (role) { - case Qt::DisplayRole: { - QString name = shape->name(); - if (name.isEmpty()) { - if (dynamic_cast(shape)) - name = i18n("Layer"); - else if (dynamic_cast(shape)) - name = i18nc("A group of shapes", "Group"); - else - name = i18n("Shape"); - } - return name; - } - case Qt::DecorationRole: - return QVariant(); - case Qt::EditRole: - return shape->name(); - case Qt::SizeHintRole: - return shape->size(); - case ActiveRole: { - KoCanvasController * canvasController = KoToolManager::instance()->activeCanvasController(); - KoSelection * selection = canvasController->canvas()->shapeManager()->selection(); - if (! selection) - return false; - - KoShapeLayer *layer = dynamic_cast(shape); - if (layer) - return (layer == selection->activeLayer()); - else - return selection->isSelected(shape); - } - case PropertiesRole: - return QVariant::fromValue(properties(shape)); - case AspectRatioRole: { - QTransform matrix = shape->absoluteTransformation(0); - QRectF bbox = matrix.mapRect(shape->outline().boundingRect()); - KoShapeContainer *container = dynamic_cast(shape); - if (container) { - bbox = QRectF(); - foreach(KoShape* shape, container->shapes()) { - bbox = bbox.united(shape->outline().boundingRect()); - } - } - return qreal(bbox.width()) / bbox.height(); - } - default: - if (role >= int(BeginThumbnailRole)) - return createThumbnail(shape, QSize(role - int(BeginThumbnailRole), role - int(BeginThumbnailRole))); - else - return QVariant(); - } -} - -Qt::ItemFlags KarbonLayerModel::flags(const QModelIndex &index) const -{ - if (! index.isValid()) - return 0; - - Q_ASSERT(index.model() == this); - Q_ASSERT(index.internalPointer()); - - Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEditable; - //if( dynamic_cast( (KoShape*)index.internalPointer() ) ) - flags |= Qt::ItemIsDropEnabled; - return flags; -} - -bool KarbonLayerModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (! index.isValid()) - return false; - - Q_ASSERT(index.model() == this); - Q_ASSERT(index.internalPointer()); - - KoShape *shape = static_cast(index.internalPointer()); - switch (role) { - case Qt::DisplayRole: - case Qt::EditRole: - shape->setName(value.toString()); - break; - case PropertiesRole: - setProperties(shape, value.value()); - // fall through - case ActiveRole: { - KoCanvasController * canvasController = KoToolManager::instance()->activeCanvasController(); - KoSelection * selection = canvasController->canvas()->shapeManager()->selection(); - - KoShapeLayer *layer = dynamic_cast(shape); - if (layer && selection) - selection->setActiveLayer(layer); - } - break; - default: - return false; - } - - emit dataChanged(index, index); - return true; -} - -KoDocumentSectionModel::PropertyList KarbonLayerModel::properties(KoShape* shape) const -{ - PropertyList l; - l << Property(i18nc("Visibility state of the shape", "Visible"), koIcon("layer-visible-on"), koIcon("layer-visible-off"), shape->isVisible()); - l << Property(i18nc("Lock state of the shape", "Locked"), koIcon("object-locked"), koIcon("object-unlocked"), shape->isGeometryProtected()); - l << Property(i18nc("The z-index of the shape", "zIndex"), QString("%1").arg(shape->zIndex())); - l << Property(i18nc("The opacity of the shape", "Opacity"), QString("%1").arg(1.0 - shape->transparency())); - l << Property(i18nc("Clipped state of the shape", "Clipped"), shape->clipPath() ? i18n("yes") : i18n("no")); - return l; -} - -void KarbonLayerModel::setProperties(KoShape* shape, const PropertyList &properties) -{ - bool oldVisibleState = shape->isVisible(); - bool oldLockedState = shape->isGeometryProtected(); - bool newVisibleState = properties.at(0).state.toBool(); - bool newLockedState = properties.at(1).state.toBool(); - - shape->setVisible(newVisibleState); - shape->setGeometryProtected(newLockedState); - - KoShapeContainer * container = dynamic_cast(shape); - if (container) - lockRecursively(container, newLockedState); - else - shape->setSelectable(!newLockedState); - - if ((oldVisibleState != shape->isVisible()) || (oldLockedState != shape->isGeometryProtected())) - shape->update(); -} - -void KarbonLayerModel::lockRecursively(KoShapeContainer *container, bool lock) -{ - if (!container) - return; - - if (!lock) { - container->setSelectable(!container->isGeometryProtected()); - } else { - container->setSelectable(!lock); - } - - foreach(KoShape *shape, container->shapes()) { - KoShapeContainer * shapeContainer = dynamic_cast(shape); - if (shapeContainer) { - lockRecursively(shapeContainer, lock); - } else { - if (!lock) { - shape->setSelectable(!shape->isGeometryProtected()); - } else { - shape->setSelectable(!lock); - } - } - } -} - -QImage KarbonLayerModel::createThumbnail(KoShape* shape, const QSize &thumbSize) const -{ - KoShapePainter painter; - - QList shapes; - - shapes.append(shape); - KoShapeContainer * container = dynamic_cast(shape); - if (container) - shapes.append(container->shapes()); - - painter.setShapes(shapes); - - QImage thumb(thumbSize, QImage::Format_RGB32); - // draw the background of the thumbnail - thumb.fill(QColor(Qt::white).rgb()); - - QRect imageRect = thumb.rect(); - // use 2 pixel border around the content - imageRect.adjust(2, 2, -2, -2); - - QPainter p(&thumb); - painter.paint(p, imageRect, painter.contentRect()); - - return thumb; -} - -KoShape * KarbonLayerModel::childFromIndex(KoShapeContainer *parent, int row) const -{ - return parent->shapes().at(row); -} - -int KarbonLayerModel::indexFromChild(KoShapeContainer *parent, KoShape *child) const -{ - return parent->shapes().indexOf(child); -} - -Qt::DropActions KarbonLayerModel::supportedDropActions() const -{ - return Qt::MoveAction | Qt::CopyAction; -} - -QStringList KarbonLayerModel::mimeTypes() const -{ - QStringList types; - types << QLatin1String("application/x-karbonlayermodeldatalist"); - return types; -} - -QMimeData * KarbonLayerModel::mimeData(const QModelIndexList & indexes) const -{ - // check if there is data to encode - if (! indexes.count()) - return 0; - - // check if we support a format - QStringList types = mimeTypes(); - if (types.isEmpty()) - return 0; - - QMimeData *data = new QMimeData(); - QString format = types[0]; - QByteArray encoded; - QDataStream stream(&encoded, QIODevice::WriteOnly); - - // encode the data - QModelIndexList::ConstIterator it = indexes.begin(); - for (; it != indexes.end(); ++it) - stream << QVariant::fromValue(qulonglong(it->internalPointer())); - - data->setData(format, encoded); - return data; -} - -bool KarbonLayerModel::dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent) -{ - Q_UNUSED(row); - Q_UNUSED(column); - - // check if the action is supported - if (! data || action != Qt::MoveAction) - return false; - // check if the format is supported - QStringList types = mimeTypes(); - if (types.isEmpty()) - return false; - QString format = types[0]; - if (! data->hasFormat(format)) - return false; - - QByteArray encoded = data->data(format); - QDataStream stream(&encoded, QIODevice::ReadOnly); - QList shapes; - - // decode the data - while (! stream.atEnd()) { - QVariant v; - stream >> v; - shapes.append(static_cast((void*)v.value())); - } - - // no shapes to drop, exit gracefully - if (shapes.count() == 0) - return false; - - QList toplevelShapes; - QList layers; - // remove shapes having its parent in the list - // and separate the layers - foreach(KoShape * shape, shapes) { - KoShapeContainer * parent = shape->parent(); - bool hasParentInList = false; - while (parent) { - if (shapes.contains(parent)) { - hasParentInList = true; - break; - } - parent = parent->parent(); - } - if (hasParentInList) - continue; - - KoShapeLayer * layer = dynamic_cast(shape); - if (layer) - layers.append(layer); - else - toplevelShapes.append(shape); - } - - if (! parent.isValid()) { - debugKarbonUi << "KarbonLayerModel::dropMimeData parent = root"; - return false; - } - KoShape *shape = static_cast(parent.internalPointer()); - KoShapeContainer * container = dynamic_cast(shape); - if (container) { - KoShapeGroup * group = dynamic_cast(container); - KoShapeLayer * layer = dynamic_cast(container); - if (layer && layers.count()) { - debugKarbonUi << "dropping layer on a layer (not implemented yet)"; - // TODO layers are dropped on a layer, so change layer ordering - return false; - } else if (group || layer) { - debugKarbonUi << "dropping on group or layer"; - if (! toplevelShapes.count()) - return false; - - emit layoutAboutToBeChanged(); - - beginInsertRows(parent, container->shapeCount(), container->shapeCount() + toplevelShapes.count()); - - KUndo2Command * cmd = new KUndo2Command(); - cmd->setText(kundo2_i18n("Reparent shapes")); - - QList clipped, inheritTransform; - foreach(KoShape * shape, toplevelShapes) { - new KoShapeUngroupCommand(shape->parent(), QList() << shape, QList(), cmd); - clipped.append(false); - inheritTransform.append(false); - } - - if (group) { - new KoShapeGroupCommand(group, toplevelShapes, cmd); - } else if (layer) { - new KoShapeGroupCommand(layer, toplevelShapes, clipped, inheritTransform, cmd); - } - KoCanvasController * canvasController = KoToolManager::instance()->activeCanvasController(); - canvasController->canvas()->addCommand(cmd); - - endInsertRows(); - - emit layoutChanged(); - } else { - debugKarbonUi << "dropping on unhandled container (" << container->shapeId() << ")"; - // every other container we don't want to handle - return false; - } - } else { - debugKarbonUi << "KarbonLayerModel::dropMimeData parent = shape"; - if (! toplevelShapes.count()) - return false; - - // TODO shapes are dropped on a shape, reorder them - return false; - } - - return true; -} - -QModelIndex KarbonLayerModel::parentIndexFromShape(const KoShape * child) const -{ - if (! m_document) - return QModelIndex(); - - // check if child shape is a layer, and return invalid model index if it is - const KoShapeLayer *childlayer = dynamic_cast(child); - if (childlayer) - return QModelIndex(); - - // get the children's parent shape - KoShapeContainer *parentShape = child->parent(); - if (! parentShape) - return QModelIndex(); - - // check if the parent is a layer - KoShapeLayer *parentLayer = dynamic_cast(parentShape); - if (parentLayer) - return createIndex(m_document->layers().indexOf(parentLayer), 0, parentShape); - - // get the grandparent to determine the row of the parent shape - KoShapeContainer *grandParentShape = parentShape->parent(); - if (! grandParentShape) - return QModelIndex(); - - return createIndex(indexFromChild(grandParentShape, parentShape), 0, parentShape); -} - - -// kate: replace-tabs on; space-indent on; indent-width 4; mixedindent off; indent-mode cstyle; diff --git a/karbon/ui/dockers/KarbonLayerModel.h b/karbon/ui/dockers/KarbonLayerModel.h deleted file mode 100644 index dce143be01d..00000000000 --- a/karbon/ui/dockers/KarbonLayerModel.h +++ /dev/null @@ -1,81 +0,0 @@ -/* This file is part of the KDE project - * Copyright (C) 2007-2008 Jan Hambrecht - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef KARBONLAYERMODEL_H -#define KARBONLAYERMODEL_H - -#include - -#include - -class KarbonDocument; -class KoShape; -class KoShapeContainer; -class QAbstractItemModel; - -class KarbonLayerModel : public KoDocumentSectionModel -{ - Q_OBJECT - -public: - /// Constructs a new layer model using the specified documents data - explicit KarbonLayerModel(QObject *parent = 0); - - /// Sets a new document to show contents of - void setDocument(KarbonDocument * newDocument); - - // from QAbstractItemModel - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; - virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; - virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; - virtual QModelIndex parent(const QModelIndex &child) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - virtual Qt::DropActions supportedDropActions() const; - virtual QStringList mimeTypes() const; - virtual QMimeData * mimeData(const QModelIndexList & indexes) const; - virtual bool dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent); - virtual Qt::DropActions supportedDragActions() const; - -public Q_SLOTS: - /// Triggers an update of the complete model - void update(); - -private: - /// Returns properties of the given shape - PropertyList properties(KoShape* shape) const; - /// Sets the properties on the given shape - void setProperties(KoShape* shape, const PropertyList &properties); - /// Creates a thumbnail image with the specified size from the given shape - QImage createThumbnail(KoShape* shape, const QSize &thumbSize) const; - /// Returns the child shape with the given index from the parent shape - KoShape * childFromIndex(KoShapeContainer *parent, int row) const; - /// Returns the zero based index of a child shape within its parent shape - int indexFromChild(KoShapeContainer *parent, KoShape *child) const; - /// Returns the parent model index from the given child shape - QModelIndex parentIndexFromShape(const KoShape * child) const; - - /// Recursively locks children of the specified shape container - void lockRecursively(KoShapeContainer *container, bool lock); - - QPointer m_document; ///< the underlying data structure -}; - -#endif // KARBONLAYERMODEL_H diff --git a/karbon/ui/dockers/KarbonLayerSortingModel.cpp b/karbon/ui/dockers/KarbonLayerSortingModel.cpp deleted file mode 100644 index 9f2dc50d2bd..00000000000 --- a/karbon/ui/dockers/KarbonLayerSortingModel.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* This file is part of the KDE project - * Copyright (C) 2008-2009 Jan Hambrecht - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "KarbonLayerSortingModel.h" -#include "KarbonDocument.h" -#include -#include -#include - -KarbonLayerSortingModel::KarbonLayerSortingModel(QObject * parent) - : QSortFilterProxyModel(parent) - , m_document(0) -{ - setDynamicSortFilter(true); - // in qt-4.5.1 there was a bug (254234) preventing sorting to be enabled - // so we explicitly trigger the sorting before setting the source model - sort(0, Qt::DescendingOrder); -} - -void KarbonLayerSortingModel::setDocument(KarbonDocument * newDocument) -{ - m_document = newDocument; - invalidate(); -} - -bool KarbonLayerSortingModel::lessThan(const QModelIndex &left, const QModelIndex &right) const -{ - KoShape * leftShape = static_cast(left.internalPointer()); - KoShape * rightShape = static_cast(right.internalPointer()); - - if (! leftShape || ! rightShape) - return false; - - if (m_document) { - KoShapeLayer * leftLayer = dynamic_cast(leftShape); - KoShapeLayer * rightLayer = dynamic_cast(rightShape); - if (leftLayer && rightLayer) { - return m_document->layerPos(leftLayer) < m_document->layerPos(rightLayer); - } else { - if (leftShape->zIndex() == rightShape->zIndex()) { - KoShapeContainer * leftParent = leftShape->parent(); - KoShapeContainer * rightParent = rightShape->parent(); - if (leftParent && leftParent == rightParent) { - QList children = leftParent->shapes(); - return children.indexOf(leftShape) < children.indexOf(rightShape); - } else { - return leftShape < rightShape; - } - } else { - return leftShape->zIndex() < rightShape->zIndex(); - } - } - } else { - if (leftShape->zIndex() == rightShape->zIndex()) - return leftShape < rightShape; - else - return leftShape->zIndex() < rightShape->zIndex(); - } -} - diff --git a/karbon/ui/widgets/KarbonCanvas.cpp b/karbon/ui/widgets/KarbonCanvas.cpp deleted file mode 100644 index d8ce5fefdac..00000000000 --- a/karbon/ui/widgets/KarbonCanvas.cpp +++ /dev/null @@ -1,469 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001-2002 Lennart Kudling - Copyright (C) 2001-2002 Rob Buis - Copyright (C) 2002-2004, 2006 Laurent Montel - Copyright (C) 2002 Benoit Vautrin - Copyright (C) 2004 Waldo Bastian - Copyright (C) 2004-2005 David Faure - Copyright (C) 2005-2006 Tim Beaulen - Copyright (C) 2007 Thomas Zander - Copyright (C) 2005-2007 Jan Hambrecht - Copyright (C) 2006 Peter Simonsson - Copyright (C) 2006 C. Boemann - Copyright (C) 2006 Thorsten Zachmann - Copyright (C) 2010 Boudewijn Rempt - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include "KarbonCanvas.h" -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -class KarbonCanvas::KarbonCanvasPrivate { -public: - KarbonCanvasPrivate() - : zoomHandler() - , part(0) - , showMargins(false) - , documentOffset(0, 0) - , viewMargin(100) - { - pixelGrid.setGrid(1.0, 1.0); - pixelGrid.setShowGrid(true); - } - - ~KarbonCanvasPrivate() { - delete toolProxy; - toolProxy = 0; - delete shapeManager; - } - - KoShapeManager* shapeManager; - KoZoomHandler zoomHandler; - - KoToolProxy *toolProxy; - - KarbonDocument *part; - QPoint origin; ///< the origin of the document page rect - bool showMargins; ///< should page margins be shown - QPoint documentOffset; ///< the offset of the virtual canvas from the viewport - int viewMargin; ///< the view margin around the document in pixels - QRectF documentViewRect; ///< the last calculated document view rect - KoGridData pixelGrid; ///< pixel grid data -}; - -KarbonCanvas::KarbonCanvas(KarbonDocument *p) - : QWidget() , KoCanvasBase(p), d(new KarbonCanvasPrivate()) -{ - d->part = p; - d->toolProxy = new KoToolProxy(this); - d->shapeManager = new KoShapeManager(this, d->part->shapes()); - connect(d->shapeManager, SIGNAL(selectionChanged()), this, SLOT(updateSizeAndOffset())); - - setBackgroundRole(QPalette::Base); - setAutoFillBackground(true); - setBackgroundColor(Qt::white); - setMouseTracking(true); - setFocusPolicy(Qt::StrongFocus); // allow to receive keyboard input - updateSizeAndOffset(); - setAttribute(Qt::WA_InputMethodEnabled, true); - setAttribute(Qt::WA_AcceptTouchEvents, true); -} - -KarbonCanvas::~KarbonCanvas() -{ - delete d; -} - -KoShapeManager * KarbonCanvas::shapeManager() const -{ - return d->shapeManager; -} - -KoViewConverter * KarbonCanvas::viewConverter() const -{ - return &d->zoomHandler; -} - -KoToolProxy * KarbonCanvas::toolProxy() const -{ - return d->toolProxy; -} - -QWidget * KarbonCanvas::canvasWidget() -{ - return this; -} - -const QWidget * KarbonCanvas::canvasWidget() const -{ - return this; -} - -bool KarbonCanvas::event(QEvent *e) -{ - if(toolProxy()) { - - if (e->type() == QEvent::TouchBegin || - e->type() == QEvent::TouchUpdate || - e->type() == QEvent::TouchEnd) { - toolProxy()->touchEvent(dynamic_cast(e)); - } - - toolProxy()->processEvent(e); - } - return QWidget::event(e); -} - -void KarbonCanvas::paintEvent(QPaintEvent * ev) -{ - QPainter painter(this); - painter.translate(-d->documentOffset); - - QRect clipRect = ev->rect().translated(d->documentOffset); - painter.setClipRect(clipRect); - - painter.translate(d->origin.x(), d->origin.y()); - painter.setPen(QPen(Qt::black, 0)); - - // paint the page rect - painter.drawRect(d->zoomHandler.documentToView(QRectF(QPointF(0.0, 0.0), d->part->pageSize()))); - - // paint the page margins - paintMargins(painter, d->zoomHandler); - - // get the cliprect in document coordinates - QRectF updateRect = d->zoomHandler.viewToDocument(widgetToView(clipRect)); - - // paint the shapes - painter.setRenderHint(QPainter::Antialiasing); - d->shapeManager->paint(painter, d->zoomHandler, false); - - // paint the grid and guides - painter.setRenderHint(QPainter::Antialiasing, false); - // check how big a single point is and paint a pixel grid if big enough - const qreal pointSize = d->zoomHandler.zoomItX(1.0); - if (pointSize > 10.0 && d->part->gridData().showGrid()) { - // set a slightly lighter color than the current grid color - d->pixelGrid.setGridColor(d->part->gridData().gridColor().lighter(110)); - d->pixelGrid.paintGrid(painter, d->zoomHandler, updateRect); - } - d->part->gridData().paintGrid(painter, d->zoomHandler, updateRect); - d->part->guidesData().paintGuides(painter, d->zoomHandler, updateRect); - - // paint the tool decorations - painter.setRenderHint(QPainter::Antialiasing); - d->toolProxy->paint(painter, d->zoomHandler); - - painter.end(); -} - -void KarbonCanvas::paintMargins(QPainter &painter, const KoViewConverter &converter) -{ - if (! d->showMargins) - return; - - KoPageLayout pl = d->part->pageLayout(); - - QSizeF pageSize = d->part->pageSize(); - QRectF marginRect(pl.leftMargin, pl.topMargin, - pageSize.width() - pl.leftMargin - pl.rightMargin, - pageSize.height() - pl.topMargin - pl.bottomMargin); - - QPen pen(Qt::blue, 0); - QVector pattern; - pattern << 5 << 5; - pen.setDashPattern(pattern); - painter.setPen(pen); - painter.drawRect(converter.documentToView(marginRect)); -} - -void KarbonCanvas::mouseMoveEvent(QMouseEvent *e) -{ - d->toolProxy->mouseMoveEvent(e, d->zoomHandler.viewToDocument(widgetToView(e->pos() + d->documentOffset))); -} - -void KarbonCanvas::mousePressEvent(QMouseEvent *e) -{ - d->toolProxy->mousePressEvent(e, d->zoomHandler.viewToDocument(widgetToView(e->pos() + d->documentOffset))); - if (!e->isAccepted() && e->button() == Qt::RightButton) { - QList actions = d->toolProxy->popupActionList(); - if (!actions.isEmpty()) { - QMenu menu(this); - foreach(QAction *action, d->toolProxy->popupActionList()) { - menu.addAction(action); - } - menu.exec(e->globalPos()); - } - } - - e->setAccepted(true); -} - -void KarbonCanvas::mouseDoubleClickEvent(QMouseEvent *e) -{ - d->toolProxy->mouseDoubleClickEvent(e, d->zoomHandler.viewToDocument(widgetToView(e->pos() + d->documentOffset))); -} - -void KarbonCanvas::mouseReleaseEvent(QMouseEvent *e) -{ - d->toolProxy->mouseReleaseEvent(e, d->zoomHandler.viewToDocument(widgetToView(e->pos() + d->documentOffset))); -} - -void KarbonCanvas::keyReleaseEvent(QKeyEvent *e) -{ - d->toolProxy->keyReleaseEvent(e); -} - -void KarbonCanvas::keyPressEvent(QKeyEvent *e) -{ - d->toolProxy->keyPressEvent(e); - if (! e->isAccepted()) { - if (e->key() == Qt::Key_Backtab - || (e->key() == Qt::Key_Tab && (e->modifiers() & Qt::ShiftModifier))) - focusNextPrevChild(false); - else if (e->key() == Qt::Key_Tab) - focusNextPrevChild(true); - } -} - -void KarbonCanvas::tabletEvent(QTabletEvent *e) -{ - d->toolProxy->tabletEvent(e, d->zoomHandler.viewToDocument(widgetToView(e->pos() + d->documentOffset))); -} - -void KarbonCanvas::wheelEvent(QWheelEvent *e) -{ - d->toolProxy->wheelEvent(e, d->zoomHandler.viewToDocument(widgetToView(e->pos() + d->documentOffset))); -} - -QVariant KarbonCanvas::inputMethodQuery(Qt::InputMethodQuery query) const -{ - if (query == Qt::ImMicroFocus) { - QRectF rect = (d->toolProxy->inputMethodQuery(query, *(viewConverter())).toRectF()).toRect(); - QPointF scroll(canvasController()->scrollBarValue()); - rect.translate(documentOrigin() - scroll); - return rect.toRect(); - } - return d->toolProxy->inputMethodQuery(query, *(viewConverter())); -} - -void KarbonCanvas::inputMethodEvent(QInputMethodEvent *event) -{ - d->toolProxy->inputMethodEvent(event); -} - -void KarbonCanvas::resizeEvent(QResizeEvent *) -{ - updateSizeAndOffset(); -} - -void KarbonCanvas::gridSize(qreal *horizontal, qreal *vertical) const -{ - if (horizontal) - *horizontal = d->part->gridData().gridX(); - if (vertical) - *vertical = d->part->gridData().gridY(); -} - -bool KarbonCanvas::snapToGrid() const -{ - return d->part->gridData().snapToGrid(); -} - -void KarbonCanvas::addCommand(KUndo2Command *command) -{ - d->part->addCommand(command); - updateSizeAndOffset(); -} - -void KarbonCanvas::updateCanvas(const QRectF& rc) -{ - QRect clipRect(viewToWidget(d->zoomHandler.documentToView(rc).toRect())); - clipRect.adjust(-2, -2, 2, 2); // grow for anti-aliasing - clipRect.moveTopLeft(clipRect.topLeft() - d->documentOffset); - update(clipRect); -} - -void KarbonCanvas::updateSizeAndOffset() -{ - // save the old view rect for comparing - QRectF oldDocumentViewRect = d->documentViewRect; - d->documentViewRect = documentViewRect(); - // check if the view rect has changed and emit signal if it has - if (oldDocumentViewRect != d->documentViewRect) { - QRectF viewRect = d->zoomHandler.documentToView(d->documentViewRect); - KoCanvasController * controller = canvasController(); - if (controller) { - // tell canvas controller the new document size in pixel - controller->updateDocumentSize(viewRect.size().toSize(), true); - // make sure the actual selection is visible - KoSelection * selection = d->shapeManager->selection(); - if (selection->count()) - controller->ensureVisible(d->zoomHandler.documentToView(selection->boundingRect())); - } - } - adjustOrigin(); - update(); -} - -void KarbonCanvas::adjustOrigin() -{ - // calculate the zoomed document bounding rect - QRect documentRect = d->zoomHandler.documentToView(documentViewRect()).toRect(); - - // save the old origin to see if it has changed - QPoint oldOrigin = d->origin; - - // set the origin to the zoom document rect origin - d->origin = -documentRect.topLeft(); - - // the document bounding rect is always centered on the virtual canvas - // if there are margins left around the zoomed document rect then - // distribute them evenly on both sides - int widthDiff = size().width() - documentRect.width(); - if (widthDiff > 0) - d->origin.rx() += qRound(0.5 * widthDiff); - int heightDiff = size().height() - documentRect.height(); - if (heightDiff > 0) - d->origin.ry() += qRound(0.5 * heightDiff); - - // check if the origin has changed and emit signal if it has - if (d->origin != oldOrigin) - emit documentOriginChanged(d->origin); -} - -void KarbonCanvas::setDocumentOffset(const QPoint &offset) -{ - d->documentOffset = offset; -} - -const QPoint &KarbonCanvas::documentOffset() const -{ - return d->documentOffset; -} - -KarbonDocument *KarbonCanvas::document() const -{ - return d->part; -} - -void KarbonCanvas::enableOutlineMode(bool on) -{ - if (on) - new KarbonOutlinePaintingStrategy(d->shapeManager); - else { - d->shapeManager->setPaintingStrategy(new KoShapeManagerPaintingStrategy(d->shapeManager)); - } -} - -QPoint KarbonCanvas::widgetToView(const QPoint& p) const -{ - return p - d->origin; -} - -QRect KarbonCanvas::widgetToView(const QRect& r) const -{ - return r.translated(- d->origin); -} - -QPoint KarbonCanvas::viewToWidget(const QPoint& p) const -{ - return p + d->origin; -} - -QRect KarbonCanvas::viewToWidget(const QRect& r) const -{ - return r.translated(d->origin); -} - -KoUnit KarbonCanvas::unit() const -{ - return d->part->unit(); -} - -QPoint KarbonCanvas::documentOrigin() const -{ - return d->origin; -} - -void KarbonCanvas::setShowPageMargins(bool on) -{ - d->showMargins = on; -} - -void KarbonCanvas::setDocumentViewMargin(int margin) -{ - d->viewMargin = margin; -} - -int KarbonCanvas::documentViewMargin() const -{ - return d->viewMargin; -} - -QRectF KarbonCanvas::documentViewRect() -{ - QRectF bbox = d->part->boundingRect(); - d->documentViewRect = bbox.adjusted(-d->viewMargin, -d->viewMargin, d->viewMargin, d->viewMargin); - return d->documentViewRect; -} - -void KarbonCanvas::updateInputMethodInfo() -{ - updateMicroFocus(); -} - -KoGuidesData * KarbonCanvas::guidesData() -{ - return &d->part->guidesData(); -} - -void KarbonCanvas::setBackgroundColor(const QColor &color) -{ - QPalette pal = palette(); - pal.setColor(QPalette::Normal, backgroundRole(), color); - pal.setColor(QPalette::Inactive, backgroundRole(), color); - setPalette(pal); -} - -void KarbonCanvas::setCursor(const QCursor &cursor) -{ - QWidget::setCursor(cursor); -} - - diff --git a/karbon/ui/widgets/KarbonCanvas.h b/karbon/ui/widgets/KarbonCanvas.h deleted file mode 100644 index 427132b688e..00000000000 --- a/karbon/ui/widgets/KarbonCanvas.h +++ /dev/null @@ -1,173 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001-2002 Lennart Kudling - Copyright (C) 2001-2003 Rob Buis - Copyright (C) 2003 Dirk Mueller - Copyright (C) 2005 Laurent Montel - Copyright (C) 2005-2007 Thomas Zander - Copyright (C) 2006-2007 Jan Hambrecht - Copyright (C) 2006 Tim Beaulen - Copyright (C) 2006 Sven Langkamp - Copyright (C) 2006 Boudewijn Rempt - Copyright (C) 2006 Thorsten Zachmann - Copyright (C) 2006 C. Boemann - Copyright (C) 2006 Peter Simonsson - Copyright (C) 2007 David Faure - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#ifndef KARBONCANVAS_H -#define KARBONCANVAS_H - -#include - -#include - -#include -#include - -class KarbonDocument; -class KoViewConverter; -class KoShapeManager; -class KoToolProxy; -class QRectF; -class QPainter; -class QPaintEvent; -class QWheelEvent; -class QTabletEvent; -class QResizeEvent; - -class KarbonCanvas: public QWidget, public KoCanvasBase -{ - Q_OBJECT - -public: - explicit KarbonCanvas(KarbonDocument *p); - virtual ~KarbonCanvas(); - - /// reimplemented from KoCanvasBase - virtual void gridSize(qreal *horizontal, qreal *vertical) const; - /// reimplemented from KoCanvasBase - virtual bool snapToGrid() const; - /// reimplemented from KoCanvasBase - virtual KoUnit unit() const; - /// reimplemented from KoCanvasBase - void addCommand(KUndo2Command *command); - /// reimplemented from KoCanvasBase - KoShapeManager *shapeManager() const; - /// reimplemented from KoCanvasBase - KoViewConverter *viewConverter() const; - /// reimplemented from KoCanvasBase - KoToolProxy * toolProxy() const; - /// reimplemented from KoCanvasBase - virtual QPoint documentOrigin() const; - /// reimplemented from KoCanvasBase - QWidget *canvasWidget(); - /// reimplemented from KoCanvasBase - const QWidget *canvasWidget() const; - /// reimplemented from KoCanvasBase - void updateCanvas(const QRectF& rc); - /// reimplemented from KoCanvasBase - virtual void updateInputMethodInfo(); - /// reimplemented from KoCanvasBase - virtual KoGuidesData * guidesData(); - virtual void setCursor(const QCursor &cursor); - /// Enables/disables showing page margins - void setShowPageMargins(bool on); - - /** - * Sets the viewing margin around the document in pt - * @param margin the viewing margin around the document - */ - void setDocumentViewMargin(int margin); - - /// Returns the viewing margin around the document - int documentViewMargin() const; - - /** - * Returns the document bounding rect with the viewing margin applied. - * The rect is returned in pt. - * @return the document bounding rect with viewing margins applied. - */ - QRectF documentViewRect(); - - /// Sets the canvas background color to the given color - void setBackgroundColor(const QColor &color); - - /// @return the offset of the document in canvas position. - const QPoint &documentOffset() const; - - /// @return the document used by the canvas. - KarbonDocument *document() const; - -public Q_SLOTS: - - /** - * Tell the canvas that it has to adjust its document origin. - * The new origin depends on the current document size, the actual zoom factor - * and the actual canvas size. - */ - void adjustOrigin(); - void setDocumentOffset(const QPoint &offset); - - /// Enables/disables outline painting mode - void enableOutlineMode(bool on); - -Q_SIGNALS: - - /** - * This signal is emitted when the document origin has changed. - * The document origin is the point (in pixel) on the virtual - * canvas where the documents origin (0,0) or the top left - * corner of the page is. - */ - void documentOriginChanged(const QPoint &origin); - -protected: - bool event(QEvent *); - void paintEvent(QPaintEvent * ev); - void mouseEvent(QMouseEvent *e); - void mouseReleaseEvent(QMouseEvent *e); - void keyReleaseEvent(QKeyEvent *e); - void keyPressEvent(QKeyEvent *e); - void mouseMoveEvent(QMouseEvent *e); - void mousePressEvent(QMouseEvent *e); - void mouseDoubleClickEvent(QMouseEvent *e); - void tabletEvent(QTabletEvent *e); - void wheelEvent(QWheelEvent *e); - void resizeEvent(QResizeEvent *e); - /// reimplemented method from superclass - virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const; - /// reimplemented method from superclass - virtual void inputMethodEvent(QInputMethodEvent *event); - - QPoint widgetToView(const QPoint& p) const; - QRect widgetToView(const QRect& r) const; - QPoint viewToWidget(const QPoint& p) const; - QRect viewToWidget(const QRect& r) const; - -private Q_SLOTS: - void updateSizeAndOffset(); - -private: - /// paint page margins - void paintMargins(QPainter &painter, const KoViewConverter &converter); - - class KarbonCanvasPrivate; - KarbonCanvasPrivate * const d; -}; - -#endif // KARBONCANVAS_H diff --git a/karbon/ui/widgets/KarbonConfigInterfacePage.cpp b/karbon/ui/widgets/KarbonConfigInterfacePage.cpp index b6d36559784..31fd723f37e 100644 --- a/karbon/ui/widgets/KarbonConfigInterfacePage.cpp +++ b/karbon/ui/widgets/KarbonConfigInterfacePage.cpp @@ -1,137 +1,138 @@ /* This file is part of the KDE project Copyright (C) 2002, 2003 Laurent Montel Copyright (C) 2006-2007 Jan Hambrecht This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KarbonConfigInterfacePage.h" #include "KarbonView.h" #include "KarbonPart.h" #include "KarbonDocument.h" #include "KarbonFactory.h" #include #include #include #include #include #include #include #include #include #include #include KarbonConfigInterfacePage::KarbonConfigInterfacePage(KarbonView* view, char* name) { setObjectName(name); m_view = view; m_config = KarbonFactory::karbonConfig(); m_oldRecentFiles = 10; m_oldDockerFontSize = 8; m_oldCanvasColor = QColor(Qt::white); bool oldShowStatusBar = true; QGroupBox* tmpQGroupBox = new QGroupBox(i18n("Interface"), this); KConfigGroup emptyGroup = m_config->group("GUI"); m_oldDockerFontSize = emptyGroup.readEntry("palettefontsize", m_oldDockerFontSize); if (m_config->hasGroup("Interface")) { KConfigGroup interfaceGroup = m_config->group("Interface"); m_oldRecentFiles = interfaceGroup.readEntry("NbRecentFile", m_oldRecentFiles); oldShowStatusBar = interfaceGroup.readEntry("ShowStatusBar", true); m_oldCanvasColor = interfaceGroup.readEntry("CanvasColor", m_oldCanvasColor); } QFormLayout *interfaceLayout = new QFormLayout(tmpQGroupBox); m_showStatusBar = new QCheckBox(tmpQGroupBox); m_showStatusBar->setChecked(oldShowStatusBar); interfaceLayout->addRow(i18n("Show status bar:"), m_showStatusBar); m_recentFiles = new QSpinBox(tmpQGroupBox); m_recentFiles->setRange(1, 20); m_recentFiles->setSingleStep(1); m_recentFiles->setValue(m_oldRecentFiles); interfaceLayout->addRow(i18n("Number of recent files:"), m_recentFiles); m_dockerFontSize = new QSpinBox(tmpQGroupBox); m_dockerFontSize->setRange(5, 20); m_dockerFontSize->setSingleStep(1); m_dockerFontSize->setValue(m_oldDockerFontSize); interfaceLayout->addRow(i18n("Palette font size:"), m_dockerFontSize); - m_canvasColor = new KColorButton(m_oldCanvasColor, tmpQGroupBox); - interfaceLayout->addRow(i18n("Canvas color:"), m_canvasColor); +// TODO or move or remove? +// m_canvasColor = new KColorButton(m_oldCanvasColor, tmpQGroupBox); +// interfaceLayout->addRow(i18n("Canvas color:"), m_canvasColor); } void KarbonConfigInterfacePage::apply() { bool showStatusBar = m_showStatusBar->isChecked(); KarbonDocument* part = m_view->part(); KConfigGroup interfaceGroup = m_config->group("Interface"); int recent = m_recentFiles->value(); if (recent != m_oldRecentFiles) { interfaceGroup.writeEntry("NbRecentFile", recent); m_view->setNumberOfRecentFiles(recent); m_oldRecentFiles = recent; } bool refreshGUI = false; if (showStatusBar != part->showStatusBar()) { interfaceGroup.writeEntry("ShowStatusBar", showStatusBar); part->setShowStatusBar(showStatusBar); refreshGUI = true; } int dockerFontSize = m_dockerFontSize->value(); if (dockerFontSize != m_oldDockerFontSize) { m_config->group("GUI").writeEntry("palettefontsize", dockerFontSize); m_oldDockerFontSize = dockerFontSize; refreshGUI = true; } - QColor canvasColor = m_canvasColor->color(); - if (canvasColor != m_oldCanvasColor) { - interfaceGroup.writeEntry("CanvasColor", canvasColor); - refreshGUI = true; - } +// QColor canvasColor = m_canvasColor->color(); +// if (canvasColor != m_oldCanvasColor) { +// interfaceGroup.writeEntry("CanvasColor", canvasColor); +// refreshGUI = true; +// } if (refreshGUI) part->reorganizeGUI(); } void KarbonConfigInterfacePage::slotDefault() { m_recentFiles->setValue(10); m_dockerFontSize->setValue(8); m_showStatusBar->setChecked(true); } diff --git a/karbon/ui/widgets/KarbonSmallStylePreview.h b/karbon/ui/widgets/KarbonSmallStylePreview.h index 09b2a1ce3d3..d763e1d1fd5 100644 --- a/karbon/ui/widgets/KarbonSmallStylePreview.h +++ b/karbon/ui/widgets/KarbonSmallStylePreview.h @@ -1,52 +1,52 @@ /* This file is part of the KDE project Copyright (c) 2005 Tomislav Lukman Copyright (c) 2008 Jan Hambrecht This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KARBONSMALLSTYLEPREVIEW_H #define KARBONSMALLSTYLEPREVIEW_H #include class KarbonFillStyleWidget; class KarbonStrokeStyleWidget; class KoCanvasBase; /// This is a small widget used on the statusbar, to display fill/stroke colors etc. class KarbonSmallStylePreview : public QWidget { Q_OBJECT public: explicit KarbonSmallStylePreview(QWidget* parent = 0L); virtual ~KarbonSmallStylePreview(); Q_SIGNALS: void fillApplied(); void strokeApplied(); -private Q_SLOTS: +public Q_SLOTS: void selectionChanged(); void canvasChanged(const KoCanvasBase *canvas); private: KarbonFillStyleWidget * m_fillFrame; KarbonStrokeStyleWidget * m_strokeFrame; }; #endif // KARBONSMALLSTYLEPREVIEW_H diff --git a/libs/pageapp/KoPADocument.cpp b/libs/pageapp/KoPADocument.cpp index eeec079a96c..70f9da6138d 100644 --- a/libs/pageapp/KoPADocument.cpp +++ b/libs/pageapp/KoPADocument.cpp @@ -1,894 +1,894 @@ /* This file is part of the KDE project Copyright (C) 2006-2011 Thorsten Zachmann Copyright (C) 2007 Thomas Zander This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KoPADocument.h" #include "KoPAView.h" #include "KoPAPage.h" #include "KoPAMasterPage.h" #include "KoPASavingContext.h" #include "KoPALoadingContext.h" #include "KoPAPageProvider.h" #include "commands/KoPAPageDeleteCommand.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class Q_DECL_HIDDEN KoPADocument::Private { public: QList pages; QList masterPages; KoInlineTextObjectManager *inlineTextObjectManager; bool rulersVisible; KoPAPageProvider *pageProvider; QPointer odfProgressUpdater; QPointer odfMasterPageProgressUpdater; QPointer odfPageProgressUpdater; QString defaultStylesResourcePath; bool showPageMargins; }; KoPADocument::KoPADocument(KoPart *part) : KoDocument(part), d(new Private()) { d->inlineTextObjectManager = resourceManager()->resource(KoText::InlineTextObjectManager).value(); Q_ASSERT(d->inlineTextObjectManager); d->rulersVisible = false; connect(documentInfo(), SIGNAL(infoUpdated(QString,QString)), d->inlineTextObjectManager, SLOT(documentInformationUpdated(QString,QString))); resourceManager()->setUndoStack(undoStack()); resourceManager()->setOdfDocument(this); // this is needed so the text shape have a shape controller set when loaded, it is needed for copy and paste new KoShapeController(0, this); QVariant variant; d->pageProvider = new KoPAPageProvider(); variant.setValue(d->pageProvider); resourceManager()->setResource(KoText::PageProvider, variant); loadConfig(); } KoPADocument::~KoPADocument() { saveConfig(); qDeleteAll( d->pages ); qDeleteAll( d->masterPages ); delete d->pageProvider; delete d; } QPixmap KoPADocument::generatePreview(const QSize& size) { // use first page as preview for all pages KoPAPageBase *page = pageByIndex(0, false); Q_ASSERT( page ); return pageThumbnail(page, size); } void KoPADocument::paintContent( QPainter &painter, const QRect &rect) { KoPAPageBase * page = pageByIndex( 0, false ); Q_ASSERT( page ); QPixmap thumbnail( pageThumbnail( page, rect.size() ) ); painter.drawPixmap( rect, thumbnail ); } bool KoPADocument::loadXML( const KoXmlDocument & doc, KoStore * ) { Q_UNUSED( doc ); //Perhaps not necessary if we use filter import/export for old file format //only needed as it is in the base class will be removed. return true; } void KoPADocument::setupOpenFileSubProgress() { if (progressUpdater()) { d->odfProgressUpdater = progressUpdater()->startSubtask(1, "KoPADocument::loadOdf"); d->odfMasterPageProgressUpdater = progressUpdater()->startSubtask(1, "KoPADocument::loadOdfMasterPages"); d->odfPageProgressUpdater = progressUpdater()->startSubtask(5, "KoPADocument::loadOdfPages"); } } bool KoPADocument::loadOdf( KoOdfReadStore & odfStore) { updateDocumentURL(); if (d->odfProgressUpdater) { d->odfProgressUpdater->setProgress(0); } KoOdfLoadingContext loadingContext( odfStore.styles(), odfStore.store(), defaultStylesResourcePath()); KoPALoadingContext paContext(loadingContext, resourceManager()); KoXmlElement content = odfStore.contentDoc().documentElement(); KoXmlElement realBody ( KoXml::namedItemNS( content, KoXmlNS::office, "body" ) ); if ( realBody.isNull() ) { errorPageApp << "No body tag found!" << endl; return false; } KoXmlElement body = KoXml::namedItemNS(realBody, KoXmlNS::office, odfTagName( false )); if ( body.isNull() ) { errorPageApp << "No office:" << odfTagName( false ) << " tag found!" << endl; return false; } // Load text styles before the corresponding text shapes try to use them! KoTextSharedLoadingData * sharedData = new KoTextSharedLoadingData(); paContext.addSharedData( KOTEXT_SHARED_LOADING_ID, sharedData ); KoStyleManager *styleManager = resourceManager()->resource(KoText::StyleManager).value(); sharedData->loadOdfStyles(paContext, styleManager); if (d->odfProgressUpdater) { d->odfProgressUpdater->setProgress(20); } d->masterPages = loadOdfMasterPages( odfStore.styles().masterPages(), paContext ); if ( !loadOdfProlog( body, paContext ) ) { return false; } d->pages = loadOdfPages( body, paContext ); // create pages if there are none if (d->masterPages.empty()) { d->masterPages.append(newMasterPage()); } if (d->pages.empty()) { d->pages.append(newPage(static_cast(d->masterPages.first()))); } if ( !loadOdfEpilogue( body, paContext ) ) { return false; } loadOdfDocumentStyles( paContext ); if ( d->pages.size() > 1 ) { emit actionsPossible(KoPAView::ActionDeletePage, false); } updatePageCount(); loadOdfSettings(odfStore.settingsDoc()); if (d->odfProgressUpdater) { d->odfProgressUpdater->setProgress(100); } return true; } bool KoPADocument::saveOdf( SavingContext & documentContext ) { KoXmlWriter* contentWriter = documentContext.odfStore.contentWriter(); if ( !contentWriter ) return false; KoGenStyles mainStyles; KoXmlWriter * bodyWriter = documentContext.odfStore.bodyWriter(); KoPASavingContext paContext(*bodyWriter, mainStyles, documentContext.embeddedSaver, 1); saveOdfDocumentStyles( paContext ); bodyWriter->startElement( "office:body" ); bodyWriter->startElement( odfTagName( true ) ); if ( !saveOdfProlog( paContext ) ) { return false; } if ( !saveOdfPages( paContext, d->pages, d->masterPages ) ) { return false; } if ( ! saveOdfEpilogue( paContext ) ) { return false; } bodyWriter->endElement(); // office:odfTagName() bodyWriter->endElement(); // office:body mainStyles.saveOdfStyles( KoGenStyles::DocumentAutomaticStyles, contentWriter ); documentContext.odfStore.closeContentWriter(); //add manifest line for content.xml documentContext.odfStore.manifestWriter()->addManifestEntry( "content.xml", "text/xml" ); if ( ! mainStyles.saveOdfStylesDotXml( documentContext.odfStore.store(), documentContext.odfStore.manifestWriter() ) ) { return false; } KoStore * store = documentContext.odfStore.store(); if ( ! store->open( "settings.xml" ) ) { return false; } saveOdfSettings( store ); if ( ! store->close() ) { return false; } documentContext.odfStore.manifestWriter()->addManifestEntry( "settings.xml", "text/xml" ); //setModified( false ); bool retval = paContext.saveDataCenter( documentContext.odfStore.store(), documentContext.odfStore.manifestWriter() ); if (retval) { updateDocumentURL(); } return retval; } QList KoPADocument::loadOdfMasterPages( const QHash masterStyles, KoPALoadingContext & context ) { context.odfLoadingContext().setUseStylesAutoStyles( true ); QList masterPages; if (d->odfMasterPageProgressUpdater) { d->odfMasterPageProgressUpdater->setProgress(0); } QHash::const_iterator it( masterStyles.constBegin() ); int count = 0; for ( ; it != masterStyles.constEnd(); ++it ) { KoPAMasterPage * masterPage = newMasterPage(); masterPage->loadOdf( *( it.value() ), context ); masterPages.append( masterPage ); context.addMasterPage( it.key(), masterPage ); if (d->odfMasterPageProgressUpdater) { int progress = 100 * ++count / masterStyles.size(); d->odfMasterPageProgressUpdater->setProgress(progress); } } context.odfLoadingContext().setUseStylesAutoStyles( false ); if (d->odfMasterPageProgressUpdater) { d->odfMasterPageProgressUpdater->setProgress(100); } return masterPages; } QList KoPADocument::loadOdfPages( const KoXmlElement & body, KoPALoadingContext & context ) { if (d->masterPages.isEmpty()) { // we require at least one master page. Auto create one if the doc was faulty. d->masterPages << newMasterPage(); } int childNodesCount = 0; int childCount = 0; if (d->odfPageProgressUpdater) { d->odfPageProgressUpdater->setProgress(0); childNodesCount = body.childNodesCount(); } QList pages; KoXmlElement element; forEachElement( element, body ) { if ( element.tagName() == "page" && element.namespaceURI() == KoXmlNS::draw ) { KoPAPage *page = newPage(static_cast(d->masterPages.first())); page->loadOdf( element, context ); pages.append( page ); // in case the page name is pageX where X is the page number remove the name as this is // remove the page name and show the default page name like Slide X or Page X. if (page->name() == QString("page%1").arg(pages.size())) { page->setName(""); } } if (d->odfPageProgressUpdater) { int progress = 100 * ++childCount / childNodesCount; d->odfPageProgressUpdater->setProgress(progress); } } if (d->odfPageProgressUpdater) { d->odfPageProgressUpdater->setProgress(100); } return pages; } bool KoPADocument::loadOdfEpilogue( const KoXmlElement & body, KoPALoadingContext & context ) { Q_UNUSED( body ); Q_UNUSED( context ); return true; } bool KoPADocument::loadOdfProlog( const KoXmlElement & body, KoPALoadingContext & context ) { Q_UNUSED( body ); Q_UNUSED( context ); // Load user defined variable declarations if (KoVariableManager *variableManager = inlineTextObjectManager()->variableManager()) { variableManager->loadOdf(body); } return true; } bool KoPADocument::saveOdfPages( KoPASavingContext &paContext, QList &pages, QList &masterPages ) { paContext.addOption( KoPASavingContext::DrawId ); paContext.addOption( KoPASavingContext::AutoStyleInStyleXml ); // save master pages foreach( KoPAPageBase *page, masterPages ) { if ( paContext.isSetClearDrawIds() ) { paContext.clearXmlIds("shape"); } page->saveOdf( paContext ); } paContext.removeOption( KoPASavingContext::AutoStyleInStyleXml ); // save pages foreach ( KoPAPageBase *page, pages ) { page->saveOdf( paContext ); paContext.incrementPage(); } return true; } bool KoPADocument::saveOdfProlog( KoPASavingContext & paContext ) { Q_UNUSED( paContext ); // Save user defined variable declarations if (KoVariableManager *variableManager = inlineTextObjectManager()->variableManager()) { variableManager->saveOdf(&paContext.xmlWriter()); } return true; } bool KoPADocument::saveOdfEpilogue( KoPASavingContext & paContext ) { Q_UNUSED( paContext ); return true; } bool KoPADocument::saveOdfSettings( KoStore * store ) { KoStoreDevice settingsDev( store ); KoXmlWriter * settingsWriter = KoOdfWriteStore::createOasisXmlWriter( &settingsDev, "office:document-settings" ); settingsWriter->startElement("office:settings"); settingsWriter->startElement("config:config-item-set"); settingsWriter->addAttribute("config:name", "view-settings"); saveUnitOdf(settingsWriter); settingsWriter->endElement(); // config:config-item-set settingsWriter->startElement("config:config-item-set"); settingsWriter->addAttribute("config:name", "ooo:view-settings"); settingsWriter->startElement("config:config-item-map-indexed" ); settingsWriter->addAttribute("config:name", "Views" ); settingsWriter->startElement("config:config-item-map-entry" ); guidesData().saveOdfSettings( *settingsWriter ); gridData().saveOdfSettings( *settingsWriter ); settingsWriter->endElement(); // config:config-item-map-entry settingsWriter->endElement(); // config:config-item-map-indexed settingsWriter->endElement(); // config:config-item-set settingsWriter->endElement(); // office:settings settingsWriter->endElement(); // office:document-settings settingsWriter->endDocument(); delete settingsWriter; return true; } void KoPADocument::loadOdfSettings( const KoXmlDocument & settingsDoc ) { if ( settingsDoc.isNull() ) { return ; // not an error if some file doesn't have settings.xml } KoOasisSettings settings( settingsDoc ); KoOasisSettings::Items viewSettings = settings.itemSet( "view-settings" ); if ( !viewSettings.isNull() ) { setUnit(KoUnit::fromSymbol(viewSettings.parseConfigItemString("unit"))); // FIXME: add other config here. } guidesData().loadOdfSettings( settingsDoc ); gridData().loadOdfSettings( settingsDoc ); } void KoPADocument::saveOdfDocumentStyles( KoPASavingContext & context ) { KoStyleManager *styleManager = resourceManager()->resource(KoText::StyleManager).value(); Q_ASSERT( styleManager ); styleManager->saveOdf(context); } bool KoPADocument::loadOdfDocumentStyles( KoPALoadingContext & context ) { Q_UNUSED( context ); return true; } KoPAPageBase* KoPADocument::pageByIndex( int index, bool masterPage ) const { if ( masterPage ) { return d->masterPages.at( index ); } else { return d->pages.at( index ); } } int KoPADocument::pageIndex( KoPAPageBase * page ) const { const QList& pages = dynamic_cast( page ) ? d->masterPages : d->pages; return pages.indexOf( page ); } KoPAPageBase* KoPADocument::pageByNavigation( KoPAPageBase * currentPage, KoPageApp::PageNavigation pageNavigation ) const { const QList& pages = dynamic_cast( currentPage ) ? d->masterPages : d->pages; Q_ASSERT( ! pages.isEmpty() ); KoPAPageBase * newPage = currentPage; switch ( pageNavigation ) { case KoPageApp::PageFirst: newPage = pages.first(); break; case KoPageApp::PageLast: newPage = pages.last(); break; case KoPageApp::PagePrevious: { int index = pages.indexOf( currentPage ) - 1; if ( index >= 0 ) { newPage = pages.at( index ); } } break; case KoPageApp::PageNext: // fall through default: { int index = pages.indexOf( currentPage ) + 1; if ( index < pages.size() ) { newPage = pages.at( index ); } break; } } return newPage; } void KoPADocument::addShape( KoShape * shape ) { if(!shape) return; // the KoShapeController sets the active layer as parent KoPAPageBase *page(pageByShape(shape)); emit shapeAdded(shape); // it can happen in Stage notes view that there is no page if ( page ) { page->shapeAdded( shape ); postAddShape( page, shape ); } } void KoPADocument::postAddShape( KoPAPageBase * page, KoShape * shape ) { Q_UNUSED( page ); Q_UNUSED( shape ); } void KoPADocument::removeShape(KoShape *shape) { if (!shape) return; KoPAPageBase *page(pageByShape(shape)); emit shapeRemoved(shape); page->shapeRemoved(shape); postRemoveShape(page, shape); } void KoPADocument::postRemoveShape( KoPAPageBase * page, KoShape * shape ) { Q_UNUSED( page ); Q_UNUSED( shape ); } void KoPADocument::removePage( KoPAPageBase * page ) { KoPAPageDeleteCommand * command = new KoPAPageDeleteCommand( this, page ); pageRemoved( page, command ); addCommand( command ); } void KoPADocument::removePages(QList &pages) { KoPAPageDeleteCommand *command = new KoPAPageDeleteCommand(this, pages); addCommand(command); } void KoPADocument::pageRemoved( KoPAPageBase * page, KUndo2Command * parent ) { Q_UNUSED( page ); Q_UNUSED( parent ); } KoPAPageBase * KoPADocument::pageByShape( KoShape * shape ) const { KoShape * parent = shape; KoPAPageBase * page = 0; while ( !page && ( parent = parent->parent() ) ) { page = dynamic_cast( parent ); } return page; } //F)XME /* void KoPADocument::updateViews(KoPAPageBase *page) { if (!page) return; foreach (KoView *view, views()) { KoPAView *paView = static_cast(view); if ( paView->activePage() == page ) { paView->viewMode()->updateActivePage( page ); } else if ( dynamic_cast( page ) ) { // if the page changed is a master page, we need to check whether it is the current page's master page KoPAPage *activePage = dynamic_cast( paView->activePage() ); if ( activePage && activePage->masterPage() == page ) { paView->viewMode()->updateActivePage( activePage ); } } } } */ KoPageApp::PageType KoPADocument::pageType() const { return KoPageApp::Page; } QPixmap KoPADocument::pageThumbnail(KoPAPageBase* page, const QSize& size) { int pageNumber = pageIndex(page) + 1; d->pageProvider->setPageData(pageNumber, page); return page->thumbnail(size); } QImage KoPADocument::pageThumbImage(KoPAPageBase* page, const QSize& size) { int pageNumber = pageIndex(page) + 1; d->pageProvider->setPageData(pageNumber, page); return page->thumbImage(size); } void KoPADocument::initEmpty() { d->masterPages.clear(); d->pages.clear(); KoPAMasterPage * masterPage = newMasterPage(); d->masterPages.append( masterPage ); KoPAPage * page = newPage( masterPage ); d->pages.append( page ); KoDocument::initEmpty(); } void KoPADocument::insertPage( KoPAPageBase* page, int index ) { if ( !page ) return; QList& pages = dynamic_cast( page ) ? d->masterPages : d->pages; if ( index > pages.size() || index < 0 ) { index = pages.size(); } pages.insert( index, page ); updatePageCount(); emit actionsPossible(KoPAView::ActionDeletePage, pages.size() > 1); emit pageAdded(page); } void KoPADocument::insertPage( KoPAPageBase* page, KoPAPageBase* after ) { if ( !page ) return; QList& pages = dynamic_cast( page ) ? d->masterPages : d->pages; int index = 0; if ( after != 0 ) { index = pages.indexOf( after ) + 1; // Append the page if after wasn't found in pages if ( index == 0 ) index = pages.count(); } pages.insert( index, page ); updatePageCount(); emit actionsPossible(KoPAView::ActionDeletePage, pages.size() > 1); emit pageAdded( page ); } int KoPADocument::takePage( KoPAPageBase *page ) { Q_ASSERT( page ); QList& pages = dynamic_cast( page ) ? d->masterPages : d->pages; int index = pages.indexOf( page ); // it should not be possible to delete the last page Q_ASSERT( pages.size() > 1 ); if ( index != -1 ) { pages.removeAt( index ); // change to previous page when the page is the active one if the first one is delete go to the next one int newIndex = index == 0 ? 0 : index - 1; KoPAPageBase * newActivePage = pages.at( newIndex ); updatePageCount(); emit replaceActivePage(page, newActivePage); - emit pageRemoved(page); + emit pageRemoved(page, index); } if ( pages.size() == 1 ) { emit actionsPossible(KoPAView::ActionDeletePage, false); } return index; } QList KoPADocument::pages( bool masterPages ) const { return masterPages ? d->masterPages : d->pages; } KoPAPage * KoPADocument::newPage( KoPAMasterPage * masterPage ) { return new KoPAPage( masterPage ); } KoPAMasterPage * KoPADocument::newMasterPage() { return new KoPAMasterPage(); } /// return the inlineTextObjectManager for this document. KoInlineTextObjectManager *KoPADocument::inlineTextObjectManager() const { return d->inlineTextObjectManager; } void KoPADocument::loadConfig() { KSharedConfigPtr config = KSharedConfig::openConfig(); if( config->hasGroup( "Grid" ) ) { KoGridData defGrid; KConfigGroup configGroup = config->group( "Grid" ); bool showGrid = configGroup.readEntry( "ShowGrid", defGrid.showGrid() ); gridData().setShowGrid(showGrid); bool paintGridInBackground = configGroup.readEntry("PaintGridInBackground", defGrid.paintGridInBackground()); gridData().setPaintGridInBackground(paintGridInBackground); bool snapToGrid = configGroup.readEntry( "SnapToGrid", defGrid.snapToGrid() ); gridData().setSnapToGrid(snapToGrid); qreal spacingX = configGroup.readEntry( "SpacingX", defGrid.gridX() ); qreal spacingY = configGroup.readEntry( "SpacingY", defGrid.gridY() ); gridData().setGrid( spacingX, spacingY ); QColor color = configGroup.readEntry( "Color", defGrid.gridColor() ); gridData().setGridColor( color ); } d->showPageMargins = true; if( config->hasGroup( "Interface" ) ) { KConfigGroup configGroup = config->group( "Interface" ); bool showRulers = configGroup.readEntry( "ShowRulers", true); setRulersVisible(showRulers); bool showPageMargins = configGroup.readEntry( "ShowPageMargins", true); setShowPageMargins(showPageMargins); } } void KoPADocument::saveConfig() { KSharedConfigPtr config = KSharedConfig::openConfig(); KConfigGroup configGroup = config->group( "Grid" ); KoGridData defGrid; bool showGrid = gridData().showGrid(); if ((showGrid == defGrid.showGrid()) && !configGroup.hasDefault("ShowGrid")) configGroup.revertToDefault("ShowGrid"); else configGroup.writeEntry("ShowGrid", showGrid); bool snapToGrid = gridData().snapToGrid(); if ((snapToGrid == defGrid.snapToGrid()) && !configGroup.hasDefault("SnapToGrid")) configGroup.revertToDefault("SnapToGrid"); else configGroup.writeEntry("SnapToGrid", snapToGrid); qreal spacingX = gridData().gridX(); if ((spacingX == defGrid.gridX()) && !configGroup.hasDefault("SpacingX")) configGroup.revertToDefault("SpacingX"); else configGroup.writeEntry("SpacingX", spacingX); qreal spacingY = gridData().gridY(); if ((spacingY == defGrid.gridY()) && !configGroup.hasDefault("SpacingY")) configGroup.revertToDefault("SpacingY"); else configGroup.writeEntry("SpacingY", spacingY); QColor color = gridData().gridColor(); if ((color == defGrid.gridColor()) && !configGroup.hasDefault("Color")) configGroup.revertToDefault("Color"); else configGroup.writeEntry("Color", color); configGroup = config->group( "Interface" ); bool showRulers = rulersVisible(); if ((showRulers == true) && !configGroup.hasDefault("ShowRulers")) configGroup.revertToDefault("ShowRulers"); else configGroup.writeEntry("ShowRulers", showRulers); bool showMargins = showPageMargins(); if ((showMargins == true) && !configGroup.hasDefault("ShowPageMargins")) { configGroup.revertToDefault("ShowPageMargins"); } else { configGroup.writeEntry("ShowPageMargins", showMargins); } } void KoPADocument::setRulersVisible(bool visible) { d->rulersVisible = visible; } bool KoPADocument::rulersVisible() const { return d->rulersVisible; } // TODO: the property "defaultStylesResourcePath" for each and every document // is not nice to have. Instead the info about that path (and similar data like?) // should be noted at some central component that all document objects etc. know // about and where the app which uses these classes can configure the path to // its needs void KoPADocument::setDefaultStylesResourcePath(const QString& defaultStylesResourcePath) { d->defaultStylesResourcePath = defaultStylesResourcePath; } QString KoPADocument::defaultStylesResourcePath() const { return d->defaultStylesResourcePath; } int KoPADocument::pageCount() const { return d->pages.count(); } void KoPADocument::updatePageCount() { if (resourceManager()->hasResource(KoText::InlineTextObjectManager)) { QVariant var = resourceManager()->resource(KoText::InlineTextObjectManager); KoInlineTextObjectManager *om = var.value(); om->setProperty( KoInlineObject::PageCount, pageCount() ); } } void KoPADocument::updateDocumentURL() { if (resourceManager()->hasResource(KoText::InlineTextObjectManager)) { QVariant var = resourceManager()->resource(KoText::InlineTextObjectManager); KoInlineTextObjectManager *om = var.value(); om->setProperty(KoInlineObject::DocumentURL, url().url(QUrl::PreferLocalFile)); } } void KoPADocument::setShowPageMargins(bool state) { d->showPageMargins = state; } bool KoPADocument::showPageMargins() const { return d->showPageMargins; } diff --git a/libs/pageapp/KoPADocument.h b/libs/pageapp/KoPADocument.h index 5aab038ef7f..e9e2c31172b 100644 --- a/libs/pageapp/KoPADocument.h +++ b/libs/pageapp/KoPADocument.h @@ -1,364 +1,364 @@ /* This file is part of the KDE project Copyright (C) 2006-2010 Thorsten Zachmann This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KOPADOCUMENT_H #define KOPADOCUMENT_H #include #include #include #include "KoPageApp.h" #include "kopageapp_export.h" class KoPAPage; class KoPAPageBase; class KoPAMasterPage; class KoPALoadingContext; class KoPASavingContext; class KoInlineTextObjectManager; /// Document class that stores KoPAPage and KoPAMasterPage objects class KOPAGEAPP_EXPORT KoPADocument : public KoDocument, public KoShapeBasedDocumentBase { Q_OBJECT public: explicit KoPADocument(KoPart *part); virtual ~KoPADocument(); QPixmap generatePreview(const QSize& size); void paintContent( QPainter &painter, const QRect &rect); bool loadXML( const KoXmlDocument & doc, KoStore *store ); bool loadOdf( KoOdfReadStore & odfStore ); bool saveOdf( SavingContext & documentContext ); /** * The tag the body is saved in */ virtual const char *odfTagName( bool withNamespace ) = 0; /** * Load master pages * * @param masterStyles * @param context */ QList loadOdfMasterPages( const QHash masterStyles, KoPALoadingContext & context ); /** * Save pages * * This is used by saveOdf and for copy and paste of pages. * * For all pages that are specified also the master slide has to be specified. */ bool saveOdfPages( KoPASavingContext & paContext, QList &pages, QList &masterPages ); /** * Save document styles */ virtual void saveOdfDocumentStyles( KoPASavingContext & context ); /** * Load document styles */ virtual bool loadOdfDocumentStyles( KoPALoadingContext & context ); /** * Get page by index. * * @param index of the page * @param masterPage if true return a masterPage, if false a normal page */ KoPAPageBase* pageByIndex( int index, bool masterPage ) const; /// reimplemnted virtual int pageCount() const; /** * Get the index of the page * * @param page The page you want to get the index for * * @return The index of the page or -1 if the page is not found */ int pageIndex( KoPAPageBase * page ) const; /** * Get page by navigation * * @param currentPage the current page * @param pageNavigation how to navigate from the current page * * @return the page which is reached by pageNavigation */ KoPAPageBase* pageByNavigation( KoPAPageBase * currentPage, KoPageApp::PageNavigation pageNavigation ) const; /** * Insert page to the document at index * * The function checks if it is a normal or a master page and puts it in * the correct list. * * @param page to insert to document * @param index where the page will be inserted. */ void insertPage( KoPAPageBase* page, int index ); /** * Insert @p page to the document after page @p before * * The function checks if it is a normal or a master page and puts it in * the correct list. * * @param page to insert to document * @param after the page which the inserted page should come after. Set after to 0 to add at the beginning */ void insertPage( KoPAPageBase* page, KoPAPageBase* after ); /** * Take @page from the page * * @param page taken from the document * @return the position of the page was taken from the document, or -1 if the page was not found */ int takePage( KoPAPageBase *page ); /** * Remove the page from the document * * This generates the command and adds the command that deletes the page * * @param page The page that gets removed */ virtual void removePage( KoPAPageBase * page ); /** * Remove the given pages from the document * * This generates the command and adds the command that deletes the pages * * @param pages The list of pages that gets removed */ virtual void removePages(QList &pages); void addShape( KoShape *shape ); void removeShape( KoShape* shape ); QList pages( bool masterPages = false ) const; /** * Get a new page for inserting into the document * * The page is created with new. * * Reimplement when you need a derived class in your kopageapplication */ virtual KoPAPage *newPage(KoPAMasterPage *masterPage); /** * Get a new master page for inserting into the document * * The page is created with new. * * Reimplement when you need a derived class in your kopageapplication */ virtual KoPAMasterPage * newMasterPage(); /** * Get the type of the document */ virtual KoOdf::DocumentType documentType() const = 0; /// return the inlineTextObjectManager for this document. KoInlineTextObjectManager *inlineTextObjectManager() const; void setRulersVisible(bool visible); bool rulersVisible() const; /** * Get the page on which the shape is located * * @param shape The shape for which the page should be found * @return The page on which the shape is located */ KoPAPageBase * pageByShape( KoShape * shape ) const; /** * Get the page type used in the document * * The default page type KoPageApp::Page is returned */ virtual KoPageApp::PageType pageType() const; /** * Get the thumbnail for the page. * * Use this method instead the one in the pages directly */ QPixmap pageThumbnail(KoPAPageBase* page, const QSize& size); QImage pageThumbImage(KoPAPageBase* page, const QSize& size); void emitUpdate(KoPAPageBase *page) {emit update(page);} /** * Sets where "defaultstyles.xml" can be found in the "data" locations. * Needs to be set before the document is loaded. * @param defaultStylesResourcePath the relative path from the data locations */ void setDefaultStylesResourcePath(const QString &defaultStylesResourcePath); QString defaultStylesResourcePath() const; void setShowPageMargins(bool state); bool showPageMargins() const; public Q_SLOTS: /// reimplemented virtual void initEmpty(); Q_SIGNALS: void shapeAdded(KoShape* shape); void shapeRemoved(KoShape* shape); void pageAdded(KoPAPageBase* page); /// This is a general signal to tell you a page was removed - void pageRemoved(KoPAPageBase* page); + void pageRemoved(KoPAPageBase* page, int index = -1); /// when page is removed this signal indicates you should replace it if it was active void replaceActivePage(KoPAPageBase *page, KoPAPageBase *newActivePage); /** * Update all views this document is displayed on * * @param page specify a page to be updated, all views with this page as active page will be updated. */ void update(KoPAPageBase *page); /** * @brief Tells if an action is possible or not * * The actions are of Type KoPAAction * * @param actions bitwise or of which actions should be enabled/disabled * @param possible new state of the actions */ void actionsPossible(int actions, bool enable); protected: /** * Load the presentation declaration * * The default implementation is empty */ virtual bool loadOdfProlog( const KoXmlElement & body, KoPALoadingContext & context ); /** * Load the epilogue * * The default implementation is empty */ virtual bool loadOdfEpilogue( const KoXmlElement & body, KoPALoadingContext & context ); /** * Save the prologue * * The default implementation is empty */ virtual bool saveOdfProlog( KoPASavingContext & paContext ); /** * Save the epilogue * * The default implementation is empty */ virtual bool saveOdfEpilogue( KoPASavingContext & paContext ); /** * Save settings */ bool saveOdfSettings( KoStore * store ); /** * Load settings */ void loadOdfSettings( const KoXmlDocument & settingsDoc ); /** * This function is called by at the end of addShape. This is used * e.g. for doing work on the application which is in the KoShapeAppData. * * The default implementation does nothing */ virtual void postAddShape( KoPAPageBase * page, KoShape * shape ); /** * This function is called by at the end of removeShape. This is used * e.g. for doing work on the application which is in the KoShapeAppData. * * The default implementation does nothing */ virtual void postRemoveShape( KoPAPageBase * page, KoShape * shape ); /** * This function is called with the command that will remove the page * given. * The default implementation is empty. * * @param page The page that will be removed * @param parent The command that will be used to delete the page */ virtual void pageRemoved( KoPAPageBase * page, KUndo2Command * parent ); /// Load the configuration void loadConfig(); /// Save the configuration void saveConfig(); /// set the page count so it gets shown correctly in variables void updatePageCount(); /// set the url so it gets shown correctly in variables void updateDocumentURL(); virtual void setupOpenFileSubProgress(); private: friend class KoPAPastePage; /** * Load pages * * @param body * @param context */ QList loadOdfPages( const KoXmlElement & body, KoPALoadingContext & context ); private: class Private; Private * const d; }; #endif /* KOPADOCUMENT_H */ diff --git a/libs/pageapp/KoPAView.cpp b/libs/pageapp/KoPAView.cpp index 9e0c7bae7c0..e537921a202 100644 --- a/libs/pageapp/KoPAView.cpp +++ b/libs/pageapp/KoPAView.cpp @@ -1,1304 +1,1315 @@ /* This file is part of the KDE project Copyright (C) 2006-2009 Thorsten Zachmann Copyright (C) 2007 Thomas Zander Copyright (C) 2009 Inge Wallin Copyright (C) 2010 Boudewijn Rempt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KoPAView.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "KoPADocumentStructureDocker.h" #include "KoShapeTraversal.h" #include "KoPACanvas.h" #include "KoPADocument.h" #include "KoPAPage.h" #include "KoPAMasterPage.h" #include "KoPAViewModeNormal.h" #include "KoPAOdfPageSaveHelper.h" #include "KoPAPastePage.h" #include "KoPAPrintJob.h" #include "commands/KoPAPageInsertCommand.h" #include "commands/KoPAChangeMasterPageCommand.h" #include "dialogs/KoPAMasterPageDialog.h" #include "dialogs/KoPAPageLayoutDialog.h" #include "dialogs/KoPAConfigureDialog.h" #include "widgets/KoPageNavigator.h" #include #include #include #include #include #include #include #include #include #include #include #include class Q_DECL_HIDDEN KoPAView::Private { public: Private( KoPADocument *document ) : doc( document ) , canvas( 0 ) , activePage( 0 ) {} ~Private() {} // These were originally private in the .h file KoPADocumentStructureDocker *documentStructureDocker; KoCanvasController *canvasController; KoZoomController *zoomController; KoCopyController *copyController; KoCutController *cutController; QAction *editPaste; QAction *deleteSelectionAction; KToggleAction *actionViewSnapToGrid; KToggleAction *actionViewShowMasterPages; QAction *actionInsertPage; QAction *actionCopyPage; QAction *actionDeletePage; QAction *actionMasterPage; QAction *actionPageLayout; QAction *actionConfigure; KoRuler *horizontalRuler; KoRuler *verticalRuler; KToggleAction *viewRulers; KoZoomAction *zoomAction; KToggleAction *showPageMargins; KoFind *find; KoPAViewMode *viewModeNormal; // This tab bar hidden by default. It could be used to alternate between view modes QTabBar *tabBar; QGridLayout *tabBarLayout; QWidget *insideWidget; // status bar KoPageNavigator *pageNavigator; QLabel *status; ///< ordinary status QWidget *zoomActionWidget; // These used to be protected. KoPADocument *doc; KoPACanvas *canvas; KoPAPageBase *activePage; }; KoPAView::KoPAView(KoPart *part, KoPADocument *document, KoPAFlags withModeBox, QWidget *parent) : KoView(part, document, parent) , d( new Private(document)) { initGUI(withModeBox); initActions(); if ( d->doc->pageCount() > 0 ) doUpdateActivePage( d->doc->pageByIndex( 0, false ) ); setAcceptDrops(true); } KoPAView::~KoPAView() { KoToolManager::instance()->removeCanvasController( d->canvasController ); removeStatusBarItem(d->status); removeStatusBarItem(d->zoomActionWidget); delete d->zoomController; // Delete only the view mode normal, let the derived class delete // the currently active view mode if it is not view mode normal // using a delete here can cause a crash if an object is deleted d->viewModeNormal->deleteLater(); delete d; } void KoPAView::addImages(const QVector &imageList, const QPoint &insertAt) { // get position from event and convert to document coordinates QPointF pos = zoomHandler()->viewToDocument(insertAt) + kopaCanvas()->documentOffset() - kopaCanvas()->documentOrigin(); // create a factory KoShapeFactoryBase *factory = KoShapeRegistry::instance()->value("PictureShape"); if (!factory) { warnPageApp << "No picture shape found, cannot drop images."; return; } foreach(const QImage &image, imageList) { KoProperties params; QVariant v; v.setValue(image); params.setProperty("qimage", v); KoShape *shape = factory->createShape(¶ms, d->doc->resourceManager()); if (!shape) { warnPageApp << "Could not create a shape from the image"; return; } shape->setPosition(pos); pos += QPointF(25,25); // increase the position for each shape we insert so the // user can see them all. KUndo2Command *cmd = kopaCanvas()->shapeController()->addShapeDirect(shape); if (cmd) { KoSelection *selection = kopaCanvas()->shapeManager()->selection(); selection->deselectAll(); selection->select(shape); } kopaCanvas()->addCommand(cmd); } } void KoPAView::initGUI(KoPAFlags flags) { d->tabBarLayout = new QGridLayout(this); d->tabBarLayout->setMargin(0); d->tabBarLayout->setSpacing(0); d->insideWidget = new QWidget(); QGridLayout *gridLayout = new QGridLayout(d->insideWidget); gridLayout->setMargin(0); gridLayout->setSpacing(0); setLayout(d->tabBarLayout); d->canvas = new KoPACanvas( this, d->doc, this ); KoCanvasControllerWidget *canvasController = new KoCanvasControllerWidget( actionCollection(), this ); if (mainWindow()) { // this needs to be done before KoCanvasControllerWidget::setCanvas is called KoPADocumentStructureDockerFactory structureDockerFactory(KoDocumentSectionView::ThumbnailMode, d->doc->pageType()); d->documentStructureDocker = qobject_cast(mainWindow()->createDockWidget(&structureDockerFactory)); connect(d->documentStructureDocker, SIGNAL(pageChanged(KoPAPageBase*)), proxyObject, SLOT(updateActivePage(KoPAPageBase*))); connect(d->documentStructureDocker, SIGNAL(dockerReset()), this, SLOT(reinitDocumentDocker())); } d->canvasController = canvasController; d->canvasController->setCanvas( d->canvas ); KoToolManager::instance()->addController( d->canvasController ); KoToolManager::instance()->registerTools( actionCollection(), d->canvasController ); d->zoomController = new KoZoomController( d->canvasController, zoomHandler(), actionCollection()); connect( d->zoomController, SIGNAL(zoomChanged(KoZoomMode::Mode,qreal)), this, SLOT(slotZoomChanged(KoZoomMode::Mode,qreal)) ); d->zoomAction = d->zoomController->zoomAction(); // page/slide navigator d->pageNavigator = new KoPageNavigator(this); addStatusBarItem(d->pageNavigator, 0); // set up status bar message d->status = new QLabel(QString(), this); d->status->setAlignment( Qt::AlignLeft | Qt::AlignVCenter ); d->status->setMinimumWidth( 300 ); addStatusBarItem( d->status, 1 ); connect( KoToolManager::instance(), SIGNAL(changedStatusText(QString)), d->status, SLOT(setText(QString)) ); d->zoomActionWidget = d->zoomAction->createWidget( statusBar() ); addStatusBarItem( d->zoomActionWidget, 0 ); d->zoomController->setZoomMode( KoZoomMode::ZOOM_PAGE ); d->viewModeNormal = new KoPAViewModeNormal( this, d->canvas ); setViewMode(d->viewModeNormal); // The rulers d->horizontalRuler = new KoRuler(this, Qt::Horizontal, viewConverter( d->canvas )); d->horizontalRuler->setShowMousePosition(true); d->horizontalRuler->setUnit(d->doc->unit()); d->verticalRuler = new KoRuler(this, Qt::Vertical, viewConverter( d->canvas )); d->verticalRuler->setUnit(d->doc->unit()); d->verticalRuler->setShowMousePosition(true); new KoRulerController(d->horizontalRuler, d->canvas->resourceManager()); connect(d->doc, SIGNAL(unitChanged(KoUnit)), this, SLOT(updateUnit(KoUnit))); //Layout a tab bar d->tabBar = new QTabBar(); d->tabBarLayout->addWidget(d->insideWidget, 1, 1); setTabBarPosition(Qt::Horizontal); gridLayout->addWidget(d->horizontalRuler->tabChooser(), 0, 0); gridLayout->addWidget(d->horizontalRuler, 0, 1); gridLayout->addWidget(d->verticalRuler, 1, 0); gridLayout->addWidget(canvasController, 1, 1); //tab bar is hidden by default a method is provided to access to the tab bar d->tabBar->hide(); connect(d->canvasController->proxyObject, SIGNAL(canvasOffsetXChanged(int)), this, SLOT(pageOffsetChanged())); connect(d->canvasController->proxyObject, SIGNAL(canvasOffsetYChanged(int)), this, SLOT(pageOffsetChanged())); connect(d->canvasController->proxyObject, SIGNAL(sizeChanged(QSize)), this, SLOT(pageOffsetChanged())); connect(d->canvasController->proxyObject, SIGNAL(canvasMousePositionChanged(QPoint)), this, SLOT(updateMousePosition(QPoint))); d->verticalRuler->createGuideToolConnection(d->canvas); d->horizontalRuler->createGuideToolConnection(d->canvas); KoMainWindow *mw = mainWindow(); if (flags & KoPAView::ModeBox) { if (mw) { KoModeBoxFactory modeBoxFactory(canvasController, qApp->applicationName(), i18n("Tools")); QDockWidget* modeBox = mw->createDockWidget(&modeBoxFactory); mw->dockerManager()->removeToolOptionsDocker(); dynamic_cast(modeBox)->setObservedCanvas(d->canvas); } } else { if (mw) { KoToolBoxFactory toolBoxFactory; mw->createDockWidget( &toolBoxFactory ); connect(canvasController, SIGNAL(toolOptionWidgetsChanged(QList>)), mw->dockerManager(), SLOT(newOptionWidgets(QList>))); } } connect(shapeManager(), SIGNAL(selectionChanged()), this, SLOT(selectionChanged())); connect(shapeManager(), SIGNAL(contentChanged()), this, SLOT(updateCanvasSize())); connect(d->doc, SIGNAL(shapeAdded(KoShape*)), this, SLOT(updateCanvasSize())); connect(d->doc, SIGNAL(shapeRemoved(KoShape*)), this, SLOT(updateCanvasSize())); connect(d->doc, SIGNAL(update(KoPAPageBase*)), this, SLOT(pageUpdated(KoPAPageBase*))); connect(d->canvas, SIGNAL(documentSize(QSize)), d->canvasController->proxyObject, SLOT(updateDocumentSize(QSize))); connect(d->canvasController->proxyObject, SIGNAL(moveDocumentOffset(QPoint)), d->canvas, SLOT(slotSetDocumentOffset(QPoint))); connect(d->canvasController->proxyObject, SIGNAL(sizeChanged(QSize)), this, SLOT(updateCanvasSize())); if (mw) { KoToolManager::instance()->requestToolActivation( d->canvasController ); } } void KoPAView::initActions() { QAction *action = actionCollection()->addAction( KStandardAction::Cut, "edit_cut", 0, 0); d->cutController = new KoCutController(kopaCanvas(), action); action = actionCollection()->addAction( KStandardAction::Copy, "edit_copy", 0, 0 ); d->copyController = new KoCopyController(kopaCanvas(), action); d->editPaste = actionCollection()->addAction( KStandardAction::Paste, "edit_paste", proxyObject, SLOT(editPaste()) ); connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(clipboardDataChanged())); connect(d->canvas->toolProxy(), SIGNAL(toolChanged(QString)), this, SLOT(clipboardDataChanged())); clipboardDataChanged(); actionCollection()->addAction(KStandardAction::SelectAll, "edit_select_all", this, SLOT(editSelectAll())); actionCollection()->addAction(KStandardAction::Deselect, "edit_deselect_all", this, SLOT(editDeselectAll())); d->deleteSelectionAction = new QAction(koIcon("edit-delete"), i18n("D&elete"), this); actionCollection()->addAction("edit_delete", d->deleteSelectionAction ); d->deleteSelectionAction->setShortcut(QKeySequence("Del")); d->deleteSelectionAction->setEnabled(false); connect(d->deleteSelectionAction, SIGNAL(triggered()), this, SLOT(editDeleteSelection())); connect(d->canvas->toolProxy(), SIGNAL(selectionChanged(bool)), d->deleteSelectionAction, SLOT(setEnabled(bool))); KToggleAction *showGrid= d->doc->gridData().gridToggleAction(d->canvas); actionCollection()->addAction("view_grid", showGrid ); d->actionViewSnapToGrid = new KToggleAction(i18n("Snap to Grid"), this); d->actionViewSnapToGrid->setChecked(d->doc->gridData().snapToGrid()); actionCollection()->addAction("view_snaptogrid", d->actionViewSnapToGrid); connect( d->actionViewSnapToGrid, SIGNAL(triggered(bool)), this, SLOT(viewSnapToGrid(bool))); KToggleAction *actionViewShowGuides = KoStandardAction::showGuides(this, SLOT(viewGuides(bool)), this); actionViewShowGuides->setChecked( d->doc->guidesData().showGuideLines() ); actionCollection()->addAction(KoStandardAction::name(KoStandardAction::ShowGuides), actionViewShowGuides ); d->actionViewShowMasterPages = new KToggleAction(i18n( "Show Master Pages" ), this ); actionCollection()->addAction( "view_masterpages", d->actionViewShowMasterPages ); connect( d->actionViewShowMasterPages, SIGNAL(triggered(bool)), this, SLOT(setMasterMode(bool)) ); d->viewRulers = new KToggleAction(i18n("Show Rulers"), this); actionCollection()->addAction("view_rulers", d->viewRulers ); d->viewRulers->setToolTip(i18n("Show/hide the view's rulers")); connect(d->viewRulers, SIGNAL(triggered(bool)), proxyObject, SLOT(setShowRulers(bool))); setShowRulers(d->doc->rulersVisible()); d->showPageMargins = new KToggleAction(i18n("Show Page Margins"), this); actionCollection()->addAction("view_page_margins", d->showPageMargins); d->showPageMargins->setToolTip(i18n("Show/hide the page margins")); connect(d->showPageMargins, SIGNAL(toggled(bool)), SLOT(setShowPageMargins(bool))); setShowPageMargins(d->doc->showPageMargins()); d->actionInsertPage = new QAction(koIcon("document-new"), i18n("Insert Page"), this); actionCollection()->addAction( "page_insertpage", d->actionInsertPage ); d->actionInsertPage->setToolTip( i18n( "Insert a new page after the current one" ) ); d->actionInsertPage->setWhatsThis( i18n( "Insert a new page after the current one" ) ); connect( d->actionInsertPage, SIGNAL(triggered()), proxyObject, SLOT(insertPage()) ); d->actionCopyPage = new QAction( i18n( "Copy Page" ), this ); actionCollection()->addAction( "page_copypage", d->actionCopyPage ); d->actionCopyPage->setToolTip( i18n( "Copy the current page" ) ); d->actionCopyPage->setWhatsThis( i18n( "Copy the current page" ) ); connect( d->actionCopyPage, SIGNAL(triggered()), this, SLOT(copyPage()) ); d->actionDeletePage = new QAction( i18n( "Delete Page" ), this ); d->actionDeletePage->setEnabled( d->doc->pageCount() > 1 ); actionCollection()->addAction( "page_deletepage", d->actionDeletePage ); d->actionDeletePage->setToolTip( i18n( "Delete the current page" ) ); d->actionDeletePage->setWhatsThis( i18n( "Delete the current page" ) ); connect( d->actionDeletePage, SIGNAL(triggered()), this, SLOT(deletePage()) ); d->actionMasterPage = new QAction(i18n("Master Page..."), this); actionCollection()->addAction("format_masterpage", d->actionMasterPage); connect(d->actionMasterPage, SIGNAL(triggered()), this, SLOT(formatMasterPage())); d->actionPageLayout = new QAction( i18n( "Page Layout..." ), this ); actionCollection()->addAction( "format_pagelayout", d->actionPageLayout ); connect( d->actionPageLayout, SIGNAL(triggered()), this, SLOT(formatPageLayout()) ); actionCollection()->addAction(KStandardAction::Prior, "page_previous", this, SLOT(goToPreviousPage())); actionCollection()->addAction(KStandardAction::Next, "page_next", this, SLOT(goToNextPage())); actionCollection()->addAction(KStandardAction::FirstPage, "page_first", this, SLOT(goToFirstPage())); actionCollection()->addAction(KStandardAction::LastPage, "page_last", this, SLOT(goToLastPage())); d->pageNavigator->initActions(); KActionMenu *actionMenu = new KActionMenu(i18n("Variable"), this); foreach(QAction *action, d->doc->inlineTextObjectManager()->createInsertVariableActions(d->canvas)) actionMenu->addAction(action); actionCollection()->addAction("insert_variable", actionMenu); QAction * am = new QAction(i18n("Import Document..."), this); actionCollection()->addAction("import_document", am); connect(am, SIGNAL(triggered()), this, SLOT(importDocument())); d->actionConfigure = new QAction(koIcon("configure"), i18n("Configure..."), this); actionCollection()->addAction("configure", d->actionConfigure); connect(d->actionConfigure, SIGNAL(triggered()), this, SLOT(configure())); // not sure why this isn't done through KStandardAction, but since it isn't // we ought to set the MenuRole manually so the item ends up in the appropriate // menu on OS X: d->actionConfigure->setMenuRole(QAction::PreferencesRole); d->find = new KoFind( this, d->canvas->resourceManager(), actionCollection() ); connect( d->find, SIGNAL(findDocumentSetNext(QTextDocument*)), this, SLOT(findDocumentSetNext(QTextDocument*)) ); connect( d->find, SIGNAL(findDocumentSetPrevious(QTextDocument*)), this, SLOT(findDocumentSetPrevious(QTextDocument*)) ); actionCollection()->action( "object_group" )->setShortcut( QKeySequence( "Ctrl+G" ) ); actionCollection()->action( "object_ungroup" )->setShortcut( QKeySequence( "Ctrl+Shift+G" ) ); + + connect(d->doc, &KoPADocument::actionsPossible, this, &KoPAView::setActionEnabled); } +KoCanvasController *KoPAView::canvasController() const +{ + return d->canvasController; +} KoPACanvasBase * KoPAView::kopaCanvas() const { return d->canvas; } KoPADocument * KoPAView::kopaDocument() const { return d->doc; } KoPAPageBase* KoPAView::activePage() const { return d->activePage; } void KoPAView::updateReadWrite( bool readwrite ) { Q_UNUSED(readwrite); } KoRuler* KoPAView::horizontalRuler() { return d->horizontalRuler; } KoRuler* KoPAView::verticalRuler() { return d->verticalRuler; } void KoPAView::setShowPageMargins(bool state) { d->showPageMargins->setChecked(state); d->canvas->setShowPageMargins(state); d->doc->setShowPageMargins(state); } KoZoomController* KoPAView::zoomController() const { return d->zoomController; } KoCopyController* KoPAView::copyController() const { return d->copyController; } KoCutController* KoPAView::cutController() const { return d->cutController; } QAction * KoPAView::deleteSelectionAction() const { return d->deleteSelectionAction; } void KoPAView::importDocument() { QFileDialog *dialog = new QFileDialog( /* QT5TODO: QUrl("kfiledialog:///OpenDialog"),*/ this ); dialog->setObjectName( "file dialog" ); dialog->setFileMode( QFileDialog::AnyFile ); if ( d->doc->pageType() == KoPageApp::Slide ) { dialog->setWindowTitle(i18n("Import Slideshow")); } else { dialog->setWindowTitle(i18n("Import Document")); } // TODO make it possible to select also other supported types (than the default format) here. // this needs to go via the filters to get the file in the correct format. // For now we only support the native mime types QStringList mimeFilter; mimeFilter << KoOdf::mimeType( d->doc->documentType() ) << KoOdf::templateMimeType( d->doc->documentType() ); dialog->setMimeTypeFilters( mimeFilter ); if (dialog->exec() == QDialog::Accepted) { QUrl url(dialog->selectedUrls().first()); QString tmpFile; if ( KIO::NetAccess::download( url, tmpFile, 0 ) ) { QFile file( tmpFile ); file.open( QIODevice::ReadOnly ); QByteArray ba; ba = file.readAll(); // set the correct mime type as otherwise it does not find the correct tag when loading QMimeData data; data.setData( KoOdf::mimeType( d->doc->documentType() ), ba); KoPAPastePage paste( d->doc,d->activePage ); if ( ! paste.paste( d->doc->documentType(), &data ) ) { KMessageBox::error(0, i18n("Could not import\n%1", url.url(QUrl::PreferLocalFile))); } } else { KMessageBox::error(0, i18n("Could not import\n%1", url.url(QUrl::PreferLocalFile))); } } delete dialog; } void KoPAView::viewSnapToGrid(bool snap) { d->doc->gridData().setSnapToGrid(snap); d->actionViewSnapToGrid->setChecked(snap); } void KoPAView::viewGuides(bool show) { d->doc->guidesData().setShowGuideLines(show); d->canvas->update(); } void KoPAView::editPaste() { if ( !d->canvas->toolProxy()->paste() ) { pagePaste(); } } void KoPAView::pagePaste() { const QMimeData * data = QApplication::clipboard()->mimeData(); KoOdf::DocumentType documentTypes[] = { KoOdf::Graphics, KoOdf::Presentation }; for ( unsigned int i = 0; i < sizeof( documentTypes ) / sizeof( KoOdf::DocumentType ); ++i ) { if ( data->hasFormat( KoOdf::mimeType( documentTypes[i] ) ) ) { KoPAPastePage paste( d->doc, d->activePage ); paste.paste( documentTypes[i], data ); break; } } } void KoPAView::editDeleteSelection() { d->canvas->toolProxy()->deleteSelection(); } void KoPAView::editSelectAll() { KoSelection* selection = kopaCanvas()->shapeManager()->selection(); if( !selection ) return; if (!this->isVisible()) { emit selectAllRequested(); return; } QList shapes = activePage()->shapes(); foreach( KoShape *shape, shapes ) { KoShapeLayer *layer = dynamic_cast( shape ); if ( layer ) { QList layerShapes( layer->shapes() ); foreach( KoShape *layerShape, layerShapes ) { selection->select( layerShape ); layerShape->update(); } } } selectionChanged(); } void KoPAView::editDeselectAll() { if (!this->isVisible()) { emit deselectAllRequested(); return; } KoSelection* selection = kopaCanvas()->shapeManager()->selection(); if( selection ) selection->deselectAll(); selectionChanged(); d->canvas->update(); } void KoPAView::formatMasterPage() { KoPAPage *page = dynamic_cast(d->activePage); Q_ASSERT(page); KoPAMasterPageDialog *dialog = new KoPAMasterPageDialog(d->doc, page->masterPage(), d->canvas); if (dialog->exec() == QDialog::Accepted) { KoPAMasterPage *masterPage = dialog->selectedMasterPage(); KoPAPage *page = dynamic_cast(d->activePage); if (page) { KoPAChangeMasterPageCommand * command = new KoPAChangeMasterPageCommand( d->doc, page, masterPage ); d->canvas->addCommand( command ); } } delete dialog; } void KoPAView::formatPageLayout() { const KoPageLayout &pageLayout = viewMode()->activePageLayout(); KoPAPageLayoutDialog dialog( d->doc, pageLayout, d->canvas ); if ( dialog.exec() == QDialog::Accepted ) { KUndo2Command *command = new KUndo2Command( kundo2_i18n( "Change page layout" ) ); viewMode()->changePageLayout( dialog.pageLayout(), dialog.applyToDocument(), command ); d->canvas->addCommand( command ); } } void KoPAView::slotZoomChanged( KoZoomMode::Mode mode, qreal zoom ) { Q_UNUSED(zoom); if (d->activePage) { if (mode == KoZoomMode::ZOOM_PAGE) { const KoPageLayout &layout = viewMode()->activePageLayout(); QRectF pageRect( 0, 0, layout.width, layout.height ); d->canvasController->ensureVisible(d->canvas->viewConverter()->documentToView(pageRect)); } else if (mode == KoZoomMode::ZOOM_WIDTH) { // horizontally center the page const KoPageLayout &layout = viewMode()->activePageLayout(); QRectF pageRect( 0, 0, layout.width, layout.height ); QRect viewRect = d->canvas->viewConverter()->documentToView(pageRect).toRect(); viewRect.translate(d->canvas->documentOrigin()); QRect currentVisible(qMax(0, -d->canvasController->canvasOffsetX()), qMax(0, -d->canvasController->canvasOffsetY()), d->canvasController->visibleWidth(), d->canvasController->visibleHeight()); int horizontalMove = viewRect.center().x() - currentVisible.center().x(); d->canvasController->pan(QPoint(horizontalMove, 0)); } updateCanvasSize(true); } } void KoPAView::configure() +{ + openConfiguration(); + // TODO update canvas +} + +void KoPAView::openConfiguration() { QPointer dialog(new KoPAConfigureDialog(this)); dialog->exec(); delete dialog; - // TODO update canvas } void KoPAView::setMasterMode( bool master ) { viewMode()->setMasterMode( master ); if (mainWindow()) { d->documentStructureDocker->setMasterMode(master); } d->actionMasterPage->setEnabled(!master); QList pages = d->doc->pages( master ); d->actionDeletePage->setEnabled( pages.size() > 1 ); } KoShapeManager* KoPAView::shapeManager() const { return d->canvas->shapeManager(); } KoShapeManager* KoPAView::masterShapeManager() const { return d->canvas->masterShapeManager(); } void KoPAView::reinitDocumentDocker() { if (mainWindow()) { d->documentStructureDocker->setActivePage( d->activePage ); } } void KoPAView::pageUpdated(KoPAPageBase* page) { // if the page was updated its content e.g. master page has been changed. Therefore we need to // set the page again to set the shapes of the new master page and get a repaint. Without this // changing the master page does not update the page. if (d->activePage == page) { doUpdateActivePage(page); } } void KoPAView::updateCanvasSize(bool forceUpdate) { const KoPageLayout &layout = viewMode()->activePageLayout(); QPoint scrollValue(d->canvasController->scrollBarValue()); QSizeF pageSize(layout.width, layout.height); QSizeF viewportSize = d->canvasController->viewportSize(); //calculate size of union page + viewport QSizeF documentMinSize(qMax(zoomHandler()->unzoomItX(viewportSize.width()), layout.width), qMax(zoomHandler()->unzoomItY(viewportSize.height()), layout.height)); // create a rect out of it with origin in tp left of page QRectF documentRect(QPointF((documentMinSize.width() - layout.width) * -0.5, (documentMinSize.height() - layout.height) * -0.5), documentMinSize); // Now make a union with the bounding rect of all shapes // Fetch boundingRect like this as a viewmode might have set other shapes than the page foreach (KoShape *layer, d->canvas->shapeManager()->shapes()) { if (! dynamic_cast(layer)) { documentRect = documentRect.united(layer->boundingRect()); } } QPointF offset = -documentRect.topLeft(); QPoint scrollChange = d->canvas->documentOrigin() - zoomHandler()->documentToView(offset).toPoint(); if (forceUpdate || scrollChange != QPoint(0, 0) || d->zoomController->documentSize() != documentRect.size() || d->zoomController->pageSize() != pageSize) { d->horizontalRuler->setRulerLength(layout.width); d->verticalRuler->setRulerLength(layout.height); d->horizontalRuler->setActiveRange(layout.leftMargin, layout.width - layout.rightMargin); d->verticalRuler->setActiveRange(layout.topMargin, layout.height - layout.bottomMargin); QSizeF documentSize(documentRect.size()); d->canvas->setDocumentOrigin(offset); d->zoomController->setDocumentSize(documentSize); d->canvas->resourceManager()->setResource(KoCanvasResourceManager::PageSize, pageSize); d->canvas->update(); QSize documentPxSize(zoomHandler()->zoomItX(documentRect.width()), zoomHandler()->zoomItY(documentRect.height())); d->canvasController->proxyObject->updateDocumentSize(documentPxSize); // this can trigger a change of the zoom level in "fit to mode" and therefore this needs to be at the end as it calls this function again d->zoomController->setPageSize(pageSize); } } void KoPAView::doUpdateActivePage( KoPAPageBase * page ) { bool pageChanged = page != d->activePage; setActivePage( page ); updateCanvasSize(true); updatePageNavigationActions(); if ( pageChanged ) { proxyObject->emitActivePageChanged(); } pageOffsetChanged(); } void KoPAView::setActivePage( KoPAPageBase* page ) { if ( !page ) return; bool pageChanged = page != d->activePage; shapeManager()->removeAdditional( d->activePage ); d->activePage = page; shapeManager()->addAdditional( d->activePage ); QList shapes = page->shapes(); shapeManager()->setShapes(shapes, KoShapeManager::AddWithoutRepaint); //Make the top most layer active if ( !shapes.isEmpty() ) { KoShapeLayer* layer = dynamic_cast( shapes.last() ); shapeManager()->selection()->setActiveLayer( layer ); } // if the page is not a master page itself set shapes of the master page KoPAPage * paPage = dynamic_cast( page ); if ( paPage ) { KoPAMasterPage * masterPage = paPage->masterPage(); QList masterShapes = masterPage->shapes(); masterShapeManager()->setShapes(masterShapes, KoShapeManager::AddWithoutRepaint); //Make the top most layer active if ( !masterShapes.isEmpty() ) { KoShapeLayer* layer = dynamic_cast( masterShapes.last() ); masterShapeManager()->selection()->setActiveLayer( layer ); } } else { // if the page is a master page no shapes are in the masterShapeManager masterShapeManager()->setShapes( QList() ); } if ( mainWindow() && pageChanged ) { d->documentStructureDocker->setActivePage(d->activePage); proxyObject->emitActivePageChanged(); } // Set the current page number in the canvas resource provider d->canvas->resourceManager()->setResource( KoCanvasResourceManager::CurrentPage, d->doc->pageIndex(d->activePage)+1 ); } void KoPAView::navigatePage( KoPageApp::PageNavigation pageNavigation ) { KoPAPageBase * newPage = d->doc->pageByNavigation( d->activePage, pageNavigation ); if ( newPage != d->activePage ) { proxyObject->updateActivePage( newPage ); } } KoPrintJob * KoPAView::createPrintJob() { return new KoPAPrintJob(this); } void KoPAView::pageOffsetChanged() { QPoint documentOrigin(d->canvas->documentOrigin()); d->horizontalRuler->setOffset(d->canvasController->canvasOffsetX() + documentOrigin.x()); d->verticalRuler->setOffset(d->canvasController->canvasOffsetY() + documentOrigin.y()); } void KoPAView::updateMousePosition(const QPoint& position) { const QPoint canvasOffset( d->canvasController->canvasOffsetX(), d->canvasController->canvasOffsetY() ); const QPoint viewPos = position - d->canvas->documentOrigin() - canvasOffset; d->horizontalRuler->updateMouseCoordinate(viewPos.x()); d->verticalRuler->updateMouseCoordinate(viewPos.y()); // Update the selection borders in the rulers while moving with the mouse if(d->canvas->shapeManager()->selection() && (d->canvas->shapeManager()->selection()->count() > 0)) { QRectF boundingRect = d->canvas->shapeManager()->selection()->boundingRect(); d->horizontalRuler->updateSelectionBorders(boundingRect.x(), boundingRect.right()); d->verticalRuler->updateSelectionBorders(boundingRect.y(), boundingRect.bottom()); } } void KoPAView::selectionChanged() { // Show the borders of the selection in the rulers if(d->canvas->shapeManager()->selection() && (d->canvas->shapeManager()->selection()->count() > 0)) { QRectF boundingRect = d->canvas->shapeManager()->selection()->boundingRect(); d->horizontalRuler->setShowSelectionBorders(true); d->verticalRuler->setShowSelectionBorders(true); d->horizontalRuler->updateSelectionBorders(boundingRect.x(), boundingRect.right()); d->verticalRuler->updateSelectionBorders(boundingRect.y(), boundingRect.bottom()); } else { d->horizontalRuler->setShowSelectionBorders(false); d->verticalRuler->setShowSelectionBorders(false); } } void KoPAView::setShowRulers(bool show) { d->horizontalRuler->setVisible(show); d->verticalRuler->setVisible(show); d->viewRulers->setChecked(show); d->doc->setRulersVisible(show); } void KoPAView::insertPage() { KoPAPageBase * page = 0; if ( viewMode()->masterMode() ) { KoPAMasterPage * masterPage = d->doc->newMasterPage(); masterPage->setBackground(QSharedPointer(new KoColorBackground(Qt::white))); // use the layout of the current active page for the new page KoPageLayout & layout = masterPage->pageLayout(); KoPAMasterPage * activeMasterPage = dynamic_cast( d->activePage ); if ( activeMasterPage ) { layout = activeMasterPage->pageLayout(); } page = masterPage; } else { KoPAPage * activePage = static_cast( d->activePage ); KoPAMasterPage * masterPage = activePage->masterPage(); page = d->doc->newPage( masterPage ); } KoPAPageInsertCommand * command = new KoPAPageInsertCommand( d->doc, page, d->activePage ); d->canvas->addCommand( command ); doUpdateActivePage(page); } void KoPAView::copyPage() { QList pages; pages.append( d->activePage ); KoPAOdfPageSaveHelper saveHelper( d->doc, pages ); KoDrag drag; drag.setOdf( KoOdf::mimeType( d->doc->documentType() ), saveHelper ); drag.addToClipboard(); } void KoPAView::deletePage() { if ( !isMasterUsed( d->activePage ) ) { d->doc->removePage( d->activePage ); } } void KoPAView::setActionEnabled( int actions, bool enable ) { if ( actions & ActionInsertPage ) { d->actionInsertPage->setEnabled( enable ); } if ( actions & ActionCopyPage ) { d->actionCopyPage->setEnabled( enable ); } if ( actions & ActionDeletePage ) { d->actionDeletePage->setEnabled( enable ); } if ( actions & ActionViewShowMasterPages ) { d->actionViewShowMasterPages->setEnabled( enable ); } if ( actions & ActionFormatMasterPage ) { d->actionMasterPage->setEnabled( enable ); } } void KoPAView::setViewMode(KoPAViewMode* mode) { KoPAViewMode* previousViewMode = viewMode(); KoPAViewBase::setViewMode(mode); if (previousViewMode && mode != previousViewMode) { disconnect(d->doc, SIGNAL(shapeAdded(KoShape*)), previousViewMode, SLOT(addShape(KoShape*))); disconnect(d->doc, SIGNAL(shapeRemoved(KoShape*)), previousViewMode, SLOT(removeShape(KoShape*))); } connect(d->doc, SIGNAL(shapeAdded(KoShape*)), mode, SLOT(addShape(KoShape*))); connect(d->doc, SIGNAL(shapeRemoved(KoShape*)), mode, SLOT(removeShape(KoShape*))); } QPixmap KoPAView::pageThumbnail(KoPAPageBase* page, const QSize& size) { return d->doc->pageThumbnail(page, size); } bool KoPAView::exportPageThumbnail( KoPAPageBase * page, const QUrl &url, const QSize& size, const char * format, int quality ) { bool res = false; QPixmap pix = d->doc->pageThumbnail( page, size ); if ( !pix.isNull() ) { // Depending on the desired target size due to rounding // errors during zoom the resulting pixmap *might* be // 1 pixel or 2 pixels wider/higher than desired: we just // remove the additional columns/rows. This can be done // since Stage is leaving a minimal border below/at // the right of the image anyway. if ( size != pix.size() ) { pix = pix.copy( 0, 0, size.width(), size.height() ); } // save the pixmap to the desired file QUrl fileUrl( url ); if ( fileUrl.scheme().isEmpty() ) { fileUrl.setScheme( "file" ); } const bool bLocalFile = fileUrl.isLocalFile(); QTemporaryFile* tmpFile = bLocalFile ? 0 : new QTemporaryFile(); if( bLocalFile || tmpFile->open() ) { QFile file( bLocalFile ? fileUrl.path() : tmpFile->fileName() ); if ( file.open( QIODevice::ReadWrite ) ) { res = pix.save( &file, format, quality ); file.close(); } if ( !bLocalFile ) { if ( res ) { res = KIO::NetAccess::upload( tmpFile->fileName(), fileUrl, this ); } } } if ( !bLocalFile ) { delete tmpFile; } } return res; } KoPADocumentStructureDocker* KoPAView::documentStructureDocker() const { return d->documentStructureDocker; } void KoPAView::clipboardDataChanged() { const QMimeData* data = QApplication::clipboard()->mimeData(); bool paste = false; if (data) { // TODO see if we can use the KoPasteController instead of having to add this feature in each calligra app. QStringList mimeTypes = d->canvas->toolProxy()->supportedPasteMimeTypes(); mimeTypes << KoOdf::mimeType( KoOdf::Graphics ); mimeTypes << KoOdf::mimeType( KoOdf::Presentation ); foreach(const QString & mimeType, mimeTypes) { if ( data->hasFormat( mimeType ) ) { paste = true; break; } } } d->editPaste->setEnabled(paste); } void KoPAView::goToPreviousPage() { navigatePage( KoPageApp::PagePrevious ); } void KoPAView::goToNextPage() { navigatePage( KoPageApp::PageNext ); } void KoPAView::goToFirstPage() { navigatePage( KoPageApp::PageFirst ); } void KoPAView::goToLastPage() { navigatePage( KoPageApp::PageLast ); } void KoPAView::findDocumentSetNext( QTextDocument * document ) { KoPAPageBase * page = 0; KoShape * startShape = 0; KoTextDocumentLayout *lay = document ? qobject_cast(document->documentLayout()) : 0; if ( lay != 0 ) { startShape = lay->shapes().value( 0 ); Q_ASSERT( startShape->shapeId() == "TextShapeID" ); page = d->doc->pageByShape( startShape ); if ( d->doc->pageIndex( page ) == -1 ) { page = 0; } } if ( page == 0 ) { page = d->activePage; startShape = page; } KoShape * shape = startShape; do { // find next text shape shape = KoShapeTraversal::nextShape( shape, "TextShapeID" ); // get next text shape if ( shape != 0 ) { if ( page != d->activePage ) { setActivePage( page ); d->canvas->update(); } KoSelection* selection = kopaCanvas()->shapeManager()->selection(); selection->deselectAll(); selection->select( shape ); // TODO can this be done nicer? is there a way to get the shape id and the tool id from the shape? KoToolManager::instance()->switchToolRequested( "TextToolFactory_ID" ); break; } else { //if none is found go to next page and try again if ( d->doc->pageIndex( page ) < d->doc->pages().size() - 1 ) { // TODO use also master slides page = d->doc->pageByNavigation( page, KoPageApp::PageNext ); } else { page = d->doc->pageByNavigation( page, KoPageApp::PageFirst ); } shape = page; } // do until you find the same start shape or you are on the same page again only if there was none } while ( page != startShape ); } void KoPAView::findDocumentSetPrevious( QTextDocument * document ) { KoPAPageBase * page = 0; KoShape * startShape = 0; KoTextDocumentLayout *lay = document ? qobject_cast(document->documentLayout()) : 0; if ( lay != 0 ) { startShape = lay->shapes().value( 0 ); Q_ASSERT( startShape->shapeId() == "TextShapeID" ); page = d->doc->pageByShape( startShape ); if ( d->doc->pageIndex( page ) == -1 ) { page = 0; } } bool check = false; if ( page == 0 ) { page = d->activePage; startShape = KoShapeTraversal::last( page ); check = true; } KoShape * shape = startShape; do { if ( !check || shape->shapeId() != "TextShapeID" ) { shape = KoShapeTraversal::previousShape( shape, "TextShapeID" ); } // get next text shape if ( shape != 0 ) { if ( page != d->activePage ) { setActivePage( page ); d->canvas->update(); } KoSelection* selection = kopaCanvas()->shapeManager()->selection(); selection->deselectAll(); selection->select( shape ); // TODO can this be done nicer? is there a way to get the shape id and the tool id from the shape? KoToolManager::instance()->switchToolRequested( "TextToolFactory_ID" ); break; } else { //if none is found go to next page and try again if ( d->doc->pageIndex( page ) > 0 ) { // TODO use also master slides page = d->doc->pageByNavigation( page, KoPageApp::PagePrevious ); } else { page = d->doc->pageByNavigation( page, KoPageApp::PageLast ); } shape = KoShapeTraversal::last( page ); check = true; } // do until you find the same start shape or you are on the same page again only if there was none } while ( shape != startShape ); } void KoPAView::updatePageNavigationActions() { int index = d->doc->pageIndex(activePage()); int pageCount = d->doc->pages(viewMode()->masterMode()).count(); actionCollection()->action("page_previous")->setEnabled(index > 0); actionCollection()->action("page_first")->setEnabled(index > 0); actionCollection()->action("page_next")->setEnabled(index < pageCount - 1); actionCollection()->action("page_last")->setEnabled(index < pageCount - 1); } bool KoPAView::isMasterUsed( KoPAPageBase * page ) { KoPAMasterPage * master = dynamic_cast( page ); bool used = false; if ( master ) { QList pages = d->doc->pages(); foreach( KoPAPageBase * page, pages ) { KoPAPage * p = dynamic_cast( page ); Q_ASSERT( p ); if ( p && p->masterPage() == master ) { used = true; break; } } } return used; } void KoPAView::centerPage() { KoPageLayout &layout = d->activePage->pageLayout(); QSizeF pageSize( layout.width, layout.height ); QPoint documentCenter = zoomHandler()->documentToView(QPoint(pageSize.width(), pageSize.height())).toPoint(); d->canvasController->setPreferredCenter(documentCenter); d->canvasController->recenterPreferred(); } QTabBar *KoPAView::tabBar() const { return d->tabBar; } void KoPAView::replaceCentralWidget(QWidget *newWidget) { // hide standard central widget d->insideWidget->hide(); // If there is already a custom central widget, it's hided and removed from the layout hideCustomCentralWidget(); // layout and show new custom widget d->tabBarLayout->addWidget(newWidget, 2, 1); newWidget->show(); } void KoPAView::restoreCentralWidget() { //hide custom central widget hideCustomCentralWidget(); //show standard central widget d->insideWidget->show(); } void KoPAView::hideCustomCentralWidget() { if (d->tabBarLayout->itemAtPosition(2, 1)) { if (d->tabBarLayout->itemAtPosition(2, 1)->widget()) { d->tabBarLayout->itemAtPosition(2, 1)->widget()->hide(); } d->tabBarLayout->removeItem(d->tabBarLayout->itemAtPosition(2, 1)); } } void KoPAView::setTabBarPosition(Qt::Orientation orientation) { switch (orientation) { case Qt::Horizontal: d->tabBarLayout->removeWidget(d->tabBar); d->tabBar->setShape(QTabBar::RoundedNorth); d->tabBarLayout->addWidget(d->tabBar, 0, 1); break; case Qt::Vertical: d->tabBarLayout->removeWidget(d->tabBar); d->tabBar->setShape(QTabBar::RoundedWest); d->tabBarLayout->addWidget(d->tabBar, 1, 0, 2, 1, Qt::AlignTop); break; default: break; } } void KoPAView::updateUnit(const KoUnit &unit) { d->horizontalRuler->setUnit(unit); d->verticalRuler->setUnit(unit); d->canvas->resourceManager()->setResource(KoCanvasResourceManager::Unit, unit); } diff --git a/libs/pageapp/KoPAView.h b/libs/pageapp/KoPAView.h index 2617c9230cf..2eaf2773672 100644 --- a/libs/pageapp/KoPAView.h +++ b/libs/pageapp/KoPAView.h @@ -1,305 +1,310 @@ /* This file is part of the KDE project Copyright (C) 2006-2009 Thorsten Zachmann Copyright (C) 2009 Inge Wallin This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KOPAVIEW_H #define KOPAVIEW_H #include "KoPAViewBase.h" #include "KoPageApp.h" #include "kopageapp_export.h" #include #include class KoPart; class KoPACanvasBase; class KoPADocument; class KoPAPageBase; class KoPAViewMode; class KoPADocumentStructureDocker; class KoRuler; class KoShapeManager; class KoZoomController; class QUrl; class QAction; class QTextDocument; class QTabBar; class KoCopyController; class KoCutController; +class KoCanvasController; /// Creates a view with a KoPACanvasBase and rulers class KOPAGEAPP_EXPORT KoPAView : public KoView, public KoPAViewBase { Q_OBJECT public: enum KoPAAction { ActionInsertPage = 1, ActionCopyPage = 2, ActionDeletePage = 4, ActionViewShowMasterPages = 8, ActionFormatMasterPage = 16, AllActions = 0xFF }; enum KoPAFlags { NormalMode =1, ModeBox = 2 }; /** * Constructor * @param document the document of this view * @param parent the parent widget */ explicit KoPAView(KoPart *part, KoPADocument *document, KoPAFlags withModeBox, QWidget *parent); virtual ~KoPAView(); // KoPAViewBase/KoView overrides void addImages(const QVector &imageList, const QPoint &insertAt); KoZoomController* zoomController() const; KoCopyController* copyController() const; KoCutController* cutController() const; QAction * deleteSelectionAction() const; void updateReadWrite( bool readwrite ); KoRuler *horizontalRuler(); KoRuler *verticalRuler(); + KoCanvasController *canvasController() const; /// @return the canvas for the application KoPACanvasBase * kopaCanvas() const; /// @return the document for the application KoPADocument * kopaDocument() const; /// @return Page that is shown in the canvas KoPAPageBase* activePage() const; /// Set page shown in the canvas to @p page void setActivePage( KoPAPageBase * page ); void navigatePage( KoPageApp::PageNavigation pageNavigation ); /// @return the shape manager used for this view KoShapeManager* shapeManager() const; /// @return the master shape manager used for this view KoShapeManager* masterShapeManager() const; - /** - * @brief Enables/Disables the given actions - * - * The actions are of Type KoPAAction - * - * @param actions which should be enabled/disabled - * @param enable new state of the actions - */ - void setActionEnabled( int actions, bool enable ); - /** * @brief Set the view mode * * @param mode the new view mode */ void setViewMode( KoPAViewMode* mode ); /** * Set the active page and updates the UI */ void doUpdateActivePage( KoPAPageBase * page ); /** * Paste the page if everything is ok */ void pagePaste(); /// reimplemented virtual KoPrintJob * createPrintJob(); /** * Get the thumbnail for the page. * * Us this method instead the on in the pages directly */ QPixmap pageThumbnail(KoPAPageBase* page, const QSize& size); /** * Save thumbnail to an image file. * * Export a thumbnail to disk using a pixmap file like e.g. PNG * This method uses a QPixmap::save() call. * * @param page page to get thumbnail of * @param url the url of the image file to be created * @param size the desired image size in px * @param format the format of the image file (see QPixmap::save()) * @param quality the quality of the image in [0,100] or -1 to use default (see QPixmap::save()) * * @returns whether the image was successfully saved */ bool exportPageThumbnail( KoPAPageBase * page, const QUrl &url, const QSize& size = QSize( 512, 512 ), const char * format = 0, int quality = -1 ); /// Update page navigation actions void updatePageNavigationActions(); /// Shows/hides the rulers void setShowRulers(bool show); /// Insert a new page after the current one void insertPage(); void centerPage(); /// return a pointer to the tab bar (horizontal by default) QTabBar *tabBar() const; /// set view Tab Bar position (vertical / horizontal) void setTabBarPosition(Qt::Orientation orientation); /// Show a custom central widget and hides the standard one. void replaceCentralWidget(QWidget *newWidget); /// hides any custom central widget and shows the standard widget. void restoreCentralWidget(); Q_SIGNALS: /// emitted when select All action is triggered and the view is not visible void selectAllRequested(); /// emitted when deselect All action is triggered and the view is not visible void deselectAllRequested(); protected: /// creates the widgets (called from the constructor) void initGUI(KoPAFlags flags); /// creates the actions (called from the constructor) void initActions(); /// Returns the document structure docker KoPADocumentStructureDocker* documentStructureDocker() const; bool isMasterUsed( KoPAPageBase * page ); void editPaste(); void hideCustomCentralWidget(); public Q_SLOTS: + /** + * @brief Enables/Disables the given actions + * + * The actions are of Type KoPAAction + * + * @param actions which should be enabled/disabled + * @param enable new state of the actions + */ + void setActionEnabled( int actions, bool enable ); /// Copy Page void copyPage(); /// Delete the current page void deletePage(); /// Make sure the canvas size matches the content void updateCanvasSize(bool forceUpdate = false); /// Show/hide page margins void setShowPageMargins(bool state); protected Q_SLOTS: void pageUpdated(KoPAPageBase* page); void viewSnapToGrid(bool snap); void viewGuides(bool show); void slotZoomChanged( KoZoomMode::Mode mode, qreal zoom ); void editDeleteSelection(); void editSelectAll(); void editDeselectAll(); void formatMasterPage(); void formatPageLayout(); /// Change the current view mode to work on master pages void setMasterMode( bool master ); // update the rulers void pageOffsetChanged(); /// Called when the mouse position changes on the canvas virtual void updateMousePosition(const QPoint& position); /// Called when the selection changed virtual void selectionChanged(); /// Called when the clipboard changed virtual void clipboardDataChanged(); /// Go to the previous page void goToPreviousPage(); /// Go to the next page void goToNextPage(); /// Go to the first page void goToFirstPage(); /// Go to the last page void goToLastPage(); /** * Set the next document that should be used in find * * @param document The current document */ void findDocumentSetNext( QTextDocument * document ); /** * Set the previous document that should be used in find * * @param document The current document */ void findDocumentSetPrevious( QTextDocument * document ); /** * Re-initialize the document structure docker after active document in this * view has been changed */ void reinitDocumentDocker(); /** * Import slideshow */ void importDocument(); /** * Configure kopapage apps */ void configure(); /** * This is called when the unit of the document changes */ void updateUnit(const KoUnit &unit); +protected: + /// Re-implement this if you need special configuration control + virtual void openConfiguration(); + private: class Private; Private * const d; }; #endif /* KOPAVIEW_H */ diff --git a/libs/pageapp/widgets/KoPageNavigator.cpp b/libs/pageapp/widgets/KoPageNavigator.cpp index 60c42aac0c9..1d0c4c9ecbe 100644 --- a/libs/pageapp/widgets/KoPageNavigator.cpp +++ b/libs/pageapp/widgets/KoPageNavigator.cpp @@ -1,257 +1,274 @@ /* This file is part of the Calligra project, made within the KDE community. * * Copyright 2012 Friedrich W. H. Kossebau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KoPageNavigator.h" #include "KoPageNavigatorButton_p.h" #include #include #include #include // KF5 #include #include // Qt #include #include #include #include #include #include #include static const int maxPageCountPattern = 999; class KoPageNavigator::Private { public: explicit Private(KoPAView *_view) : view(_view) {} // normal display QLabel* displayLabel; // interactive state KoPageNavigatorButton *gotoFirstPageButton; KoPageNavigatorButton *gotoPreviousPageButton; KoPageNavigatorButton *gotoNextPageButton; KoPageNavigatorButton *gotoLastPageButton; QLineEdit *pageNumberEdit; QIntValidator *pageNumberEditValidator; KoPAView *view; }; static QString displayText(bool isMaster, bool isSlideType, int pageNumber, int pageCount) { return isSlideType ? (isMaster ? i18n("Master Slide %1/%2", pageNumber, pageCount) : i18n("Slide %1/%2", pageNumber, pageCount)) : (isMaster ? i18n("Master Page %1/%2", pageNumber, pageCount) : i18n("Page %1/%2", pageNumber, pageCount)); } KoPageNavigator::KoPageNavigator(KoPAView *view) : QStackedWidget(view) , d(new Private(view)) { const bool isSlideType = (d->view->kopaDocument()->pageType() == KoPageApp::Slide); #ifdef Q_WS_MAC setAttribute(Qt::WA_MacMiniSize, true); #endif // normal display d->displayLabel = new QLabel(this); d->displayLabel->setAlignment(Qt::AlignCenter | Qt::AlignVCenter); addWidget(d->displayLabel); // add interactive variant QWidget* controlWidget = new QWidget(this); QHBoxLayout* layout = new QHBoxLayout(controlWidget); layout->setSpacing(0); layout->setMargin(0); // the original go-*-view-page icons as set for the actions are not reused, // because they look too complex, at least with the Oxygen icons // also installing an event filter for all buttons, to get wheel events even // for disabled buttons d->gotoFirstPageButton = new KoPageNavigatorButton(koIconNameCStr("go-first-view"), this); d->gotoFirstPageButton->installEventFilter(this); d->gotoPreviousPageButton = new KoPageNavigatorButton(koIconNameCStr("go-previous-view"), this); d->gotoPreviousPageButton->installEventFilter(this); d->gotoNextPageButton = new KoPageNavigatorButton(koIconNameCStr("go-next-view"), this); d->gotoNextPageButton->installEventFilter(this); d->gotoLastPageButton = new KoPageNavigatorButton(koIconNameCStr("go-last-view"), this); d->gotoLastPageButton->installEventFilter(this); d->pageNumberEdit = new QLineEdit(this); d->pageNumberEdit->installEventFilter(this); d->pageNumberEditValidator = new QIntValidator(d->pageNumberEdit); d->pageNumberEditValidator->setBottom(1); d->pageNumberEdit->setValidator(d->pageNumberEditValidator); d->pageNumberEdit->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); connect(d->pageNumberEdit, SIGNAL(returnPressed()), SLOT(onPageNumberEntered())); layout->addWidget(d->gotoFirstPageButton); layout->addWidget(d->gotoPreviousPageButton); layout->addWidget(d->pageNumberEdit); layout->addWidget(d->gotoNextPageButton); layout->addWidget(d->gotoLastPageButton); addWidget(controlWidget); KoPADocument *const kopaDocument = d->view->kopaDocument(); connect(kopaDocument, SIGNAL(pageAdded(KoPAPageBase*)), SLOT(updateDisplayLabel())); - connect(kopaDocument, SIGNAL(pageRemoved(KoPAPageBase*)), SLOT(updateDisplayLabel())); + connect(kopaDocument, SIGNAL(pageRemoved(KoPAPageBase*,int)), SLOT(slotPageRemoved(KoPAPageBase*,int))); connect(d->view->proxyObject, SIGNAL(activePageChanged()), SLOT(updateDisplayLabel())); // Fix width by the largest needed QFontMetrics fontMetrics(font()); d->pageNumberEdit->setMinimumWidth(fontMetrics.width(QString::number(maxPageCountPattern*10))); //one more const int editWidth = widget(Edit)->minimumWidth(); const int normalWidth = fontMetrics.width(displayText(false, isSlideType, maxPageCountPattern, maxPageCountPattern)); const int masterWidth = fontMetrics.width(displayText(true, isSlideType, maxPageCountPattern, maxPageCountPattern)); setFixedWidth(qMax(editWidth, qMax(normalWidth, masterWidth))); updateDisplayLabel(); } KoPageNavigator::~KoPageNavigator() { delete d; } void KoPageNavigator::initActions() { KActionCollection *actionCollection = d->view->actionCollection(); d->gotoFirstPageButton->setAction(actionCollection->action(QLatin1String("page_first"))); d->gotoPreviousPageButton->setAction(actionCollection->action(QLatin1String("page_previous"))); d->gotoNextPageButton->setAction(actionCollection->action(QLatin1String("page_next"))); d->gotoLastPageButton->setAction(actionCollection->action(QLatin1String("page_last"))); } void KoPageNavigator::enterEvent(QEvent *event) { Q_UNUSED(event); setCurrentIndex(Edit); } void KoPageNavigator::leaveEvent(QEvent *event) { Q_UNUSED(event); if (! d->pageNumberEdit->hasFocus()) { setCurrentIndex(Display); } } bool KoPageNavigator::eventFilter(QObject *watched, QEvent *event) { if (event->type() == QEvent::FocusOut && watched == d->pageNumberEdit) { if (! underMouse()) { setCurrentIndex(Display); } // reset editor in any case KoPADocument *const kopaDocument = d->view->kopaDocument(); KoPAPageBase *const activePage = d->view->activePage(); const int pageNumber = kopaDocument->pageIndex(activePage) + 1; const QString text = (pageNumber > 0) ? QString::number(pageNumber) : QString(); d->pageNumberEdit->setText(text); } else if (event->type() == QEvent::Wheel) { // Scroll the pages by the wheel // Because the numbers are representatives of the actual pages // and the list of pages is ordered by smaller number first, // here an increasing delta means going up in the list, so go to // smaller page numbers, and vice versa. QWheelEvent *wheelEvent = static_cast(event); const int delta = wheelEvent->delta(); // trigger the respective actions if (delta > 0) { QAction *gotoPreviousPageAction = d->gotoPreviousPageButton->action(); if (gotoPreviousPageAction->isEnabled()) { gotoPreviousPageAction->activate(QAction::Trigger); } } else if (delta < 0) { QAction *gotoNextPageAction = d->gotoNextPageButton->action(); if (gotoNextPageAction->isEnabled()) { gotoNextPageAction->activate(QAction::Trigger); } } // scroll wheel events also cancel the editing, // so move focus out of the pageNumberEdit if (d->pageNumberEdit->hasFocus()) { d->view->setFocus(); } } return false; } void KoPageNavigator::updateDisplayLabel() { KoPADocument *const kopaDocument = d->view->kopaDocument(); KoPAPageBase *const activePage = d->view->activePage(); const int pageNumber = kopaDocument->pageIndex(activePage) + 1; if (pageNumber > 0) { const bool isMasterPage = (dynamic_cast(activePage) == 0); const int pageCount = d->view->kopaDocument()->pages(isMasterPage).size(); const bool isSlideType = (d->view->kopaDocument()->pageType() == KoPageApp::Slide); d->displayLabel->setText(displayText(isMasterPage, isSlideType, pageNumber, pageCount)); d->pageNumberEdit->setText(QString::number(pageNumber)); d->pageNumberEditValidator->setTop(pageCount); } // also leave the editor if in it if (d->pageNumberEdit->hasFocus()) { d->view->setFocus(); } } void KoPageNavigator::onPageNumberEntered() { const int pageNumber = d->pageNumberEdit->text().toInt(); KoPADocument *const kopaDocument = d->view->kopaDocument(); KoPAPageBase *const activePage = d->view->activePage(); const bool isMasterPage = (dynamic_cast(activePage) == 0); const QList pages = kopaDocument->pages(isMasterPage); KoPAPageBase* newPage = pages.value(pageNumber-1); if (newPage) { d->view->proxyObject->updateActivePage(newPage); } } + +void KoPageNavigator::slotPageRemoved(KoPAPageBase *page, int index) +{ + KoPAPageBase *const activePage = d->view->activePage(); + if (page != activePage) { + updateDisplayLabel(); + } else { + KoPADocument *const kopaDocument = d->view->kopaDocument(); + const int pageNumber = index == 0 ? 0 : index - 1; + KoPAPageBase* newPage = kopaDocument->pages().value(pageNumber); + if (newPage && d->view->proxyObject) { + d->view->proxyObject->updateActivePage(newPage); + } else { + updateDisplayLabel(); + } + } +} diff --git a/libs/pageapp/widgets/KoPageNavigator.h b/libs/pageapp/widgets/KoPageNavigator.h index 80db5bd905c..9b81c1fae99 100644 --- a/libs/pageapp/widgets/KoPageNavigator.h +++ b/libs/pageapp/widgets/KoPageNavigator.h @@ -1,56 +1,58 @@ /* This file is part of the Calligra project, made within the KDE community. * * Copyright 2012 Friedrich W. H. Kossebau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KOPAGENAVIGATOR_H #define KOPAGENAVIGATOR_H // Qt #include class KoPAView; +class KoPAPageBase; class KoPageNavigator : public QStackedWidget { Q_OBJECT enum State {Display = 0, Edit = 1}; public: explicit KoPageNavigator(KoPAView *view); virtual ~KoPageNavigator(); void initActions(); protected: virtual void enterEvent(QEvent *event); virtual void leaveEvent(QEvent *event); virtual bool eventFilter(QObject *watched, QEvent *event); private Q_SLOTS: void updateDisplayLabel(); void onPageNumberEntered(); + void slotPageRemoved(KoPAPageBase *page, int index); private: class Private; Private *const d; }; #endif //KOPAGENAVIGATOR_H