View Issue Details

IDProjectCategoryView StatusLast Update
0010560ScribusScripterpublic2014-08-20 23:35
Reportergpittman Assigned Toplinnell 
PrioritynormalSeverityfeatureReproducibilityN/A
Status closedResolutionfixed 
Product Version1.4.1.svn 
Fixed in Version1.5.0svn 
Summary0010560: two new Scripter commands: copyObject() and pasteObject()
DescriptionThese two new commands represent a simple splitting of the functions already contained in duplicateObject(), so that one can first copy an object to the clipboard, then later in a script paste.
What this allows for is switching pages between copying and pasting, and first copying then pasting to multiple pages.
Additional InformationThe uploaded file contains the necessary modified files for the scripter plugin, and also the appropriate documentation page to go into doc/en/

I have also made a script using these commands, and created a wiki page:

http://wiki.scribus.net/canvas/CopyObject%28%29_and_pasteObject%28%29

to illustrate its usage. I plan to develop the script to be more flexible, such as being able specify specific pages to paste to.

Incidentally, the original duplicateObject() command does NOT work for a selected group.
TagsNo tags attached.
Patch

Activities

gpittman

2012-01-31 18:20

developer  

cmdobj.tar (112,640 bytes)

gpittman

2012-01-31 18:24

developer  

paste2all.py (2,302 bytes)   
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# File: paste2all.py
# © 2012.01.29 Gregory Pittman
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
"""
USAGE
You must have a document open. Select a single object. Run the script, which asks whether you want

all, odd, or even pages to get a copy of the selected object (no copy is made to the original

page of the object). Any other input is ignored. When pasted, the copies go to the same page

coordinates of the original.

The script does not work with groups, and in fact Scribus will hang and then crash if you have

selected a group. If you select more than one item without grouping, only one of those

will be copied and pasted.



"""
import scribus

if scribus.haveDoc():


    if scribus.selectionCount() == 0:
        scribus.messageBox('Scribus - Usage Error',
                           "There is no object selected.\nPlease try again.",
                           scribus.ICON_WARNING, scribus.BUTTON_OK)
        sys.exit(2)
    if scribus.selectionCount() > 1:
	scribus.messageBox('Scribus - Usage Error', "You have more than one object selected.\nPlease select one text frame and try again.", scribus.ICON_WARNING, scribus.BUTTON_OK)
	sys.exit(2)
    paste2 = scribus.valueDialog('Paste to...',"Paste where?\n(all, odd, even)","all")
    selframe = scribus.getSelectedObject()
    pages = scribus.pageCount()
    currpage = scribus.currentPage()
    scribus.copyObject(selframe)
    if (paste2 == 'all'):
	i = 1
	while (i <= pages):
	    if (i != currpage):
		scribus.gotoPage(i)
		scribus.pasteObject(selframe)
	    i=i+1
    elif (paste2 == 'odd'):
	i = 1
	while (i <= pages):
	    if (i != currpage):
		scribus.gotoPage(i)
		scribus.pasteObject(selframe)
	    i=i+2
    elif (paste2 == 'even'):
	i = 2
	while (i <= pages):
	    if (i != currpage):
		scribus.gotoPage(i)
		scribus.pasteObject(selframe)
	    i=i+2
    scribus.setRedraw(1)
    scribus.docChanged(1)
    scribus.messageBox("Finished", "Done",icon=0,button1=1)

else:
    scribus.messageBox('Usage Error', 'You need a Document open', icon=0, button1=1)
    sys.exit(2)
paste2all.py (2,302 bytes)   

gpittman

2012-01-31 18:25

developer   ~0027636

Last edited: 2012-01-31 20:40

I've uploaded the script here also, since I find that copying and pasting scripts from the wiki isn't always so easy.

gpittman

2012-03-23 00:36

developer  

paste2pagelist.py (2,212 bytes)   
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# File: paste2pagelist.py
# © 2012.03.22 Gregory Pittman
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
"""
USAGE
You must have a document open. Select a single object. Run the script, which asks for a list

of page numbers -- do not use commas to separate, just whitespace.

When pasted, the copies go to the same page coordinates of the original.

The script does not work with groups, and in fact Scribus will hang and then crash if you have

selected a group. If you select more than one item without grouping, only one of those

will be copied and pasted.



"""
import scribus

if scribus.haveDoc():


    if scribus.selectionCount() == 0:
        scribus.messageBox('Scribus - Usage Error',
                           "There is no object selected.\nPlease try again.",
                           scribus.ICON_WARNING, scribus.BUTTON_OK)
        sys.exit(2)
    if scribus.selectionCount() > 1:
	scribus.messageBox('Scribus - Usage Error', "You have more than one object selected.\nPlease select one text frame and try again.", scribus.ICON_WARNING, scribus.BUTTON_OK)
	sys.exit(2)
    pagelist = scribus.valueDialog('Paste to...',"Paste to which pages?\n(page numbers, separated by white space)","1")
    pageslist = pagelist.split()
    selframe = scribus.getSelectedObject()
    pages = scribus.pageCount()
    for p in pageslist:
        p_no = int(p)
        if ((p_no > pages) or (p_no < 1)):
            scribus.messageBox('OOPS!', "You have a page number outside the range of pages in your document", scribus.ICON_WARNING, scribus.BUTTON_OK)
            sys.exit(2)
    currpage = scribus.currentPage()
    scribus.copyObject(selframe)

    for p in pageslist:
	p_no = int(p)
	scribus.gotoPage(p_no)
	scribus.pasteObject(selframe)
    scribus.setRedraw(1)
    scribus.docChanged(1)
    scribus.messageBox("Finished", "Done",icon=0,button1=1)

else:
    scribus.messageBox('Usage Error', 'You need a Document open', icon=0, button1=1)
    sys.exit(2)
paste2pagelist.py (2,212 bytes)   

gpittman

2012-03-23 00:37

developer   ~0027850

I have now added another script, paste2pagelist.py, which allows you to paste to a list of pages entered in a valueDialog. There is error checking to make sure all page numbers are in the correct range.

cbradney

2014-06-03 20:18

administrator   ~0031982

Greg.. can you perhaps create diffs against current SVN for 1.5 and I will commit these?

gpittman

2014-06-09 16:02

developer   ~0032058

I've started looking at this.
One issue of course is that these were created for 1.4.1, and even so, 1.4.4 has a lot of mods since 2012.

Nonetheless, I can still go back and make the necessary mods to 1.5.0svn, then submit the patch. My plan will be to only submit here the changes for cmdobject.h, cmdobject.cpp, and scriptplugin.cpp. I can commit the doc changes myself once the code is committed.

gpittman

2014-06-15 02:06

developer   ~0032169

Last edited: 2014-06-15 02:12

Ok, I've gone through the old files, and inserted necessary parts to the 1.5.0 code.
Am uploading a patchfile.

I've checked this out with my scripts paste2all.py and paste2list.py and seems to work fine. These are on the wiki page linked to above in this bug report.

gpittman

2014-06-15 02:07

developer  

patchfile (4,968 bytes)   
Index: scribus/plugins/scriptplugin/cmdobj.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdobj.cpp	(revision 19217)
+++ scribus/plugins/scriptplugin/cmdobj.cpp	(working copy)
@@ -715,6 +715,54 @@
 	Py_RETURN_NONE;
 }
 
+PyObject *scribus_copyobject(PyObject * /* self */, PyObject *args)
+{
+	char* name = const_cast<char*>("");
+	if (!PyArg_ParseTuple(args, "|es", "utf-8", &name)) {
+		return NULL;
+	}
+	if(!checkHaveDocument()) {
+		return NULL;
+	}
+	// Is there a special name given? Yes -> add this to selection
+	PageItem *i = GetUniqueItem(QString::fromUtf8(name));
+	if (i != NULL) {
+		ScCore->primaryMainWindow()->doc->m_Selection->clear();
+		ScCore->primaryMainWindow()->doc->m_Selection->addItem(i);
+	}
+	else
+		return NULL;
+	// do the duplicate
+	ScCore->primaryMainWindow()->slotEditCopy();
+//	Py_INCREF(Py_None);
+//	return Py_None;
+	Py_RETURN_NONE;
+}
+
+PyObject *scribus_pasteobject(PyObject * /* self */, PyObject *args)
+{
+	char* name = const_cast<char*>("");
+	if (!PyArg_ParseTuple(args, "|es", "utf-8", &name)) {
+		return NULL;
+	}
+	if(!checkHaveDocument()) {
+		return NULL;
+	}
+	// Is there a special name given? Yes -> add this to selection
+	PageItem *i = GetUniqueItem(QString::fromUtf8(name));
+	if (i != NULL) {
+		ScCore->primaryMainWindow()->doc->m_Selection->clear();
+		ScCore->primaryMainWindow()->doc->m_Selection->addItem(i);
+	}
+	else
+		return NULL;
+	// do the duplicate
+	ScCore->primaryMainWindow()->slotEditPaste();
+//	Py_INCREF(Py_None);
+//	return Py_None;
+	Py_RETURN_NONE;
+}
+
 /*! HACK: this removes "warning: 'blah' defined but not used" compiler warnings
 with header files structure untouched (docstrings are kept near declarations)
 PV */
@@ -721,5 +769,5 @@
 void cmdobjdocwarnings()
 {
     QStringList s;
-	s << scribus_newrect__doc__ <<scribus_newellipse__doc__ << scribus_newimage__doc__ << scribus_newtext__doc__ << scribus_newtable__doc__ << scribus_newline__doc__ <<scribus_polyline__doc__ << scribus_polygon__doc__ << scribus_bezierline__doc__ <<scribus_pathtext__doc__ <<scribus_deleteobj__doc__ <<scribus_textflow__doc__ <<scribus_objectexists__doc__ <<scribus_setstyle__doc__ <<scribus_getstylenames__doc__ <<scribus_getcharstylenames__doc__ <<scribus_duplicateobject__doc__;
+	s << scribus_newrect__doc__ <<scribus_newellipse__doc__ << scribus_newimage__doc__ << scribus_newtext__doc__ << scribus_newtable__doc__ << scribus_newline__doc__ <<scribus_polyline__doc__ << scribus_polygon__doc__ << scribus_bezierline__doc__ <<scribus_pathtext__doc__ <<scribus_deleteobj__doc__ <<scribus_textflow__doc__ <<scribus_objectexists__doc__ <<scribus_setstyle__doc__ <<scribus_getstylenames__doc__ <<scribus_getcharstylenames__doc__ <<scribus_duplicateobject__doc__ <<scribus_copyobject__doc__ <<scribus_pasteobject__doc__;
 }
Index: scribus/plugins/scriptplugin/cmdobj.h
===================================================================
--- scribus/plugins/scriptplugin/cmdobj.h	(revision 19217)
+++ scribus/plugins/scriptplugin/cmdobj.h	(working copy)
@@ -282,6 +282,30 @@
 */
 PyObject *scribus_duplicateobject(PyObject * /* self */, PyObject *args);
 
+/*! docstring */
+PyDoc_STRVAR(scribus_copyobject__doc__,
+QT_TR_NOOP("copyObject([\"name\"]) -> string\n\
+\n\
+copies the selected Object (or Selection Group).\n\
+"));
+/**
+ Gregory Pittman, 2012-01-12
+ copy an object
+*/
+PyObject *scribus_copyobject(PyObject * /* self */, PyObject *args);
+
+/*! docstring */
+PyDoc_STRVAR(scribus_pasteobject__doc__,
+QT_TR_NOOP("pasteObject([\"name\"]) -> string\n\
+\n\
+pastes a Duplicate of the selected Object (or Selection Group).\n\
+"));
+/**
+ Gregory Pittman, 2012-01-29
+ pastes an object
+*/
+PyObject *scribus_pasteobject(PyObject * /* self */, PyObject *args);
+
 /* Internal function not intended for general use; no docstring */
 PyObject* scribus_getframetype(PyObject* self, PyObject* args, PyObject* kw);
 
Index: scribus/plugins/scriptplugin/scriptplugin.cpp
===================================================================
--- scribus/plugins/scriptplugin/scriptplugin.cpp	(revision 19217)
+++ scribus/plugins/scriptplugin/scriptplugin.cpp	(working copy)
@@ -559,6 +559,8 @@
 // 	{const_cast<char*>("getChild"), (PyCFunction)scribus_getchild, METH_KEYWORDS, tr(scribus_getchild__doc__)},
 	// by Christian Hausknecht
 	{const_cast<char*>("duplicateObject"), scribus_duplicateobject, METH_VARARGS, tr(scribus_duplicateobject__doc__)},
+	{const_cast<char*>("copyObject"), scribus_copyobject, METH_VARARGS, tr(scribus_copyobject__doc__)},
+	{const_cast<char*>("pasteObject"), scribus_pasteobject, METH_VARARGS, tr(scribus_pasteobject__doc__)},
 	// Internal methods - Not for public use
 	{const_cast<char*>("retval"), (PyCFunction)scribus_retval, METH_VARARGS, const_cast<char*>("Scribus internal.")},
 	{const_cast<char*>("getval"), (PyCFunction)scribus_getval, METH_NOARGS, const_cast<char*>("Scribus internal.")},
patchfile (4,968 bytes)   

gpittman

2014-06-15 02:25

developer   ~0032170

Last edited: 2014-06-15 02:27

Something I just discovered is that the scripts DO work with a selected group!
Perhaps something in 1.5.0 corrected this former problem.

I'll update the wiki page once this patch is committed.

ale

2014-06-16 06:14

manager   ~0032194

just one note: i see this as a potential "dangerous" command.

people will copy in a loop and paste afterwards... wondering why they're only getting the last element.

personally, from a programming point of view, i would prefer not to have this in, but (if needed) improve the duplication and placement of the items.

the workflow in a program should in my eyes be: duplicate and keep a reference to the new item. when you're ready move the referenced item to the new page / place.
copying an item to the scrapbook and getting it back from there seems to be very inflexible to me, when i can reference items with variables...

... of course, i might ignore a use case that does not fit the duplicate and move model :-) if there is one, then the copy paste is also ok!

gpittman

2014-06-16 11:49

developer   ~0032196

Last edited: 2014-06-16 11:59

Just because a command exists doesn't mean it must be used. I think the scripts I wrote demonstrate the utility of these commands.

Trials have shown using the scripts that I wrote show that the script is undoable - you just repeatedly Undo to remove copies from last to first.

I don't understand the danger -- you copy to the clipboard, then paste one or multiple times. Why someone would serially copy objects then later try to paste them serially makes no sense to me.

There are more dangerous commands than these.

copyObject() is the same as pressing Ctrl-C
pasteObject() the same as Ctrl-V

ale

2014-06-17 09:22

manager   ~0032212

as far as i know, there is nothing like ctrl-c and ctrl-v as such in programming.
... there must be good reasons for it...
(even if languages like actionscript might implement it... :-)


for sure, i see the reasons why you like to have those commands.

but i still prefer not to have those in the scripter API: the main reason being that using duplicate and references to the created objects, allows python to catch some of the possible errors.

while copy/paste is wonderful for simple cases, it might fail in unexpected and hard to debug ways in more complicated scripts:

def do_something:
  copy
  ...
  paste

copy
do_something
paste

this is imo a very common -- even if not 100% clean -- pattern for scripts that are duplicating content.
and it will fail :-(
and it will be hard to spot if you script is a few dozens of lines long...

ale

2014-06-17 09:38

manager   ~0032213

Last edited: 2014-06-17 11:19

p.s.: it's clear, not because the scripter gets copy / paste that it will be a bad scripter... but i would not add "dangerous" commands, when alternatives already exist, that are almost as simple and safer...

i would rather well document how to do copy paste with the existing duplicate command...

gpittman

2014-06-17 17:12

developer   ~0032222

1. copy-paste with duplicate isn't possible. It's why I submitted this feature request.

2. I am still trying to understand why you are attacking this feature. Please show us a script that causes the havoc you envision.

copy
do something
paste
 
is not a functioning script. You seem to be trying to file a bug report on this not-yet-included feature, but without any concrete example of how you see it failing. Can you write such a script for us to examine?

ale

2014-06-17 18:37

manager   ~0032223

greg, i'm sorry, that your are feeling that i'm attacking this feature.

i have looked a bit deeper into the issue and indeed scribus seems to be missing a command: moving an object to a specific page.

ciao
a.l.e

JLuc

2014-07-06 17:01

developer   ~0032501

Ale : they are such commands that go very much like copy 'n' paste in various languages : its push and pull. Push some object on a stack, and pull it back when needed. For some languages as forth, its the main data management process.

Kunda

2014-07-09 22:24

updater   ~0032639

Reminder sent to: gpittman

Is this merged in to trunk and resolved?

gpittman

2014-07-10 01:31

developer   ~0032646

Commands have been added to 1.5.0svn

Kunda

2014-07-21 00:25

updater   ~0032853

Closing

Issue History

Date Modified Username Field Change
2012-01-31 18:20 gpittman New Issue
2012-01-31 18:20 gpittman File Added: cmdobj.tar
2012-01-31 18:24 gpittman File Added: paste2all.py
2012-01-31 18:25 gpittman Note Added: 0027636
2012-01-31 20:40 gpittman Note Edited: 0027636
2012-03-23 00:36 gpittman File Added: paste2pagelist.py
2012-03-23 00:37 gpittman Note Added: 0027850
2012-05-29 23:40 plinnell Assigned To => plinnell
2012-05-29 23:40 plinnell Status new => assigned
2014-06-03 20:18 cbradney Note Added: 0031982
2014-06-09 16:02 gpittman Note Added: 0032058
2014-06-15 02:06 gpittman Note Added: 0032169
2014-06-15 02:07 gpittman File Added: patchfile
2014-06-15 02:12 gpittman Note Edited: 0032169
2014-06-15 02:12 gpittman Note Edited: 0032169
2014-06-15 02:25 gpittman Note Added: 0032170
2014-06-15 02:27 gpittman Note Edited: 0032170
2014-06-16 06:14 ale Note Added: 0032194
2014-06-16 11:49 gpittman Note Added: 0032196
2014-06-16 11:59 gpittman Note Edited: 0032196
2014-06-17 09:22 ale Note Added: 0032212
2014-06-17 09:38 ale Note Added: 0032213
2014-06-17 11:19 ale Note Edited: 0032213
2014-06-17 17:12 gpittman Note Added: 0032222
2014-06-17 18:37 ale Note Added: 0032223
2014-07-06 17:01 JLuc Note Added: 0032501
2014-07-09 22:24 Kunda Note Added: 0032639
2014-07-10 01:31 gpittman Note Added: 0032646
2014-07-10 01:31 gpittman Status assigned => resolved
2014-07-10 01:31 gpittman Fixed in Version => 1.5.0
2014-07-10 01:31 gpittman Resolution open => fixed
2014-07-21 00:25 Kunda Note Added: 0032853
2014-07-21 00:25 Kunda Status resolved => closed
2014-08-20 23:35 jghali Fixed in Version 1.5.0 => 1.5.0svn